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