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