*** empty log message ***
[bpt/guile.git] / libguile / socket.c
CommitLineData
09270afd 1/* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003, 2004 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
370312ae 756static struct sockaddr *
439006bf
GH
757scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
758 const char *proc, int *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));
439006bf
GH
774 if (!soka)
775 scm_memory_error (proc);
93b047f4 776#if HAVE_STRUCT_SOCKADDR_SIN_LEN
3453619b
GH
777 soka->sin_len = sizeof (struct sockaddr_in);
778#endif
370312ae 779 soka->sin_family = AF_INET;
3453619b
GH
780 soka->sin_addr.s_addr = htonl (addr);
781 soka->sin_port = htons (port);
370312ae
GH
782 *size = sizeof (struct sockaddr_in);
783 return (struct sockaddr *) soka;
784 }
a57a0b1e 785#ifdef HAVE_IPV6
3453619b
GH
786 case AF_INET6:
787 {
788 /* see RFC2553. */
789 int port;
790 struct sockaddr_in6 *soka;
791 unsigned long flowinfo = 0;
792 unsigned long scope_id = 0;
793
3453619b 794 SCM_VALIDATE_CONS (which_arg + 1, *args);
7cee5b31 795 port = scm_to_int (SCM_CAR (*args));
3453619b 796 *args = SCM_CDR (*args);
d2e53ed6 797 if (scm_is_pair (*args))
3453619b
GH
798 {
799 SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
800 *args = SCM_CDR (*args);
d2e53ed6 801 if (scm_is_pair (*args))
3453619b
GH
802 {
803 SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
804 scope_id);
805 *args = SCM_CDR (*args);
806 }
807 }
67329a9e 808 soka = (struct sockaddr_in6 *) scm_malloc (sizeof (struct sockaddr_in6));
3453619b
GH
809 if (!soka)
810 scm_memory_error (proc);
93b047f4 811#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
3453619b
GH
812 soka->sin6_len = sizeof (struct sockaddr_in6);
813#endif
814 soka->sin6_family = AF_INET6;
7cee5b31 815 scm_to_ipv6 (soka->sin6_addr.s6_addr, address);
5a525b84 816 soka->sin6_port = htons (port);
3453619b 817 soka->sin6_flowinfo = flowinfo;
5a525b84 818#ifdef HAVE_SIN6_SCOPE_ID
3453619b 819 soka->sin6_scope_id = scope_id;
5a525b84 820#endif
3453619b
GH
821 *size = sizeof (struct sockaddr_in6);
822 return (struct sockaddr *) soka;
823 }
824#endif
1ba8c23a 825#ifdef HAVE_UNIX_DOMAIN_SOCKETS
370312ae
GH
826 case AF_UNIX:
827 {
828 struct sockaddr_un *soka;
439006bf 829 int addr_size;
7f9994d9
MV
830 char *c_address;
831
832 scm_frame_begin (0);
833
834 c_address = scm_to_locale_string (address);
835 scm_frame_free (c_address);
370312ae 836
439006bf
GH
837 /* the static buffer size in sockaddr_un seems to be arbitrary
838 and not necessarily a hard limit. e.g., the glibc manual
839 suggests it may be possible to declare it size 0. let's
840 ignore it. if the O/S doesn't like the size it will cause
841 connect/bind etc., to fail. sun_path is always the last
842 member of the structure. */
843 addr_size = sizeof (struct sockaddr_un)
7f9994d9 844 + max (0, strlen (c_address) + 1 - (sizeof soka->sun_path));
67329a9e 845 soka = (struct sockaddr_un *) scm_malloc (addr_size);
439006bf
GH
846 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
847 soka->sun_family = AF_UNIX;
7f9994d9 848 strcpy (soka->sun_path, c_address);
439006bf 849 *size = SUN_LEN (soka);
7f9994d9
MV
850
851 scm_frame_end ();
370312ae
GH
852 return (struct sockaddr *) soka;
853 }
0e958795 854#endif
370312ae 855 default:
e11e83f3 856 scm_out_of_range (proc, scm_from_int (fam));
0f2d19dd 857 }
0f2d19dd 858}
3453619b 859#undef FUNC_NAME
370312ae 860
a1ec6916 861SCM_DEFINE (scm_connect, "connect", 3, 0, 1,
1bbd0b84 862 (SCM sock, SCM fam, SCM address, SCM args),
eefae538 863 "Initiate a connection from a socket using a specified address\n"
3453619b
GH
864 "family to the address\n"
865 "specified by @var{address} and possibly @var{args}.\n"
866 "The format required for @var{address}\n"
867 "and @var{args} depends on the family of the socket.\n\n"
b380b885 868 "For a socket of family @code{AF_UNIX},\n"
3453619b 869 "only @var{address} is specified and must be a string with the\n"
b380b885
MD
870 "filename where the socket is to be created.\n\n"
871 "For a socket of family @code{AF_INET},\n"
3453619b
GH
872 "@var{address} must be an integer IPv4 host address and\n"
873 "@var{args} must be a single integer port number.\n\n"
874 "For a socket of family @code{AF_INET6},\n"
875 "@var{address} must be an integer IPv6 host address and\n"
876 "@var{args} may be up to three integers:\n"
877 "port [flowinfo] [scope_id],\n"
878 "where flowinfo and scope_id default to zero.\n\n"
b380b885 879 "The return value is unspecified.")
1bbd0b84 880#define FUNC_NAME s_scm_connect
0f2d19dd 881{
370312ae
GH
882 int fd;
883 struct sockaddr *soka;
439006bf 884 int size;
0f2d19dd 885
78446828 886 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 887 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 888 fd = SCM_FPORT_FDES (sock);
7cee5b31 889 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args, 3, FUNC_NAME,
439006bf 890 &size);
370312ae 891 if (connect (fd, soka, size) == -1)
439006bf
GH
892 {
893 int save_errno = errno;
894
895 free (soka);
896 errno = save_errno;
897 SCM_SYSERROR;
898 }
899 free (soka);
370312ae 900 return SCM_UNSPECIFIED;
0f2d19dd 901}
1bbd0b84 902#undef FUNC_NAME
0f2d19dd 903
a1ec6916 904SCM_DEFINE (scm_bind, "bind", 3, 0, 1,
1bbd0b84 905 (SCM sock, SCM fam, SCM address, SCM args),
eefae538 906 "Assign an address to the socket port @var{sock}.\n"
b380b885
MD
907 "Generally this only needs to be done for server sockets,\n"
908 "so they know where to look for incoming connections. A socket\n"
909 "without an address will be assigned one automatically when it\n"
910 "starts communicating.\n\n"
eefae538
GH
911 "The format of @var{address} and @var{args} depends\n"
912 "on the family of the socket.\n\n"
b380b885 913 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
eefae538
GH
914 "is specified and must be a string with the filename where\n"
915 "the socket is to be created.\n\n"
916 "For a socket of family @code{AF_INET}, @var{address}\n"
917 "must be an integer IPv4 address and @var{args}\n"
918 "must be a single integer port number.\n\n"
919 "The values of the following variables can also be used for\n"
920 "@var{address}:\n\n"
b380b885
MD
921 "@defvar INADDR_ANY\n"
922 "Allow connections from any address.\n"
923 "@end defvar\n\n"
924 "@defvar INADDR_LOOPBACK\n"
925 "The address of the local host using the loopback device.\n"
926 "@end defvar\n\n"
927 "@defvar INADDR_BROADCAST\n"
928 "The broadcast address on the local network.\n"
929 "@end defvar\n\n"
930 "@defvar INADDR_NONE\n"
931 "No address.\n"
932 "@end defvar\n\n"
eefae538
GH
933 "For a socket of family @code{AF_INET6}, @var{address}\n"
934 "must be an integer IPv6 address and @var{args}\n"
935 "may be up to three integers:\n"
936 "port [flowinfo] [scope_id],\n"
937 "where flowinfo and scope_id default to zero.\n\n"
b380b885 938 "The return value is unspecified.")
1bbd0b84 939#define FUNC_NAME s_scm_bind
370312ae 940{
370312ae 941 struct sockaddr *soka;
439006bf 942 int size;
370312ae
GH
943 int fd;
944
78446828 945 sock = SCM_COERCE_OUTPORT (sock);
439006bf 946 SCM_VALIDATE_OPFPORT (1, sock);
7cee5b31 947 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args, 3, FUNC_NAME,
439006bf 948 &size);
ee149d03 949 fd = SCM_FPORT_FDES (sock);
439006bf
GH
950 if (bind (fd, soka, size) == -1)
951 {
952 int save_errno = errno;
953
954 free (soka);
955 errno = save_errno;
1bbd0b84 956 SCM_SYSERROR;
439006bf
GH
957 }
958 free (soka);
370312ae
GH
959 return SCM_UNSPECIFIED;
960}
1bbd0b84 961#undef FUNC_NAME
370312ae 962
a1ec6916 963SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
1bbd0b84 964 (SCM sock, SCM backlog),
eefae538 965 "Enable @var{sock} to accept connection\n"
b380b885
MD
966 "requests. @var{backlog} is an integer specifying\n"
967 "the maximum length of the queue for pending connections.\n"
eefae538
GH
968 "If the queue fills, new clients will fail to connect until\n"
969 "the server calls @code{accept} to accept a connection from\n"
970 "the queue.\n\n"
b380b885 971 "The return value is unspecified.")
1bbd0b84 972#define FUNC_NAME s_scm_listen
370312ae
GH
973{
974 int fd;
78446828 975 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 976 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 977 fd = SCM_FPORT_FDES (sock);
7cee5b31 978 if (listen (fd, scm_to_int (backlog)) == -1)
1bbd0b84 979 SCM_SYSERROR;
370312ae
GH
980 return SCM_UNSPECIFIED;
981}
1bbd0b84 982#undef FUNC_NAME
370312ae
GH
983
984/* Put the components of a sockaddr into a new SCM vector. */
370312ae 985static SCM
aca23b65
MV
986scm_addr_vector (const struct sockaddr *address, int addr_size,
987 const char *proc)
0f2d19dd 988{
370312ae 989 short int fam = address->sa_family;
1d1559ce 990 SCM result =SCM_EOL;
34d19ef6 991
439006bf 992
5a525b84 993 switch (fam)
0f2d19dd 994 {
5a525b84
GH
995 case AF_INET:
996 {
e1368a8d 997 const struct sockaddr_in *nad = (struct sockaddr_in *) address;
439006bf 998
1d1559ce 999 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
34d19ef6 1000
4057a3e0
MV
1001 SCM_SIMPLE_VECTOR_SET(result, 0,
1002 scm_from_short (fam));
1003 SCM_SIMPLE_VECTOR_SET(result, 1,
1004 scm_from_ulong (ntohl (nad->sin_addr.s_addr)));
1005 SCM_SIMPLE_VECTOR_SET(result, 2,
1006 scm_from_ushort (ntohs (nad->sin_port)));
5a525b84
GH
1007 }
1008 break;
a57a0b1e 1009#ifdef HAVE_IPV6
5a525b84
GH
1010 case AF_INET6:
1011 {
e1368a8d 1012 const struct sockaddr_in6 *nad = (struct sockaddr_in6 *) address;
5a525b84 1013
1d1559ce 1014 result = scm_c_make_vector (5, SCM_UNSPECIFIED);
4057a3e0
MV
1015 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_short (fam));
1016 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_ipv6 (nad->sin6_addr.s6_addr));
1017 SCM_SIMPLE_VECTOR_SET(result, 2, scm_from_ushort (ntohs (nad->sin6_port)));
1018 SCM_SIMPLE_VECTOR_SET(result, 3, scm_from_uint32 (nad->sin6_flowinfo));
5a525b84 1019#ifdef HAVE_SIN6_SCOPE_ID
4057a3e0 1020 SCM_SIMPLE_VECTOR_SET(result, 4, scm_from_ulong (nad->sin6_scope_id));
5a525b84 1021#else
4057a3e0 1022 SCM_SIMPLE_VECTOR_SET(result, 4, SCM_INUM0);
0e958795 1023#endif
5a525b84
GH
1024 }
1025 break;
1026#endif
1027#ifdef HAVE_UNIX_DOMAIN_SOCKETS
1028 case AF_UNIX:
1029 {
e1368a8d 1030 const struct sockaddr_un *nad = (struct sockaddr_un *) address;
439006bf 1031
1d1559ce 1032 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
34d19ef6 1033
4057a3e0 1034 SCM_SIMPLE_VECTOR_SET(result, 0, scm_from_short (fam));
aca23b65
MV
1035 /* When addr_size is not enough to cover sun_path, do not try
1036 to access it. */
1037 if (addr_size <= offsetof (struct sockaddr_un, sun_path))
4057a3e0 1038 SCM_SIMPLE_VECTOR_SET(result, 1, SCM_BOOL_F);
aca23b65 1039 else
4057a3e0 1040 SCM_SIMPLE_VECTOR_SET(result, 1, scm_from_locale_string (nad->sun_path));
5a525b84
GH
1041 }
1042 break;
1043#endif
1044 default:
1045 scm_misc_error (proc, "Unrecognised address family: ~A",
e11e83f3 1046 scm_list_1 (scm_from_int (fam)));
0f2d19dd 1047 }
1d1559ce 1048 return result;
370312ae
GH
1049}
1050
439006bf
GH
1051/* calculate the size of a buffer large enough to hold any supported
1052 sockaddr type. if the buffer isn't large enough, certain system
1053 calls will return a truncated address. */
370312ae 1054
439006bf
GH
1055#if defined (HAVE_UNIX_DOMAIN_SOCKETS)
1056#define MAX_SIZE_UN sizeof (struct sockaddr_un)
0e958795 1057#else
439006bf 1058#define MAX_SIZE_UN 0
0e958795 1059#endif
439006bf 1060
a57a0b1e 1061#if defined (HAVE_IPV6)
5a525b84
GH
1062#define MAX_SIZE_IN6 sizeof (struct sockaddr_in6)
1063#else
1064#define MAX_SIZE_IN6 0
1065#endif
1066
1067#define MAX_ADDR_SIZE max (max (sizeof (struct sockaddr_in), MAX_SIZE_IN6),\
1068 MAX_SIZE_UN)
0f2d19dd 1069
a1ec6916 1070SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1bbd0b84 1071 (SCM sock),
eefae538
GH
1072 "Accept a connection on a bound, listening socket.\n"
1073 "If there\n"
1074 "are no pending connections in the queue, wait until\n"
1075 "one is available unless the non-blocking option has been\n"
1076 "set on the socket.\n\n"
b380b885 1077 "The return value is a\n"
eefae538
GH
1078 "pair in which the @emph{car} is a new socket port for the\n"
1079 "connection and\n"
1080 "the @emph{cdr} is an object with address information about the\n"
1081 "client which initiated the connection.\n\n"
1082 "@var{sock} does not become part of the\n"
b380b885 1083 "connection and will continue to accept new requests.")
1bbd0b84 1084#define FUNC_NAME s_scm_accept
0f2d19dd 1085{
370312ae
GH
1086 int fd;
1087 int newfd;
1088 SCM address;
1089 SCM newsock;
5ee417fc 1090 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1091 char max_addr[MAX_ADDR_SIZE];
1092 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 1093
78446828 1094 sock = SCM_COERCE_OUTPORT (sock);
439006bf 1095 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1096 fd = SCM_FPORT_FDES (sock);
439006bf
GH
1097 newfd = accept (fd, addr, &addr_size);
1098 if (newfd == -1)
1099 SCM_SYSERROR;
1100 newsock = SCM_SOCK_FD_TO_PORT (newfd);
aca23b65 1101 address = scm_addr_vector (addr, addr_size, FUNC_NAME);
370312ae 1102 return scm_cons (newsock, address);
0f2d19dd 1103}
1bbd0b84 1104#undef FUNC_NAME
0f2d19dd 1105
a1ec6916 1106SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1bbd0b84 1107 (SCM sock),
eefae538 1108 "Return the address of @var{sock}, in the same form as the\n"
1e6808ea
MG
1109 "object returned by @code{accept}. On many systems the address\n"
1110 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1bbd0b84 1111#define FUNC_NAME s_scm_getsockname
0f2d19dd 1112{
370312ae 1113 int fd;
5ee417fc 1114 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1115 char max_addr[MAX_ADDR_SIZE];
1116 struct sockaddr *addr = (struct sockaddr *) max_addr;
1117
78446828 1118 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1119 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1120 fd = SCM_FPORT_FDES (sock);
439006bf 1121 if (getsockname (fd, addr, &addr_size) == -1)
1bbd0b84 1122 SCM_SYSERROR;
aca23b65 1123 return scm_addr_vector (addr, addr_size, FUNC_NAME);
0f2d19dd 1124}
1bbd0b84 1125#undef FUNC_NAME
0f2d19dd 1126
a1ec6916 1127SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1bbd0b84 1128 (SCM sock),
eefae538 1129 "Return the address that @var{sock}\n"
1e6808ea
MG
1130 "is connected to, in the same form as the object returned by\n"
1131 "@code{accept}. On many systems the address of a socket in the\n"
1132 "@code{AF_FILE} namespace cannot be read.")
1bbd0b84 1133#define FUNC_NAME s_scm_getpeername
0f2d19dd 1134{
370312ae 1135 int fd;
5ee417fc 1136 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1137 char max_addr[MAX_ADDR_SIZE];
1138 struct sockaddr *addr = (struct sockaddr *) max_addr;
1139
78446828 1140 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1141 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1142 fd = SCM_FPORT_FDES (sock);
439006bf 1143 if (getpeername (fd, addr, &addr_size) == -1)
1bbd0b84 1144 SCM_SYSERROR;
aca23b65 1145 return scm_addr_vector (addr, addr_size, FUNC_NAME);
0f2d19dd 1146}
1bbd0b84 1147#undef FUNC_NAME
0f2d19dd 1148
a1ec6916 1149SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1bbd0b84 1150 (SCM sock, SCM buf, SCM flags),
eefae538
GH
1151 "Receive data from a socket port.\n"
1152 "@var{sock} must already\n"
b380b885
MD
1153 "be bound to the address from which data is to be received.\n"
1154 "@var{buf} is a string into which\n"
eefae538
GH
1155 "the data will be written. The size of @var{buf} limits\n"
1156 "the amount of\n"
b380b885 1157 "data which can be received: in the case of packet\n"
eefae538
GH
1158 "protocols, if a packet larger than this limit is encountered\n"
1159 "then some data\n"
b380b885
MD
1160 "will be irrevocably lost.\n\n"
1161 "The optional @var{flags} argument is a value or\n"
1162 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1163 "The value returned is the number of bytes read from the\n"
1164 "socket.\n\n"
1165 "Note that the data is read directly from the socket file\n"
1166 "descriptor:\n"
09831f94 1167 "any unread buffered port data is ignored.")
1bbd0b84 1168#define FUNC_NAME s_scm_recv
0f2d19dd 1169{
370312ae
GH
1170 int rv;
1171 int fd;
1172 int flg;
cc95e00a
MV
1173 char *dest;
1174 size_t len;
370312ae 1175
34d19ef6
HWN
1176 SCM_VALIDATE_OPFPORT (1, sock);
1177 SCM_VALIDATE_STRING (2, buf);
7cee5b31
MV
1178 if (SCM_UNBNDP (flags))
1179 flg = 0;
1180 else
1181 flg = scm_to_int (flags);
ee149d03 1182 fd = SCM_FPORT_FDES (sock);
370312ae 1183
cc95e00a
MV
1184 len = scm_i_string_length (buf);
1185 dest = scm_i_string_writable_chars (buf);
1186 SCM_SYSCALL (rv = recv (fd, dest, len, flg));
1187 scm_i_string_stop_writing ();
1188
370312ae 1189 if (rv == -1)
1bbd0b84 1190 SCM_SYSERROR;
370312ae 1191
396e5506 1192 scm_remember_upto_here_1 (buf);
7cee5b31 1193 return scm_from_int (rv);
370312ae 1194}
1bbd0b84 1195#undef FUNC_NAME
370312ae 1196
a1ec6916 1197SCM_DEFINE (scm_send, "send", 2, 1, 0,
1bbd0b84 1198 (SCM sock, SCM message, SCM flags),
eefae538
GH
1199 "Transmit the string @var{message} on a socket port @var{sock}.\n"
1200 "@var{sock} must already be bound to a destination address. The\n"
1201 "value returned is the number of bytes transmitted --\n"
1202 "it's possible for\n"
1203 "this to be less than the length of @var{message}\n"
1204 "if the socket is\n"
1205 "set to be non-blocking. The optional @var{flags} argument\n"
1206 "is a value or\n"
b380b885 1207 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1208 "Note that the data is written directly to the socket\n"
1209 "file descriptor:\n"
b380b885 1210 "any unflushed buffered port data is ignored.")
1bbd0b84 1211#define FUNC_NAME s_scm_send
370312ae
GH
1212{
1213 int rv;
1214 int fd;
1215 int flg;
cc95e00a
MV
1216 const char *src;
1217 size_t len;
370312ae 1218
78446828 1219 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1220 SCM_VALIDATE_OPFPORT (1, sock);
a6d9e5ab 1221 SCM_VALIDATE_STRING (2, message);
7cee5b31
MV
1222 if (SCM_UNBNDP (flags))
1223 flg = 0;
1224 else
1225 flg = scm_to_int (flags);
ee149d03 1226 fd = SCM_FPORT_FDES (sock);
370312ae 1227
cc95e00a
MV
1228 len = scm_i_string_length (message);
1229 src = scm_i_string_writable_chars (message);
1230 SCM_SYSCALL (rv = send (fd, src, len, flg));
1231 scm_i_string_stop_writing ();
1232
370312ae 1233 if (rv == -1)
1bbd0b84 1234 SCM_SYSERROR;
396e5506
MV
1235
1236 scm_remember_upto_here_1 (message);
7cee5b31 1237 return scm_from_int (rv);
370312ae 1238}
1bbd0b84 1239#undef FUNC_NAME
370312ae 1240
a1ec6916 1241SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
60d02d09 1242 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
eefae538 1243 "Return data from the socket port @var{sock} and also\n"
1e6808ea 1244 "information about where the data was received from.\n"
eefae538 1245 "@var{sock} must already be bound to the address from which\n"
1e6808ea
MG
1246 "data is to be received. @code{str}, is a string into which the\n"
1247 "data will be written. The size of @var{str} limits the amount\n"
1248 "of data which can be received: in the case of packet protocols,\n"
1249 "if a packet larger than this limit is encountered then some\n"
eefae538 1250 "data will be irrevocably lost.\n\n"
1e6808ea 1251 "The optional @var{flags} argument is a value or bitwise OR of\n"
eefae538 1252 "@code{MSG_OOB}, @code{MSG_PEEK}, @code{MSG_DONTROUTE} etc.\n\n"
1e6808ea
MG
1253 "The value returned is a pair: the @emph{car} is the number of\n"
1254 "bytes read from the socket and the @emph{cdr} an address object\n"
eefae538
GH
1255 "in the same form as returned by @code{accept}. The address\n"
1256 "will given as @code{#f} if not available, as is usually the\n"
1257 "case for stream sockets.\n\n"
1e6808ea 1258 "The @var{start} and @var{end} arguments specify a substring of\n"
eefae538 1259 "@var{str} to which the data should be written.\n\n"
1e6808ea
MG
1260 "Note that the data is read directly from the socket file\n"
1261 "descriptor: any unread buffered port data is ignored.")
1bbd0b84 1262#define FUNC_NAME s_scm_recvfrom
370312ae
GH
1263{
1264 int rv;
1265 int fd;
1266 int flg;
60d02d09 1267 char *buf;
396e5506
MV
1268 size_t offset;
1269 size_t cend;
370312ae 1270 SCM address;
5ee417fc 1271 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1272 char max_addr[MAX_ADDR_SIZE];
1273 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 1274
34d19ef6 1275 SCM_VALIDATE_OPFPORT (1, sock);
60d02d09 1276 fd = SCM_FPORT_FDES (sock);
396e5506
MV
1277
1278 SCM_VALIDATE_STRING (2, str);
cc95e00a 1279 scm_i_get_substring_spec (scm_i_string_length (str),
396e5506
MV
1280 start, &offset, end, &cend);
1281
1146b6cd
GH
1282 if (SCM_UNBNDP (flags))
1283 flg = 0;
370312ae 1284 else
60d02d09 1285 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
370312ae 1286
97d0e20b
GH
1287 /* recvfrom will not necessarily return an address. usually nothing
1288 is returned for stream sockets. */
cc95e00a 1289 buf = scm_i_string_writable_chars (str);
439006bf 1290 addr->sa_family = AF_UNSPEC;
60d02d09 1291 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
1146b6cd 1292 cend - offset, flg,
439006bf 1293 addr, &addr_size));
cc95e00a
MV
1294 scm_i_string_stop_writing ();
1295
370312ae 1296 if (rv == -1)
1bbd0b84 1297 SCM_SYSERROR;
eefae538 1298 if (addr->sa_family != AF_UNSPEC)
aca23b65 1299 address = scm_addr_vector (addr, addr_size, FUNC_NAME);
370312ae
GH
1300 else
1301 address = SCM_BOOL_F;
1302
396e5506 1303 scm_remember_upto_here_1 (str);
e11e83f3 1304 return scm_cons (scm_from_int (rv), address);
0f2d19dd 1305}
1bbd0b84 1306#undef FUNC_NAME
0f2d19dd 1307
a1ec6916 1308SCM_DEFINE (scm_sendto, "sendto", 4, 0, 1,
1bbd0b84 1309 (SCM sock, SCM message, SCM fam, SCM address, SCM args_and_flags),
eefae538
GH
1310 "Transmit the string @var{message} on the socket port\n"
1311 "@var{sock}. The\n"
1312 "destination address is specified using the @var{fam},\n"
1313 "@var{address} and\n"
1314 "@var{args_and_flags} arguments, in a similar way to the\n"
1315 "@code{connect} procedure. @var{args_and_flags} contains\n"
1316 "the usual connection arguments optionally followed by\n"
1317 "a flags argument, which is a value or\n"
b380b885 1318 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1319 "The value returned is the number of bytes transmitted --\n"
1320 "it's possible for\n"
1321 "this to be less than the length of @var{message} if the\n"
1322 "socket is\n"
1323 "set to be non-blocking.\n"
1324 "Note that the data is written directly to the socket\n"
1325 "file descriptor:\n"
b380b885 1326 "any unflushed buffered port data is ignored.")
1bbd0b84 1327#define FUNC_NAME s_scm_sendto
370312ae
GH
1328{
1329 int rv;
1330 int fd;
1331 int flg;
1332 struct sockaddr *soka;
439006bf 1333 int size;
370312ae 1334
78446828 1335 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1336 SCM_VALIDATE_FPORT (1, sock);
a6d9e5ab 1337 SCM_VALIDATE_STRING (2, message);
ee149d03 1338 fd = SCM_FPORT_FDES (sock);
7cee5b31 1339 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args_and_flags, 4,
1bbd0b84 1340 FUNC_NAME, &size);
d2e53ed6 1341 if (scm_is_null (args_and_flags))
370312ae
GH
1342 flg = 0;
1343 else
1344 {
34d19ef6 1345 SCM_VALIDATE_CONS (5, args_and_flags);
e4b265d8 1346 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
370312ae 1347 }
396e5506 1348 SCM_SYSCALL (rv = sendto (fd,
cc95e00a
MV
1349 scm_i_string_chars (message),
1350 scm_i_string_length (message),
ae2fa5bc 1351 flg, soka, size));
370312ae 1352 if (rv == -1)
439006bf
GH
1353 {
1354 int save_errno = errno;
1355 free (soka);
1356 errno = save_errno;
1357 SCM_SYSERROR;
1358 }
1359 free (soka);
396e5506
MV
1360
1361 scm_remember_upto_here_1 (message);
e11e83f3 1362 return scm_from_int (rv);
370312ae 1363}
1bbd0b84 1364#undef FUNC_NAME
370312ae
GH
1365\f
1366
1367
1368void
0f2d19dd 1369scm_init_socket ()
0f2d19dd 1370{
370312ae
GH
1371 /* protocol families. */
1372#ifdef AF_UNSPEC
e11e83f3 1373 scm_c_define ("AF_UNSPEC", scm_from_int (AF_UNSPEC));
370312ae
GH
1374#endif
1375#ifdef AF_UNIX
e11e83f3 1376 scm_c_define ("AF_UNIX", scm_from_int (AF_UNIX));
370312ae
GH
1377#endif
1378#ifdef AF_INET
e11e83f3 1379 scm_c_define ("AF_INET", scm_from_int (AF_INET));
370312ae 1380#endif
3453619b 1381#ifdef AF_INET6
e11e83f3 1382 scm_c_define ("AF_INET6", scm_from_int (AF_INET6));
3453619b 1383#endif
370312ae
GH
1384
1385#ifdef PF_UNSPEC
e11e83f3 1386 scm_c_define ("PF_UNSPEC", scm_from_int (PF_UNSPEC));
370312ae
GH
1387#endif
1388#ifdef PF_UNIX
e11e83f3 1389 scm_c_define ("PF_UNIX", scm_from_int (PF_UNIX));
370312ae
GH
1390#endif
1391#ifdef PF_INET
e11e83f3 1392 scm_c_define ("PF_INET", scm_from_int (PF_INET));
370312ae 1393#endif
3453619b 1394#ifdef PF_INET6
e11e83f3 1395 scm_c_define ("PF_INET6", scm_from_int (PF_INET6));
3453619b 1396#endif
370312ae 1397
66c73b76
GH
1398 /* standard addresses. */
1399#ifdef INADDR_ANY
b9bd8526 1400 scm_c_define ("INADDR_ANY", scm_from_ulong (INADDR_ANY));
66c73b76
GH
1401#endif
1402#ifdef INADDR_BROADCAST
b9bd8526 1403 scm_c_define ("INADDR_BROADCAST", scm_from_ulong (INADDR_BROADCAST));
66c73b76
GH
1404#endif
1405#ifdef INADDR_NONE
b9bd8526 1406 scm_c_define ("INADDR_NONE", scm_from_ulong (INADDR_NONE));
66c73b76
GH
1407#endif
1408#ifdef INADDR_LOOPBACK
b9bd8526 1409 scm_c_define ("INADDR_LOOPBACK", scm_from_ulong (INADDR_LOOPBACK));
66c73b76
GH
1410#endif
1411
6f637a1b
KR
1412 /* socket types.
1413
1414 SOCK_PACKET is deliberately omitted, the GNU/Linux socket(2) and
1415 packet(7) advise that it's obsolete and strongly deprecated. */
1416
370312ae 1417#ifdef SOCK_STREAM
e11e83f3 1418 scm_c_define ("SOCK_STREAM", scm_from_int (SOCK_STREAM));
370312ae
GH
1419#endif
1420#ifdef SOCK_DGRAM
e11e83f3 1421 scm_c_define ("SOCK_DGRAM", scm_from_int (SOCK_DGRAM));
370312ae 1422#endif
6f637a1b
KR
1423#ifdef SOCK_SEQPACKET
1424 scm_c_define ("SOCK_SEQPACKET", scm_from_int (SOCK_SEQPACKET));
1425#endif
370312ae 1426#ifdef SOCK_RAW
e11e83f3 1427 scm_c_define ("SOCK_RAW", scm_from_int (SOCK_RAW));
370312ae 1428#endif
6f637a1b
KR
1429#ifdef SOCK_RDM
1430 scm_c_define ("SOCK_RDM", scm_from_int (SOCK_RDM));
1431#endif
370312ae 1432
8fae2bf4
KR
1433 /* setsockopt level.
1434
1435 SOL_IP, SOL_TCP and SOL_UDP are defined on gnu/linux, but not on for
1436 instance NetBSD. We define IPPROTOs because that's what the posix spec
1437 shows in its example at
1438
1439 http://www.opengroup.org/onlinepubs/007904975/functions/getsockopt.html
1440 */
370312ae 1441#ifdef SOL_SOCKET
e11e83f3 1442 scm_c_define ("SOL_SOCKET", scm_from_int (SOL_SOCKET));
370312ae 1443#endif
8fae2bf4
KR
1444#ifdef IPPROTO_IP
1445 scm_c_define ("IPPROTO_IP", scm_from_int (IPPROTO_IP));
370312ae 1446#endif
8fae2bf4
KR
1447#ifdef IPPROTO_TCP
1448 scm_c_define ("IPPROTO_TCP", scm_from_int (IPPROTO_TCP));
370312ae 1449#endif
8fae2bf4
KR
1450#ifdef IPPROTO_UDP
1451 scm_c_define ("IPPROTO_UDP", scm_from_int (IPPROTO_UDP));
370312ae
GH
1452#endif
1453
1454 /* setsockopt names. */
1455#ifdef SO_DEBUG
e11e83f3 1456 scm_c_define ("SO_DEBUG", scm_from_int (SO_DEBUG));
370312ae
GH
1457#endif
1458#ifdef SO_REUSEADDR
e11e83f3 1459 scm_c_define ("SO_REUSEADDR", scm_from_int (SO_REUSEADDR));
370312ae
GH
1460#endif
1461#ifdef SO_STYLE
e11e83f3 1462 scm_c_define ("SO_STYLE", scm_from_int (SO_STYLE));
370312ae
GH
1463#endif
1464#ifdef SO_TYPE
e11e83f3 1465 scm_c_define ("SO_TYPE", scm_from_int (SO_TYPE));
370312ae
GH
1466#endif
1467#ifdef SO_ERROR
e11e83f3 1468 scm_c_define ("SO_ERROR", scm_from_int (SO_ERROR));
370312ae
GH
1469#endif
1470#ifdef SO_DONTROUTE
e11e83f3 1471 scm_c_define ("SO_DONTROUTE", scm_from_int (SO_DONTROUTE));
370312ae
GH
1472#endif
1473#ifdef SO_BROADCAST
e11e83f3 1474 scm_c_define ("SO_BROADCAST", scm_from_int (SO_BROADCAST));
370312ae
GH
1475#endif
1476#ifdef SO_SNDBUF
e11e83f3 1477 scm_c_define ("SO_SNDBUF", scm_from_int (SO_SNDBUF));
370312ae
GH
1478#endif
1479#ifdef SO_RCVBUF
e11e83f3 1480 scm_c_define ("SO_RCVBUF", scm_from_int (SO_RCVBUF));
370312ae
GH
1481#endif
1482#ifdef SO_KEEPALIVE
e11e83f3 1483 scm_c_define ("SO_KEEPALIVE", scm_from_int (SO_KEEPALIVE));
370312ae
GH
1484#endif
1485#ifdef SO_OOBINLINE
e11e83f3 1486 scm_c_define ("SO_OOBINLINE", scm_from_int (SO_OOBINLINE));
370312ae
GH
1487#endif
1488#ifdef SO_NO_CHECK
e11e83f3 1489 scm_c_define ("SO_NO_CHECK", scm_from_int (SO_NO_CHECK));
370312ae
GH
1490#endif
1491#ifdef SO_PRIORITY
e11e83f3 1492 scm_c_define ("SO_PRIORITY", scm_from_int (SO_PRIORITY));
370312ae
GH
1493#endif
1494#ifdef SO_LINGER
e11e83f3 1495 scm_c_define ("SO_LINGER", scm_from_int (SO_LINGER));
370312ae
GH
1496#endif
1497
1498 /* recv/send options. */
1499#ifdef MSG_OOB
e11e83f3 1500 scm_c_define ("MSG_OOB", scm_from_int (MSG_OOB));
370312ae
GH
1501#endif
1502#ifdef MSG_PEEK
e11e83f3 1503 scm_c_define ("MSG_PEEK", scm_from_int (MSG_PEEK));
370312ae
GH
1504#endif
1505#ifdef MSG_DONTROUTE
e11e83f3 1506 scm_c_define ("MSG_DONTROUTE", scm_from_int (MSG_DONTROUTE));
370312ae
GH
1507#endif
1508
b4e15479
SJ
1509#ifdef __MINGW32__
1510 scm_i_init_socket_Win32 ();
1511#endif
1512
1c80707c
MV
1513#ifdef IP_ADD_MEMBERSHIP
1514 scm_c_define ("IP_ADD_MEMBERSHIP", scm_from_int (IP_ADD_MEMBERSHIP));
1515 scm_c_define ("IP_DROP_MEMBERSHIP", scm_from_int (IP_DROP_MEMBERSHIP));
1516#endif
1517
0f2d19dd 1518 scm_add_feature ("socket");
370312ae 1519
a0599745 1520#include "libguile/socket.x"
0f2d19dd
JB
1521}
1522
89e00824
ML
1523
1524/*
1525 Local Variables:
1526 c-file-style: "gnu"
1527 End:
1528*/