*** empty log message ***
[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"
629 "interface index number, on systems supporting that.")
1bbd0b84 630#define FUNC_NAME s_scm_setsockopt
0f2d19dd 631{
370312ae 632 int fd;
1c80707c
MV
633
634 int opt_int;
370312ae 635#ifdef HAVE_STRUCT_LINGER
1c80707c 636 struct linger opt_linger;
370312ae 637#endif
ecc9f40f
MV
638
639#if HAVE_STRUCT_IP_MREQ
1c80707c 640 struct ip_mreq opt_mreq;
ecc9f40f 641#endif
1c80707c
MV
642
643 const void *optval = NULL;
644 socklen_t optlen = 0;
645
370312ae 646 int ilevel, ioptname;
439006bf 647
78446828 648 sock = SCM_COERCE_OUTPORT (sock);
439006bf
GH
649
650 SCM_VALIDATE_OPFPORT (1, sock);
7cee5b31
MV
651 ilevel = scm_to_int (level);
652 ioptname = scm_to_int (optname);
439006bf 653
ee149d03 654 fd = SCM_FPORT_FDES (sock);
1c80707c 655
439006bf 656 if (ilevel == SOL_SOCKET)
370312ae 657 {
439006bf
GH
658#ifdef SO_LINGER
659 if (ioptname == SO_LINGER)
660 {
370312ae 661#ifdef HAVE_STRUCT_LINGER
d2e53ed6 662 SCM_ASSERT (scm_is_pair (value), value, SCM_ARG4, FUNC_NAME);
1c80707c
MV
663 opt_linger.l_onoff = scm_to_int (SCM_CAR (value));
664 opt_linger.l_linger = scm_to_int (SCM_CDR (value));
665 optlen = sizeof (struct linger);
666 optval = &opt_linger;
370312ae 667#else
d2e53ed6 668 SCM_ASSERT (scm_is_pair (value), value, SCM_ARG4, FUNC_NAME);
1c80707c 669 opt_int = scm_to_int (SCM_CAR (value));
439006bf 670 /* timeout is ignored, but may as well validate it. */
1c80707c
MV
671 scm_to_int (SCM_CDR (value));
672 optlen = sizeof (int);
673 optval = &opt_int;
439006bf
GH
674#endif
675 }
676 else
677#endif
678 if (0
370312ae 679#ifdef SO_SNDBUF
439006bf 680 || ioptname == SO_SNDBUF
370312ae
GH
681#endif
682#ifdef SO_RCVBUF
439006bf 683 || ioptname == SO_RCVBUF
370312ae 684#endif
439006bf
GH
685 )
686 {
1c80707c
MV
687 opt_int = scm_to_int (value);
688 optlen = sizeof (size_t);
689 optval = &opt_int;
439006bf
GH
690 }
691 }
1c80707c 692
ecc9f40f 693#if HAVE_STRUCT_IP_MREQ
1c80707c
MV
694 if (ilevel == IPPROTO_IP &&
695 (ioptname == IP_ADD_MEMBERSHIP || ioptname == IP_DROP_MEMBERSHIP))
0f2d19dd 696 {
1c80707c
MV
697 /* Fourth argument must be a pair of addresses. */
698 SCM_ASSERT (scm_is_pair (value), value, SCM_ARG4, FUNC_NAME);
699 opt_mreq.imr_multiaddr.s_addr = htonl (scm_to_ulong (SCM_CAR (value)));
700 opt_mreq.imr_interface.s_addr = htonl (scm_to_ulong (SCM_CDR (value)));
701 optlen = sizeof (opt_mreq);
702 optval = &opt_mreq;
703 }
ecc9f40f 704#endif
439006bf 705
1c80707c
MV
706 if (optval == NULL)
707 {
708 /* Most options take an int. */
709 opt_int = scm_to_int (value);
710 optlen = sizeof (int);
711 optval = &opt_int;
0f2d19dd 712 }
1c80707c
MV
713
714 if (setsockopt (fd, ilevel, ioptname, optval, optlen) == -1)
1bbd0b84 715 SCM_SYSERROR;
370312ae 716 return SCM_UNSPECIFIED;
0f2d19dd 717}
1bbd0b84 718#undef FUNC_NAME
0f2d19dd 719
a1ec6916 720SCM_DEFINE (scm_shutdown, "shutdown", 2, 0, 0,
1bbd0b84 721 (SCM sock, SCM how),
b380b885 722 "Sockets can be closed simply by using @code{close-port}. The\n"
bb2c02f2 723 "@code{shutdown} procedure allows reception or transmission on a\n"
b380b885
MD
724 "connection to be shut down individually, according to the parameter\n"
725 "@var{how}:\n\n"
726 "@table @asis\n"
727 "@item 0\n"
728 "Stop receiving data for this socket. If further data arrives, reject it.\n"
729 "@item 1\n"
730 "Stop trying to transmit data from this socket. Discard any\n"
731 "data waiting to be sent. Stop looking for acknowledgement of\n"
732 "data already sent; don't retransmit it if it is lost.\n"
733 "@item 2\n"
734 "Stop both reception and transmission.\n"
735 "@end table\n\n"
736 "The return value is unspecified.")
1bbd0b84 737#define FUNC_NAME s_scm_shutdown
0f2d19dd 738{
370312ae 739 int fd;
78446828 740 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 741 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 742 fd = SCM_FPORT_FDES (sock);
7cee5b31 743 if (shutdown (fd, scm_to_signed_integer (how, 0, 2)) == -1)
1bbd0b84 744 SCM_SYSERROR;
370312ae
GH
745 return SCM_UNSPECIFIED;
746}
1bbd0b84 747#undef FUNC_NAME
0f2d19dd 748
370312ae
GH
749/* convert fam/address/args into a sockaddr of the appropriate type.
750 args is modified by removing the arguments actually used.
751 which_arg and proc are used when reporting errors:
752 which_arg is the position of address in the original argument list.
753 proc is the name of the original procedure.
754 size returns the size of the structure allocated. */
755
9c0129ac 756static SCM_C_INLINE_KEYWORD struct sockaddr *
439006bf 757scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
9c0129ac 758 const char *proc, size_t *size)
3453619b 759#define FUNC_NAME proc
370312ae
GH
760{
761 switch (fam)
0f2d19dd 762 {
370312ae
GH
763 case AF_INET:
764 {
370312ae 765 struct sockaddr_in *soka;
3453619b
GH
766 unsigned long addr;
767 int port;
370312ae 768
3453619b
GH
769 SCM_VALIDATE_ULONG_COPY (which_arg, address, addr);
770 SCM_VALIDATE_CONS (which_arg + 1, *args);
7cee5b31 771 port = scm_to_int (SCM_CAR (*args));
3453619b 772 *args = SCM_CDR (*args);
67329a9e 773 soka = (struct sockaddr_in *) scm_malloc (sizeof (struct sockaddr_in));
9c0129ac 774
93b047f4 775#if HAVE_STRUCT_SOCKADDR_SIN_LEN
3453619b
GH
776 soka->sin_len = sizeof (struct sockaddr_in);
777#endif
370312ae 778 soka->sin_family = AF_INET;
3453619b
GH
779 soka->sin_addr.s_addr = htonl (addr);
780 soka->sin_port = htons (port);
370312ae
GH
781 *size = sizeof (struct sockaddr_in);
782 return (struct sockaddr *) soka;
783 }
a57a0b1e 784#ifdef HAVE_IPV6
3453619b
GH
785 case AF_INET6:
786 {
787 /* see RFC2553. */
788 int port;
789 struct sockaddr_in6 *soka;
790 unsigned long flowinfo = 0;
791 unsigned long scope_id = 0;
792
3453619b 793 SCM_VALIDATE_CONS (which_arg + 1, *args);
7cee5b31 794 port = scm_to_int (SCM_CAR (*args));
3453619b 795 *args = SCM_CDR (*args);
d2e53ed6 796 if (scm_is_pair (*args))
3453619b
GH
797 {
798 SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
799 *args = SCM_CDR (*args);
d2e53ed6 800 if (scm_is_pair (*args))
3453619b
GH
801 {
802 SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
803 scope_id);
804 *args = SCM_CDR (*args);
805 }
806 }
67329a9e 807 soka = (struct sockaddr_in6 *) scm_malloc (sizeof (struct sockaddr_in6));
9c0129ac 808
93b047f4 809#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
3453619b
GH
810 soka->sin6_len = sizeof (struct sockaddr_in6);
811#endif
812 soka->sin6_family = AF_INET6;
7cee5b31 813 scm_to_ipv6 (soka->sin6_addr.s6_addr, address);
5a525b84 814 soka->sin6_port = htons (port);
3453619b 815 soka->sin6_flowinfo = flowinfo;
5a525b84 816#ifdef HAVE_SIN6_SCOPE_ID
3453619b 817 soka->sin6_scope_id = scope_id;
5a525b84 818#endif
3453619b
GH
819 *size = sizeof (struct sockaddr_in6);
820 return (struct sockaddr *) soka;
821 }
822#endif
1ba8c23a 823#ifdef HAVE_UNIX_DOMAIN_SOCKETS
370312ae
GH
824 case AF_UNIX:
825 {
826 struct sockaddr_un *soka;
439006bf 827 int addr_size;
7f9994d9
MV
828 char *c_address;
829
830 scm_frame_begin (0);
831
832 c_address = scm_to_locale_string (address);
833 scm_frame_free (c_address);
370312ae 834
439006bf
GH
835 /* the static buffer size in sockaddr_un seems to be arbitrary
836 and not necessarily a hard limit. e.g., the glibc manual
837 suggests it may be possible to declare it size 0. let's
838 ignore it. if the O/S doesn't like the size it will cause
839 connect/bind etc., to fail. sun_path is always the last
840 member of the structure. */
841 addr_size = sizeof (struct sockaddr_un)
7f9994d9 842 + max (0, strlen (c_address) + 1 - (sizeof soka->sun_path));
67329a9e 843 soka = (struct sockaddr_un *) scm_malloc (addr_size);
439006bf
GH
844 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
845 soka->sun_family = AF_UNIX;
7f9994d9 846 strcpy (soka->sun_path, c_address);
439006bf 847 *size = SUN_LEN (soka);
7f9994d9
MV
848
849 scm_frame_end ();
370312ae
GH
850 return (struct sockaddr *) soka;
851 }
0e958795 852#endif
370312ae 853 default:
e11e83f3 854 scm_out_of_range (proc, scm_from_int (fam));
0f2d19dd 855 }
0f2d19dd 856}
3453619b 857#undef FUNC_NAME
9c0129ac
KR
858
859SCM_DEFINE (scm_connect, "connect", 2, 1, 1,
860 (SCM sock, SCM fam_or_sockaddr, SCM address, SCM args),
eefae538 861 "Initiate a connection from a socket using a specified address\n"
3453619b
GH
862 "family to the address\n"
863 "specified by @var{address} and possibly @var{args}.\n"
864 "The format required for @var{address}\n"
865 "and @var{args} depends on the family of the socket.\n\n"
b380b885 866 "For a socket of family @code{AF_UNIX},\n"
3453619b 867 "only @var{address} is specified and must be a string with the\n"
b380b885
MD
868 "filename where the socket is to be created.\n\n"
869 "For a socket of family @code{AF_INET},\n"
3453619b
GH
870 "@var{address} must be an integer IPv4 host address and\n"
871 "@var{args} must be a single integer port number.\n\n"
872 "For a socket of family @code{AF_INET6},\n"
873 "@var{address} must be an integer IPv6 host address and\n"
874 "@var{args} may be up to three integers:\n"
875 "port [flowinfo] [scope_id],\n"
876 "where flowinfo and scope_id default to zero.\n\n"
9c0129ac
KR
877 "Alternatively, the second argument can be a socket address object "
878 "as returned by @code{make-socket-address}, in which case the "
879 "no additional arguments should be passed.\n\n"
b380b885 880 "The return value is unspecified.")
1bbd0b84 881#define FUNC_NAME s_scm_connect
0f2d19dd 882{
370312ae
GH
883 int fd;
884 struct sockaddr *soka;
9c0129ac 885 size_t size;
0f2d19dd 886
78446828 887 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 888 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 889 fd = SCM_FPORT_FDES (sock);
9c0129ac
KR
890
891 if (address == SCM_UNDEFINED)
892 /* No third argument was passed to FAM_OR_SOCKADDR must actually be a
893 `socket address' object. */
894 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
895 else
896 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
897 &args, 3, FUNC_NAME, &size);
898
370312ae 899 if (connect (fd, soka, size) == -1)
439006bf
GH
900 {
901 int save_errno = errno;
9c0129ac 902
439006bf
GH
903 free (soka);
904 errno = save_errno;
905 SCM_SYSERROR;
906 }
907 free (soka);
370312ae 908 return SCM_UNSPECIFIED;
0f2d19dd 909}
1bbd0b84 910#undef FUNC_NAME
0f2d19dd 911
9c0129ac
KR
912SCM_DEFINE (scm_bind, "bind", 2, 1, 1,
913 (SCM sock, SCM fam_or_sockaddr, SCM address, SCM args),
eefae538 914 "Assign an address to the socket port @var{sock}.\n"
b380b885
MD
915 "Generally this only needs to be done for server sockets,\n"
916 "so they know where to look for incoming connections. A socket\n"
917 "without an address will be assigned one automatically when it\n"
918 "starts communicating.\n\n"
eefae538
GH
919 "The format of @var{address} and @var{args} depends\n"
920 "on the family of the socket.\n\n"
b380b885 921 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
eefae538
GH
922 "is specified and must be a string with the filename where\n"
923 "the socket is to be created.\n\n"
924 "For a socket of family @code{AF_INET}, @var{address}\n"
925 "must be an integer IPv4 address and @var{args}\n"
926 "must be a single integer port number.\n\n"
927 "The values of the following variables can also be used for\n"
928 "@var{address}:\n\n"
b380b885
MD
929 "@defvar INADDR_ANY\n"
930 "Allow connections from any address.\n"
931 "@end defvar\n\n"
932 "@defvar INADDR_LOOPBACK\n"
933 "The address of the local host using the loopback device.\n"
934 "@end defvar\n\n"
935 "@defvar INADDR_BROADCAST\n"
936 "The broadcast address on the local network.\n"
937 "@end defvar\n\n"
938 "@defvar INADDR_NONE\n"
939 "No address.\n"
940 "@end defvar\n\n"
eefae538
GH
941 "For a socket of family @code{AF_INET6}, @var{address}\n"
942 "must be an integer IPv6 address and @var{args}\n"
943 "may be up to three integers:\n"
944 "port [flowinfo] [scope_id],\n"
945 "where flowinfo and scope_id default to zero.\n\n"
9c0129ac
KR
946 "Alternatively, the second argument can be a socket address object "
947 "as returned by @code{make-socket-address}, in which case the "
948 "no additional arguments should be passed.\n\n"
b380b885 949 "The return value is unspecified.")
1bbd0b84 950#define FUNC_NAME s_scm_bind
370312ae 951{
370312ae 952 struct sockaddr *soka;
9c0129ac 953 size_t size;
370312ae
GH
954 int fd;
955
78446828 956 sock = SCM_COERCE_OUTPORT (sock);
439006bf 957 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 958 fd = SCM_FPORT_FDES (sock);
9c0129ac
KR
959
960 if (address == SCM_UNDEFINED)
961 /* No third argument was passed to FAM_OR_SOCKADDR must actually be a
962 `socket address' object. */
963 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
964 else
965 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
966 &args, 3, FUNC_NAME, &size);
967
968
439006bf
GH
969 if (bind (fd, soka, size) == -1)
970 {
971 int save_errno = errno;
9c0129ac 972
439006bf
GH
973 free (soka);
974 errno = save_errno;
1bbd0b84 975 SCM_SYSERROR;
439006bf
GH
976 }
977 free (soka);
370312ae
GH
978 return SCM_UNSPECIFIED;
979}
1bbd0b84 980#undef FUNC_NAME
370312ae 981
a1ec6916 982SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
1bbd0b84 983 (SCM sock, SCM backlog),
eefae538 984 "Enable @var{sock} to accept connection\n"
b380b885
MD
985 "requests. @var{backlog} is an integer specifying\n"
986 "the maximum length of the queue for pending connections.\n"
eefae538
GH
987 "If the queue fills, new clients will fail to connect until\n"
988 "the server calls @code{accept} to accept a connection from\n"
989 "the queue.\n\n"
b380b885 990 "The return value is unspecified.")
1bbd0b84 991#define FUNC_NAME s_scm_listen
370312ae
GH
992{
993 int fd;
78446828 994 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 995 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 996 fd = SCM_FPORT_FDES (sock);
7cee5b31 997 if (listen (fd, scm_to_int (backlog)) == -1)
1bbd0b84 998 SCM_SYSERROR;
370312ae
GH
999 return SCM_UNSPECIFIED;
1000}
1bbd0b84 1001#undef FUNC_NAME
370312ae
GH
1002
1003/* Put the components of a sockaddr into a new SCM vector. */
9c0129ac
KR
1004static SCM_C_INLINE_KEYWORD SCM
1005_scm_from_sockaddr (const struct sockaddr *address, unsigned addr_size,
aca23b65 1006 const char *proc)
0f2d19dd 1007{
370312ae 1008 short int fam = address->sa_family;
1d1559ce 1009 SCM result =SCM_EOL;
34d19ef6 1010
439006bf 1011
5a525b84 1012 switch (fam)
0f2d19dd 1013 {
5a525b84
GH
1014 case AF_INET:
1015 {
e1368a8d 1016 const struct sockaddr_in *nad = (struct sockaddr_in *) address;
439006bf 1017
1d1559ce 1018 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
34d19ef6 1019
4057a3e0
MV
1020 SCM_SIMPLE_VECTOR_SET(result, 0,
1021 scm_from_short (fam));
1022 SCM_SIMPLE_VECTOR_SET(result, 1,
1023 scm_from_ulong (ntohl (nad->sin_addr.s_addr)));
1024 SCM_SIMPLE_VECTOR_SET(result, 2,
1025 scm_from_ushort (ntohs (nad->sin_port)));
5a525b84
GH
1026 }
1027 break;
a57a0b1e 1028#ifdef HAVE_IPV6
5a525b84
GH
1029 case AF_INET6:
1030 {
e1368a8d 1031 const struct sockaddr_in6 *nad = (struct sockaddr_in6 *) address;
5a525b84 1032
1d1559ce 1033 result = scm_c_make_vector (5, SCM_UNSPECIFIED);
4057a3e0
MV
1034 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_short (fam));
1035 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_ipv6 (nad->sin6_addr.s6_addr));
1036 SCM_SIMPLE_VECTOR_SET(result, 2, scm_from_ushort (ntohs (nad->sin6_port)));
1037 SCM_SIMPLE_VECTOR_SET(result, 3, scm_from_uint32 (nad->sin6_flowinfo));
5a525b84 1038#ifdef HAVE_SIN6_SCOPE_ID
4057a3e0 1039 SCM_SIMPLE_VECTOR_SET(result, 4, scm_from_ulong (nad->sin6_scope_id));
5a525b84 1040#else
4057a3e0 1041 SCM_SIMPLE_VECTOR_SET(result, 4, SCM_INUM0);
0e958795 1042#endif
5a525b84
GH
1043 }
1044 break;
1045#endif
1046#ifdef HAVE_UNIX_DOMAIN_SOCKETS
1047 case AF_UNIX:
1048 {
e1368a8d 1049 const struct sockaddr_un *nad = (struct sockaddr_un *) address;
439006bf 1050
1d1559ce 1051 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
34d19ef6 1052
4057a3e0 1053 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_short (fam));
aca23b65
MV
1054 /* When addr_size is not enough to cover sun_path, do not try
1055 to access it. */
1056 if (addr_size <= offsetof (struct sockaddr_un, sun_path))
4057a3e0 1057 SCM_SIMPLE_VECTOR_SET(result, 1, SCM_BOOL_F);
aca23b65 1058 else
4057a3e0 1059 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_locale_string (nad->sun_path));
5a525b84
GH
1060 }
1061 break;
1062#endif
1063 default:
9c0129ac
KR
1064 result = SCM_UNSPECIFIED;
1065 scm_misc_error (proc, "unrecognised address family: ~A",
e11e83f3 1066 scm_list_1 (scm_from_int (fam)));
9c0129ac 1067
0f2d19dd 1068 }
1d1559ce 1069 return result;
370312ae
GH
1070}
1071
9c0129ac
KR
1072/* The publicly-visible function. Return a Scheme object representing
1073 ADDRESS, an address of ADDR_SIZE bytes. */
1074SCM
1075scm_from_sockaddr (const struct sockaddr *address, unsigned addr_size)
1076{
1077 return (_scm_from_sockaddr (address, addr_size, "scm_from_sockaddr"));
1078}
1079
1080/* Convert ADDRESS, an address object returned by either
1081 `scm_from_sockaddr ()' or `scm_make_socket_address ()', into its C
1082 representation. On success, a non-NULL pointer is returned and
1083 ADDRESS_SIZE is updated to the actual size (in bytes) of the returned
1084 address. The result must eventually be freed using `free ()'. */
1085struct sockaddr *
1086scm_to_sockaddr (SCM address, size_t *address_size)
1087#define FUNC_NAME "scm_to_sockaddr"
1088{
1089 short int family;
1090 struct sockaddr *c_address = NULL;
1091
1092 SCM_VALIDATE_VECTOR (1, address);
1093
1094 *address_size = 0;
1095 family = scm_to_short (SCM_SIMPLE_VECTOR_REF (address, 0));
1096
1097 switch (family)
1098 {
1099 case AF_INET:
1100 {
1101 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 3)
1102 scm_misc_error (FUNC_NAME,
1103 "invalid inet address representation: ~A",
1104 scm_list_1 (address));
1105 else
1106 {
1107 struct sockaddr_in c_inet;
1108
1109 c_inet.sin_addr.s_addr =
1110 htonl (scm_to_ulong (SCM_SIMPLE_VECTOR_REF (address, 1)));
1111 c_inet.sin_port =
1112 htons (scm_to_ushort (SCM_SIMPLE_VECTOR_REF (address, 2)));
1113 c_inet.sin_family = AF_INET;
1114
1115 *address_size = sizeof (c_inet);
1116 c_address = scm_malloc (sizeof (c_inet));
1117 memcpy (c_address, &c_inet, sizeof (c_inet));
1118 }
1119
1120 break;
1121 }
1122
1123#ifdef HAVE_IPV6
1124 case AF_INET6:
1125 {
1126 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 5)
1127 scm_misc_error (FUNC_NAME, "invalid inet6 address representation: ~A",
1128 scm_list_1 (address));
1129 else
1130 {
1131 struct sockaddr_in6 c_inet6;
1132
1133 scm_to_ipv6 (c_inet6.sin6_addr.s6_addr, address);
1134 c_inet6.sin6_port =
1135 htons (scm_to_ushort (SCM_SIMPLE_VECTOR_REF (address, 2)));
1136 c_inet6.sin6_flowinfo =
1137 scm_to_uint32 (SCM_SIMPLE_VECTOR_REF (address, 3));
1138#ifdef HAVE_SIN6_SCOPE_ID
1139 c_inet6.sin6_scope_id =
1140 scm_to_ulong (SCM_SIMPLE_VECTOR_REF (address, 4));
1141#endif
1142
1143 c_inet6.sin6_family = AF_INET6;
1144
1145 *address_size = sizeof (c_inet6);
1146 c_address = scm_malloc (sizeof (c_inet6));
1147 memcpy (c_address, &c_inet6, sizeof (c_inet6));
1148 }
1149
1150 break;
1151 }
1152#endif
1153
1154#ifdef HAVE_UNIX_DOMAIN_SOCKETS
1155 case AF_UNIX:
1156 {
1157 if (SCM_SIMPLE_VECTOR_LENGTH (address) != 2)
1158 scm_misc_error (FUNC_NAME, "invalid unix address representation: ~A",
1159 scm_list_1 (address));
1160 else
1161 {
1162 SCM path;
1163 size_t path_len = 0;
1164
1165 path = SCM_SIMPLE_VECTOR_REF (address, 1);
1166 if ((!scm_is_string (path)) && (path != SCM_BOOL_F))
1167 scm_misc_error (FUNC_NAME, "invalid unix address "
1168 "path: ~A", scm_list_1 (path));
1169 else
1170 {
1171 struct sockaddr_un c_unix;
1172
1173 if (path == SCM_BOOL_F)
1174 path_len = 0;
1175 else
1176 path_len = scm_c_string_length (path);
1177
1178#ifdef UNIX_PATH_MAX
1179 if (path_len >= UNIX_PATH_MAX)
1180#else
1181/* We can hope that this limit will eventually vanish, at least on GNU.
1182 However, currently, while glibc doesn't define `UNIX_PATH_MAX', it
1183 documents it has being limited to 108 bytes. */
1184 if (path_len >= sizeof (c_unix.sun_path))
1185#endif
1186 scm_misc_error (FUNC_NAME, "unix address path "
1187 "too long: ~A", scm_list_1 (path));
1188 else
1189 {
1190 if (path_len)
1191 {
1192 scm_to_locale_stringbuf (path, c_unix.sun_path,
1193#ifdef UNIX_PATH_MAX
1194 UNIX_PATH_MAX);
1195#else
1196 sizeof (c_unix.sun_path));
1197#endif
1198 c_unix.sun_path[path_len] = '\0';
1199
1200 /* Sanity check. */
1201 if (strlen (c_unix.sun_path) != path_len)
1202 scm_misc_error (FUNC_NAME, "unix address path "
1203 "contains nul characters: ~A",
1204 scm_list_1 (path));
1205 }
1206 else
1207 c_unix.sun_path[0] = '\0';
1208
1209 c_unix.sun_family = AF_UNIX;
1210
1211 *address_size = SUN_LEN (&c_unix);
1212 c_address = scm_malloc (sizeof (c_unix));
1213 memcpy (c_address, &c_unix, sizeof (c_unix));
1214 }
1215 }
1216 }
1217
1218 break;
1219 }
1220#endif
1221
1222 default:
1223 scm_misc_error (FUNC_NAME, "unrecognised address family: ~A",
1224 scm_list_1 (scm_from_ushort (family)));
1225 }
1226
1227 return c_address;
1228}
1229#undef FUNC_NAME
1230
1231
1232/* Return a newly-allocated `sockaddr' structure that reflects ADDRESS, being
1233 an address of family FAMILY, with the family-specific parameters ARGS (see
1234 the description of `connect' for details). The returned structure may be
1235 freed using `free ()'. */
1236struct sockaddr *
1237scm_c_make_socket_address (SCM family, SCM address, SCM args,
1238 size_t *address_size)
1239{
1240 size_t size;
1241 struct sockaddr *soka;
1242
1243 soka = scm_fill_sockaddr (scm_to_ushort (family), address, &args, 1,
1244 "scm_c_make_socket_address", &size);
1245
1246 return soka;
1247}
1248
1249SCM_DEFINE (scm_make_socket_address, "make-socket-address", 2, 0, 1,
1250 (SCM family, SCM address, SCM args),
1251 "Return a Scheme address object that reflects @var{address}, "
1252 "being an address of family @var{family}, with the "
1253 "family-specific parameters @var{args} (see the description of "
1254 "@code{connect} for details).")
1255#define FUNC_NAME s_scm_make_socket_address
1256{
1257 struct sockaddr *c_address;
1258 size_t c_address_size;
1259
1260 c_address = scm_c_make_socket_address (family, address, args,
1261 &c_address_size);
1262 if (!c_address)
1263 return SCM_BOOL_F;
1264
1265 return (scm_from_sockaddr (c_address, c_address_size));
1266}
1267#undef FUNC_NAME
1268
1269\f
439006bf
GH
1270/* calculate the size of a buffer large enough to hold any supported
1271 sockaddr type. if the buffer isn't large enough, certain system
1272 calls will return a truncated address. */
370312ae 1273
439006bf
GH
1274#if defined (HAVE_UNIX_DOMAIN_SOCKETS)
1275#define MAX_SIZE_UN sizeof (struct sockaddr_un)
0e958795 1276#else
439006bf 1277#define MAX_SIZE_UN 0
0e958795 1278#endif
439006bf 1279
a57a0b1e 1280#if defined (HAVE_IPV6)
5a525b84
GH
1281#define MAX_SIZE_IN6 sizeof (struct sockaddr_in6)
1282#else
1283#define MAX_SIZE_IN6 0
1284#endif
1285
1286#define MAX_ADDR_SIZE max (max (sizeof (struct sockaddr_in), MAX_SIZE_IN6),\
1287 MAX_SIZE_UN)
0f2d19dd 1288
a1ec6916 1289SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1bbd0b84 1290 (SCM sock),
eefae538
GH
1291 "Accept a connection on a bound, listening socket.\n"
1292 "If there\n"
1293 "are no pending connections in the queue, wait until\n"
1294 "one is available unless the non-blocking option has been\n"
1295 "set on the socket.\n\n"
b380b885 1296 "The return value is a\n"
eefae538
GH
1297 "pair in which the @emph{car} is a new socket port for the\n"
1298 "connection and\n"
1299 "the @emph{cdr} is an object with address information about the\n"
1300 "client which initiated the connection.\n\n"
1301 "@var{sock} does not become part of the\n"
b380b885 1302 "connection and will continue to accept new requests.")
1bbd0b84 1303#define FUNC_NAME s_scm_accept
0f2d19dd 1304{
370312ae
GH
1305 int fd;
1306 int newfd;
1307 SCM address;
1308 SCM newsock;
5ee417fc 1309 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1310 char max_addr[MAX_ADDR_SIZE];
1311 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 1312
78446828 1313 sock = SCM_COERCE_OUTPORT (sock);
439006bf 1314 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1315 fd = SCM_FPORT_FDES (sock);
439006bf
GH
1316 newfd = accept (fd, addr, &addr_size);
1317 if (newfd == -1)
1318 SCM_SYSERROR;
1319 newsock = SCM_SOCK_FD_TO_PORT (newfd);
9c0129ac 1320 address = _scm_from_sockaddr (addr, addr_size, FUNC_NAME);
370312ae 1321 return scm_cons (newsock, address);
0f2d19dd 1322}
1bbd0b84 1323#undef FUNC_NAME
0f2d19dd 1324
a1ec6916 1325SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1bbd0b84 1326 (SCM sock),
eefae538 1327 "Return the address of @var{sock}, in the same form as the\n"
1e6808ea
MG
1328 "object returned by @code{accept}. On many systems the address\n"
1329 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1bbd0b84 1330#define FUNC_NAME s_scm_getsockname
0f2d19dd 1331{
370312ae 1332 int fd;
5ee417fc 1333 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1334 char max_addr[MAX_ADDR_SIZE];
1335 struct sockaddr *addr = (struct sockaddr *) max_addr;
1336
78446828 1337 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1338 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1339 fd = SCM_FPORT_FDES (sock);
439006bf 1340 if (getsockname (fd, addr, &addr_size) == -1)
1bbd0b84 1341 SCM_SYSERROR;
9c0129ac 1342 return _scm_from_sockaddr (addr, addr_size, FUNC_NAME);
0f2d19dd 1343}
1bbd0b84 1344#undef FUNC_NAME
0f2d19dd 1345
a1ec6916 1346SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1bbd0b84 1347 (SCM sock),
eefae538 1348 "Return the address that @var{sock}\n"
1e6808ea
MG
1349 "is connected to, in the same form as the object returned by\n"
1350 "@code{accept}. On many systems the address of a socket in the\n"
1351 "@code{AF_FILE} namespace cannot be read.")
1bbd0b84 1352#define FUNC_NAME s_scm_getpeername
0f2d19dd 1353{
370312ae 1354 int fd;
5ee417fc 1355 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1356 char max_addr[MAX_ADDR_SIZE];
1357 struct sockaddr *addr = (struct sockaddr *) max_addr;
1358
78446828 1359 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1360 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1361 fd = SCM_FPORT_FDES (sock);
439006bf 1362 if (getpeername (fd, addr, &addr_size) == -1)
1bbd0b84 1363 SCM_SYSERROR;
9c0129ac 1364 return _scm_from_sockaddr (addr, addr_size, FUNC_NAME);
0f2d19dd 1365}
1bbd0b84 1366#undef FUNC_NAME
0f2d19dd 1367
a1ec6916 1368SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1bbd0b84 1369 (SCM sock, SCM buf, SCM flags),
eefae538
GH
1370 "Receive data from a socket port.\n"
1371 "@var{sock} must already\n"
b380b885
MD
1372 "be bound to the address from which data is to be received.\n"
1373 "@var{buf} is a string into which\n"
eefae538
GH
1374 "the data will be written. The size of @var{buf} limits\n"
1375 "the amount of\n"
b380b885 1376 "data which can be received: in the case of packet\n"
eefae538
GH
1377 "protocols, if a packet larger than this limit is encountered\n"
1378 "then some data\n"
b380b885
MD
1379 "will be irrevocably lost.\n\n"
1380 "The optional @var{flags} argument is a value or\n"
1381 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1382 "The value returned is the number of bytes read from the\n"
1383 "socket.\n\n"
1384 "Note that the data is read directly from the socket file\n"
1385 "descriptor:\n"
09831f94 1386 "any unread buffered port data is ignored.")
1bbd0b84 1387#define FUNC_NAME s_scm_recv
0f2d19dd 1388{
370312ae
GH
1389 int rv;
1390 int fd;
1391 int flg;
cc95e00a
MV
1392 char *dest;
1393 size_t len;
370312ae 1394
34d19ef6
HWN
1395 SCM_VALIDATE_OPFPORT (1, sock);
1396 SCM_VALIDATE_STRING (2, buf);
7cee5b31
MV
1397 if (SCM_UNBNDP (flags))
1398 flg = 0;
1399 else
1400 flg = scm_to_int (flags);
ee149d03 1401 fd = SCM_FPORT_FDES (sock);
370312ae 1402
cc95e00a
MV
1403 len = scm_i_string_length (buf);
1404 dest = scm_i_string_writable_chars (buf);
1405 SCM_SYSCALL (rv = recv (fd, dest, len, flg));
1406 scm_i_string_stop_writing ();
1407
370312ae 1408 if (rv == -1)
1bbd0b84 1409 SCM_SYSERROR;
370312ae 1410
396e5506 1411 scm_remember_upto_here_1 (buf);
7cee5b31 1412 return scm_from_int (rv);
370312ae 1413}
1bbd0b84 1414#undef FUNC_NAME
370312ae 1415
a1ec6916 1416SCM_DEFINE (scm_send, "send", 2, 1, 0,
1bbd0b84 1417 (SCM sock, SCM message, SCM flags),
eefae538
GH
1418 "Transmit the string @var{message} on a socket port @var{sock}.\n"
1419 "@var{sock} must already be bound to a destination address. The\n"
1420 "value returned is the number of bytes transmitted --\n"
1421 "it's possible for\n"
1422 "this to be less than the length of @var{message}\n"
1423 "if the socket is\n"
1424 "set to be non-blocking. The optional @var{flags} argument\n"
1425 "is a value or\n"
b380b885 1426 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1427 "Note that the data is written directly to the socket\n"
1428 "file descriptor:\n"
b380b885 1429 "any unflushed buffered port data is ignored.")
1bbd0b84 1430#define FUNC_NAME s_scm_send
370312ae
GH
1431{
1432 int rv;
1433 int fd;
1434 int flg;
cc95e00a
MV
1435 const char *src;
1436 size_t len;
370312ae 1437
78446828 1438 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1439 SCM_VALIDATE_OPFPORT (1, sock);
a6d9e5ab 1440 SCM_VALIDATE_STRING (2, message);
7cee5b31
MV
1441 if (SCM_UNBNDP (flags))
1442 flg = 0;
1443 else
1444 flg = scm_to_int (flags);
ee149d03 1445 fd = SCM_FPORT_FDES (sock);
370312ae 1446
cc95e00a
MV
1447 len = scm_i_string_length (message);
1448 src = scm_i_string_writable_chars (message);
1449 SCM_SYSCALL (rv = send (fd, src, len, flg));
1450 scm_i_string_stop_writing ();
1451
370312ae 1452 if (rv == -1)
1bbd0b84 1453 SCM_SYSERROR;
396e5506
MV
1454
1455 scm_remember_upto_here_1 (message);
7cee5b31 1456 return scm_from_int (rv);
370312ae 1457}
1bbd0b84 1458#undef FUNC_NAME
370312ae 1459
a1ec6916 1460SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
60d02d09 1461 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
eefae538 1462 "Return data from the socket port @var{sock} and also\n"
1e6808ea 1463 "information about where the data was received from.\n"
eefae538 1464 "@var{sock} must already be bound to the address from which\n"
1e6808ea
MG
1465 "data is to be received. @code{str}, is a string into which the\n"
1466 "data will be written. The size of @var{str} limits the amount\n"
1467 "of data which can be received: in the case of packet protocols,\n"
1468 "if a packet larger than this limit is encountered then some\n"
eefae538 1469 "data will be irrevocably lost.\n\n"
1e6808ea 1470 "The optional @var{flags} argument is a value or bitwise OR of\n"
eefae538 1471 "@code{MSG_OOB}, @code{MSG_PEEK}, @code{MSG_DONTROUTE} etc.\n\n"
1e6808ea
MG
1472 "The value returned is a pair: the @emph{car} is the number of\n"
1473 "bytes read from the socket and the @emph{cdr} an address object\n"
eefae538
GH
1474 "in the same form as returned by @code{accept}. The address\n"
1475 "will given as @code{#f} if not available, as is usually the\n"
1476 "case for stream sockets.\n\n"
1e6808ea 1477 "The @var{start} and @var{end} arguments specify a substring of\n"
eefae538 1478 "@var{str} to which the data should be written.\n\n"
1e6808ea
MG
1479 "Note that the data is read directly from the socket file\n"
1480 "descriptor: any unread buffered port data is ignored.")
1bbd0b84 1481#define FUNC_NAME s_scm_recvfrom
370312ae
GH
1482{
1483 int rv;
1484 int fd;
1485 int flg;
60d02d09 1486 char *buf;
396e5506
MV
1487 size_t offset;
1488 size_t cend;
370312ae 1489 SCM address;
5ee417fc 1490 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1491 char max_addr[MAX_ADDR_SIZE];
1492 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 1493
34d19ef6 1494 SCM_VALIDATE_OPFPORT (1, sock);
60d02d09 1495 fd = SCM_FPORT_FDES (sock);
396e5506
MV
1496
1497 SCM_VALIDATE_STRING (2, str);
cc95e00a 1498 scm_i_get_substring_spec (scm_i_string_length (str),
396e5506
MV
1499 start, &offset, end, &cend);
1500
1146b6cd
GH
1501 if (SCM_UNBNDP (flags))
1502 flg = 0;
370312ae 1503 else
60d02d09 1504 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
370312ae 1505
97d0e20b
GH
1506 /* recvfrom will not necessarily return an address. usually nothing
1507 is returned for stream sockets. */
cc95e00a 1508 buf = scm_i_string_writable_chars (str);
439006bf 1509 addr->sa_family = AF_UNSPEC;
60d02d09 1510 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
1146b6cd 1511 cend - offset, flg,
439006bf 1512 addr, &addr_size));
cc95e00a
MV
1513 scm_i_string_stop_writing ();
1514
370312ae 1515 if (rv == -1)
1bbd0b84 1516 SCM_SYSERROR;
eefae538 1517 if (addr->sa_family != AF_UNSPEC)
9c0129ac 1518 address = _scm_from_sockaddr (addr, addr_size, FUNC_NAME);
370312ae
GH
1519 else
1520 address = SCM_BOOL_F;
1521
396e5506 1522 scm_remember_upto_here_1 (str);
e11e83f3 1523 return scm_cons (scm_from_int (rv), address);
0f2d19dd 1524}
1bbd0b84 1525#undef FUNC_NAME
0f2d19dd 1526
9c0129ac
KR
1527SCM_DEFINE (scm_sendto, "sendto", 3, 1, 1,
1528 (SCM sock, SCM message, SCM fam_or_sockaddr, SCM address, SCM args_and_flags),
eefae538
GH
1529 "Transmit the string @var{message} on the socket port\n"
1530 "@var{sock}. The\n"
1531 "destination address is specified using the @var{fam},\n"
1532 "@var{address} and\n"
9c0129ac
KR
1533 "@var{args_and_flags} arguments, or just a socket address object "
1534 "returned by @code{make-socket-address}, in a similar way to the\n"
eefae538
GH
1535 "@code{connect} procedure. @var{args_and_flags} contains\n"
1536 "the usual connection arguments optionally followed by\n"
1537 "a flags argument, which is a value or\n"
b380b885 1538 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1539 "The value returned is the number of bytes transmitted --\n"
1540 "it's possible for\n"
1541 "this to be less than the length of @var{message} if the\n"
1542 "socket is\n"
1543 "set to be non-blocking.\n"
1544 "Note that the data is written directly to the socket\n"
1545 "file descriptor:\n"
b380b885 1546 "any unflushed buffered port data is ignored.")
1bbd0b84 1547#define FUNC_NAME s_scm_sendto
370312ae
GH
1548{
1549 int rv;
1550 int fd;
1551 int flg;
1552 struct sockaddr *soka;
9c0129ac 1553 size_t size;
370312ae 1554
78446828 1555 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1556 SCM_VALIDATE_FPORT (1, sock);
a6d9e5ab 1557 SCM_VALIDATE_STRING (2, message);
ee149d03 1558 fd = SCM_FPORT_FDES (sock);
9c0129ac
KR
1559
1560 if (!scm_is_number (fam_or_sockaddr))
1561 {
1562 /* FAM_OR_SOCKADDR must actually be a `socket address' object. This
1563 means that the following arguments, i.e. ADDRESS and those listed in
1564 ARGS_AND_FLAGS, are the `MSG_' flags. */
1565 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
1566 if (address != SCM_UNDEFINED)
1567 args_and_flags = scm_cons (address, args_and_flags);
1568 }
1569 else
1570 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
1571 &args_and_flags, 3, FUNC_NAME, &size);
1572
d2e53ed6 1573 if (scm_is_null (args_and_flags))
370312ae
GH
1574 flg = 0;
1575 else
1576 {
34d19ef6 1577 SCM_VALIDATE_CONS (5, args_and_flags);
e4b265d8 1578 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
370312ae 1579 }
396e5506 1580 SCM_SYSCALL (rv = sendto (fd,
cc95e00a
MV
1581 scm_i_string_chars (message),
1582 scm_i_string_length (message),
ae2fa5bc 1583 flg, soka, size));
370312ae 1584 if (rv == -1)
439006bf
GH
1585 {
1586 int save_errno = errno;
1587 free (soka);
1588 errno = save_errno;
1589 SCM_SYSERROR;
1590 }
1591 free (soka);
396e5506
MV
1592
1593 scm_remember_upto_here_1 (message);
e11e83f3 1594 return scm_from_int (rv);
370312ae 1595}
1bbd0b84 1596#undef FUNC_NAME
370312ae
GH
1597\f
1598
1599
1600void
0f2d19dd 1601scm_init_socket ()
0f2d19dd 1602{
370312ae
GH
1603 /* protocol families. */
1604#ifdef AF_UNSPEC
e11e83f3 1605 scm_c_define ("AF_UNSPEC", scm_from_int (AF_UNSPEC));
370312ae
GH
1606#endif
1607#ifdef AF_UNIX
e11e83f3 1608 scm_c_define ("AF_UNIX", scm_from_int (AF_UNIX));
370312ae
GH
1609#endif
1610#ifdef AF_INET
e11e83f3 1611 scm_c_define ("AF_INET", scm_from_int (AF_INET));
370312ae 1612#endif
3453619b 1613#ifdef AF_INET6
e11e83f3 1614 scm_c_define ("AF_INET6", scm_from_int (AF_INET6));
3453619b 1615#endif
370312ae
GH
1616
1617#ifdef PF_UNSPEC
e11e83f3 1618 scm_c_define ("PF_UNSPEC", scm_from_int (PF_UNSPEC));
370312ae
GH
1619#endif
1620#ifdef PF_UNIX
e11e83f3 1621 scm_c_define ("PF_UNIX", scm_from_int (PF_UNIX));
370312ae
GH
1622#endif
1623#ifdef PF_INET
e11e83f3 1624 scm_c_define ("PF_INET", scm_from_int (PF_INET));
370312ae 1625#endif
3453619b 1626#ifdef PF_INET6
e11e83f3 1627 scm_c_define ("PF_INET6", scm_from_int (PF_INET6));
3453619b 1628#endif
370312ae 1629
66c73b76
GH
1630 /* standard addresses. */
1631#ifdef INADDR_ANY
b9bd8526 1632 scm_c_define ("INADDR_ANY", scm_from_ulong (INADDR_ANY));
66c73b76
GH
1633#endif
1634#ifdef INADDR_BROADCAST
b9bd8526 1635 scm_c_define ("INADDR_BROADCAST", scm_from_ulong (INADDR_BROADCAST));
66c73b76
GH
1636#endif
1637#ifdef INADDR_NONE
b9bd8526 1638 scm_c_define ("INADDR_NONE", scm_from_ulong (INADDR_NONE));
66c73b76
GH
1639#endif
1640#ifdef INADDR_LOOPBACK
b9bd8526 1641 scm_c_define ("INADDR_LOOPBACK", scm_from_ulong (INADDR_LOOPBACK));
66c73b76
GH
1642#endif
1643
6f637a1b
KR
1644 /* socket types.
1645
1646 SOCK_PACKET is deliberately omitted, the GNU/Linux socket(2) and
1647 packet(7) advise that it's obsolete and strongly deprecated. */
1648
370312ae 1649#ifdef SOCK_STREAM
e11e83f3 1650 scm_c_define ("SOCK_STREAM", scm_from_int (SOCK_STREAM));
370312ae
GH
1651#endif
1652#ifdef SOCK_DGRAM
e11e83f3 1653 scm_c_define ("SOCK_DGRAM", scm_from_int (SOCK_DGRAM));
370312ae 1654#endif
6f637a1b
KR
1655#ifdef SOCK_SEQPACKET
1656 scm_c_define ("SOCK_SEQPACKET", scm_from_int (SOCK_SEQPACKET));
1657#endif
370312ae 1658#ifdef SOCK_RAW
e11e83f3 1659 scm_c_define ("SOCK_RAW", scm_from_int (SOCK_RAW));
370312ae 1660#endif
6f637a1b
KR
1661#ifdef SOCK_RDM
1662 scm_c_define ("SOCK_RDM", scm_from_int (SOCK_RDM));
1663#endif
370312ae 1664
8fae2bf4
KR
1665 /* setsockopt level.
1666
1667 SOL_IP, SOL_TCP and SOL_UDP are defined on gnu/linux, but not on for
1668 instance NetBSD. We define IPPROTOs because that's what the posix spec
1669 shows in its example at
1670
1671 http://www.opengroup.org/onlinepubs/007904975/functions/getsockopt.html
1672 */
370312ae 1673#ifdef SOL_SOCKET
e11e83f3 1674 scm_c_define ("SOL_SOCKET", scm_from_int (SOL_SOCKET));
370312ae 1675#endif
8fae2bf4
KR
1676#ifdef IPPROTO_IP
1677 scm_c_define ("IPPROTO_IP", scm_from_int (IPPROTO_IP));
370312ae 1678#endif
8fae2bf4
KR
1679#ifdef IPPROTO_TCP
1680 scm_c_define ("IPPROTO_TCP", scm_from_int (IPPROTO_TCP));
370312ae 1681#endif
8fae2bf4
KR
1682#ifdef IPPROTO_UDP
1683 scm_c_define ("IPPROTO_UDP", scm_from_int (IPPROTO_UDP));
370312ae
GH
1684#endif
1685
1686 /* setsockopt names. */
1687#ifdef SO_DEBUG
e11e83f3 1688 scm_c_define ("SO_DEBUG", scm_from_int (SO_DEBUG));
370312ae
GH
1689#endif
1690#ifdef SO_REUSEADDR
e11e83f3 1691 scm_c_define ("SO_REUSEADDR", scm_from_int (SO_REUSEADDR));
370312ae
GH
1692#endif
1693#ifdef SO_STYLE
e11e83f3 1694 scm_c_define ("SO_STYLE", scm_from_int (SO_STYLE));
370312ae
GH
1695#endif
1696#ifdef SO_TYPE
e11e83f3 1697 scm_c_define ("SO_TYPE", scm_from_int (SO_TYPE));
370312ae
GH
1698#endif
1699#ifdef SO_ERROR
e11e83f3 1700 scm_c_define ("SO_ERROR", scm_from_int (SO_ERROR));
370312ae
GH
1701#endif
1702#ifdef SO_DONTROUTE
e11e83f3 1703 scm_c_define ("SO_DONTROUTE", scm_from_int (SO_DONTROUTE));
370312ae
GH
1704#endif
1705#ifdef SO_BROADCAST
e11e83f3 1706 scm_c_define ("SO_BROADCAST", scm_from_int (SO_BROADCAST));
370312ae
GH
1707#endif
1708#ifdef SO_SNDBUF
e11e83f3 1709 scm_c_define ("SO_SNDBUF", scm_from_int (SO_SNDBUF));
370312ae
GH
1710#endif
1711#ifdef SO_RCVBUF
e11e83f3 1712 scm_c_define ("SO_RCVBUF", scm_from_int (SO_RCVBUF));
370312ae
GH
1713#endif
1714#ifdef SO_KEEPALIVE
e11e83f3 1715 scm_c_define ("SO_KEEPALIVE", scm_from_int (SO_KEEPALIVE));
370312ae
GH
1716#endif
1717#ifdef SO_OOBINLINE
e11e83f3 1718 scm_c_define ("SO_OOBINLINE", scm_from_int (SO_OOBINLINE));
370312ae
GH
1719#endif
1720#ifdef SO_NO_CHECK
e11e83f3 1721 scm_c_define ("SO_NO_CHECK", scm_from_int (SO_NO_CHECK));
370312ae
GH
1722#endif
1723#ifdef SO_PRIORITY
e11e83f3 1724 scm_c_define ("SO_PRIORITY", scm_from_int (SO_PRIORITY));
370312ae
GH
1725#endif
1726#ifdef SO_LINGER
e11e83f3 1727 scm_c_define ("SO_LINGER", scm_from_int (SO_LINGER));
370312ae
GH
1728#endif
1729
1730 /* recv/send options. */
1731#ifdef MSG_OOB
e11e83f3 1732 scm_c_define ("MSG_OOB", scm_from_int (MSG_OOB));
370312ae
GH
1733#endif
1734#ifdef MSG_PEEK
e11e83f3 1735 scm_c_define ("MSG_PEEK", scm_from_int (MSG_PEEK));
370312ae
GH
1736#endif
1737#ifdef MSG_DONTROUTE
e11e83f3 1738 scm_c_define ("MSG_DONTROUTE", scm_from_int (MSG_DONTROUTE));
370312ae
GH
1739#endif
1740
b4e15479
SJ
1741#ifdef __MINGW32__
1742 scm_i_init_socket_Win32 ();
1743#endif
1744
1c80707c
MV
1745#ifdef IP_ADD_MEMBERSHIP
1746 scm_c_define ("IP_ADD_MEMBERSHIP", scm_from_int (IP_ADD_MEMBERSHIP));
1747 scm_c_define ("IP_DROP_MEMBERSHIP", scm_from_int (IP_DROP_MEMBERSHIP));
1748#endif
1749
0f2d19dd 1750 scm_add_feature ("socket");
370312ae 1751
a0599745 1752#include "libguile/socket.x"
0f2d19dd
JB
1753}
1754
89e00824
ML
1755
1756/*
1757 Local Variables:
1758 c-file-style: "gnu"
1759 End:
1760*/