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