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