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