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