doc: Update `release.org'.
[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"
b7e64f8b
BT
522 "The value returned is a pair of integers\n"
523 "@code{(@var{enable} . @var{timeout})}. On old systems without\n"
72e3dae1 524 "timeout support (ie.@: without @code{struct linger}), only\n"
b7e64f8b 525 "@var{enable} has an effect but the value in Guile is always a\n"
72e3dae1
KR
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));
333a81cc 799 memset (soka, '\0', sizeof (struct sockaddr_in));
9c0129ac 800
482d311b 801#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
3453619b
GH
802 soka->sin_len = sizeof (struct sockaddr_in);
803#endif
370312ae 804 soka->sin_family = AF_INET;
3453619b
GH
805 soka->sin_addr.s_addr = htonl (addr);
806 soka->sin_port = htons (port);
370312ae
GH
807 *size = sizeof (struct sockaddr_in);
808 return (struct sockaddr *) soka;
809 }
a57a0b1e 810#ifdef HAVE_IPV6
3453619b
GH
811 case AF_INET6:
812 {
813 /* see RFC2553. */
814 int port;
815 struct sockaddr_in6 *soka;
816 unsigned long flowinfo = 0;
817 unsigned long scope_id = 0;
818
3453619b 819 SCM_VALIDATE_CONS (which_arg + 1, *args);
7cee5b31 820 port = scm_to_int (SCM_CAR (*args));
3453619b 821 *args = SCM_CDR (*args);
d2e53ed6 822 if (scm_is_pair (*args))
3453619b
GH
823 {
824 SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
825 *args = SCM_CDR (*args);
d2e53ed6 826 if (scm_is_pair (*args))
3453619b
GH
827 {
828 SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
829 scope_id);
830 *args = SCM_CDR (*args);
831 }
832 }
67329a9e 833 soka = (struct sockaddr_in6 *) scm_malloc (sizeof (struct sockaddr_in6));
9c0129ac 834
56a3dcd4 835#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
3453619b
GH
836 soka->sin6_len = sizeof (struct sockaddr_in6);
837#endif
838 soka->sin6_family = AF_INET6;
7cee5b31 839 scm_to_ipv6 (soka->sin6_addr.s6_addr, address);
5a525b84 840 soka->sin6_port = htons (port);
3453619b 841 soka->sin6_flowinfo = flowinfo;
5a525b84 842#ifdef HAVE_SIN6_SCOPE_ID
3453619b 843 soka->sin6_scope_id = scope_id;
5a525b84 844#endif
3453619b
GH
845 *size = sizeof (struct sockaddr_in6);
846 return (struct sockaddr *) soka;
847 }
848#endif
1ba8c23a 849#ifdef HAVE_UNIX_DOMAIN_SOCKETS
370312ae
GH
850 case AF_UNIX:
851 {
852 struct sockaddr_un *soka;
439006bf 853 int addr_size;
7f9994d9
MV
854 char *c_address;
855
661ae7ab 856 scm_dynwind_begin (0);
7f9994d9
MV
857
858 c_address = scm_to_locale_string (address);
661ae7ab 859 scm_dynwind_free (c_address);
370312ae 860
439006bf
GH
861 /* the static buffer size in sockaddr_un seems to be arbitrary
862 and not necessarily a hard limit. e.g., the glibc manual
863 suggests it may be possible to declare it size 0. let's
864 ignore it. if the O/S doesn't like the size it will cause
865 connect/bind etc., to fail. sun_path is always the last
866 member of the structure. */
867 addr_size = sizeof (struct sockaddr_un)
7f9994d9 868 + max (0, strlen (c_address) + 1 - (sizeof soka->sun_path));
67329a9e 869 soka = (struct sockaddr_un *) scm_malloc (addr_size);
439006bf
GH
870 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
871 soka->sun_family = AF_UNIX;
7f9994d9 872 strcpy (soka->sun_path, c_address);
439006bf 873 *size = SUN_LEN (soka);
7f9994d9 874
661ae7ab 875 scm_dynwind_end ();
370312ae
GH
876 return (struct sockaddr *) soka;
877 }
0e958795 878#endif
370312ae 879 default:
e11e83f3 880 scm_out_of_range (proc, scm_from_int (fam));
0f2d19dd 881 }
0f2d19dd 882}
3453619b 883#undef FUNC_NAME
9c0129ac
KR
884
885SCM_DEFINE (scm_connect, "connect", 2, 1, 1,
886 (SCM sock, SCM fam_or_sockaddr, SCM address, SCM args),
eefae538 887 "Initiate a connection from a socket using a specified address\n"
3453619b
GH
888 "family to the address\n"
889 "specified by @var{address} and possibly @var{args}.\n"
890 "The format required for @var{address}\n"
891 "and @var{args} depends on the family of the socket.\n\n"
b380b885 892 "For a socket of family @code{AF_UNIX},\n"
3453619b 893 "only @var{address} is specified and must be a string with the\n"
b380b885
MD
894 "filename where the socket is to be created.\n\n"
895 "For a socket of family @code{AF_INET},\n"
3453619b
GH
896 "@var{address} must be an integer IPv4 host address and\n"
897 "@var{args} must be a single integer port number.\n\n"
898 "For a socket of family @code{AF_INET6},\n"
899 "@var{address} must be an integer IPv6 host address and\n"
900 "@var{args} may be up to three integers:\n"
901 "port [flowinfo] [scope_id],\n"
902 "where flowinfo and scope_id default to zero.\n\n"
9c0129ac
KR
903 "Alternatively, the second argument can be a socket address object "
904 "as returned by @code{make-socket-address}, in which case the "
905 "no additional arguments should be passed.\n\n"
b380b885 906 "The return value is unspecified.")
1bbd0b84 907#define FUNC_NAME s_scm_connect
0f2d19dd 908{
370312ae
GH
909 int fd;
910 struct sockaddr *soka;
9c0129ac 911 size_t size;
0f2d19dd 912
78446828 913 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 914 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 915 fd = SCM_FPORT_FDES (sock);
9c0129ac 916
d223c3fc 917 if (scm_is_eq (address, SCM_UNDEFINED))
9c0129ac
KR
918 /* No third argument was passed to FAM_OR_SOCKADDR must actually be a
919 `socket address' object. */
920 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
921 else
922 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
923 &args, 3, FUNC_NAME, &size);
924
370312ae 925 if (connect (fd, soka, size) == -1)
439006bf
GH
926 {
927 int save_errno = errno;
9c0129ac 928
439006bf
GH
929 free (soka);
930 errno = save_errno;
931 SCM_SYSERROR;
932 }
933 free (soka);
370312ae 934 return SCM_UNSPECIFIED;
0f2d19dd 935}
1bbd0b84 936#undef FUNC_NAME
0f2d19dd 937
9c0129ac
KR
938SCM_DEFINE (scm_bind, "bind", 2, 1, 1,
939 (SCM sock, SCM fam_or_sockaddr, SCM address, SCM args),
eefae538 940 "Assign an address to the socket port @var{sock}.\n"
b380b885
MD
941 "Generally this only needs to be done for server sockets,\n"
942 "so they know where to look for incoming connections. A socket\n"
943 "without an address will be assigned one automatically when it\n"
944 "starts communicating.\n\n"
eefae538
GH
945 "The format of @var{address} and @var{args} depends\n"
946 "on the family of the socket.\n\n"
b380b885 947 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
eefae538
GH
948 "is specified and must be a string with the filename where\n"
949 "the socket is to be created.\n\n"
950 "For a socket of family @code{AF_INET}, @var{address}\n"
951 "must be an integer IPv4 address and @var{args}\n"
952 "must be a single integer port number.\n\n"
953 "The values of the following variables can also be used for\n"
954 "@var{address}:\n\n"
b380b885
MD
955 "@defvar INADDR_ANY\n"
956 "Allow connections from any address.\n"
957 "@end defvar\n\n"
958 "@defvar INADDR_LOOPBACK\n"
959 "The address of the local host using the loopback device.\n"
960 "@end defvar\n\n"
961 "@defvar INADDR_BROADCAST\n"
962 "The broadcast address on the local network.\n"
963 "@end defvar\n\n"
964 "@defvar INADDR_NONE\n"
965 "No address.\n"
966 "@end defvar\n\n"
eefae538
GH
967 "For a socket of family @code{AF_INET6}, @var{address}\n"
968 "must be an integer IPv6 address and @var{args}\n"
969 "may be up to three integers:\n"
970 "port [flowinfo] [scope_id],\n"
971 "where flowinfo and scope_id default to zero.\n\n"
9c0129ac
KR
972 "Alternatively, the second argument can be a socket address object "
973 "as returned by @code{make-socket-address}, in which case the "
974 "no additional arguments should be passed.\n\n"
b380b885 975 "The return value is unspecified.")
1bbd0b84 976#define FUNC_NAME s_scm_bind
370312ae 977{
370312ae 978 struct sockaddr *soka;
9c0129ac 979 size_t size;
370312ae
GH
980 int fd;
981
78446828 982 sock = SCM_COERCE_OUTPORT (sock);
439006bf 983 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 984 fd = SCM_FPORT_FDES (sock);
9c0129ac 985
d223c3fc 986 if (scm_is_eq (address, SCM_UNDEFINED))
9c0129ac
KR
987 /* No third argument was passed to FAM_OR_SOCKADDR must actually be a
988 `socket address' object. */
989 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
990 else
991 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
992 &args, 3, FUNC_NAME, &size);
993
994
439006bf
GH
995 if (bind (fd, soka, size) == -1)
996 {
997 int save_errno = errno;
9c0129ac 998
439006bf
GH
999 free (soka);
1000 errno = save_errno;
1bbd0b84 1001 SCM_SYSERROR;
439006bf
GH
1002 }
1003 free (soka);
370312ae
GH
1004 return SCM_UNSPECIFIED;
1005}
1bbd0b84 1006#undef FUNC_NAME
370312ae 1007
a1ec6916 1008SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
1bbd0b84 1009 (SCM sock, SCM backlog),
eefae538 1010 "Enable @var{sock} to accept connection\n"
b380b885
MD
1011 "requests. @var{backlog} is an integer specifying\n"
1012 "the maximum length of the queue for pending connections.\n"
eefae538
GH
1013 "If the queue fills, new clients will fail to connect until\n"
1014 "the server calls @code{accept} to accept a connection from\n"
1015 "the queue.\n\n"
b380b885 1016 "The return value is unspecified.")
1bbd0b84 1017#define FUNC_NAME s_scm_listen
370312ae
GH
1018{
1019 int fd;
78446828 1020 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1021 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1022 fd = SCM_FPORT_FDES (sock);
7cee5b31 1023 if (listen (fd, scm_to_int (backlog)) == -1)
1bbd0b84 1024 SCM_SYSERROR;
370312ae
GH
1025 return SCM_UNSPECIFIED;
1026}
1bbd0b84 1027#undef FUNC_NAME
370312ae
GH
1028
1029/* Put the components of a sockaddr into a new SCM vector. */
9c0129ac 1030static SCM_C_INLINE_KEYWORD SCM
f43f3620
LC
1031_scm_from_sockaddr (const scm_t_max_sockaddr *address, unsigned addr_size,
1032 const char *proc)
0f2d19dd 1033{
f43f3620
LC
1034 SCM result = SCM_EOL;
1035 short int fam = ((struct sockaddr *) address)->sa_family;
439006bf 1036
5a525b84 1037 switch (fam)
0f2d19dd 1038 {
5a525b84
GH
1039 case AF_INET:
1040 {
e1368a8d 1041 const struct sockaddr_in *nad = (struct sockaddr_in *) address;
439006bf 1042
1d1559ce 1043 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
34d19ef6 1044
4057a3e0
MV
1045 SCM_SIMPLE_VECTOR_SET(result, 0,
1046 scm_from_short (fam));
1047 SCM_SIMPLE_VECTOR_SET(result, 1,
1048 scm_from_ulong (ntohl (nad->sin_addr.s_addr)));
1049 SCM_SIMPLE_VECTOR_SET(result, 2,
1050 scm_from_ushort (ntohs (nad->sin_port)));
5a525b84
GH
1051 }
1052 break;
a57a0b1e 1053#ifdef HAVE_IPV6
5a525b84
GH
1054 case AF_INET6:
1055 {
e1368a8d 1056 const struct sockaddr_in6 *nad = (struct sockaddr_in6 *) address;
5a525b84 1057
1d1559ce 1058 result = scm_c_make_vector (5, SCM_UNSPECIFIED);
4057a3e0
MV
1059 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_short (fam));
1060 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_ipv6 (nad->sin6_addr.s6_addr));
1061 SCM_SIMPLE_VECTOR_SET(result, 2, scm_from_ushort (ntohs (nad->sin6_port)));
1062 SCM_SIMPLE_VECTOR_SET(result, 3, scm_from_uint32 (nad->sin6_flowinfo));
5a525b84 1063#ifdef HAVE_SIN6_SCOPE_ID
4057a3e0 1064 SCM_SIMPLE_VECTOR_SET(result, 4, scm_from_ulong (nad->sin6_scope_id));
5a525b84 1065#else
4057a3e0 1066 SCM_SIMPLE_VECTOR_SET(result, 4, SCM_INUM0);
0e958795 1067#endif
5a525b84
GH
1068 }
1069 break;
1070#endif
1071#ifdef HAVE_UNIX_DOMAIN_SOCKETS
1072 case AF_UNIX:
1073 {
e1368a8d 1074 const struct sockaddr_un *nad = (struct sockaddr_un *) address;
439006bf 1075
1d1559ce 1076 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
34d19ef6 1077
4057a3e0 1078 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_short (fam));
aca23b65
MV
1079 /* When addr_size is not enough to cover sun_path, do not try
1080 to access it. */
1081 if (addr_size <= offsetof (struct sockaddr_un, sun_path))
4057a3e0 1082 SCM_SIMPLE_VECTOR_SET(result, 1, SCM_BOOL_F);
aca23b65 1083 else
4057a3e0 1084 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_locale_string (nad->sun_path));
5a525b84
GH
1085 }
1086 break;
1087#endif
1088 default:
9c0129ac
KR
1089 result = SCM_UNSPECIFIED;
1090 scm_misc_error (proc, "unrecognised address family: ~A",
e11e83f3 1091 scm_list_1 (scm_from_int (fam)));
9c0129ac 1092
0f2d19dd 1093 }
1d1559ce 1094 return result;
370312ae
GH
1095}
1096
9c0129ac
KR
1097/* The publicly-visible function. Return a Scheme object representing
1098 ADDRESS, an address of ADDR_SIZE bytes. */
1099SCM
1100scm_from_sockaddr (const struct sockaddr *address, unsigned addr_size)
1101{
f43f3620
LC
1102 return (_scm_from_sockaddr ((scm_t_max_sockaddr *) address,
1103 addr_size, "scm_from_sockaddr"));
9c0129ac
KR
1104}
1105
1106/* Convert ADDRESS, an address object returned by either
1107 `scm_from_sockaddr ()' or `scm_make_socket_address ()', into its C
1108 representation. On success, a non-NULL pointer is returned and
1109 ADDRESS_SIZE is updated to the actual size (in bytes) of the returned
1110 address. The result must eventually be freed using `free ()'. */
1111struct sockaddr *
1112scm_to_sockaddr (SCM address, size_t *address_size)
1113#define FUNC_NAME "scm_to_sockaddr"
1114{
1115 short int family;
1116 struct sockaddr *c_address = NULL;
1117
1118 SCM_VALIDATE_VECTOR (1, address);
1119
1120 *address_size = 0;
1121 family = scm_to_short (SCM_SIMPLE_VECTOR_REF (address, 0));
1122
1123 switch (family)
1124 {
1125 case AF_INET:
1126 {
1127 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 3)
1128 scm_misc_error (FUNC_NAME,
1129 "invalid inet address representation: ~A",
1130 scm_list_1 (address));
1131 else
1132 {
1133 struct sockaddr_in c_inet;
1134
333a81cc
NL
1135 memset (&c_inet, '\0', sizeof (struct sockaddr_in));
1136
482d311b
NL
1137#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1138 c_inet.sin_len = sizeof (struct sockaddr_in);
1139#endif
1140
9c0129ac
KR
1141 c_inet.sin_addr.s_addr =
1142 htonl (scm_to_ulong (SCM_SIMPLE_VECTOR_REF (address, 1)));
1143 c_inet.sin_port =
1144 htons (scm_to_ushort (SCM_SIMPLE_VECTOR_REF (address, 2)));
1145 c_inet.sin_family = AF_INET;
1146
1147 *address_size = sizeof (c_inet);
1148 c_address = scm_malloc (sizeof (c_inet));
1149 memcpy (c_address, &c_inet, sizeof (c_inet));
1150 }
1151
1152 break;
1153 }
1154
1155#ifdef HAVE_IPV6
1156 case AF_INET6:
1157 {
1158 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 5)
1159 scm_misc_error (FUNC_NAME, "invalid inet6 address representation: ~A",
1160 scm_list_1 (address));
1161 else
1162 {
1163 struct sockaddr_in6 c_inet6;
1164
1ff4da65
NJ
1165 scm_to_ipv6 (c_inet6.sin6_addr.s6_addr,
1166 SCM_SIMPLE_VECTOR_REF (address, 1));
9c0129ac
KR
1167 c_inet6.sin6_port =
1168 htons (scm_to_ushort (SCM_SIMPLE_VECTOR_REF (address, 2)));
1169 c_inet6.sin6_flowinfo =
1170 scm_to_uint32 (SCM_SIMPLE_VECTOR_REF (address, 3));
1171#ifdef HAVE_SIN6_SCOPE_ID
1172 c_inet6.sin6_scope_id =
1173 scm_to_ulong (SCM_SIMPLE_VECTOR_REF (address, 4));
1174#endif
1175
1176 c_inet6.sin6_family = AF_INET6;
1177
1178 *address_size = sizeof (c_inet6);
1179 c_address = scm_malloc (sizeof (c_inet6));
1180 memcpy (c_address, &c_inet6, sizeof (c_inet6));
1181 }
1182
1183 break;
1184 }
1185#endif
1186
1187#ifdef HAVE_UNIX_DOMAIN_SOCKETS
1188 case AF_UNIX:
1189 {
1190 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 2)
1191 scm_misc_error (FUNC_NAME, "invalid unix address representation: ~A",
1192 scm_list_1 (address));
1193 else
1194 {
1195 SCM path;
1196 size_t path_len = 0;
1197
1198 path = SCM_SIMPLE_VECTOR_REF (address, 1);
393baa8a 1199 if (!scm_is_string (path) && !scm_is_false (path))
9c0129ac
KR
1200 scm_misc_error (FUNC_NAME, "invalid unix address "
1201 "path: ~A", scm_list_1 (path));
1202 else
1203 {
1204 struct sockaddr_un c_unix;
1205
393baa8a 1206 if (scm_is_false (path))
9c0129ac
KR
1207 path_len = 0;
1208 else
1209 path_len = scm_c_string_length (path);
1210
1211#ifdef UNIX_PATH_MAX
1212 if (path_len >= UNIX_PATH_MAX)
1213#else
1214/* We can hope that this limit will eventually vanish, at least on GNU.
1215 However, currently, while glibc doesn't define `UNIX_PATH_MAX', it
1216 documents it has being limited to 108 bytes. */
1217 if (path_len >= sizeof (c_unix.sun_path))
1218#endif
1219 scm_misc_error (FUNC_NAME, "unix address path "
1220 "too long: ~A", scm_list_1 (path));
1221 else
1222 {
1223 if (path_len)
1224 {
1225 scm_to_locale_stringbuf (path, c_unix.sun_path,
1226#ifdef UNIX_PATH_MAX
1227 UNIX_PATH_MAX);
1228#else
1229 sizeof (c_unix.sun_path));
1230#endif
1231 c_unix.sun_path[path_len] = '\0';
1232
1233 /* Sanity check. */
1234 if (strlen (c_unix.sun_path) != path_len)
1235 scm_misc_error (FUNC_NAME, "unix address path "
1236 "contains nul characters: ~A",
1237 scm_list_1 (path));
1238 }
1239 else
1240 c_unix.sun_path[0] = '\0';
1241
1242 c_unix.sun_family = AF_UNIX;
1243
1244 *address_size = SUN_LEN (&c_unix);
1245 c_address = scm_malloc (sizeof (c_unix));
1246 memcpy (c_address, &c_unix, sizeof (c_unix));
1247 }
1248 }
1249 }
1250
1251 break;
1252 }
1253#endif
1254
1255 default:
1256 scm_misc_error (FUNC_NAME, "unrecognised address family: ~A",
1257 scm_list_1 (scm_from_ushort (family)));
1258 }
1259
1260 return c_address;
1261}
1262#undef FUNC_NAME
1263
1264
1265/* Return a newly-allocated `sockaddr' structure that reflects ADDRESS, being
1266 an address of family FAMILY, with the family-specific parameters ARGS (see
1267 the description of `connect' for details). The returned structure may be
1268 freed using `free ()'. */
1269struct sockaddr *
1270scm_c_make_socket_address (SCM family, SCM address, SCM args,
1271 size_t *address_size)
1272{
9c0129ac
KR
1273 struct sockaddr *soka;
1274
1275 soka = scm_fill_sockaddr (scm_to_ushort (family), address, &args, 1,
d7c6575f 1276 "scm_c_make_socket_address", address_size);
9c0129ac
KR
1277
1278 return soka;
1279}
1280
1281SCM_DEFINE (scm_make_socket_address, "make-socket-address", 2, 0, 1,
1282 (SCM family, SCM address, SCM args),
1283 "Return a Scheme address object that reflects @var{address}, "
1284 "being an address of family @var{family}, with the "
1285 "family-specific parameters @var{args} (see the description of "
1286 "@code{connect} for details).")
1287#define FUNC_NAME s_scm_make_socket_address
1288{
1ac5fb45 1289 SCM result = SCM_BOOL_F;
9c0129ac
KR
1290 struct sockaddr *c_address;
1291 size_t c_address_size;
1292
1293 c_address = scm_c_make_socket_address (family, address, args,
1294 &c_address_size);
1ac5fb45
LC
1295 if (c_address != NULL)
1296 {
1297 result = scm_from_sockaddr (c_address, c_address_size);
1298 free (c_address);
1299 }
9c0129ac 1300
1ac5fb45 1301 return result;
9c0129ac
KR
1302}
1303#undef FUNC_NAME
1304
1305\f
a1ec6916 1306SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1bbd0b84 1307 (SCM sock),
eefae538
GH
1308 "Accept a connection on a bound, listening socket.\n"
1309 "If there\n"
1310 "are no pending connections in the queue, wait until\n"
1311 "one is available unless the non-blocking option has been\n"
1312 "set on the socket.\n\n"
b380b885 1313 "The return value is a\n"
eefae538
GH
1314 "pair in which the @emph{car} is a new socket port for the\n"
1315 "connection and\n"
1316 "the @emph{cdr} is an object with address information about the\n"
1317 "client which initiated the connection.\n\n"
1318 "@var{sock} does not become part of the\n"
b380b885 1319 "connection and will continue to accept new requests.")
1bbd0b84 1320#define FUNC_NAME s_scm_accept
0f2d19dd 1321{
e68e0369 1322 int fd;
370312ae
GH
1323 int newfd;
1324 SCM address;
1325 SCM newsock;
5ee417fc 1326 socklen_t addr_size = MAX_ADDR_SIZE;
f43f3620 1327 scm_t_max_sockaddr addr;
370312ae 1328
78446828 1329 sock = SCM_COERCE_OUTPORT (sock);
439006bf 1330 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1331 fd = SCM_FPORT_FDES (sock);
f43f3620 1332 newfd = accept (fd, (struct sockaddr *) &addr, &addr_size);
439006bf
GH
1333 if (newfd == -1)
1334 SCM_SYSERROR;
1335 newsock = SCM_SOCK_FD_TO_PORT (newfd);
f43f3620
LC
1336 address = _scm_from_sockaddr (&addr, addr_size,
1337 FUNC_NAME);
1338
370312ae 1339 return scm_cons (newsock, address);
0f2d19dd 1340}
1bbd0b84 1341#undef FUNC_NAME
0f2d19dd 1342
a1ec6916 1343SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1bbd0b84 1344 (SCM sock),
eefae538 1345 "Return the address of @var{sock}, in the same form as the\n"
1e6808ea
MG
1346 "object returned by @code{accept}. On many systems the address\n"
1347 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1bbd0b84 1348#define FUNC_NAME s_scm_getsockname
0f2d19dd 1349{
370312ae 1350 int fd;
5ee417fc 1351 socklen_t addr_size = MAX_ADDR_SIZE;
f43f3620 1352 scm_t_max_sockaddr addr;
439006bf 1353
78446828 1354 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1355 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1356 fd = SCM_FPORT_FDES (sock);
f43f3620 1357 if (getsockname (fd, (struct sockaddr *) &addr, &addr_size) == -1)
1bbd0b84 1358 SCM_SYSERROR;
f43f3620
LC
1359
1360 return _scm_from_sockaddr (&addr, addr_size, FUNC_NAME);
0f2d19dd 1361}
1bbd0b84 1362#undef FUNC_NAME
0f2d19dd 1363
a1ec6916 1364SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1bbd0b84 1365 (SCM sock),
eefae538 1366 "Return the address that @var{sock}\n"
1e6808ea
MG
1367 "is connected to, in the same form as the object returned by\n"
1368 "@code{accept}. On many systems the address of a socket in the\n"
1369 "@code{AF_FILE} namespace cannot be read.")
1bbd0b84 1370#define FUNC_NAME s_scm_getpeername
0f2d19dd 1371{
370312ae 1372 int fd;
5ee417fc 1373 socklen_t addr_size = MAX_ADDR_SIZE;
f43f3620 1374 scm_t_max_sockaddr addr;
439006bf 1375
78446828 1376 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1377 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1378 fd = SCM_FPORT_FDES (sock);
f43f3620 1379 if (getpeername (fd, (struct sockaddr *) &addr, &addr_size) == -1)
1bbd0b84 1380 SCM_SYSERROR;
f43f3620
LC
1381
1382 return _scm_from_sockaddr (&addr, addr_size, FUNC_NAME);
0f2d19dd 1383}
1bbd0b84 1384#undef FUNC_NAME
0f2d19dd 1385
a1ec6916 1386SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1bbd0b84 1387 (SCM sock, SCM buf, SCM flags),
eefae538
GH
1388 "Receive data from a socket port.\n"
1389 "@var{sock} must already\n"
b380b885 1390 "be bound to the address from which data is to be received.\n"
d21a1dc8 1391 "@var{buf} is a bytevector into which\n"
eefae538
GH
1392 "the data will be written. The size of @var{buf} limits\n"
1393 "the amount of\n"
b380b885 1394 "data which can be received: in the case of packet\n"
eefae538
GH
1395 "protocols, if a packet larger than this limit is encountered\n"
1396 "then some data\n"
b380b885
MD
1397 "will be irrevocably lost.\n\n"
1398 "The optional @var{flags} argument is a value or\n"
1399 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1400 "The value returned is the number of bytes read from the\n"
1401 "socket.\n\n"
1402 "Note that the data is read directly from the socket file\n"
1403 "descriptor:\n"
09831f94 1404 "any unread buffered port data is ignored.")
1bbd0b84 1405#define FUNC_NAME s_scm_recv
0f2d19dd 1406{
d21a1dc8 1407 int rv, fd, flg;
370312ae 1408
34d19ef6 1409 SCM_VALIDATE_OPFPORT (1, sock);
d21a1dc8 1410
7cee5b31
MV
1411 if (SCM_UNBNDP (flags))
1412 flg = 0;
1413 else
1414 flg = scm_to_int (flags);
ee149d03 1415 fd = SCM_FPORT_FDES (sock);
370312ae 1416
d21a1dc8
LC
1417#if SCM_ENABLE_DEPRECATED == 1
1418 if (SCM_UNLIKELY (scm_is_string (buf)))
1419 {
1420 SCM msg;
1421 char *dest;
1422 size_t len;
1423
1424 scm_c_issue_deprecation_warning
1425 ("Passing a string to `recv!' is deprecated, "
1426 "use a bytevector instead.");
1427
1428 len = scm_i_string_length (buf);
190d4b0d 1429 msg = scm_i_make_string (len, &dest, 0);
d21a1dc8
LC
1430 SCM_SYSCALL (rv = recv (fd, dest, len, flg));
1431 scm_string_copy_x (buf, scm_from_int (0),
1432 msg, scm_from_int (0), scm_from_size_t (len));
1433 }
1434 else
1435#endif
1436 {
1437 SCM_VALIDATE_BYTEVECTOR (1, buf);
1438
1439 SCM_SYSCALL (rv = recv (fd,
1440 SCM_BYTEVECTOR_CONTENTS (buf),
1441 SCM_BYTEVECTOR_LENGTH (buf),
1442 flg));
1443 }
cc95e00a 1444
d21a1dc8 1445 if (SCM_UNLIKELY (rv == -1))
1bbd0b84 1446 SCM_SYSERROR;
370312ae 1447
d21a1dc8 1448 scm_remember_upto_here (buf);
7cee5b31 1449 return scm_from_int (rv);
370312ae 1450}
1bbd0b84 1451#undef FUNC_NAME
370312ae 1452
a1ec6916 1453SCM_DEFINE (scm_send, "send", 2, 1, 0,
1bbd0b84 1454 (SCM sock, SCM message, SCM flags),
d21a1dc8 1455 "Transmit bytevector @var{message} on socket port @var{sock}.\n"
eefae538
GH
1456 "@var{sock} must already be bound to a destination address. The\n"
1457 "value returned is the number of bytes transmitted --\n"
1458 "it's possible for\n"
1459 "this to be less than the length of @var{message}\n"
1460 "if the socket is\n"
1461 "set to be non-blocking. The optional @var{flags} argument\n"
1462 "is a value or\n"
b380b885 1463 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1464 "Note that the data is written directly to the socket\n"
1465 "file descriptor:\n"
587a3355
MG
1466 "any unflushed buffered port data is ignored.\n\n"
1467 "This operation is defined only for strings containing codepoints\n"
1468 "zero to 255.")
1bbd0b84 1469#define FUNC_NAME s_scm_send
370312ae 1470{
d21a1dc8 1471 int rv, fd, flg;
370312ae 1472
78446828 1473 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1474 SCM_VALIDATE_OPFPORT (1, sock);
587a3355 1475
7cee5b31
MV
1476 if (SCM_UNBNDP (flags))
1477 flg = 0;
1478 else
1479 flg = scm_to_int (flags);
d21a1dc8 1480
ee149d03 1481 fd = SCM_FPORT_FDES (sock);
370312ae 1482
d21a1dc8
LC
1483#if SCM_ENABLE_DEPRECATED == 1
1484 if (SCM_UNLIKELY (scm_is_string (message)))
1485 {
1486 scm_c_issue_deprecation_warning
1487 ("Passing a string to `send' is deprecated, "
1488 "use a bytevector instead.");
1489
1490 /* If the string is wide, see if it can be coerced into a narrow
1491 string. */
1492 if (!scm_i_is_narrow_string (message)
1493 || !scm_i_try_narrow_string (message))
1494 SCM_MISC_ERROR ("the message string is not 8-bit: ~s",
1495 scm_list_1 (message));
1496
1497 SCM_SYSCALL (rv = send (fd,
1498 scm_i_string_chars (message),
1499 scm_i_string_length (message),
1500 flg));
1501 }
1502 else
1503#endif
1504 {
1505 SCM_VALIDATE_BYTEVECTOR (1, message);
1506
1507 SCM_SYSCALL (rv = send (fd,
1508 SCM_BYTEVECTOR_CONTENTS (message),
1509 SCM_BYTEVECTOR_LENGTH (message),
1510 flg));
1511 }
cc95e00a 1512
370312ae 1513 if (rv == -1)
1bbd0b84 1514 SCM_SYSERROR;
396e5506
MV
1515
1516 scm_remember_upto_here_1 (message);
7cee5b31 1517 return scm_from_int (rv);
370312ae 1518}
1bbd0b84 1519#undef FUNC_NAME
370312ae 1520
a1ec6916 1521SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
d21a1dc8 1522 (SCM sock, SCM buf, SCM flags, SCM start, SCM end),
8ab3d8a0
KR
1523 "Receive data from socket port @var{sock} (which must be already\n"
1524 "bound), returning the originating address as well as the data.\n"
1525 "This is usually for use on datagram sockets, but can be used on\n"
1526 "stream-oriented sockets too.\n"
1527 "\n"
d21a1dc8
LC
1528 "The data received is stored in bytevector @var{buf}, using\n"
1529 "either the whole bytevector or just the region between the optional\n"
1530 "@var{start} and @var{end} positions. The size of @var{buf}\n"
1531 "limits the amount of data that can be received. For datagram\n"
8ab3d8a0
KR
1532 "protocols, if a packet larger than this is received then excess\n"
1533 "bytes are irrevocably lost.\n"
1534 "\n"
1535 "The return value is a pair. The @code{car} is the number of\n"
1536 "bytes read. The @code{cdr} is a socket address object which is\n"
d21a1dc8 1537 "where the data came from, or @code{#f} if the origin is\n"
8ab3d8a0
KR
1538 "unknown.\n"
1539 "\n"
1540 "The optional @var{flags} argument is a or bitwise OR\n"
1541 "(@code{logior}) of @code{MSG_OOB}, @code{MSG_PEEK},\n"
1542 "@code{MSG_DONTROUTE} etc.\n"
1543 "\n"
1544 "Data is read directly from the socket file descriptor, any\n"
1545 "buffered port data is ignored.\n"
1546 "\n"
1547 "On a GNU/Linux system @code{recvfrom!} is not multi-threading,\n"
1548 "all threads stop while a @code{recvfrom!} call is in progress.\n"
1549 "An application may need to use @code{select}, @code{O_NONBLOCK}\n"
1550 "or @code{MSG_DONTWAIT} to avoid this.")
1bbd0b84 1551#define FUNC_NAME s_scm_recvfrom
370312ae 1552{
d21a1dc8 1553 int rv, fd, flg;
370312ae 1554 SCM address;
d21a1dc8 1555 size_t offset, cend;
5ee417fc 1556 socklen_t addr_size = MAX_ADDR_SIZE;
f43f3620 1557 scm_t_max_sockaddr addr;
370312ae 1558
34d19ef6 1559 SCM_VALIDATE_OPFPORT (1, sock);
60d02d09 1560 fd = SCM_FPORT_FDES (sock);
396e5506 1561
1146b6cd
GH
1562 if (SCM_UNBNDP (flags))
1563 flg = 0;
370312ae 1564 else
60d02d09 1565 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
370312ae 1566
f43f3620 1567 ((struct sockaddr *) &addr)->sa_family = AF_UNSPEC;
d21a1dc8
LC
1568
1569#if SCM_ENABLE_DEPRECATED == 1
1570 if (SCM_UNLIKELY (scm_is_string (buf)))
1571 {
1572 char *cbuf;
1573
1574 scm_c_issue_deprecation_warning
1575 ("Passing a string to `recvfrom!' is deprecated, "
1576 "use a bytevector instead.");
1577
1578 scm_i_get_substring_spec (scm_i_string_length (buf),
1579 start, &offset, end, &cend);
1580
1581 buf = scm_i_string_start_writing (buf);
1582 cbuf = scm_i_string_writable_chars (buf);
1583
1584 SCM_SYSCALL (rv = recvfrom (fd, cbuf + offset,
1585 cend - offset, flg,
1586 (struct sockaddr *) &addr, &addr_size));
1587 scm_i_string_stop_writing ();
1588 }
1589 else
1590#endif
1591 {
1592 SCM_VALIDATE_BYTEVECTOR (1, buf);
1593
1594 if (SCM_UNBNDP (start))
1595 offset = 0;
1596 else
1597 offset = scm_to_size_t (start);
1598
1599 if (SCM_UNBNDP (end))
1600 cend = SCM_BYTEVECTOR_LENGTH (buf);
1601 else
1602 {
1603 cend = scm_to_size_t (end);
1604 if (SCM_UNLIKELY (cend >= SCM_BYTEVECTOR_LENGTH (buf)
1605 || cend < offset))
1606 scm_out_of_range (FUNC_NAME, end);
1607 }
1608
1609 SCM_SYSCALL (rv = recvfrom (fd,
1610 SCM_BYTEVECTOR_CONTENTS (buf) + offset,
1611 cend - offset, flg,
1612 (struct sockaddr *) &addr, &addr_size));
1613 }
cc95e00a 1614
370312ae 1615 if (rv == -1)
1bbd0b84 1616 SCM_SYSERROR;
d21a1dc8
LC
1617
1618 /* `recvfrom' does not necessarily return an address. Usually nothing
1619 is returned for stream sockets. */
f43f3620
LC
1620 if (((struct sockaddr *) &addr)->sa_family != AF_UNSPEC)
1621 address = _scm_from_sockaddr (&addr, addr_size, FUNC_NAME);
370312ae
GH
1622 else
1623 address = SCM_BOOL_F;
1624
d21a1dc8 1625 scm_remember_upto_here_1 (buf);
f43f3620 1626
e11e83f3 1627 return scm_cons (scm_from_int (rv), address);
0f2d19dd 1628}
1bbd0b84 1629#undef FUNC_NAME
0f2d19dd 1630
9c0129ac
KR
1631SCM_DEFINE (scm_sendto, "sendto", 3, 1, 1,
1632 (SCM sock, SCM message, SCM fam_or_sockaddr, SCM address, SCM args_and_flags),
d21a1dc8 1633 "Transmit bytevector @var{message} on socket port\n"
eefae538 1634 "@var{sock}. The\n"
b7e64f8b 1635 "destination address is specified using the @var{fam_or_sockaddr},\n"
eefae538 1636 "@var{address} and\n"
9c0129ac
KR
1637 "@var{args_and_flags} arguments, or just a socket address object "
1638 "returned by @code{make-socket-address}, in a similar way to the\n"
eefae538
GH
1639 "@code{connect} procedure. @var{args_and_flags} contains\n"
1640 "the usual connection arguments optionally followed by\n"
1641 "a flags argument, which is a value or\n"
b380b885 1642 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1643 "The value returned is the number of bytes transmitted --\n"
1644 "it's possible for\n"
1645 "this to be less than the length of @var{message} if the\n"
1646 "socket is\n"
1647 "set to be non-blocking.\n"
1648 "Note that the data is written directly to the socket\n"
1649 "file descriptor:\n"
587a3355
MG
1650 "any unflushed buffered port data is ignored.\n"
1651 "This operation is defined only for strings containing codepoints\n"
1652 "zero to 255.")
1bbd0b84 1653#define FUNC_NAME s_scm_sendto
370312ae 1654{
d21a1dc8 1655 int rv, fd, flg;
370312ae 1656 struct sockaddr *soka;
9c0129ac 1657 size_t size;
370312ae 1658
78446828 1659 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1660 SCM_VALIDATE_FPORT (1, sock);
ee149d03 1661 fd = SCM_FPORT_FDES (sock);
9c0129ac
KR
1662
1663 if (!scm_is_number (fam_or_sockaddr))
1664 {
1665 /* FAM_OR_SOCKADDR must actually be a `socket address' object. This
1666 means that the following arguments, i.e. ADDRESS and those listed in
1667 ARGS_AND_FLAGS, are the `MSG_' flags. */
1668 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
d223c3fc 1669 if (!scm_is_eq (address, SCM_UNDEFINED))
9c0129ac
KR
1670 args_and_flags = scm_cons (address, args_and_flags);
1671 }
1672 else
1673 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
1674 &args_and_flags, 3, FUNC_NAME, &size);
1675
d2e53ed6 1676 if (scm_is_null (args_and_flags))
370312ae
GH
1677 flg = 0;
1678 else
1679 {
34d19ef6 1680 SCM_VALIDATE_CONS (5, args_and_flags);
e4b265d8 1681 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
370312ae 1682 }
d21a1dc8
LC
1683
1684#if SCM_ENABLE_DEPRECATED == 1
1685 if (SCM_UNLIKELY (scm_is_string (message)))
1686 {
1687 scm_c_issue_deprecation_warning
1688 ("Passing a string to `sendto' is deprecated, "
1689 "use a bytevector instead.");
1690
1691 /* If the string is wide, see if it can be coerced into a narrow
1692 string. */
1693 if (!scm_i_is_narrow_string (message)
1694 || !scm_i_try_narrow_string (message))
1695 SCM_MISC_ERROR ("the message string is not 8-bit: ~s",
1696 scm_list_1 (message));
1697
1698 SCM_SYSCALL (rv = sendto (fd,
1699 scm_i_string_chars (message),
1700 scm_i_string_length (message),
1701 flg, soka, size));
1702 }
1703 else
1704#endif
1705 {
1706 SCM_VALIDATE_BYTEVECTOR (1, message);
1707
1708 SCM_SYSCALL (rv = sendto (fd,
1709 SCM_BYTEVECTOR_CONTENTS (message),
1710 SCM_BYTEVECTOR_LENGTH (message),
1711 flg, soka, size));
1712 }
1713
370312ae 1714 if (rv == -1)
439006bf
GH
1715 {
1716 int save_errno = errno;
1717 free (soka);
1718 errno = save_errno;
1719 SCM_SYSERROR;
1720 }
1721 free (soka);
396e5506
MV
1722
1723 scm_remember_upto_here_1 (message);
e11e83f3 1724 return scm_from_int (rv);
370312ae 1725}
1bbd0b84 1726#undef FUNC_NAME
370312ae
GH
1727\f
1728
1729
1730void
0f2d19dd 1731scm_init_socket ()
0f2d19dd 1732{
370312ae
GH
1733 /* protocol families. */
1734#ifdef AF_UNSPEC
e11e83f3 1735 scm_c_define ("AF_UNSPEC", scm_from_int (AF_UNSPEC));
370312ae
GH
1736#endif
1737#ifdef AF_UNIX
e11e83f3 1738 scm_c_define ("AF_UNIX", scm_from_int (AF_UNIX));
370312ae
GH
1739#endif
1740#ifdef AF_INET
e11e83f3 1741 scm_c_define ("AF_INET", scm_from_int (AF_INET));
370312ae 1742#endif
3453619b 1743#ifdef AF_INET6
e11e83f3 1744 scm_c_define ("AF_INET6", scm_from_int (AF_INET6));
3453619b 1745#endif
370312ae
GH
1746
1747#ifdef PF_UNSPEC
e11e83f3 1748 scm_c_define ("PF_UNSPEC", scm_from_int (PF_UNSPEC));
370312ae
GH
1749#endif
1750#ifdef PF_UNIX
e11e83f3 1751 scm_c_define ("PF_UNIX", scm_from_int (PF_UNIX));
370312ae
GH
1752#endif
1753#ifdef PF_INET
e11e83f3 1754 scm_c_define ("PF_INET", scm_from_int (PF_INET));
370312ae 1755#endif
3453619b 1756#ifdef PF_INET6
e11e83f3 1757 scm_c_define ("PF_INET6", scm_from_int (PF_INET6));
3453619b 1758#endif
370312ae 1759
66c73b76
GH
1760 /* standard addresses. */
1761#ifdef INADDR_ANY
b9bd8526 1762 scm_c_define ("INADDR_ANY", scm_from_ulong (INADDR_ANY));
66c73b76
GH
1763#endif
1764#ifdef INADDR_BROADCAST
b9bd8526 1765 scm_c_define ("INADDR_BROADCAST", scm_from_ulong (INADDR_BROADCAST));
66c73b76
GH
1766#endif
1767#ifdef INADDR_NONE
b9bd8526 1768 scm_c_define ("INADDR_NONE", scm_from_ulong (INADDR_NONE));
66c73b76
GH
1769#endif
1770#ifdef INADDR_LOOPBACK
b9bd8526 1771 scm_c_define ("INADDR_LOOPBACK", scm_from_ulong (INADDR_LOOPBACK));
66c73b76
GH
1772#endif
1773
6f637a1b
KR
1774 /* socket types.
1775
1776 SOCK_PACKET is deliberately omitted, the GNU/Linux socket(2) and
1777 packet(7) advise that it's obsolete and strongly deprecated. */
1778
370312ae 1779#ifdef SOCK_STREAM
e11e83f3 1780 scm_c_define ("SOCK_STREAM", scm_from_int (SOCK_STREAM));
370312ae
GH
1781#endif
1782#ifdef SOCK_DGRAM
e11e83f3 1783 scm_c_define ("SOCK_DGRAM", scm_from_int (SOCK_DGRAM));
370312ae 1784#endif
6f637a1b
KR
1785#ifdef SOCK_SEQPACKET
1786 scm_c_define ("SOCK_SEQPACKET", scm_from_int (SOCK_SEQPACKET));
1787#endif
370312ae 1788#ifdef SOCK_RAW
e11e83f3 1789 scm_c_define ("SOCK_RAW", scm_from_int (SOCK_RAW));
370312ae 1790#endif
6f637a1b
KR
1791#ifdef SOCK_RDM
1792 scm_c_define ("SOCK_RDM", scm_from_int (SOCK_RDM));
1793#endif
370312ae 1794
8fae2bf4
KR
1795 /* setsockopt level.
1796
1797 SOL_IP, SOL_TCP and SOL_UDP are defined on gnu/linux, but not on for
1798 instance NetBSD. We define IPPROTOs because that's what the posix spec
1799 shows in its example at
1800
1801 http://www.opengroup.org/onlinepubs/007904975/functions/getsockopt.html
1802 */
370312ae 1803#ifdef SOL_SOCKET
e11e83f3 1804 scm_c_define ("SOL_SOCKET", scm_from_int (SOL_SOCKET));
370312ae 1805#endif
8fae2bf4
KR
1806#ifdef IPPROTO_IP
1807 scm_c_define ("IPPROTO_IP", scm_from_int (IPPROTO_IP));
370312ae 1808#endif
8fae2bf4
KR
1809#ifdef IPPROTO_TCP
1810 scm_c_define ("IPPROTO_TCP", scm_from_int (IPPROTO_TCP));
370312ae 1811#endif
8fae2bf4
KR
1812#ifdef IPPROTO_UDP
1813 scm_c_define ("IPPROTO_UDP", scm_from_int (IPPROTO_UDP));
370312ae
GH
1814#endif
1815
1816 /* setsockopt names. */
1817#ifdef SO_DEBUG
e11e83f3 1818 scm_c_define ("SO_DEBUG", scm_from_int (SO_DEBUG));
370312ae
GH
1819#endif
1820#ifdef SO_REUSEADDR
e11e83f3 1821 scm_c_define ("SO_REUSEADDR", scm_from_int (SO_REUSEADDR));
370312ae
GH
1822#endif
1823#ifdef SO_STYLE
e11e83f3 1824 scm_c_define ("SO_STYLE", scm_from_int (SO_STYLE));
370312ae
GH
1825#endif
1826#ifdef SO_TYPE
e11e83f3 1827 scm_c_define ("SO_TYPE", scm_from_int (SO_TYPE));
370312ae
GH
1828#endif
1829#ifdef SO_ERROR
e11e83f3 1830 scm_c_define ("SO_ERROR", scm_from_int (SO_ERROR));
370312ae
GH
1831#endif
1832#ifdef SO_DONTROUTE
e11e83f3 1833 scm_c_define ("SO_DONTROUTE", scm_from_int (SO_DONTROUTE));
370312ae
GH
1834#endif
1835#ifdef SO_BROADCAST
e11e83f3 1836 scm_c_define ("SO_BROADCAST", scm_from_int (SO_BROADCAST));
370312ae
GH
1837#endif
1838#ifdef SO_SNDBUF
e11e83f3 1839 scm_c_define ("SO_SNDBUF", scm_from_int (SO_SNDBUF));
370312ae
GH
1840#endif
1841#ifdef SO_RCVBUF
e11e83f3 1842 scm_c_define ("SO_RCVBUF", scm_from_int (SO_RCVBUF));
370312ae
GH
1843#endif
1844#ifdef SO_KEEPALIVE
e11e83f3 1845 scm_c_define ("SO_KEEPALIVE", scm_from_int (SO_KEEPALIVE));
370312ae
GH
1846#endif
1847#ifdef SO_OOBINLINE
e11e83f3 1848 scm_c_define ("SO_OOBINLINE", scm_from_int (SO_OOBINLINE));
370312ae
GH
1849#endif
1850#ifdef SO_NO_CHECK
e11e83f3 1851 scm_c_define ("SO_NO_CHECK", scm_from_int (SO_NO_CHECK));
370312ae
GH
1852#endif
1853#ifdef SO_PRIORITY
e11e83f3 1854 scm_c_define ("SO_PRIORITY", scm_from_int (SO_PRIORITY));
370312ae
GH
1855#endif
1856#ifdef SO_LINGER
e11e83f3 1857 scm_c_define ("SO_LINGER", scm_from_int (SO_LINGER));
370312ae
GH
1858#endif
1859
1860 /* recv/send options. */
8ab3d8a0
KR
1861#ifdef MSG_DONTWAIT
1862 scm_c_define ("MSG_DONTWAIT", scm_from_int (MSG_DONTWAIT));
1863#endif
370312ae 1864#ifdef MSG_OOB
e11e83f3 1865 scm_c_define ("MSG_OOB", scm_from_int (MSG_OOB));
370312ae
GH
1866#endif
1867#ifdef MSG_PEEK
e11e83f3 1868 scm_c_define ("MSG_PEEK", scm_from_int (MSG_PEEK));
370312ae
GH
1869#endif
1870#ifdef MSG_DONTROUTE
e11e83f3 1871 scm_c_define ("MSG_DONTROUTE", scm_from_int (MSG_DONTROUTE));
370312ae
GH
1872#endif
1873
b4e15479
SJ
1874#ifdef __MINGW32__
1875 scm_i_init_socket_Win32 ();
1876#endif
1877
1c80707c
MV
1878#ifdef IP_ADD_MEMBERSHIP
1879 scm_c_define ("IP_ADD_MEMBERSHIP", scm_from_int (IP_ADD_MEMBERSHIP));
1880 scm_c_define ("IP_DROP_MEMBERSHIP", scm_from_int (IP_DROP_MEMBERSHIP));
1881#endif
1882
511246a1
TCM
1883#ifdef IP_MULTICAST_TTL
1884 scm_c_define ("IP_MULTICAST_TTL", scm_from_int ( IP_MULTICAST_TTL));
1885#endif
1886
1887#ifdef IP_MULTICAST_IF
1888 scm_c_define ("IP_MULTICAST_IF", scm_from_int ( IP_MULTICAST_IF));
1889#endif
1890
0f2d19dd 1891 scm_add_feature ("socket");
370312ae 1892
a0599745 1893#include "libguile/socket.x"
0f2d19dd
JB
1894}
1895
89e00824
ML
1896
1897/*
1898 Local Variables:
1899 c-file-style: "gnu"
1900 End:
1901*/