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