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