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