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