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