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