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