*** empty log message ***
[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{
1ac5fb45 1265 SCM result = SCM_BOOL_F;
9c0129ac
KR
1266 struct sockaddr *c_address;
1267 size_t c_address_size;
1268
1269 c_address = scm_c_make_socket_address (family, address, args,
1270 &c_address_size);
1ac5fb45
LC
1271 if (c_address != NULL)
1272 {
1273 result = scm_from_sockaddr (c_address, c_address_size);
1274 free (c_address);
1275 }
9c0129ac 1276
1ac5fb45 1277 return result;
9c0129ac
KR
1278}
1279#undef FUNC_NAME
1280
1281\f
439006bf
GH
1282/* calculate the size of a buffer large enough to hold any supported
1283 sockaddr type. if the buffer isn't large enough, certain system
1284 calls will return a truncated address. */
370312ae 1285
439006bf
GH
1286#if defined (HAVE_UNIX_DOMAIN_SOCKETS)
1287#define MAX_SIZE_UN sizeof (struct sockaddr_un)
0e958795 1288#else
439006bf 1289#define MAX_SIZE_UN 0
0e958795 1290#endif
439006bf 1291
a57a0b1e 1292#if defined (HAVE_IPV6)
5a525b84
GH
1293#define MAX_SIZE_IN6 sizeof (struct sockaddr_in6)
1294#else
1295#define MAX_SIZE_IN6 0
1296#endif
1297
1298#define MAX_ADDR_SIZE max (max (sizeof (struct sockaddr_in), MAX_SIZE_IN6),\
1299 MAX_SIZE_UN)
0f2d19dd 1300
a1ec6916 1301SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1bbd0b84 1302 (SCM sock),
eefae538
GH
1303 "Accept a connection on a bound, listening socket.\n"
1304 "If there\n"
1305 "are no pending connections in the queue, wait until\n"
1306 "one is available unless the non-blocking option has been\n"
1307 "set on the socket.\n\n"
b380b885 1308 "The return value is a\n"
eefae538
GH
1309 "pair in which the @emph{car} is a new socket port for the\n"
1310 "connection and\n"
1311 "the @emph{cdr} is an object with address information about the\n"
1312 "client which initiated the connection.\n\n"
1313 "@var{sock} does not become part of the\n"
b380b885 1314 "connection and will continue to accept new requests.")
1bbd0b84 1315#define FUNC_NAME s_scm_accept
0f2d19dd 1316{
370312ae
GH
1317 int fd;
1318 int newfd;
1319 SCM address;
1320 SCM newsock;
5ee417fc 1321 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1322 char max_addr[MAX_ADDR_SIZE];
1323 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 1324
78446828 1325 sock = SCM_COERCE_OUTPORT (sock);
439006bf 1326 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1327 fd = SCM_FPORT_FDES (sock);
439006bf
GH
1328 newfd = accept (fd, addr, &addr_size);
1329 if (newfd == -1)
1330 SCM_SYSERROR;
1331 newsock = SCM_SOCK_FD_TO_PORT (newfd);
9c0129ac 1332 address = _scm_from_sockaddr (addr, addr_size, FUNC_NAME);
370312ae 1333 return scm_cons (newsock, address);
0f2d19dd 1334}
1bbd0b84 1335#undef FUNC_NAME
0f2d19dd 1336
a1ec6916 1337SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1bbd0b84 1338 (SCM sock),
eefae538 1339 "Return the address of @var{sock}, in the same form as the\n"
1e6808ea
MG
1340 "object returned by @code{accept}. On many systems the address\n"
1341 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1bbd0b84 1342#define FUNC_NAME s_scm_getsockname
0f2d19dd 1343{
370312ae 1344 int fd;
5ee417fc 1345 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1346 char max_addr[MAX_ADDR_SIZE];
1347 struct sockaddr *addr = (struct sockaddr *) max_addr;
1348
78446828 1349 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1350 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1351 fd = SCM_FPORT_FDES (sock);
439006bf 1352 if (getsockname (fd, addr, &addr_size) == -1)
1bbd0b84 1353 SCM_SYSERROR;
9c0129ac 1354 return _scm_from_sockaddr (addr, addr_size, FUNC_NAME);
0f2d19dd 1355}
1bbd0b84 1356#undef FUNC_NAME
0f2d19dd 1357
a1ec6916 1358SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1bbd0b84 1359 (SCM sock),
eefae538 1360 "Return the address that @var{sock}\n"
1e6808ea
MG
1361 "is connected to, in the same form as the object returned by\n"
1362 "@code{accept}. On many systems the address of a socket in the\n"
1363 "@code{AF_FILE} namespace cannot be read.")
1bbd0b84 1364#define FUNC_NAME s_scm_getpeername
0f2d19dd 1365{
370312ae 1366 int fd;
5ee417fc 1367 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1368 char max_addr[MAX_ADDR_SIZE];
1369 struct sockaddr *addr = (struct sockaddr *) max_addr;
1370
78446828 1371 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1372 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1373 fd = SCM_FPORT_FDES (sock);
439006bf 1374 if (getpeername (fd, addr, &addr_size) == -1)
1bbd0b84 1375 SCM_SYSERROR;
9c0129ac 1376 return _scm_from_sockaddr (addr, addr_size, FUNC_NAME);
0f2d19dd 1377}
1bbd0b84 1378#undef FUNC_NAME
0f2d19dd 1379
a1ec6916 1380SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1bbd0b84 1381 (SCM sock, SCM buf, SCM flags),
eefae538
GH
1382 "Receive data from a socket port.\n"
1383 "@var{sock} must already\n"
b380b885
MD
1384 "be bound to the address from which data is to be received.\n"
1385 "@var{buf} is a string into which\n"
eefae538
GH
1386 "the data will be written. The size of @var{buf} limits\n"
1387 "the amount of\n"
b380b885 1388 "data which can be received: in the case of packet\n"
eefae538
GH
1389 "protocols, if a packet larger than this limit is encountered\n"
1390 "then some data\n"
b380b885
MD
1391 "will be irrevocably lost.\n\n"
1392 "The optional @var{flags} argument is a value or\n"
1393 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1394 "The value returned is the number of bytes read from the\n"
1395 "socket.\n\n"
1396 "Note that the data is read directly from the socket file\n"
1397 "descriptor:\n"
09831f94 1398 "any unread buffered port data is ignored.")
1bbd0b84 1399#define FUNC_NAME s_scm_recv
0f2d19dd 1400{
370312ae
GH
1401 int rv;
1402 int fd;
1403 int flg;
cc95e00a
MV
1404 char *dest;
1405 size_t len;
370312ae 1406
34d19ef6
HWN
1407 SCM_VALIDATE_OPFPORT (1, sock);
1408 SCM_VALIDATE_STRING (2, buf);
7cee5b31
MV
1409 if (SCM_UNBNDP (flags))
1410 flg = 0;
1411 else
1412 flg = scm_to_int (flags);
ee149d03 1413 fd = SCM_FPORT_FDES (sock);
370312ae 1414
cc95e00a
MV
1415 len = scm_i_string_length (buf);
1416 dest = scm_i_string_writable_chars (buf);
1417 SCM_SYSCALL (rv = recv (fd, dest, len, flg));
1418 scm_i_string_stop_writing ();
1419
370312ae 1420 if (rv == -1)
1bbd0b84 1421 SCM_SYSERROR;
370312ae 1422
396e5506 1423 scm_remember_upto_here_1 (buf);
7cee5b31 1424 return scm_from_int (rv);
370312ae 1425}
1bbd0b84 1426#undef FUNC_NAME
370312ae 1427
a1ec6916 1428SCM_DEFINE (scm_send, "send", 2, 1, 0,
1bbd0b84 1429 (SCM sock, SCM message, SCM flags),
eefae538
GH
1430 "Transmit the string @var{message} on a socket port @var{sock}.\n"
1431 "@var{sock} must already be bound to a destination address. The\n"
1432 "value returned is the number of bytes transmitted --\n"
1433 "it's possible for\n"
1434 "this to be less than the length of @var{message}\n"
1435 "if the socket is\n"
1436 "set to be non-blocking. The optional @var{flags} argument\n"
1437 "is a value or\n"
b380b885 1438 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1439 "Note that the data is written directly to the socket\n"
1440 "file descriptor:\n"
b380b885 1441 "any unflushed buffered port data is ignored.")
1bbd0b84 1442#define FUNC_NAME s_scm_send
370312ae
GH
1443{
1444 int rv;
1445 int fd;
1446 int flg;
cc95e00a
MV
1447 const char *src;
1448 size_t len;
370312ae 1449
78446828 1450 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1451 SCM_VALIDATE_OPFPORT (1, sock);
a6d9e5ab 1452 SCM_VALIDATE_STRING (2, message);
7cee5b31
MV
1453 if (SCM_UNBNDP (flags))
1454 flg = 0;
1455 else
1456 flg = scm_to_int (flags);
ee149d03 1457 fd = SCM_FPORT_FDES (sock);
370312ae 1458
cc95e00a
MV
1459 len = scm_i_string_length (message);
1460 src = scm_i_string_writable_chars (message);
1461 SCM_SYSCALL (rv = send (fd, src, len, flg));
1462 scm_i_string_stop_writing ();
1463
370312ae 1464 if (rv == -1)
1bbd0b84 1465 SCM_SYSERROR;
396e5506
MV
1466
1467 scm_remember_upto_here_1 (message);
7cee5b31 1468 return scm_from_int (rv);
370312ae 1469}
1bbd0b84 1470#undef FUNC_NAME
370312ae 1471
a1ec6916 1472SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
60d02d09 1473 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
8ab3d8a0
KR
1474 "Receive data from socket port @var{sock} (which must be already\n"
1475 "bound), returning the originating address as well as the data.\n"
1476 "This is usually for use on datagram sockets, but can be used on\n"
1477 "stream-oriented sockets too.\n"
1478 "\n"
1479 "The data received is stored in the given @var{str}, using\n"
1480 "either the whole string or just the region between the optional\n"
1481 "@var{start} and @var{end} positions. The size of @var{str}\n"
1482 "limits the amount of data which can be received. For datagram\n"
1483 "protocols, if a packet larger than this is received then excess\n"
1484 "bytes are irrevocably lost.\n"
1485 "\n"
1486 "The return value is a pair. The @code{car} is the number of\n"
1487 "bytes read. The @code{cdr} is a socket address object which is\n"
1488 "where the data come from, or @code{#f} if the origin is\n"
1489 "unknown.\n"
1490 "\n"
1491 "The optional @var{flags} argument is a or bitwise OR\n"
1492 "(@code{logior}) of @code{MSG_OOB}, @code{MSG_PEEK},\n"
1493 "@code{MSG_DONTROUTE} etc.\n"
1494 "\n"
1495 "Data is read directly from the socket file descriptor, any\n"
1496 "buffered port data is ignored.\n"
1497 "\n"
1498 "On a GNU/Linux system @code{recvfrom!} is not multi-threading,\n"
1499 "all threads stop while a @code{recvfrom!} call is in progress.\n"
1500 "An application may need to use @code{select}, @code{O_NONBLOCK}\n"
1501 "or @code{MSG_DONTWAIT} to avoid this.")
1bbd0b84 1502#define FUNC_NAME s_scm_recvfrom
370312ae
GH
1503{
1504 int rv;
1505 int fd;
1506 int flg;
60d02d09 1507 char *buf;
396e5506
MV
1508 size_t offset;
1509 size_t cend;
370312ae 1510 SCM address;
5ee417fc 1511 socklen_t addr_size = MAX_ADDR_SIZE;
439006bf
GH
1512 char max_addr[MAX_ADDR_SIZE];
1513 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 1514
34d19ef6 1515 SCM_VALIDATE_OPFPORT (1, sock);
60d02d09 1516 fd = SCM_FPORT_FDES (sock);
396e5506
MV
1517
1518 SCM_VALIDATE_STRING (2, str);
cc95e00a 1519 scm_i_get_substring_spec (scm_i_string_length (str),
396e5506
MV
1520 start, &offset, end, &cend);
1521
1146b6cd
GH
1522 if (SCM_UNBNDP (flags))
1523 flg = 0;
370312ae 1524 else
60d02d09 1525 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
370312ae 1526
97d0e20b
GH
1527 /* recvfrom will not necessarily return an address. usually nothing
1528 is returned for stream sockets. */
cc95e00a 1529 buf = scm_i_string_writable_chars (str);
439006bf 1530 addr->sa_family = AF_UNSPEC;
60d02d09 1531 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
1146b6cd 1532 cend - offset, flg,
439006bf 1533 addr, &addr_size));
cc95e00a
MV
1534 scm_i_string_stop_writing ();
1535
370312ae 1536 if (rv == -1)
1bbd0b84 1537 SCM_SYSERROR;
eefae538 1538 if (addr->sa_family != AF_UNSPEC)
9c0129ac 1539 address = _scm_from_sockaddr (addr, addr_size, FUNC_NAME);
370312ae
GH
1540 else
1541 address = SCM_BOOL_F;
1542
396e5506 1543 scm_remember_upto_here_1 (str);
e11e83f3 1544 return scm_cons (scm_from_int (rv), address);
0f2d19dd 1545}
1bbd0b84 1546#undef FUNC_NAME
0f2d19dd 1547
9c0129ac
KR
1548SCM_DEFINE (scm_sendto, "sendto", 3, 1, 1,
1549 (SCM sock, SCM message, SCM fam_or_sockaddr, SCM address, SCM args_and_flags),
eefae538
GH
1550 "Transmit the string @var{message} on the socket port\n"
1551 "@var{sock}. The\n"
1552 "destination address is specified using the @var{fam},\n"
1553 "@var{address} and\n"
9c0129ac
KR
1554 "@var{args_and_flags} arguments, or just a socket address object "
1555 "returned by @code{make-socket-address}, in a similar way to the\n"
eefae538
GH
1556 "@code{connect} procedure. @var{args_and_flags} contains\n"
1557 "the usual connection arguments optionally followed by\n"
1558 "a flags argument, which is a value or\n"
b380b885 1559 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1560 "The value returned is the number of bytes transmitted --\n"
1561 "it's possible for\n"
1562 "this to be less than the length of @var{message} if the\n"
1563 "socket is\n"
1564 "set to be non-blocking.\n"
1565 "Note that the data is written directly to the socket\n"
1566 "file descriptor:\n"
b380b885 1567 "any unflushed buffered port data is ignored.")
1bbd0b84 1568#define FUNC_NAME s_scm_sendto
370312ae
GH
1569{
1570 int rv;
1571 int fd;
1572 int flg;
1573 struct sockaddr *soka;
9c0129ac 1574 size_t size;
370312ae 1575
78446828 1576 sock = SCM_COERCE_OUTPORT (sock);
34d19ef6 1577 SCM_VALIDATE_FPORT (1, sock);
a6d9e5ab 1578 SCM_VALIDATE_STRING (2, message);
ee149d03 1579 fd = SCM_FPORT_FDES (sock);
9c0129ac
KR
1580
1581 if (!scm_is_number (fam_or_sockaddr))
1582 {
1583 /* FAM_OR_SOCKADDR must actually be a `socket address' object. This
1584 means that the following arguments, i.e. ADDRESS and those listed in
1585 ARGS_AND_FLAGS, are the `MSG_' flags. */
1586 soka = scm_to_sockaddr (fam_or_sockaddr, &size);
1587 if (address != SCM_UNDEFINED)
1588 args_and_flags = scm_cons (address, args_and_flags);
1589 }
1590 else
1591 soka = scm_fill_sockaddr (scm_to_int (fam_or_sockaddr), address,
1592 &args_and_flags, 3, FUNC_NAME, &size);
1593
d2e53ed6 1594 if (scm_is_null (args_and_flags))
370312ae
GH
1595 flg = 0;
1596 else
1597 {
34d19ef6 1598 SCM_VALIDATE_CONS (5, args_and_flags);
e4b265d8 1599 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
370312ae 1600 }
396e5506 1601 SCM_SYSCALL (rv = sendto (fd,
cc95e00a
MV
1602 scm_i_string_chars (message),
1603 scm_i_string_length (message),
ae2fa5bc 1604 flg, soka, size));
370312ae 1605 if (rv == -1)
439006bf
GH
1606 {
1607 int save_errno = errno;
1608 free (soka);
1609 errno = save_errno;
1610 SCM_SYSERROR;
1611 }
1612 free (soka);
396e5506
MV
1613
1614 scm_remember_upto_here_1 (message);
e11e83f3 1615 return scm_from_int (rv);
370312ae 1616}
1bbd0b84 1617#undef FUNC_NAME
370312ae
GH
1618\f
1619
1620
1621void
0f2d19dd 1622scm_init_socket ()
0f2d19dd 1623{
370312ae
GH
1624 /* protocol families. */
1625#ifdef AF_UNSPEC
e11e83f3 1626 scm_c_define ("AF_UNSPEC", scm_from_int (AF_UNSPEC));
370312ae
GH
1627#endif
1628#ifdef AF_UNIX
e11e83f3 1629 scm_c_define ("AF_UNIX", scm_from_int (AF_UNIX));
370312ae
GH
1630#endif
1631#ifdef AF_INET
e11e83f3 1632 scm_c_define ("AF_INET", scm_from_int (AF_INET));
370312ae 1633#endif
3453619b 1634#ifdef AF_INET6
e11e83f3 1635 scm_c_define ("AF_INET6", scm_from_int (AF_INET6));
3453619b 1636#endif
370312ae
GH
1637
1638#ifdef PF_UNSPEC
e11e83f3 1639 scm_c_define ("PF_UNSPEC", scm_from_int (PF_UNSPEC));
370312ae
GH
1640#endif
1641#ifdef PF_UNIX
e11e83f3 1642 scm_c_define ("PF_UNIX", scm_from_int (PF_UNIX));
370312ae
GH
1643#endif
1644#ifdef PF_INET
e11e83f3 1645 scm_c_define ("PF_INET", scm_from_int (PF_INET));
370312ae 1646#endif
3453619b 1647#ifdef PF_INET6
e11e83f3 1648 scm_c_define ("PF_INET6", scm_from_int (PF_INET6));
3453619b 1649#endif
370312ae 1650
66c73b76
GH
1651 /* standard addresses. */
1652#ifdef INADDR_ANY
b9bd8526 1653 scm_c_define ("INADDR_ANY", scm_from_ulong (INADDR_ANY));
66c73b76
GH
1654#endif
1655#ifdef INADDR_BROADCAST
b9bd8526 1656 scm_c_define ("INADDR_BROADCAST", scm_from_ulong (INADDR_BROADCAST));
66c73b76
GH
1657#endif
1658#ifdef INADDR_NONE
b9bd8526 1659 scm_c_define ("INADDR_NONE", scm_from_ulong (INADDR_NONE));
66c73b76
GH
1660#endif
1661#ifdef INADDR_LOOPBACK
b9bd8526 1662 scm_c_define ("INADDR_LOOPBACK", scm_from_ulong (INADDR_LOOPBACK));
66c73b76
GH
1663#endif
1664
6f637a1b
KR
1665 /* socket types.
1666
1667 SOCK_PACKET is deliberately omitted, the GNU/Linux socket(2) and
1668 packet(7) advise that it's obsolete and strongly deprecated. */
1669
370312ae 1670#ifdef SOCK_STREAM
e11e83f3 1671 scm_c_define ("SOCK_STREAM", scm_from_int (SOCK_STREAM));
370312ae
GH
1672#endif
1673#ifdef SOCK_DGRAM
e11e83f3 1674 scm_c_define ("SOCK_DGRAM", scm_from_int (SOCK_DGRAM));
370312ae 1675#endif
6f637a1b
KR
1676#ifdef SOCK_SEQPACKET
1677 scm_c_define ("SOCK_SEQPACKET", scm_from_int (SOCK_SEQPACKET));
1678#endif
370312ae 1679#ifdef SOCK_RAW
e11e83f3 1680 scm_c_define ("SOCK_RAW", scm_from_int (SOCK_RAW));
370312ae 1681#endif
6f637a1b
KR
1682#ifdef SOCK_RDM
1683 scm_c_define ("SOCK_RDM", scm_from_int (SOCK_RDM));
1684#endif
370312ae 1685
8fae2bf4
KR
1686 /* setsockopt level.
1687
1688 SOL_IP, SOL_TCP and SOL_UDP are defined on gnu/linux, but not on for
1689 instance NetBSD. We define IPPROTOs because that's what the posix spec
1690 shows in its example at
1691
1692 http://www.opengroup.org/onlinepubs/007904975/functions/getsockopt.html
1693 */
370312ae 1694#ifdef SOL_SOCKET
e11e83f3 1695 scm_c_define ("SOL_SOCKET", scm_from_int (SOL_SOCKET));
370312ae 1696#endif
8fae2bf4
KR
1697#ifdef IPPROTO_IP
1698 scm_c_define ("IPPROTO_IP", scm_from_int (IPPROTO_IP));
370312ae 1699#endif
8fae2bf4
KR
1700#ifdef IPPROTO_TCP
1701 scm_c_define ("IPPROTO_TCP", scm_from_int (IPPROTO_TCP));
370312ae 1702#endif
8fae2bf4
KR
1703#ifdef IPPROTO_UDP
1704 scm_c_define ("IPPROTO_UDP", scm_from_int (IPPROTO_UDP));
370312ae
GH
1705#endif
1706
1707 /* setsockopt names. */
1708#ifdef SO_DEBUG
e11e83f3 1709 scm_c_define ("SO_DEBUG", scm_from_int (SO_DEBUG));
370312ae
GH
1710#endif
1711#ifdef SO_REUSEADDR
e11e83f3 1712 scm_c_define ("SO_REUSEADDR", scm_from_int (SO_REUSEADDR));
370312ae
GH
1713#endif
1714#ifdef SO_STYLE
e11e83f3 1715 scm_c_define ("SO_STYLE", scm_from_int (SO_STYLE));
370312ae
GH
1716#endif
1717#ifdef SO_TYPE
e11e83f3 1718 scm_c_define ("SO_TYPE", scm_from_int (SO_TYPE));
370312ae
GH
1719#endif
1720#ifdef SO_ERROR
e11e83f3 1721 scm_c_define ("SO_ERROR", scm_from_int (SO_ERROR));
370312ae
GH
1722#endif
1723#ifdef SO_DONTROUTE
e11e83f3 1724 scm_c_define ("SO_DONTROUTE", scm_from_int (SO_DONTROUTE));
370312ae
GH
1725#endif
1726#ifdef SO_BROADCAST
e11e83f3 1727 scm_c_define ("SO_BROADCAST", scm_from_int (SO_BROADCAST));
370312ae
GH
1728#endif
1729#ifdef SO_SNDBUF
e11e83f3 1730 scm_c_define ("SO_SNDBUF", scm_from_int (SO_SNDBUF));
370312ae
GH
1731#endif
1732#ifdef SO_RCVBUF
e11e83f3 1733 scm_c_define ("SO_RCVBUF", scm_from_int (SO_RCVBUF));
370312ae
GH
1734#endif
1735#ifdef SO_KEEPALIVE
e11e83f3 1736 scm_c_define ("SO_KEEPALIVE", scm_from_int (SO_KEEPALIVE));
370312ae
GH
1737#endif
1738#ifdef SO_OOBINLINE
e11e83f3 1739 scm_c_define ("SO_OOBINLINE", scm_from_int (SO_OOBINLINE));
370312ae
GH
1740#endif
1741#ifdef SO_NO_CHECK
e11e83f3 1742 scm_c_define ("SO_NO_CHECK", scm_from_int (SO_NO_CHECK));
370312ae
GH
1743#endif
1744#ifdef SO_PRIORITY
e11e83f3 1745 scm_c_define ("SO_PRIORITY", scm_from_int (SO_PRIORITY));
370312ae
GH
1746#endif
1747#ifdef SO_LINGER
e11e83f3 1748 scm_c_define ("SO_LINGER", scm_from_int (SO_LINGER));
370312ae
GH
1749#endif
1750
1751 /* recv/send options. */
8ab3d8a0
KR
1752#ifdef MSG_DONTWAIT
1753 scm_c_define ("MSG_DONTWAIT", scm_from_int (MSG_DONTWAIT));
1754#endif
370312ae 1755#ifdef MSG_OOB
e11e83f3 1756 scm_c_define ("MSG_OOB", scm_from_int (MSG_OOB));
370312ae
GH
1757#endif
1758#ifdef MSG_PEEK
e11e83f3 1759 scm_c_define ("MSG_PEEK", scm_from_int (MSG_PEEK));
370312ae
GH
1760#endif
1761#ifdef MSG_DONTROUTE
e11e83f3 1762 scm_c_define ("MSG_DONTROUTE", scm_from_int (MSG_DONTROUTE));
370312ae
GH
1763#endif
1764
b4e15479
SJ
1765#ifdef __MINGW32__
1766 scm_i_init_socket_Win32 ();
1767#endif
1768
1c80707c
MV
1769#ifdef IP_ADD_MEMBERSHIP
1770 scm_c_define ("IP_ADD_MEMBERSHIP", scm_from_int (IP_ADD_MEMBERSHIP));
1771 scm_c_define ("IP_DROP_MEMBERSHIP", scm_from_int (IP_DROP_MEMBERSHIP));
1772#endif
1773
0f2d19dd 1774 scm_add_feature ("socket");
370312ae 1775
a0599745 1776#include "libguile/socket.x"
0f2d19dd
JB
1777}
1778
89e00824
ML
1779
1780/*
1781 Local Variables:
1782 c-file-style: "gnu"
1783 End:
1784*/