Add `-lgc' to `Libs' in `guile-2.0.pc'.
[bpt/guile.git] / libguile / socket.c
CommitLineData
2fa901a5 1/* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
86667910 2 *
73be1d9e 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
86667910 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
86667910 12 *
73be1d9e
MV
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
73be1d9e 17 */
1bbd0b84 18
1bbd0b84 19
0f2d19dd
JB
20\f
21
dbb605f5 22#ifdef HAVE_CONFIG_H
eccde741
RB
23# include <config.h>
24#endif
25
e6e2e95a 26#include <errno.h>
69d49ac8 27#include <gmp.h>
e6e2e95a 28
a0599745 29#include "libguile/_scm.h"
2fa901a5 30#include "libguile/arrays.h"
a0599745
MD
31#include "libguile/feature.h"
32#include "libguile/fports.h"
33#include "libguile/strings.h"
34#include "libguile/vectors.h"
7f9994d9 35#include "libguile/dynwind.h"
587a3355 36#include "libguile/srfi-13.h"
20e6290e 37
a0599745
MD
38#include "libguile/validate.h"
39#include "libguile/socket.h"
95b88819 40
b4e15479
SJ
41#ifdef __MINGW32__
42#include "win32-socket.h"
43#endif
44
af68e5e5
SJ
45#ifdef HAVE_STDINT_H
46#include <stdint.h>
47#endif
95b88819
GH
48#ifdef HAVE_STRING_H
49#include <string.h>
50#endif
370312ae
GH
51#ifdef HAVE_UNISTD_H
52#include <unistd.h>
53#endif
0f2d19dd 54#include <sys/types.h>
f87c105a 55#ifdef HAVE_WINSOCK2_H
82893676
MG
56#include <winsock2.h>
57#else
0f2d19dd 58#include <sys/socket.h>
1ba8c23a 59#ifdef HAVE_UNIX_DOMAIN_SOCKETS
0f2d19dd 60#include <sys/un.h>
0e958795 61#endif
0f2d19dd
JB
62#include <netinet/in.h>
63#include <netdb.h>
64#include <arpa/inet.h>
82893676 65#endif
0f2d19dd 66
97d0e20b
GH
67#if defined (HAVE_UNIX_DOMAIN_SOCKETS) && !defined (SUN_LEN)
68#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
69 + strlen ((ptr)->sun_path))
70#endif
71
f43f3620
LC
72/* The largest possible socket address. Wrapping it in a union guarantees
73 that the compiler will make it suitably aligned. */
74typedef union
75{
76 struct sockaddr sockaddr;
77 struct sockaddr_in sockaddr_in;
78
79#ifdef HAVE_UNIX_DOMAIN_SOCKETS
80 struct sockaddr_un sockaddr_un;
81#endif
82#ifdef HAVE_IPV6
83 struct sockaddr_in6 sockaddr_in6;
84#endif
85} scm_t_max_sockaddr;
86
87
88/* Maximum size of a socket address. */
89#define MAX_ADDR_SIZE (sizeof (scm_t_max_sockaddr))
90
91
0f2d19dd
JB
92\f
93
a1ec6916 94SCM_DEFINE (scm_htons, "htons", 1, 0, 0,
eefae538
GH
95 (SCM value),
96 "Convert a 16 bit quantity from host to network byte ordering.\n"
97 "@var{value} is packed into 2 bytes, which are then converted\n"
98 "and returned as a new integer.")
1bbd0b84 99#define FUNC_NAME s_scm_htons
5c11cc9d 100{
7cee5b31 101 return scm_from_ushort (htons (scm_to_ushort (value)));
5c11cc9d 102}
1bbd0b84 103#undef FUNC_NAME
5c11cc9d 104
a1ec6916 105SCM_DEFINE (scm_ntohs, "ntohs", 1, 0, 0,
eefae538
GH
106 (SCM value),
107 "Convert a 16 bit quantity from network to host byte ordering.\n"
108 "@var{value} is packed into 2 bytes, which are then converted\n"
109 "and returned as a new integer.")
1bbd0b84 110#define FUNC_NAME s_scm_ntohs
5c11cc9d 111{
7cee5b31 112 return scm_from_ushort (ntohs (scm_to_ushort (value)));
5c11cc9d 113}
1bbd0b84 114#undef FUNC_NAME
5c11cc9d 115
a1ec6916 116SCM_DEFINE (scm_htonl, "htonl", 1, 0, 0,
eefae538
GH
117 (SCM value),
118 "Convert a 32 bit quantity from host to network byte ordering.\n"
119 "@var{value} is packed into 4 bytes, which are then converted\n"
120 "and returned as a new integer.")
1bbd0b84 121#define FUNC_NAME s_scm_htonl
5c11cc9d 122{
8ab3d8a0 123 return scm_from_ulong (htonl (scm_to_uint32 (value)));
5c11cc9d 124}
1bbd0b84 125#undef FUNC_NAME
5c11cc9d 126
a1ec6916 127SCM_DEFINE (scm_ntohl, "ntohl", 1, 0, 0,
eefae538
GH
128 (SCM value),
129 "Convert a 32 bit quantity from network to host byte ordering.\n"
130 "@var{value} is packed into 4 bytes, which are then converted\n"
131 "and returned as a new integer.")
1bbd0b84 132#define FUNC_NAME s_scm_ntohl
5c11cc9d 133{
8ab3d8a0 134 return scm_from_ulong (ntohl (scm_to_uint32 (value)));
5c11cc9d 135}
1bbd0b84 136#undef FUNC_NAME
5c11cc9d 137
66c73b76
GH
138#ifdef HAVE_INET_NETOF
139SCM_DEFINE (scm_inet_netof, "inet-netof", 1, 0, 0,
140 (SCM address),
eefae538
GH
141 "Return the network number part of the given IPv4\n"
142 "Internet address. E.g.,\n\n"
66c73b76
GH
143 "@lisp\n"
144 "(inet-netof 2130706433) @result{} 127\n"
145 "@end lisp")
146#define FUNC_NAME s_scm_inet_netof
147{
148 struct in_addr addr;
149 addr.s_addr = htonl (SCM_NUM2ULONG (1, address));
b9bd8526 150 return scm_from_ulong (inet_netof (addr));
66c73b76
GH
151}
152#undef FUNC_NAME
153#endif
154
155#ifdef HAVE_INET_LNAOF
156SCM_DEFINE (scm_lnaof, "inet-lnaof", 1, 0, 0,
157 (SCM address),
158 "Return the local-address-with-network part of the given\n"
eefae538
GH
159 "IPv4 Internet address, using the obsolete class A/B/C system.\n"
160 "E.g.,\n\n"
66c73b76
GH
161 "@lisp\n"
162 "(inet-lnaof 2130706433) @result{} 1\n"
163 "@end lisp")
164#define FUNC_NAME s_scm_lnaof
165{
166 struct in_addr addr;
167 addr.s_addr = htonl (SCM_NUM2ULONG (1, address));
b9bd8526 168 return scm_from_ulong (inet_lnaof (addr));
66c73b76
GH
169}
170#undef FUNC_NAME
171#endif
172
173#ifdef HAVE_INET_MAKEADDR
174SCM_DEFINE (scm_inet_makeaddr, "inet-makeaddr", 2, 0, 0,
175 (SCM net, SCM lna),
eefae538 176 "Make an IPv4 Internet address by combining the network number\n"
66c73b76 177 "@var{net} with the local-address-within-network number\n"
eefae538 178 "@var{lna}. E.g.,\n\n"
66c73b76
GH
179 "@lisp\n"
180 "(inet-makeaddr 127 1) @result{} 2130706433\n"
181 "@end lisp")
182#define FUNC_NAME s_scm_inet_makeaddr
183{
184 struct in_addr addr;
185 unsigned long netnum;
186 unsigned long lnanum;
187
188 netnum = SCM_NUM2ULONG (1, net);
189 lnanum = SCM_NUM2ULONG (2, lna);
190 addr = inet_makeaddr (netnum, lnanum);
b9bd8526 191 return scm_from_ulong (ntohl (addr.s_addr));
66c73b76
GH
192}
193#undef FUNC_NAME
194#endif
195
a57a0b1e 196#ifdef HAVE_IPV6
eefae538 197
66c73b76
GH
198/* flip a 128 bit IPv6 address between host and network order. */
199#ifdef WORDS_BIGENDIAN
200#define FLIP_NET_HOST_128(addr)
201#else
202#define FLIP_NET_HOST_128(addr)\
203{\
204 int i;\
205 \
206 for (i = 0; i < 8; i++)\
207 {\
2de4f939 208 scm_t_uint8 c = (addr)[i];\
66c73b76
GH
209 \
210 (addr)[i] = (addr)[15 - i];\
211 (addr)[15 - i] = c;\
212 }\
213}
214#endif
215
2de4f939
RB
216#ifdef WORDS_BIGENDIAN
217#define FLIPCPY_NET_HOST_128(dest, src) memcpy (dest, src, 16)
218#else
219#define FLIPCPY_NET_HOST_128(dest, src) \
220{ \
221 const scm_t_uint8 *tmp_srcp = (src) + 15; \
222 scm_t_uint8 *tmp_destp = (dest); \
223 \
224 do { \
225 *tmp_destp++ = *tmp_srcp--; \
226 } while (tmp_srcp != (src)); \
227}
228#endif
229
230
7310ad0c 231#if (SIZEOF_SCM_T_BITS * SCM_CHAR_BIT) > 128
2de4f939
RB
232#error "Assumption that scm_t_bits <= 128 bits has been violated."
233#endif
234
7310ad0c 235#if (SIZEOF_UNSIGNED_LONG * SCM_CHAR_BIT) > 128
2de4f939
RB
236#error "Assumption that unsigned long <= 128 bits has been violated."
237#endif
238
7310ad0c 239#if (SIZEOF_UNSIGNED_LONG_LONG * SCM_CHAR_BIT) > 128
2de4f939
RB
240#error "Assumption that unsigned long long <= 128 bits has been violated."
241#endif
242
66c73b76
GH
243/* convert a 128 bit IPv6 address in network order to a host ordered
244 SCM integer. */
7cee5b31
MV
245static SCM
246scm_from_ipv6 (const scm_t_uint8 *src)
66c73b76 247{
2b4d1547
KR
248 SCM result = scm_i_mkbig ();
249 mpz_import (SCM_I_BIG_MPZ (result),
250 1, /* chunk */
251 1, /* big-endian chunk ordering */
252 16, /* chunks are 16 bytes long */
253 1, /* big-endian byte ordering */
254 0, /* "nails" -- leading unused bits per chunk */
255 src);
256 return scm_i_normbig (result);
257}
66c73b76
GH
258
259/* convert a host ordered SCM integer to a 128 bit IPv6 address in
260 network order. */
7cee5b31
MV
261static void
262scm_to_ipv6 (scm_t_uint8 dst[16], SCM src)
66c73b76 263{
e11e83f3 264 if (SCM_I_INUMP (src))
66c73b76 265 {
e11e83f3 266 scm_t_signed_bits n = SCM_I_INUM (src);
7cee5b31
MV
267 if (n < 0)
268 scm_out_of_range (NULL, src);
2de4f939
RB
269#ifdef WORDS_BIGENDIAN
270 memset (dst, 0, 16 - sizeof (scm_t_signed_bits));
271 memcpy (dst + (16 - sizeof (scm_t_signed_bits)),
272 &n,
273 sizeof (scm_t_signed_bits));
274#else
275 memset (dst + sizeof (scm_t_signed_bits),
276 0,
277 16 - sizeof (scm_t_signed_bits));
278 /* FIXME: this pair of ops is kinda wasteful -- should rewrite as
279 a single loop perhaps, similar to the handling of bignums. */
280 memcpy (dst, &n, sizeof (scm_t_signed_bits));
281 FLIP_NET_HOST_128 (dst);
282#endif
66c73b76 283 }
7cee5b31 284 else if (SCM_BIGP (src))
66c73b76 285 {
2de4f939 286 size_t count;
7cee5b31
MV
287
288 if ((mpz_sgn (SCM_I_BIG_MPZ (src)) < 0)
289 || mpz_sizeinbase (SCM_I_BIG_MPZ (src), 2) > 128)
290 scm_out_of_range (NULL, src);
291
66c73b76 292 memset (dst, 0, 16);
2de4f939
RB
293 mpz_export (dst,
294 &count,
295 1, /* big-endian chunk ordering */
296 16, /* chunks are 16 bytes long */
297 1, /* big-endian byte ordering */
298 0, /* "nails" -- leading unused bits per chunk */
299 SCM_I_BIG_MPZ (src));
300 scm_remember_upto_here_1 (src);
66c73b76 301 }
2de4f939 302 else
1ff4da65 303 scm_wrong_type_arg_msg ("scm_to_ipv6", 0, src, "integer");
2de4f939
RB
304}
305
66c73b76
GH
306SCM_DEFINE (scm_inet_pton, "inet-pton", 2, 0, 0,
307 (SCM family, SCM address),
eefae538
GH
308 "Convert a string containing a printable network address to\n"
309 "an integer address. Note that unlike the C version of this\n"
310 "function,\n"
66c73b76 311 "the result is an integer with normal host byte ordering.\n"
eefae538 312 "@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g.,\n\n"
66c73b76 313 "@lisp\n"
dd85ce47
ML
314 "(inet-pton AF_INET \"127.0.0.1\") @result{} 2130706433\n"
315 "(inet-pton AF_INET6 \"::1\") @result{} 1\n"
66c73b76
GH
316 "@end lisp")
317#define FUNC_NAME s_scm_inet_pton
318{
319 int af;
320 char *src;
f43f3620 321 scm_t_uint32 dst[4];
396e5506 322 int rv, eno;
66c73b76 323
7cee5b31 324 af = scm_to_int (family);
66c73b76 325 SCM_ASSERT_RANGE (1, family, af == AF_INET || af == AF_INET6);
396e5506 326 src = scm_to_locale_string (address);
66c73b76 327 rv = inet_pton (af, src, dst);
396e5506
MV
328 eno = errno;
329 free (src);
330 errno = eno;
66c73b76
GH
331 if (rv == -1)
332 SCM_SYSERROR;
333 else if (rv == 0)
334 SCM_MISC_ERROR ("Bad address", SCM_EOL);
335 if (af == AF_INET)
f43f3620 336 return scm_from_ulong (ntohl (*dst));
66c73b76 337 else
5ee417fc 338 return scm_from_ipv6 ((scm_t_uint8 *) dst);
66c73b76
GH
339}
340#undef FUNC_NAME
66c73b76 341
66c73b76
GH
342SCM_DEFINE (scm_inet_ntop, "inet-ntop", 2, 0, 0,
343 (SCM family, SCM address),
eefae538 344 "Convert a network address into a printable string.\n"
66c73b76
GH
345 "Note that unlike the C version of this function,\n"
346 "the input is an integer with normal host byte ordering.\n"
eefae538 347 "@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g.,\n\n"
66c73b76 348 "@lisp\n"
dd85ce47 349 "(inet-ntop AF_INET 2130706433) @result{} \"127.0.0.1\"\n"
187a4390
NJ
350 "(inet-ntop AF_INET6 (- (expt 2 128) 1))\n"
351 " @result{} \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\"\n"
66c73b76
GH
352 "@end lisp")
353#define FUNC_NAME s_scm_inet_ntop
354{
355 int af;
356#ifdef INET6_ADDRSTRLEN
357 char dst[INET6_ADDRSTRLEN];
358#else
359 char dst[46];
360#endif
7a5fb796 361 const char *result;
66c73b76 362
7cee5b31 363 af = scm_to_int (family);
66c73b76
GH
364 SCM_ASSERT_RANGE (1, family, af == AF_INET || af == AF_INET6);
365 if (af == AF_INET)
7a5fb796
LC
366 {
367 scm_t_uint32 addr4;
368
369 addr4 = htonl (SCM_NUM2ULONG (2, address));
370 result = inet_ntop (af, &addr4, dst, sizeof (dst));
371 }
66c73b76 372 else
7a5fb796
LC
373 {
374 char addr6[16];
375
376 scm_to_ipv6 ((scm_t_uint8 *) addr6, address);
377 result = inet_ntop (af, &addr6, dst, sizeof (dst));
378 }
379
380 if (result == NULL)
66c73b76 381 SCM_SYSERROR;
7a5fb796 382
cc95e00a 383 return scm_from_locale_string (dst);
66c73b76
GH
384}
385#undef FUNC_NAME
66c73b76 386
a57a0b1e 387#endif /* HAVE_IPV6 */
eefae538 388
bc45012d 389SCM_SYMBOL (sym_socket, "socket");
82ddea4e 390
439006bf 391#define SCM_SOCK_FD_TO_PORT(fd) scm_fdes_to_port (fd, "r+0", sym_socket)
1bbd0b84 392
a1ec6916 393SCM_DEFINE (scm_socket, "socket", 3, 0, 0,
1bbd0b84 394 (SCM family, SCM style, SCM proto),
1e6808ea 395 "Return a new socket port of the type specified by @var{family},\n"
eefae538 396 "@var{style} and @var{proto}. All three parameters are\n"
3453619b
GH
397 "integers. Supported values for @var{family} are\n"
398 "@code{AF_UNIX}, @code{AF_INET} and @code{AF_INET6}.\n"
399 "Typical values for @var{style} are @code{SOCK_STREAM},\n"
eefae538
GH
400 "@code{SOCK_DGRAM} and @code{SOCK_RAW}.\n\n"
401 "@var{proto} can be obtained from a protocol name using\n"
1e6808ea 402 "@code{getprotobyname}. A value of zero specifies the default\n"
eefae538 403 "protocol, which is usually right.\n\n"
1e6808ea
MG
404 "A single socket port cannot by used for communication until it\n"
405 "has been connected to another socket.")
1bbd0b84 406#define FUNC_NAME s_scm_socket
0f2d19dd 407{
370312ae 408 int fd;
370312ae 409
7cee5b31
MV
410 fd = socket (scm_to_int (family),
411 scm_to_int (style),
412 scm_to_int (proto));
439006bf
GH
413 if (fd == -1)
414 SCM_SYSERROR;
415 return SCM_SOCK_FD_TO_PORT (fd);
0f2d19dd 416}
1bbd0b84 417#undef FUNC_NAME
0f2d19dd 418
0e958795 419#ifdef HAVE_SOCKETPAIR
a1ec6916 420SCM_DEFINE (scm_socketpair, "socketpair", 3, 0, 0,
1bbd0b84 421 (SCM family, SCM style, SCM proto),
1e6808ea 422 "Return a pair of connected (but unnamed) socket ports of the\n"
eefae538 423 "type specified by @var{family}, @var{style} and @var{proto}.\n"
1e6808ea
MG
424 "Many systems support only socket pairs of the @code{AF_UNIX}\n"
425 "family. Zero is likely to be the only meaningful value for\n"
eefae538 426 "@var{proto}.")
1bbd0b84 427#define FUNC_NAME s_scm_socketpair
0f2d19dd 428{
370312ae
GH
429 int fam;
430 int fd[2];
370312ae 431
7cee5b31 432 fam = scm_to_int (family);
370312ae 433
7cee5b31 434 if (socketpair (fam, scm_to_int (style), scm_to_int (proto), fd) == -1)
1bbd0b84 435 SCM_SYSERROR;
370312ae 436
439006bf 437 return scm_cons (SCM_SOCK_FD_TO_PORT (fd[0]), SCM_SOCK_FD_TO_PORT (fd[1]));
0f2d19dd 438}
1bbd0b84 439#undef FUNC_NAME
0e958795 440#endif
0f2d19dd 441
f43f3620
LC
442/* Possible results for `getsockopt ()'. Wrapping it into a union guarantees
443 suitable alignment. */
444typedef union
445{
446#ifdef HAVE_STRUCT_LINGER
447 struct linger linger;
448#endif
449 size_t size;
450 int integer;
451} scm_t_getsockopt_result;
452
a1ec6916 453SCM_DEFINE (scm_getsockopt, "getsockopt", 3, 0, 0,
1bbd0b84 454 (SCM sock, SCM level, SCM optname),
72e3dae1
KR
455 "Return an option value from socket port @var{sock}.\n"
456 "\n"
457 "@var{level} is an integer specifying a protocol layer, either\n"
458 "@code{SOL_SOCKET} for socket level options, or a protocol\n"
459 "number from the @code{IPPROTO} constants or @code{getprotoent}\n"
460 "(@pxref{Network Databases}).\n"
461 "\n"
462 "@defvar SOL_SOCKET\n"
463 "@defvarx IPPROTO_IP\n"
464 "@defvarx IPPROTO_TCP\n"
465 "@defvarx IPPROTO_UDP\n"
466 "@end defvar\n"
467 "\n"
468 "@var{optname} is an integer specifying an option within the\n"
469 "protocol layer.\n"
470 "\n"
471 "For @code{SOL_SOCKET} level the following @var{optname}s are\n"
472 "defined (when provided by the system). For their meaning see\n"
473 "@ref{Socket-Level Options,,, libc, The GNU C Library Reference\n"
474 "Manual}, or @command{man 7 socket}.\n"
475 "\n"
476 "@defvar SO_DEBUG\n"
477 "@defvarx SO_REUSEADDR\n"
478 "@defvarx SO_STYLE\n"
479 "@defvarx SO_TYPE\n"
480 "@defvarx SO_ERROR\n"
481 "@defvarx SO_DONTROUTE\n"
482 "@defvarx SO_BROADCAST\n"
483 "@defvarx SO_SNDBUF\n"
484 "@defvarx SO_RCVBUF\n"
485 "@defvarx SO_KEEPALIVE\n"
486 "@defvarx SO_OOBINLINE\n"
487 "@defvarx SO_NO_CHECK\n"
488 "@defvarx SO_PRIORITY\n"
489 "The value returned is an integer.\n"
490 "@end defvar\n"
491 "\n"
492 "@defvar SO_LINGER\n"
493 "The @var{value} returned is a pair of integers\n"
494 "@code{(@var{ENABLE} . @var{TIMEOUT})}. On old systems without\n"
495 "timeout support (ie.@: without @code{struct linger}), only\n"
496 "@var{ENABLE} has an effect but the value in Guile is always a\n"
497 "pair.\n"
498 "@end defvar")
1bbd0b84 499#define FUNC_NAME s_scm_getsockopt
0f2d19dd 500{
370312ae 501 int fd;
439006bf 502 /* size of optval is the largest supported option. */
f43f3620
LC
503 scm_t_getsockopt_result optval;
504 socklen_t optlen = sizeof (optval);
370312ae
GH
505 int ilevel;
506 int ioptname;
0f2d19dd 507
78446828 508 sock = SCM_COERCE_OUTPORT (sock);
2cf6d014 509 SCM_VALIDATE_OPFPORT (1, sock);
7cee5b31
MV
510 ilevel = scm_to_int (level);
511 ioptname = scm_to_int (optname);
0f2d19dd 512
ee149d03 513 fd = SCM_FPORT_FDES (sock);
f43f3620 514 if (getsockopt (fd, ilevel, ioptname, (void *) &optval, &optlen) == -1)
1bbd0b84 515 SCM_SYSERROR;
1cc91f1b 516
439006bf 517 if (ilevel == SOL_SOCKET)
0f2d19dd 518 {
439006bf
GH
519#ifdef SO_LINGER
520 if (ioptname == SO_LINGER)
521 {
370312ae 522#ifdef HAVE_STRUCT_LINGER
f43f3620 523 struct linger *ling = (struct linger *) &optval;
439006bf 524
b9bd8526
MV
525 return scm_cons (scm_from_long (ling->l_onoff),
526 scm_from_long (ling->l_linger));
370312ae 527#else
f43f3620 528 return scm_cons (scm_from_long (*(int *) &optval),
7cee5b31 529 scm_from_int (0));
0f2d19dd 530#endif
439006bf
GH
531 }
532 else
370312ae 533#endif
439006bf 534 if (0
370312ae 535#ifdef SO_SNDBUF
439006bf 536 || ioptname == SO_SNDBUF
370312ae
GH
537#endif
538#ifdef SO_RCVBUF
439006bf 539 || ioptname == SO_RCVBUF
370312ae 540#endif
439006bf
GH
541 )
542 {
f43f3620 543 return scm_from_size_t (*(size_t *) &optval);
439006bf
GH
544 }
545 }
f43f3620 546 return scm_from_int (*(int *) &optval);
0f2d19dd 547}
1bbd0b84 548#undef FUNC_NAME
0f2d19dd 549
a1ec6916 550SCM_DEFINE (scm_setsockopt, "setsockopt", 4, 0, 0,
1bbd0b84 551 (SCM sock, SCM level, SCM optname, SCM value),
72e3dae1
KR
552 "Set an option on socket port @var{sock}. The return value is\n"
553 "unspecified.\n"
554 "\n"
555 "@var{level} is an integer specifying a protocol layer, either\n"
556 "@code{SOL_SOCKET} for socket level options, or a protocol\n"
557 "number from the @code{IPPROTO} constants or @code{getprotoent}\n"
558 "(@pxref{Network Databases}).\n"
559 "\n"
560 "@defvar SOL_SOCKET\n"
561 "@defvarx IPPROTO_IP\n"
562 "@defvarx IPPROTO_TCP\n"
563 "@defvarx IPPROTO_UDP\n"
564 "@end defvar\n"
565 "\n"
566 "@var{optname} is an integer specifying an option within the\n"
567 "protocol layer.\n"
568 "\n"
569 "For @code{SOL_SOCKET} level the following @var{optname}s are\n"
570 "defined (when provided by the system). For their meaning see\n"
571 "@ref{Socket-Level Options,,, libc, The GNU C Library Reference\n"
572 "Manual}, or @command{man 7 socket}.\n"
573 "\n"
574 "@defvar SO_DEBUG\n"
575 "@defvarx SO_REUSEADDR\n"
576 "@defvarx SO_STYLE\n"
577 "@defvarx SO_TYPE\n"
578 "@defvarx SO_ERROR\n"
579 "@defvarx SO_DONTROUTE\n"
580 "@defvarx SO_BROADCAST\n"
581 "@defvarx SO_SNDBUF\n"
582 "@defvarx SO_RCVBUF\n"
583 "@defvarx SO_KEEPALIVE\n"
584 "@defvarx SO_OOBINLINE\n"
585 "@defvarx SO_NO_CHECK\n"
586 "@defvarx SO_PRIORITY\n"
587 "@var{value} is an integer.\n"
588 "@end defvar\n"
589 "\n"
590 "@defvar SO_LINGER\n"
591 "@var{value} is a pair of integers @code{(@var{ENABLE}\n"
592 ". @var{TIMEOUT})}. On old systems without timeout support\n"
593 "(ie.@: without @code{struct linger}), only @var{ENABLE} has an\n"
594 "effect but the value in Guile is always a pair.\n"
595 "@end defvar\n"
596 "\n"
597 "@c Note that we refer only to ``man ip'' here. On GNU/Linux it's\n"
598 "@c ``man 7 ip'' but on NetBSD it's ``man 4 ip''.\n"
599 "@c \n"
600 "For IP level (@code{IPPROTO_IP}) the following @var{optname}s\n"
601 "are defined (when provided by the system). See @command{man\n"
602 "ip} for what they mean.\n"
603 "\n"
511246a1
TCM
604 "@defvar IP_MULTICAST_IF\n"
605 "This sets the source interface used by multicast traffic.\n"
606 "@end defvar\n"
607 "\n"
608 "@defvar IP_MULTICAST_TTL\n"
609 "This sets the default TTL for multicast traffic. This defaults \n"
610 "to 1 and should be increased to allow traffic to pass beyond the\n"
611 "local network.\n"
612 "@end defvar\n"
613 "\n"
72e3dae1
KR
614 "@defvar IP_ADD_MEMBERSHIP\n"
615 "@defvarx IP_DROP_MEMBERSHIP\n"
616 "These can be used only with @code{setsockopt}, not\n"
617 "@code{getsockopt}. @var{value} is a pair\n"
618 "@code{(@var{MULTIADDR} . @var{INTERFACEADDR})} of IPv4\n"
619 "addresses (@pxref{Network Address Conversion}).\n"
620 "@var{MULTIADDR} is a multicast address to be added to or\n"
621 "dropped from the interface @var{INTERFACEADDR}.\n"
622 "@var{INTERFACEADDR} can be @code{INADDR_ANY} to have the system\n"
623 "select the interface. @var{INTERFACEADDR} can also be an\n"
f1b7209b
KR
624 "interface index number, on systems supporting that.\n"
625 "@end defvar")
1bbd0b84 626#define FUNC_NAME s_scm_setsockopt
0f2d19dd 627{
370312ae 628 int fd;
1c80707c
MV
629
630 int opt_int;
370312ae 631#ifdef HAVE_STRUCT_LINGER
1c80707c 632 struct linger opt_linger;
370312ae 633#endif
ecc9f40f 634
56a3dcd4 635#ifdef HAVE_STRUCT_IP_MREQ
1c80707c 636 struct ip_mreq opt_mreq;
ecc9f40f 637#endif
1c80707c
MV
638
639 const void *optval = NULL;
640 socklen_t optlen = 0;
641
370312ae 642 int ilevel, ioptname;
439006bf 643
78446828 644 sock = SCM_COERCE_OUTPORT (sock);
439006bf
GH
645
646 SCM_VALIDATE_OPFPORT (1, sock);
7cee5b31
MV
647 ilevel = scm_to_int (level);
648 ioptname = scm_to_int (optname);
439006bf 649
ee149d03 650 fd = SCM_FPORT_FDES (sock);
1c80707c 651
439006bf 652 if (ilevel == SOL_SOCKET)
370312ae 653 {
439006bf
GH
654#ifdef SO_LINGER
655 if (ioptname == SO_LINGER)
656 {
370312ae 657#ifdef HAVE_STRUCT_LINGER
d2e53ed6 658 SCM_ASSERT (scm_is_pair (value), value, SCM_ARG4, FUNC_NAME);
1c80707c
MV
659 opt_linger.l_onoff = scm_to_int (SCM_CAR (value));
660 opt_linger.l_linger = scm_to_int (SCM_CDR (value));
661 optlen = sizeof (struct linger);
662 optval = &opt_linger;
370312ae 663#else
d2e53ed6 664 SCM_ASSERT (scm_is_pair (value), value, SCM_ARG4, FUNC_NAME);
1c80707c 665 opt_int = scm_to_int (SCM_CAR (value));
439006bf 666 /* timeout is ignored, but may as well validate it. */
1c80707c
MV
667 scm_to_int (SCM_CDR (value));
668 optlen = sizeof (int);
669 optval = &opt_int;
439006bf
GH
670#endif
671 }
672 else
673#endif
674 if (0
370312ae 675#ifdef SO_SNDBUF
439006bf 676 || ioptname == SO_SNDBUF
370312ae
GH
677#endif
678#ifdef SO_RCVBUF
439006bf 679 || ioptname == SO_RCVBUF
370312ae 680#endif
439006bf
GH
681 )
682 {
1c80707c
MV
683 opt_int = scm_to_int (value);
684 optlen = sizeof (size_t);
685 optval = &opt_int;
439006bf
GH
686 }
687 }
1c80707c 688
56a3dcd4 689#ifdef HAVE_STRUCT_IP_MREQ
1c80707c
MV
690 if (ilevel == IPPROTO_IP &&
691 (ioptname == IP_ADD_MEMBERSHIP || ioptname == IP_DROP_MEMBERSHIP))
0f2d19dd 692 {
1c80707c
MV
693 /* Fourth argument must be a pair of addresses. */
694 SCM_ASSERT (scm_is_pair (value), value, SCM_ARG4, FUNC_NAME);
695 opt_mreq.imr_multiaddr.s_addr = htonl (scm_to_ulong (SCM_CAR (value)));
696 opt_mreq.imr_interface.s_addr = htonl (scm_to_ulong (SCM_CDR (value)));
697 optlen = sizeof (opt_mreq);
698 optval = &opt_mreq;
699 }
ecc9f40f 700#endif
439006bf 701
1c80707c
MV
702 if (optval == NULL)
703 {
704 /* Most options take an int. */
705 opt_int = scm_to_int (value);
706 optlen = sizeof (int);
707 optval = &opt_int;
0f2d19dd 708 }
1c80707c
MV
709
710 if (setsockopt (fd, ilevel, ioptname, optval, optlen) == -1)
1bbd0b84 711 SCM_SYSERROR;
370312ae 712 return SCM_UNSPECIFIED;
0f2d19dd 713}
1bbd0b84 714#undef FUNC_NAME
0f2d19dd 715
a1ec6916 716SCM_DEFINE (scm_shutdown, "shutdown", 2, 0, 0,
1bbd0b84 717 (SCM sock, SCM how),
b380b885 718 "Sockets can be closed simply by using @code{close-port}. The\n"
bb2c02f2 719 "@code{shutdown} procedure allows reception or transmission on a\n"
b380b885
MD
720 "connection to be shut down individually, according to the parameter\n"
721 "@var{how}:\n\n"
722 "@table @asis\n"
723 "@item 0\n"
724 "Stop receiving data for this socket. If further data arrives, reject it.\n"
725 "@item 1\n"
726 "Stop trying to transmit data from this socket. Discard any\n"
727 "data waiting to be sent. Stop looking for acknowledgement of\n"
728 "data already sent; don't retransmit it if it is lost.\n"
729 "@item 2\n"
730 "Stop both reception and transmission.\n"
731 "@end table\n\n"
732 "The return value is unspecified.")
1bbd0b84 733#define FUNC_NAME s_scm_shutdown
0f2d19dd 734{
370312ae 735 int fd;
78446828 736 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 737 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 738 fd = SCM_FPORT_FDES (sock);
7cee5b31 739 if (shutdown (fd, scm_to_signed_integer (how, 0, 2)) == -1)
1bbd0b84 740 SCM_SYSERROR;
370312ae
GH
741 return SCM_UNSPECIFIED;
742}
1bbd0b84 743#undef FUNC_NAME
0f2d19dd 744
370312ae
GH
745/* convert fam/address/args into a sockaddr of the appropriate type.
746 args is modified by removing the arguments actually used.
747 which_arg and proc are used when reporting errors:
748 which_arg is the position of address in the original argument list.
749 proc is the name of the original procedure.
750 size returns the size of the structure allocated. */
751
bc732342 752static struct sockaddr *
439006bf 753scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
9c0129ac 754 const char *proc, size_t *size)
3453619b 755#define FUNC_NAME proc
370312ae
GH
756{
757 switch (fam)
0f2d19dd 758 {
370312ae
GH
759 case AF_INET:
760 {
370312ae 761 struct sockaddr_in *soka;
3453619b
GH
762 unsigned long addr;
763 int port;
370312ae 764
3453619b
GH
765 SCM_VALIDATE_ULONG_COPY (which_arg, address, addr);
766 SCM_VALIDATE_CONS (which_arg + 1, *args);
7cee5b31 767 port = scm_to_int (SCM_CAR (*args));
3453619b 768 *args = SCM_CDR (*args);
67329a9e 769 soka = (struct sockaddr_in *) scm_malloc (sizeof (struct sockaddr_in));
9c0129ac 770
56a3dcd4 771#ifdef HAVE_STRUCT_SOCKADDR_SIN_LEN
3453619b
GH
772 soka->sin_len = sizeof (struct sockaddr_in);
773#endif
370312ae 774 soka->sin_family = AF_INET;
3453619b
GH
775 soka->sin_addr.s_addr = htonl (addr);
776 soka->sin_port = htons (port);
370312ae
GH
777 *size = sizeof (struct sockaddr_in);
778 return (struct sockaddr *) soka;
779 }
a57a0b1e 780#ifdef HAVE_IPV6
3453619b
GH
781 case AF_INET6:
782 {
783 /* see RFC2553. */
784 int port;
785 struct sockaddr_in6 *soka;
786 unsigned long flowinfo = 0;
787 unsigned long scope_id = 0;
788
3453619b 789 SCM_VALIDATE_CONS (which_arg + 1, *args);
7cee5b31 790 port = scm_to_int (SCM_CAR (*args));
3453619b 791 *args = SCM_CDR (*args);
d2e53ed6 792 if (scm_is_pair (*args))
3453619b
GH
793 {
794 SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
795 *args = SCM_CDR (*args);
d2e53ed6 796 if (scm_is_pair (*args))
3453619b
GH
797 {
798 SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
799 scope_id);
800 *args = SCM_CDR (*args);
801 }
802 }
67329a9e 803 soka = (struct sockaddr_in6 *) scm_malloc (sizeof (struct sockaddr_in6));
9c0129ac 804
56a3dcd4 805#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
3453619b
GH
806 soka->sin6_len = sizeof (struct sockaddr_in6);
807#endif
808 soka->sin6_family = AF_INET6;
7cee5b31 809 scm_to_ipv6 (soka->sin6_addr.s6_addr, address);
5a525b84 810 soka->sin6_port = htons (port);
3453619b 811 soka->sin6_flowinfo = flowinfo;
5a525b84 812#ifdef HAVE_SIN6_SCOPE_ID
3453619b 813 soka->sin6_scope_id = scope_id;
5a525b84 814#endif
3453619b
GH
815 *size = sizeof (struct sockaddr_in6);
816 return (struct sockaddr *) soka;
817 }
818#endif
1ba8c23a 819#ifdef HAVE_UNIX_DOMAIN_SOCKETS
370312ae
GH
820 case AF_UNIX:
821 {
822 struct sockaddr_un *soka;
439006bf 823 int addr_size;
7f9994d9
MV
824 char *c_address;
825
661ae7ab 826 scm_dynwind_begin (0);
7f9994d9
MV
827
828 c_address = scm_to_locale_string (address);
661ae7ab 829 scm_dynwind_free (c_address);
370312ae 830
439006bf
GH
831 /* the static buffer size in sockaddr_un seems to be arbitrary
832 and not necessarily a hard limit. e.g., the glibc manual
833 suggests it may be possible to declare it size 0. let's
834 ignore it. if the O/S doesn't like the size it will cause
835 connect/bind etc., to fail. sun_path is always the last
836 member of the structure. */
837 addr_size = sizeof (struct sockaddr_un)
7f9994d9 838 + max (0, strlen (c_address) + 1 - (sizeof soka->sun_path));
67329a9e 839 soka = (struct sockaddr_un *) scm_malloc (addr_size);
439006bf
GH
840 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
841 soka->sun_family = AF_UNIX;
7f9994d9 842 strcpy (soka->sun_path, c_address);
439006bf 843 *size = SUN_LEN (soka);
7f9994d9 844
661ae7ab 845 scm_dynwind_end ();
370312ae
GH
846 return (struct sockaddr *) soka;
847 }
0e958795 848#endif
370312ae 849 default:
e11e83f3 850 scm_out_of_range (proc, scm_from_int (fam));
0f2d19dd 851 }
0f2d19dd 852}
3453619b 853#undef FUNC_NAME
9c0129ac
KR
854
855SCM_DEFINE (scm_connect, "connect", 2, 1, 1,
856 (SCM sock, SCM fam_or_sockaddr, SCM address, SCM args),
eefae538 857 "Initiate a connection from a socket using a specified address\n"
3453619b
GH
858 "family to the address\n"
859 "specified by @var{address} and possibly @var{args}.\n"
860 "The format required for @var{address}\n"
861 "and @var{args} depends on the family of the socket.\n\n"
b380b885 862 "For a socket of family @code{AF_UNIX},\n"
3453619b 863 "only @var{address} is specified and must be a string with the\n"
b380b885
MD
864 "filename where the socket is to be created.\n\n"
865 "For a socket of family @code{AF_INET},\n"
3453619b
GH
866 "@var{address} must be an integer IPv4 host address and\n"
867 "@var{args} must be a single integer port number.\n\n"
868 "For a socket of family @code{AF_INET6},\n"
869 "@var{address} must be an integer IPv6 host address and\n"
870 "@var{args} may be up to three integers:\n"
871 "port [flowinfo] [scope_id],\n"
872 "where flowinfo and scope_id default to zero.\n\n"
9c0129ac
KR
873 "Alternatively, the second argument can be a socket address object "
874 "as returned by @code{make-socket-address}, in which case the "
875 "no additional arguments should be passed.\n\n"
b380b885 876 "The return value is unspecified.")
1bbd0b84 877#define FUNC_NAME s_scm_connect
0f2d19dd 878{
370312ae
GH
879 int fd;
880 struct sockaddr *soka;
9c0129ac 881 size_t size;
0f2d19dd 882
78446828 883 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 884 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 885 fd = SCM_FPORT_FDES (sock);
9c0129ac
KR
886
887 if (address == SCM_UNDEFINED)
888 /* No third argument was passed to FAM_OR_SOCKADDR must actually be a
889 `socket address' object. */
890 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
891 else
892 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
893 &args, 3, FUNC_NAME, &size);
894
370312ae 895 if (connect (fd, soka, size) == -1)
439006bf
GH
896 {
897 int save_errno = errno;
9c0129ac 898
439006bf
GH
899 free (soka);
900 errno = save_errno;
901 SCM_SYSERROR;
902 }
903 free (soka);
370312ae 904 return SCM_UNSPECIFIED;
0f2d19dd 905}
1bbd0b84 906#undef FUNC_NAME
0f2d19dd 907
9c0129ac
KR
908SCM_DEFINE (scm_bind, "bind", 2, 1, 1,
909 (SCM sock, SCM fam_or_sockaddr, SCM address, SCM args),
eefae538 910 "Assign an address to the socket port @var{sock}.\n"
b380b885
MD
911 "Generally this only needs to be done for server sockets,\n"
912 "so they know where to look for incoming connections. A socket\n"
913 "without an address will be assigned one automatically when it\n"
914 "starts communicating.\n\n"
eefae538
GH
915 "The format of @var{address} and @var{args} depends\n"
916 "on the family of the socket.\n\n"
b380b885 917 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
eefae538
GH
918 "is specified and must be a string with the filename where\n"
919 "the socket is to be created.\n\n"
920 "For a socket of family @code{AF_INET}, @var{address}\n"
921 "must be an integer IPv4 address and @var{args}\n"
922 "must be a single integer port number.\n\n"
923 "The values of the following variables can also be used for\n"
924 "@var{address}:\n\n"
b380b885
MD
925 "@defvar INADDR_ANY\n"
926 "Allow connections from any address.\n"
927 "@end defvar\n\n"
928 "@defvar INADDR_LOOPBACK\n"
929 "The address of the local host using the loopback device.\n"
930 "@end defvar\n\n"
931 "@defvar INADDR_BROADCAST\n"
932 "The broadcast address on the local network.\n"
933 "@end defvar\n\n"
934 "@defvar INADDR_NONE\n"
935 "No address.\n"
936 "@end defvar\n\n"
eefae538
GH
937 "For a socket of family @code{AF_INET6}, @var{address}\n"
938 "must be an integer IPv6 address and @var{args}\n"
939 "may be up to three integers:\n"
940 "port [flowinfo] [scope_id],\n"
941 "where flowinfo and scope_id default to zero.\n\n"
9c0129ac
KR
942 "Alternatively, the second argument can be a socket address object "
943 "as returned by @code{make-socket-address}, in which case the "
944 "no additional arguments should be passed.\n\n"
b380b885 945 "The return value is unspecified.")
1bbd0b84 946#define FUNC_NAME s_scm_bind
370312ae 947{
370312ae 948 struct sockaddr *soka;
9c0129ac 949 size_t size;
370312ae
GH
950 int fd;
951
78446828 952 sock = SCM_COERCE_OUTPORT (sock);
439006bf 953 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 954 fd = SCM_FPORT_FDES (sock);
9c0129ac
KR
955
956 if (address == SCM_UNDEFINED)
957 /* No third argument was passed to FAM_OR_SOCKADDR must actually be a
958 `socket address' object. */
959 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
960 else
961 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
962 &args, 3, FUNC_NAME, &size);
963
964
439006bf
GH
965 if (bind (fd, soka, size) == -1)
966 {
967 int save_errno = errno;
9c0129ac 968
439006bf
GH
969 free (soka);
970 errno = save_errno;
1bbd0b84 971 SCM_SYSERROR;
439006bf
GH
972 }
973 free (soka);
370312ae
GH
974 return SCM_UNSPECIFIED;
975}
1bbd0b84 976#undef FUNC_NAME
370312ae 977
a1ec6916 978SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
1bbd0b84 979 (SCM sock, SCM backlog),
eefae538 980 "Enable @var{sock} to accept connection\n"
b380b885
MD
981 "requests. @var{backlog} is an integer specifying\n"
982 "the maximum length of the queue for pending connections.\n"
eefae538
GH
983 "If the queue fills, new clients will fail to connect until\n"
984 "the server calls @code{accept} to accept a connection from\n"
985 "the queue.\n\n"
b380b885 986 "The return value is unspecified.")
1bbd0b84 987#define FUNC_NAME s_scm_listen
370312ae
GH
988{
989 int fd;
78446828 990 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 991 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 992 fd = SCM_FPORT_FDES (sock);
7cee5b31 993 if (listen (fd, scm_to_int (backlog)) == -1)
1bbd0b84 994 SCM_SYSERROR;
370312ae
GH
995 return SCM_UNSPECIFIED;
996}
1bbd0b84 997#undef FUNC_NAME
370312ae
GH
998
999/* Put the components of a sockaddr into a new SCM vector. */
9c0129ac 1000static SCM_C_INLINE_KEYWORD SCM
f43f3620
LC
1001_scm_from_sockaddr (const scm_t_max_sockaddr *address, unsigned addr_size,
1002 const char *proc)
0f2d19dd 1003{
f43f3620
LC
1004 SCM result = SCM_EOL;
1005 short int fam = ((struct sockaddr *) address)->sa_family;
439006bf 1006
5a525b84 1007 switch (fam)
0f2d19dd 1008 {
5a525b84
GH
1009 case AF_INET:
1010 {
e1368a8d 1011 const struct sockaddr_in *nad = (struct sockaddr_in *) address;
439006bf 1012
1d1559ce 1013 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
34d19ef6 1014
4057a3e0
MV
1015 SCM_SIMPLE_VECTOR_SET(result, 0,
1016 scm_from_short (fam));
1017 SCM_SIMPLE_VECTOR_SET(result, 1,
1018 scm_from_ulong (ntohl (nad->sin_addr.s_addr)));
1019 SCM_SIMPLE_VECTOR_SET(result, 2,
1020 scm_from_ushort (ntohs (nad->sin_port)));
5a525b84
GH
1021 }
1022 break;
a57a0b1e 1023#ifdef HAVE_IPV6
5a525b84
GH
1024 case AF_INET6:
1025 {
e1368a8d 1026 const struct sockaddr_in6 *nad = (struct sockaddr_in6 *) address;
5a525b84 1027
1d1559ce 1028 result = scm_c_make_vector (5, SCM_UNSPECIFIED);
4057a3e0
MV
1029 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_short (fam));
1030 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_ipv6 (nad->sin6_addr.s6_addr));
1031 SCM_SIMPLE_VECTOR_SET(result, 2, scm_from_ushort (ntohs (nad->sin6_port)));
1032 SCM_SIMPLE_VECTOR_SET(result, 3, scm_from_uint32 (nad->sin6_flowinfo));
5a525b84 1033#ifdef HAVE_SIN6_SCOPE_ID
4057a3e0 1034 SCM_SIMPLE_VECTOR_SET(result, 4, scm_from_ulong (nad->sin6_scope_id));
5a525b84 1035#else
4057a3e0 1036 SCM_SIMPLE_VECTOR_SET(result, 4, SCM_INUM0);
0e958795 1037#endif
5a525b84
GH
1038 }
1039 break;
1040#endif
1041#ifdef HAVE_UNIX_DOMAIN_SOCKETS
1042 case AF_UNIX:
1043 {
e1368a8d 1044 const struct sockaddr_un *nad = (struct sockaddr_un *) address;
439006bf 1045
1d1559ce 1046 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
34d19ef6 1047
4057a3e0 1048 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_short (fam));
aca23b65
MV
1049 /* When addr_size is not enough to cover sun_path, do not try
1050 to access it. */
1051 if (addr_size <= offsetof (struct sockaddr_un, sun_path))
4057a3e0 1052 SCM_SIMPLE_VECTOR_SET(result, 1, SCM_BOOL_F);
aca23b65 1053 else
4057a3e0 1054 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_locale_string (nad->sun_path));
5a525b84
GH
1055 }
1056 break;
1057#endif
1058 default:
9c0129ac
KR
1059 result = SCM_UNSPECIFIED;
1060 scm_misc_error (proc, "unrecognised address family: ~A",
e11e83f3 1061 scm_list_1 (scm_from_int (fam)));
9c0129ac 1062
0f2d19dd 1063 }
1d1559ce 1064 return result;
370312ae
GH
1065}
1066
9c0129ac
KR
1067/* The publicly-visible function. Return a Scheme object representing
1068 ADDRESS, an address of ADDR_SIZE bytes. */
1069SCM
1070scm_from_sockaddr (const struct sockaddr *address, unsigned addr_size)
1071{
f43f3620
LC
1072 return (_scm_from_sockaddr ((scm_t_max_sockaddr *) address,
1073 addr_size, "scm_from_sockaddr"));
9c0129ac
KR
1074}
1075
1076/* Convert ADDRESS, an address object returned by either
1077 `scm_from_sockaddr ()' or `scm_make_socket_address ()', into its C
1078 representation. On success, a non-NULL pointer is returned and
1079 ADDRESS_SIZE is updated to the actual size (in bytes) of the returned
1080 address. The result must eventually be freed using `free ()'. */
1081struct sockaddr *
1082scm_to_sockaddr (SCM address, size_t *address_size)
1083#define FUNC_NAME "scm_to_sockaddr"
1084{
1085 short int family;
1086 struct sockaddr *c_address = NULL;
1087
1088 SCM_VALIDATE_VECTOR (1, address);
1089
1090 *address_size = 0;
1091 family = scm_to_short (SCM_SIMPLE_VECTOR_REF (address, 0));
1092
1093 switch (family)
1094 {
1095 case AF_INET:
1096 {
1097 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 3)
1098 scm_misc_error (FUNC_NAME,
1099 "invalid inet address representation: ~A",
1100 scm_list_1 (address));
1101 else
1102 {
1103 struct sockaddr_in c_inet;
1104
1105 c_inet.sin_addr.s_addr =
1106 htonl (scm_to_ulong (SCM_SIMPLE_VECTOR_REF (address, 1)));
1107 c_inet.sin_port =
1108 htons (scm_to_ushort (SCM_SIMPLE_VECTOR_REF (address, 2)));
1109 c_inet.sin_family = AF_INET;
1110
1111 *address_size = sizeof (c_inet);
1112 c_address = scm_malloc (sizeof (c_inet));
1113 memcpy (c_address, &c_inet, sizeof (c_inet));
1114 }
1115
1116 break;
1117 }
1118
1119#ifdef HAVE_IPV6
1120 case AF_INET6:
1121 {
1122 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 5)
1123 scm_misc_error (FUNC_NAME, "invalid inet6 address representation: ~A",
1124 scm_list_1 (address));
1125 else
1126 {
1127 struct sockaddr_in6 c_inet6;
1128
1ff4da65
NJ
1129 scm_to_ipv6 (c_inet6.sin6_addr.s6_addr,
1130 SCM_SIMPLE_VECTOR_REF (address, 1));
9c0129ac
KR
1131 c_inet6.sin6_port =
1132 htons (scm_to_ushort (SCM_SIMPLE_VECTOR_REF (address, 2)));
1133 c_inet6.sin6_flowinfo =
1134 scm_to_uint32 (SCM_SIMPLE_VECTOR_REF (address, 3));
1135#ifdef HAVE_SIN6_SCOPE_ID
1136 c_inet6.sin6_scope_id =
1137 scm_to_ulong (SCM_SIMPLE_VECTOR_REF (address, 4));
1138#endif
1139
1140 c_inet6.sin6_family = AF_INET6;
1141
1142 *address_size = sizeof (c_inet6);
1143 c_address = scm_malloc (sizeof (c_inet6));
1144 memcpy (c_address, &c_inet6, sizeof (c_inet6));
1145 }
1146
1147 break;
1148 }
1149#endif
1150
1151#ifdef HAVE_UNIX_DOMAIN_SOCKETS
1152 case AF_UNIX:
1153 {
1154 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 2)
1155 scm_misc_error (FUNC_NAME, "invalid unix address representation: ~A",
1156 scm_list_1 (address));
1157 else
1158 {
1159 SCM path;
1160 size_t path_len = 0;
1161
1162 path = SCM_SIMPLE_VECTOR_REF (address, 1);
1163 if ((!scm_is_string (path)) && (path != SCM_BOOL_F))
1164 scm_misc_error (FUNC_NAME, "invalid unix address "
1165 "path: ~A", scm_list_1 (path));
1166 else
1167 {
1168 struct sockaddr_un c_unix;
1169
1170 if (path == SCM_BOOL_F)
1171 path_len = 0;
1172 else
1173 path_len = scm_c_string_length (path);
1174
1175#ifdef UNIX_PATH_MAX
1176 if (path_len >= UNIX_PATH_MAX)
1177#else
1178/* We can hope that this limit will eventually vanish, at least on GNU.
1179 However, currently, while glibc doesn't define `UNIX_PATH_MAX', it
1180 documents it has being limited to 108 bytes. */
1181 if (path_len >= sizeof (c_unix.sun_path))
1182#endif
1183 scm_misc_error (FUNC_NAME, "unix address path "
1184 "too long: ~A", scm_list_1 (path));
1185 else
1186 {
1187 if (path_len)
1188 {
1189 scm_to_locale_stringbuf (path, c_unix.sun_path,
1190#ifdef UNIX_PATH_MAX
1191 UNIX_PATH_MAX);
1192#else
1193 sizeof (c_unix.sun_path));
1194#endif
1195 c_unix.sun_path[path_len] = '\0';
1196
1197 /* Sanity check. */
1198 if (strlen (c_unix.sun_path) != path_len)
1199 scm_misc_error (FUNC_NAME, "unix address path "
1200 "contains nul characters: ~A",
1201 scm_list_1 (path));
1202 }
1203 else
1204 c_unix.sun_path[0] = '\0';
1205
1206 c_unix.sun_family = AF_UNIX;
1207
1208 *address_size = SUN_LEN (&c_unix);
1209 c_address = scm_malloc (sizeof (c_unix));
1210 memcpy (c_address, &c_unix, sizeof (c_unix));
1211 }
1212 }
1213 }
1214
1215 break;
1216 }
1217#endif
1218
1219 default:
1220 scm_misc_error (FUNC_NAME, "unrecognised address family: ~A",
1221 scm_list_1 (scm_from_ushort (family)));
1222 }
1223
1224 return c_address;
1225}
1226#undef FUNC_NAME
1227
1228
1229/* Return a newly-allocated `sockaddr' structure that reflects ADDRESS, being
1230 an address of family FAMILY, with the family-specific parameters ARGS (see
1231 the description of `connect' for details). The returned structure may be
1232 freed using `free ()'. */
1233struct sockaddr *
1234scm_c_make_socket_address (SCM family, SCM address, SCM args,
1235 size_t *address_size)
1236{
9c0129ac
KR
1237 struct sockaddr *soka;
1238
1239 soka = scm_fill_sockaddr (scm_to_ushort (family), address, &args, 1,
d7c6575f 1240 "scm_c_make_socket_address", address_size);
9c0129ac
KR
1241
1242 return soka;
1243}
1244
1245SCM_DEFINE (scm_make_socket_address, "make-socket-address", 2, 0, 1,
1246 (SCM family, SCM address, SCM args),
1247 "Return a Scheme address object that reflects @var{address}, "
1248 "being an address of family @var{family}, with the "
1249 "family-specific parameters @var{args} (see the description of "
1250 "@code{connect} for details).")
1251#define FUNC_NAME s_scm_make_socket_address
1252{
1ac5fb45 1253 SCM result = SCM_BOOL_F;
9c0129ac
KR
1254 struct sockaddr *c_address;
1255 size_t c_address_size;
1256
1257 c_address = scm_c_make_socket_address (family, address, args,
1258 &c_address_size);
1ac5fb45
LC
1259 if (c_address != NULL)
1260 {
1261 result = scm_from_sockaddr (c_address, c_address_size);
1262 free (c_address);
1263 }
9c0129ac 1264
1ac5fb45 1265 return result;
9c0129ac
KR
1266}
1267#undef FUNC_NAME
1268
1269\f
a1ec6916 1270SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1bbd0b84 1271 (SCM sock),
eefae538
GH
1272 "Accept a connection on a bound, listening socket.\n"
1273 "If there\n"
1274 "are no pending connections in the queue, wait until\n"
1275 "one is available unless the non-blocking option has been\n"
1276 "set on the socket.\n\n"
b380b885 1277 "The return value is a\n"
eefae538
GH
1278 "pair in which the @emph{car} is a new socket port for the\n"
1279 "connection and\n"
1280 "the @emph{cdr} is an object with address information about the\n"
1281 "client which initiated the connection.\n\n"
1282 "@var{sock} does not become part of the\n"
b380b885 1283 "connection and will continue to accept new requests.")
1bbd0b84 1284#define FUNC_NAME s_scm_accept
0f2d19dd 1285{
e68e0369 1286 int fd;
370312ae
GH
1287 int newfd;
1288 SCM address;
1289 SCM newsock;
5ee417fc 1290 socklen_t addr_size = MAX_ADDR_SIZE;
f43f3620 1291 scm_t_max_sockaddr addr;
370312ae 1292
78446828 1293 sock = SCM_COERCE_OUTPORT (sock);
439006bf 1294 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1295 fd = SCM_FPORT_FDES (sock);
f43f3620 1296 newfd = accept (fd, (struct sockaddr *) &addr, &addr_size);
439006bf
GH
1297 if (newfd == -1)
1298 SCM_SYSERROR;
1299 newsock = SCM_SOCK_FD_TO_PORT (newfd);
f43f3620
LC
1300 address = _scm_from_sockaddr (&addr, addr_size,
1301 FUNC_NAME);
1302
370312ae 1303 return scm_cons (newsock, address);
0f2d19dd 1304}
1bbd0b84 1305#undef FUNC_NAME
0f2d19dd 1306
a1ec6916 1307SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1bbd0b84 1308 (SCM sock),
eefae538 1309 "Return the address of @var{sock}, in the same form as the\n"
1e6808ea
MG
1310 "object returned by @code{accept}. On many systems the address\n"
1311 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1bbd0b84 1312#define FUNC_NAME s_scm_getsockname
0f2d19dd 1313{
370312ae 1314 int fd;
5ee417fc 1315 socklen_t addr_size = MAX_ADDR_SIZE;
f43f3620 1316 scm_t_max_sockaddr addr;
439006bf 1317
78446828 1318 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1319 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1320 fd = SCM_FPORT_FDES (sock);
f43f3620 1321 if (getsockname (fd, (struct sockaddr *) &addr, &addr_size) == -1)
1bbd0b84 1322 SCM_SYSERROR;
f43f3620
LC
1323
1324 return _scm_from_sockaddr (&addr, addr_size, FUNC_NAME);
0f2d19dd 1325}
1bbd0b84 1326#undef FUNC_NAME
0f2d19dd 1327
a1ec6916 1328SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1bbd0b84 1329 (SCM sock),
eefae538 1330 "Return the address that @var{sock}\n"
1e6808ea
MG
1331 "is connected to, in the same form as the object returned by\n"
1332 "@code{accept}. On many systems the address of a socket in the\n"
1333 "@code{AF_FILE} namespace cannot be read.")
1bbd0b84 1334#define FUNC_NAME s_scm_getpeername
0f2d19dd 1335{
370312ae 1336 int fd;
5ee417fc 1337 socklen_t addr_size = MAX_ADDR_SIZE;
f43f3620 1338 scm_t_max_sockaddr addr;
439006bf 1339
78446828 1340 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1341 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1342 fd = SCM_FPORT_FDES (sock);
f43f3620 1343 if (getpeername (fd, (struct sockaddr *) &addr, &addr_size) == -1)
1bbd0b84 1344 SCM_SYSERROR;
f43f3620
LC
1345
1346 return _scm_from_sockaddr (&addr, addr_size, FUNC_NAME);
0f2d19dd 1347}
1bbd0b84 1348#undef FUNC_NAME
0f2d19dd 1349
a1ec6916 1350SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1bbd0b84 1351 (SCM sock, SCM buf, SCM flags),
eefae538
GH
1352 "Receive data from a socket port.\n"
1353 "@var{sock} must already\n"
b380b885
MD
1354 "be bound to the address from which data is to be received.\n"
1355 "@var{buf} is a string into which\n"
eefae538
GH
1356 "the data will be written. The size of @var{buf} limits\n"
1357 "the amount of\n"
b380b885 1358 "data which can be received: in the case of packet\n"
eefae538
GH
1359 "protocols, if a packet larger than this limit is encountered\n"
1360 "then some data\n"
b380b885 1361 "will be irrevocably lost.\n\n"
587a3355
MG
1362 "The data is assumed to be binary, and there is no decoding of\n"
1363 "of locale-encoded strings.\n\n"
b380b885
MD
1364 "The optional @var{flags} argument is a value or\n"
1365 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1366 "The value returned is the number of bytes read from the\n"
1367 "socket.\n\n"
1368 "Note that the data is read directly from the socket file\n"
1369 "descriptor:\n"
09831f94 1370 "any unread buffered port data is ignored.")
1bbd0b84 1371#define FUNC_NAME s_scm_recv
0f2d19dd 1372{
370312ae
GH
1373 int rv;
1374 int fd;
1375 int flg;
cc95e00a
MV
1376 char *dest;
1377 size_t len;
587a3355 1378 SCM msg;
370312ae 1379
34d19ef6
HWN
1380 SCM_VALIDATE_OPFPORT (1, sock);
1381 SCM_VALIDATE_STRING (2, buf);
7cee5b31
MV
1382 if (SCM_UNBNDP (flags))
1383 flg = 0;
1384 else
1385 flg = scm_to_int (flags);
ee149d03 1386 fd = SCM_FPORT_FDES (sock);
370312ae 1387
587a3355
MG
1388 len = scm_i_string_length (buf);
1389 msg = scm_i_make_string (len, &dest);
cc95e00a 1390 SCM_SYSCALL (rv = recv (fd, dest, len, flg));
587a3355
MG
1391 scm_string_copy_x (buf, scm_from_int (0),
1392 msg, scm_from_int (0), scm_from_size_t (len));
cc95e00a 1393
370312ae 1394 if (rv == -1)
1bbd0b84 1395 SCM_SYSERROR;
370312ae 1396
587a3355 1397 scm_remember_upto_here_2 (buf, msg);
7cee5b31 1398 return scm_from_int (rv);
370312ae 1399}
1bbd0b84 1400#undef FUNC_NAME
370312ae 1401
a1ec6916 1402SCM_DEFINE (scm_send, "send", 2, 1, 0,
1bbd0b84 1403 (SCM sock, SCM message, SCM flags),
eefae538
GH
1404 "Transmit the string @var{message} on a socket port @var{sock}.\n"
1405 "@var{sock} must already be bound to a destination address. The\n"
1406 "value returned is the number of bytes transmitted --\n"
1407 "it's possible for\n"
1408 "this to be less than the length of @var{message}\n"
1409 "if the socket is\n"
1410 "set to be non-blocking. The optional @var{flags} argument\n"
1411 "is a value or\n"
b380b885 1412 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1413 "Note that the data is written directly to the socket\n"
1414 "file descriptor:\n"
587a3355
MG
1415 "any unflushed buffered port data is ignored.\n\n"
1416 "This operation is defined only for strings containing codepoints\n"
1417 "zero to 255.")
1bbd0b84 1418#define FUNC_NAME s_scm_send
370312ae
GH
1419{
1420 int rv;
1421 int fd;
1422 int flg;
587a3355 1423 char *src;
cc95e00a 1424 size_t len;
370312ae 1425
78446828 1426 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1427 SCM_VALIDATE_OPFPORT (1, sock);
a6d9e5ab 1428 SCM_VALIDATE_STRING (2, message);
587a3355
MG
1429
1430 /* If the string is wide, see if it can be coerced into
1431 a narrow string. */
1432 if (!scm_i_is_narrow_string (message)
1433 || scm_i_try_narrow_string (message))
1434 SCM_MISC_ERROR ("the message string is not 8-bit: ~s",
1435 scm_list_1 (message));
1436
7cee5b31
MV
1437 if (SCM_UNBNDP (flags))
1438 flg = 0;
1439 else
1440 flg = scm_to_int (flags);
ee149d03 1441 fd = SCM_FPORT_FDES (sock);
370312ae 1442
cc95e00a 1443 len = scm_i_string_length (message);
9c44cd45 1444 message = scm_i_string_start_writing (message);
cc95e00a
MV
1445 src = scm_i_string_writable_chars (message);
1446 SCM_SYSCALL (rv = send (fd, src, len, flg));
1447 scm_i_string_stop_writing ();
1448
370312ae 1449 if (rv == -1)
1bbd0b84 1450 SCM_SYSERROR;
396e5506
MV
1451
1452 scm_remember_upto_here_1 (message);
7cee5b31 1453 return scm_from_int (rv);
370312ae 1454}
1bbd0b84 1455#undef FUNC_NAME
370312ae 1456
a1ec6916 1457SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
60d02d09 1458 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
8ab3d8a0
KR
1459 "Receive data from socket port @var{sock} (which must be already\n"
1460 "bound), returning the originating address as well as the data.\n"
1461 "This is usually for use on datagram sockets, but can be used on\n"
1462 "stream-oriented sockets too.\n"
1463 "\n"
1464 "The data received is stored in the given @var{str}, using\n"
1465 "either the whole string or just the region between the optional\n"
1466 "@var{start} and @var{end} positions. The size of @var{str}\n"
1467 "limits the amount of data which can be received. For datagram\n"
1468 "protocols, if a packet larger than this is received then excess\n"
1469 "bytes are irrevocably lost.\n"
1470 "\n"
1471 "The return value is a pair. The @code{car} is the number of\n"
1472 "bytes read. The @code{cdr} is a socket address object which is\n"
1473 "where the data come from, or @code{#f} if the origin is\n"
1474 "unknown.\n"
1475 "\n"
1476 "The optional @var{flags} argument is a or bitwise OR\n"
1477 "(@code{logior}) of @code{MSG_OOB}, @code{MSG_PEEK},\n"
1478 "@code{MSG_DONTROUTE} etc.\n"
1479 "\n"
1480 "Data is read directly from the socket file descriptor, any\n"
1481 "buffered port data is ignored.\n"
1482 "\n"
1483 "On a GNU/Linux system @code{recvfrom!} is not multi-threading,\n"
1484 "all threads stop while a @code{recvfrom!} call is in progress.\n"
1485 "An application may need to use @code{select}, @code{O_NONBLOCK}\n"
1486 "or @code{MSG_DONTWAIT} to avoid this.")
1bbd0b84 1487#define FUNC_NAME s_scm_recvfrom
370312ae
GH
1488{
1489 int rv;
1490 int fd;
1491 int flg;
60d02d09 1492 char *buf;
396e5506
MV
1493 size_t offset;
1494 size_t cend;
370312ae 1495 SCM address;
5ee417fc 1496 socklen_t addr_size = MAX_ADDR_SIZE;
f43f3620 1497 scm_t_max_sockaddr addr;
370312ae 1498
34d19ef6 1499 SCM_VALIDATE_OPFPORT (1, sock);
60d02d09 1500 fd = SCM_FPORT_FDES (sock);
396e5506
MV
1501
1502 SCM_VALIDATE_STRING (2, str);
cc95e00a 1503 scm_i_get_substring_spec (scm_i_string_length (str),
396e5506
MV
1504 start, &offset, end, &cend);
1505
1146b6cd
GH
1506 if (SCM_UNBNDP (flags))
1507 flg = 0;
370312ae 1508 else
60d02d09 1509 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
370312ae 1510
97d0e20b
GH
1511 /* recvfrom will not necessarily return an address. usually nothing
1512 is returned for stream sockets. */
9c44cd45 1513 str = scm_i_string_start_writing (str);
cc95e00a 1514 buf = scm_i_string_writable_chars (str);
f43f3620 1515 ((struct sockaddr *) &addr)->sa_family = AF_UNSPEC;
60d02d09 1516 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
1146b6cd 1517 cend - offset, flg,
f43f3620 1518 (struct sockaddr *) &addr, &addr_size));
cc95e00a
MV
1519 scm_i_string_stop_writing ();
1520
370312ae 1521 if (rv == -1)
1bbd0b84 1522 SCM_SYSERROR;
f43f3620
LC
1523 if (((struct sockaddr *) &addr)->sa_family != AF_UNSPEC)
1524 address = _scm_from_sockaddr (&addr, addr_size, FUNC_NAME);
370312ae
GH
1525 else
1526 address = SCM_BOOL_F;
1527
396e5506 1528 scm_remember_upto_here_1 (str);
f43f3620 1529
e11e83f3 1530 return scm_cons (scm_from_int (rv), address);
0f2d19dd 1531}
1bbd0b84 1532#undef FUNC_NAME
0f2d19dd 1533
9c0129ac
KR
1534SCM_DEFINE (scm_sendto, "sendto", 3, 1, 1,
1535 (SCM sock, SCM message, SCM fam_or_sockaddr, SCM address, SCM args_and_flags),
eefae538
GH
1536 "Transmit the string @var{message} on the socket port\n"
1537 "@var{sock}. The\n"
1538 "destination address is specified using the @var{fam},\n"
1539 "@var{address} and\n"
9c0129ac
KR
1540 "@var{args_and_flags} arguments, or just a socket address object "
1541 "returned by @code{make-socket-address}, in a similar way to the\n"
eefae538
GH
1542 "@code{connect} procedure. @var{args_and_flags} contains\n"
1543 "the usual connection arguments optionally followed by\n"
1544 "a flags argument, which is a value or\n"
b380b885 1545 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1546 "The value returned is the number of bytes transmitted --\n"
1547 "it's possible for\n"
1548 "this to be less than the length of @var{message} if the\n"
1549 "socket is\n"
1550 "set to be non-blocking.\n"
1551 "Note that the data is written directly to the socket\n"
1552 "file descriptor:\n"
587a3355
MG
1553 "any unflushed buffered port data is ignored.\n"
1554 "This operation is defined only for strings containing codepoints\n"
1555 "zero to 255.")
1bbd0b84 1556#define FUNC_NAME s_scm_sendto
370312ae
GH
1557{
1558 int rv;
1559 int fd;
1560 int flg;
1561 struct sockaddr *soka;
9c0129ac 1562 size_t size;
370312ae 1563
78446828 1564 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1565 SCM_VALIDATE_FPORT (1, sock);
a6d9e5ab 1566 SCM_VALIDATE_STRING (2, message);
ee149d03 1567 fd = SCM_FPORT_FDES (sock);
9c0129ac
KR
1568
1569 if (!scm_is_number (fam_or_sockaddr))
1570 {
1571 /* FAM_OR_SOCKADDR must actually be a `socket address' object. This
1572 means that the following arguments, i.e. ADDRESS and those listed in
1573 ARGS_AND_FLAGS, are the `MSG_' flags. */
1574 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
1575 if (address != SCM_UNDEFINED)
1576 args_and_flags = scm_cons (address, args_and_flags);
1577 }
1578 else
1579 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
1580 &args_and_flags, 3, FUNC_NAME, &size);
1581
d2e53ed6 1582 if (scm_is_null (args_and_flags))
370312ae
GH
1583 flg = 0;
1584 else
1585 {
34d19ef6 1586 SCM_VALIDATE_CONS (5, args_and_flags);
e4b265d8 1587 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
370312ae 1588 }
396e5506 1589 SCM_SYSCALL (rv = sendto (fd,
cc95e00a
MV
1590 scm_i_string_chars (message),
1591 scm_i_string_length (message),
ae2fa5bc 1592 flg, soka, size));
370312ae 1593 if (rv == -1)
439006bf
GH
1594 {
1595 int save_errno = errno;
1596 free (soka);
1597 errno = save_errno;
1598 SCM_SYSERROR;
1599 }
1600 free (soka);
396e5506
MV
1601
1602 scm_remember_upto_here_1 (message);
e11e83f3 1603 return scm_from_int (rv);
370312ae 1604}
1bbd0b84 1605#undef FUNC_NAME
370312ae
GH
1606\f
1607
1608
1609void
0f2d19dd 1610scm_init_socket ()
0f2d19dd 1611{
370312ae
GH
1612 /* protocol families. */
1613#ifdef AF_UNSPEC
e11e83f3 1614 scm_c_define ("AF_UNSPEC", scm_from_int (AF_UNSPEC));
370312ae
GH
1615#endif
1616#ifdef AF_UNIX
e11e83f3 1617 scm_c_define ("AF_UNIX", scm_from_int (AF_UNIX));
370312ae
GH
1618#endif
1619#ifdef AF_INET
e11e83f3 1620 scm_c_define ("AF_INET", scm_from_int (AF_INET));
370312ae 1621#endif
3453619b 1622#ifdef AF_INET6
e11e83f3 1623 scm_c_define ("AF_INET6", scm_from_int (AF_INET6));
3453619b 1624#endif
370312ae
GH
1625
1626#ifdef PF_UNSPEC
e11e83f3 1627 scm_c_define ("PF_UNSPEC", scm_from_int (PF_UNSPEC));
370312ae
GH
1628#endif
1629#ifdef PF_UNIX
e11e83f3 1630 scm_c_define ("PF_UNIX", scm_from_int (PF_UNIX));
370312ae
GH
1631#endif
1632#ifdef PF_INET
e11e83f3 1633 scm_c_define ("PF_INET", scm_from_int (PF_INET));
370312ae 1634#endif
3453619b 1635#ifdef PF_INET6
e11e83f3 1636 scm_c_define ("PF_INET6", scm_from_int (PF_INET6));
3453619b 1637#endif
370312ae 1638
66c73b76
GH
1639 /* standard addresses. */
1640#ifdef INADDR_ANY
b9bd8526 1641 scm_c_define ("INADDR_ANY", scm_from_ulong (INADDR_ANY));
66c73b76
GH
1642#endif
1643#ifdef INADDR_BROADCAST
b9bd8526 1644 scm_c_define ("INADDR_BROADCAST", scm_from_ulong (INADDR_BROADCAST));
66c73b76
GH
1645#endif
1646#ifdef INADDR_NONE
b9bd8526 1647 scm_c_define ("INADDR_NONE", scm_from_ulong (INADDR_NONE));
66c73b76
GH
1648#endif
1649#ifdef INADDR_LOOPBACK
b9bd8526 1650 scm_c_define ("INADDR_LOOPBACK", scm_from_ulong (INADDR_LOOPBACK));
66c73b76
GH
1651#endif
1652
6f637a1b
KR
1653 /* socket types.
1654
1655 SOCK_PACKET is deliberately omitted, the GNU/Linux socket(2) and
1656 packet(7) advise that it's obsolete and strongly deprecated. */
1657
370312ae 1658#ifdef SOCK_STREAM
e11e83f3 1659 scm_c_define ("SOCK_STREAM", scm_from_int (SOCK_STREAM));
370312ae
GH
1660#endif
1661#ifdef SOCK_DGRAM
e11e83f3 1662 scm_c_define ("SOCK_DGRAM", scm_from_int (SOCK_DGRAM));
370312ae 1663#endif
6f637a1b
KR
1664#ifdef SOCK_SEQPACKET
1665 scm_c_define ("SOCK_SEQPACKET", scm_from_int (SOCK_SEQPACKET));
1666#endif
370312ae 1667#ifdef SOCK_RAW
e11e83f3 1668 scm_c_define ("SOCK_RAW", scm_from_int (SOCK_RAW));
370312ae 1669#endif
6f637a1b
KR
1670#ifdef SOCK_RDM
1671 scm_c_define ("SOCK_RDM", scm_from_int (SOCK_RDM));
1672#endif
370312ae 1673
8fae2bf4
KR
1674 /* setsockopt level.
1675
1676 SOL_IP, SOL_TCP and SOL_UDP are defined on gnu/linux, but not on for
1677 instance NetBSD. We define IPPROTOs because that's what the posix spec
1678 shows in its example at
1679
1680 http://www.opengroup.org/onlinepubs/007904975/functions/getsockopt.html
1681 */
370312ae 1682#ifdef SOL_SOCKET
e11e83f3 1683 scm_c_define ("SOL_SOCKET", scm_from_int (SOL_SOCKET));
370312ae 1684#endif
8fae2bf4
KR
1685#ifdef IPPROTO_IP
1686 scm_c_define ("IPPROTO_IP", scm_from_int (IPPROTO_IP));
370312ae 1687#endif
8fae2bf4
KR
1688#ifdef IPPROTO_TCP
1689 scm_c_define ("IPPROTO_TCP", scm_from_int (IPPROTO_TCP));
370312ae 1690#endif
8fae2bf4
KR
1691#ifdef IPPROTO_UDP
1692 scm_c_define ("IPPROTO_UDP", scm_from_int (IPPROTO_UDP));
370312ae
GH
1693#endif
1694
1695 /* setsockopt names. */
1696#ifdef SO_DEBUG
e11e83f3 1697 scm_c_define ("SO_DEBUG", scm_from_int (SO_DEBUG));
370312ae
GH
1698#endif
1699#ifdef SO_REUSEADDR
e11e83f3 1700 scm_c_define ("SO_REUSEADDR", scm_from_int (SO_REUSEADDR));
370312ae
GH
1701#endif
1702#ifdef SO_STYLE
e11e83f3 1703 scm_c_define ("SO_STYLE", scm_from_int (SO_STYLE));
370312ae
GH
1704#endif
1705#ifdef SO_TYPE
e11e83f3 1706 scm_c_define ("SO_TYPE", scm_from_int (SO_TYPE));
370312ae
GH
1707#endif
1708#ifdef SO_ERROR
e11e83f3 1709 scm_c_define ("SO_ERROR", scm_from_int (SO_ERROR));
370312ae
GH
1710#endif
1711#ifdef SO_DONTROUTE
e11e83f3 1712 scm_c_define ("SO_DONTROUTE", scm_from_int (SO_DONTROUTE));
370312ae
GH
1713#endif
1714#ifdef SO_BROADCAST
e11e83f3 1715 scm_c_define ("SO_BROADCAST", scm_from_int (SO_BROADCAST));
370312ae
GH
1716#endif
1717#ifdef SO_SNDBUF
e11e83f3 1718 scm_c_define ("SO_SNDBUF", scm_from_int (SO_SNDBUF));
370312ae
GH
1719#endif
1720#ifdef SO_RCVBUF
e11e83f3 1721 scm_c_define ("SO_RCVBUF", scm_from_int (SO_RCVBUF));
370312ae
GH
1722#endif
1723#ifdef SO_KEEPALIVE
e11e83f3 1724 scm_c_define ("SO_KEEPALIVE", scm_from_int (SO_KEEPALIVE));
370312ae
GH
1725#endif
1726#ifdef SO_OOBINLINE
e11e83f3 1727 scm_c_define ("SO_OOBINLINE", scm_from_int (SO_OOBINLINE));
370312ae
GH
1728#endif
1729#ifdef SO_NO_CHECK
e11e83f3 1730 scm_c_define ("SO_NO_CHECK", scm_from_int (SO_NO_CHECK));
370312ae
GH
1731#endif
1732#ifdef SO_PRIORITY
e11e83f3 1733 scm_c_define ("SO_PRIORITY", scm_from_int (SO_PRIORITY));
370312ae
GH
1734#endif
1735#ifdef SO_LINGER
e11e83f3 1736 scm_c_define ("SO_LINGER", scm_from_int (SO_LINGER));
370312ae
GH
1737#endif
1738
1739 /* recv/send options. */
8ab3d8a0
KR
1740#ifdef MSG_DONTWAIT
1741 scm_c_define ("MSG_DONTWAIT", scm_from_int (MSG_DONTWAIT));
1742#endif
370312ae 1743#ifdef MSG_OOB
e11e83f3 1744 scm_c_define ("MSG_OOB", scm_from_int (MSG_OOB));
370312ae
GH
1745#endif
1746#ifdef MSG_PEEK
e11e83f3 1747 scm_c_define ("MSG_PEEK", scm_from_int (MSG_PEEK));
370312ae
GH
1748#endif
1749#ifdef MSG_DONTROUTE
e11e83f3 1750 scm_c_define ("MSG_DONTROUTE", scm_from_int (MSG_DONTROUTE));
370312ae
GH
1751#endif
1752
b4e15479
SJ
1753#ifdef __MINGW32__
1754 scm_i_init_socket_Win32 ();
1755#endif
1756
1c80707c
MV
1757#ifdef IP_ADD_MEMBERSHIP
1758 scm_c_define ("IP_ADD_MEMBERSHIP", scm_from_int (IP_ADD_MEMBERSHIP));
1759 scm_c_define ("IP_DROP_MEMBERSHIP", scm_from_int (IP_DROP_MEMBERSHIP));
1760#endif
1761
511246a1
TCM
1762#ifdef IP_MULTICAST_TTL
1763 scm_c_define ("IP_MULTICAST_TTL", scm_from_int ( IP_MULTICAST_TTL));
1764#endif
1765
1766#ifdef IP_MULTICAST_IF
1767 scm_c_define ("IP_MULTICAST_IF", scm_from_int ( IP_MULTICAST_IF));
1768#endif
1769
0f2d19dd 1770 scm_add_feature ("socket");
370312ae 1771
a0599745 1772#include "libguile/socket.x"
0f2d19dd
JB
1773}
1774
89e00824
ML
1775
1776/*
1777 Local Variables:
1778 c-file-style: "gnu"
1779 End:
1780*/