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