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