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