(scm_init_socket): Add SOCK_SEQPACKET and SOCK_RDM.
[bpt/guile.git] / libguile / socket.c
1 /* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003, 2004 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 /* we are not currently using socklen_t. it's not defined on all systems,
71 so would need to be checked by configure. in the meantime, plain
72 int is the best alternative. */
73
74 \f
75
76 SCM_DEFINE (scm_htons, "htons", 1, 0, 0,
77 (SCM value),
78 "Convert a 16 bit quantity from host to network byte ordering.\n"
79 "@var{value} is packed into 2 bytes, which are then converted\n"
80 "and returned as a new integer.")
81 #define FUNC_NAME s_scm_htons
82 {
83 return scm_from_ushort (htons (scm_to_ushort (value)));
84 }
85 #undef FUNC_NAME
86
87 SCM_DEFINE (scm_ntohs, "ntohs", 1, 0, 0,
88 (SCM value),
89 "Convert a 16 bit quantity from network to host byte ordering.\n"
90 "@var{value} is packed into 2 bytes, which are then converted\n"
91 "and returned as a new integer.")
92 #define FUNC_NAME s_scm_ntohs
93 {
94 return scm_from_ushort (ntohs (scm_to_ushort (value)));
95 }
96 #undef FUNC_NAME
97
98 SCM_DEFINE (scm_htonl, "htonl", 1, 0, 0,
99 (SCM value),
100 "Convert a 32 bit quantity from host to network byte ordering.\n"
101 "@var{value} is packed into 4 bytes, which are then converted\n"
102 "and returned as a new integer.")
103 #define FUNC_NAME s_scm_htonl
104 {
105 scm_t_uint32 c_in = SCM_NUM2ULONG (1, value);
106
107 return scm_from_ulong (htonl (c_in));
108 }
109 #undef FUNC_NAME
110
111 SCM_DEFINE (scm_ntohl, "ntohl", 1, 0, 0,
112 (SCM value),
113 "Convert a 32 bit quantity from network to host byte ordering.\n"
114 "@var{value} is packed into 4 bytes, which are then converted\n"
115 "and returned as a new integer.")
116 #define FUNC_NAME s_scm_ntohl
117 {
118 scm_t_uint32 c_in = SCM_NUM2ULONG (1, value);
119
120 return scm_from_ulong (ntohl (c_in));
121 }
122 #undef FUNC_NAME
123
124 #ifndef HAVE_INET_ATON
125 /* for our definition in inet_aton.c, not usually needed. */
126 extern int inet_aton ();
127 #endif
128
129 SCM_DEFINE (scm_inet_aton, "inet-aton", 1, 0, 0,
130 (SCM address),
131 "Convert an IPv4 Internet address from printable string\n"
132 "(dotted decimal notation) to an integer. E.g.,\n\n"
133 "@lisp\n"
134 "(inet-aton \"127.0.0.1\") @result{} 2130706433\n"
135 "@end lisp")
136 #define FUNC_NAME s_scm_inet_aton
137 {
138 struct in_addr soka;
139 char *c_address;
140 int rv;
141
142 c_address = scm_to_locale_string (address);
143 rv = inet_aton (c_address, &soka);
144 free (c_address);
145 if (rv == 0)
146 SCM_MISC_ERROR ("bad address", SCM_EOL);
147 return scm_from_ulong (ntohl (soka.s_addr));
148 }
149 #undef FUNC_NAME
150
151
152 SCM_DEFINE (scm_inet_ntoa, "inet-ntoa", 1, 0, 0,
153 (SCM inetid),
154 "Convert an IPv4 Internet address to a printable\n"
155 "(dotted decimal notation) string. E.g.,\n\n"
156 "@lisp\n"
157 "(inet-ntoa 2130706433) @result{} \"127.0.0.1\"\n"
158 "@end lisp")
159 #define FUNC_NAME s_scm_inet_ntoa
160 {
161 struct in_addr addr;
162 char *s;
163 SCM answer;
164 addr.s_addr = htonl (SCM_NUM2ULONG (1, inetid));
165 s = inet_ntoa (addr);
166 answer = scm_mem2string (s, strlen (s));
167 return answer;
168 }
169 #undef FUNC_NAME
170
171 #ifdef HAVE_INET_NETOF
172 SCM_DEFINE (scm_inet_netof, "inet-netof", 1, 0, 0,
173 (SCM address),
174 "Return the network number part of the given IPv4\n"
175 "Internet address. E.g.,\n\n"
176 "@lisp\n"
177 "(inet-netof 2130706433) @result{} 127\n"
178 "@end lisp")
179 #define FUNC_NAME s_scm_inet_netof
180 {
181 struct in_addr addr;
182 addr.s_addr = htonl (SCM_NUM2ULONG (1, address));
183 return scm_from_ulong (inet_netof (addr));
184 }
185 #undef FUNC_NAME
186 #endif
187
188 #ifdef HAVE_INET_LNAOF
189 SCM_DEFINE (scm_lnaof, "inet-lnaof", 1, 0, 0,
190 (SCM address),
191 "Return the local-address-with-network part of the given\n"
192 "IPv4 Internet address, using the obsolete class A/B/C system.\n"
193 "E.g.,\n\n"
194 "@lisp\n"
195 "(inet-lnaof 2130706433) @result{} 1\n"
196 "@end lisp")
197 #define FUNC_NAME s_scm_lnaof
198 {
199 struct in_addr addr;
200 addr.s_addr = htonl (SCM_NUM2ULONG (1, address));
201 return scm_from_ulong (inet_lnaof (addr));
202 }
203 #undef FUNC_NAME
204 #endif
205
206 #ifdef HAVE_INET_MAKEADDR
207 SCM_DEFINE (scm_inet_makeaddr, "inet-makeaddr", 2, 0, 0,
208 (SCM net, SCM lna),
209 "Make an IPv4 Internet address by combining the network number\n"
210 "@var{net} with the local-address-within-network number\n"
211 "@var{lna}. E.g.,\n\n"
212 "@lisp\n"
213 "(inet-makeaddr 127 1) @result{} 2130706433\n"
214 "@end lisp")
215 #define FUNC_NAME s_scm_inet_makeaddr
216 {
217 struct in_addr addr;
218 unsigned long netnum;
219 unsigned long lnanum;
220
221 netnum = SCM_NUM2ULONG (1, net);
222 lnanum = SCM_NUM2ULONG (2, lna);
223 addr = inet_makeaddr (netnum, lnanum);
224 return scm_from_ulong (ntohl (addr.s_addr));
225 }
226 #undef FUNC_NAME
227 #endif
228
229 #ifdef HAVE_IPV6
230
231 /* flip a 128 bit IPv6 address between host and network order. */
232 #ifdef WORDS_BIGENDIAN
233 #define FLIP_NET_HOST_128(addr)
234 #else
235 #define FLIP_NET_HOST_128(addr)\
236 {\
237 int i;\
238 \
239 for (i = 0; i < 8; i++)\
240 {\
241 scm_t_uint8 c = (addr)[i];\
242 \
243 (addr)[i] = (addr)[15 - i];\
244 (addr)[15 - i] = c;\
245 }\
246 }
247 #endif
248
249 #ifdef WORDS_BIGENDIAN
250 #define FLIPCPY_NET_HOST_128(dest, src) memcpy (dest, src, 16)
251 #else
252 #define FLIPCPY_NET_HOST_128(dest, src) \
253 { \
254 const scm_t_uint8 *tmp_srcp = (src) + 15; \
255 scm_t_uint8 *tmp_destp = (dest); \
256 \
257 do { \
258 *tmp_destp++ = *tmp_srcp--; \
259 } while (tmp_srcp != (src)); \
260 }
261 #endif
262
263
264 #if (SIZEOF_SCM_T_BITS * SCM_CHAR_BIT) > 128
265 #error "Assumption that scm_t_bits <= 128 bits has been violated."
266 #endif
267
268 #if (SIZEOF_UNSIGNED_LONG * SCM_CHAR_BIT) > 128
269 #error "Assumption that unsigned long <= 128 bits has been violated."
270 #endif
271
272 #if (SIZEOF_UNSIGNED_LONG_LONG * SCM_CHAR_BIT) > 128
273 #error "Assumption that unsigned long long <= 128 bits has been violated."
274 #endif
275
276 /* convert a 128 bit IPv6 address in network order to a host ordered
277 SCM integer. */
278 static SCM
279 scm_from_ipv6 (const scm_t_uint8 *src)
280 {
281 int i = 0;
282 const scm_t_uint8 *ptr = src;
283 int num_zero_bytes = 0;
284 scm_t_uint8 addr[16];
285
286 /* count leading zeros (since we know it's bigendian, they'll be first) */
287 while (i < 16)
288 {
289 if (*ptr) break;
290 num_zero_bytes++;
291 i++;
292 }
293
294 if (SCM_SIZEOF_UNSIGNED_LONG_LONG != 0) /* compiler should optimize this */
295 {
296 if ((16 - num_zero_bytes) <= sizeof (unsigned long long))
297 {
298 /* it fits */
299 unsigned long long x;
300
301 FLIPCPY_NET_HOST_128(addr, src);
302 #ifdef WORDS_BIGENDIAN
303 memcpy (&x, addr + (16 - sizeof (x)), sizeof (x));
304 #else
305 memcpy (&x, addr, sizeof (x));
306 #endif
307 return scm_from_ulong_long (x);
308 }
309 }
310 else
311 {
312 if ((16 - num_zero_bytes) <= sizeof (unsigned long))
313 {
314 /* this is just so that we use INUM where possible. */
315 unsigned long x;
316
317 FLIPCPY_NET_HOST_128(addr, src);
318 #ifdef WORDS_BIGENDIAN
319 memcpy (&x, addr + (16 - sizeof (x)), sizeof (x));
320 #else
321 memcpy (&x, addr, sizeof (x));
322 #endif
323 return scm_from_ulong (x);
324 }
325 }
326 /* otherwise get the big hammer */
327 {
328 SCM result = scm_i_mkbig ();
329
330 mpz_import (SCM_I_BIG_MPZ (result),
331 1, /* chunk */
332 1, /* big-endian chunk ordering */
333 16, /* chunks are 16 bytes long */
334 1, /* big-endian byte ordering */
335 0, /* "nails" -- leading unused bits per chunk */
336 src);
337 return scm_i_normbig (result);
338 }
339 }
340
341 /* convert a host ordered SCM integer to a 128 bit IPv6 address in
342 network order. */
343 static void
344 scm_to_ipv6 (scm_t_uint8 dst[16], SCM src)
345 {
346 if (SCM_I_INUMP (src))
347 {
348 scm_t_signed_bits n = SCM_I_INUM (src);
349 if (n < 0)
350 scm_out_of_range (NULL, src);
351 #ifdef WORDS_BIGENDIAN
352 memset (dst, 0, 16 - sizeof (scm_t_signed_bits));
353 memcpy (dst + (16 - sizeof (scm_t_signed_bits)),
354 &n,
355 sizeof (scm_t_signed_bits));
356 #else
357 memset (dst + sizeof (scm_t_signed_bits),
358 0,
359 16 - sizeof (scm_t_signed_bits));
360 /* FIXME: this pair of ops is kinda wasteful -- should rewrite as
361 a single loop perhaps, similar to the handling of bignums. */
362 memcpy (dst, &n, sizeof (scm_t_signed_bits));
363 FLIP_NET_HOST_128 (dst);
364 #endif
365 }
366 else if (SCM_BIGP (src))
367 {
368 size_t count;
369
370 if ((mpz_sgn (SCM_I_BIG_MPZ (src)) < 0)
371 || mpz_sizeinbase (SCM_I_BIG_MPZ (src), 2) > 128)
372 scm_out_of_range (NULL, src);
373
374 memset (dst, 0, 16);
375 mpz_export (dst,
376 &count,
377 1, /* big-endian chunk ordering */
378 16, /* chunks are 16 bytes long */
379 1, /* big-endian byte ordering */
380 0, /* "nails" -- leading unused bits per chunk */
381 SCM_I_BIG_MPZ (src));
382 scm_remember_upto_here_1 (src);
383 }
384 else
385 scm_wrong_type_arg (NULL, 0, src);
386 }
387
388 #ifdef HAVE_INET_PTON
389 SCM_DEFINE (scm_inet_pton, "inet-pton", 2, 0, 0,
390 (SCM family, SCM address),
391 "Convert a string containing a printable network address to\n"
392 "an integer address. Note that unlike the C version of this\n"
393 "function,\n"
394 "the result is an integer with normal host byte ordering.\n"
395 "@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g.,\n\n"
396 "@lisp\n"
397 "(inet-pton AF_INET \"127.0.0.1\") @result{} 2130706433\n"
398 "(inet-pton AF_INET6 \"::1\") @result{} 1\n"
399 "@end lisp")
400 #define FUNC_NAME s_scm_inet_pton
401 {
402 int af;
403 char *src;
404 char dst[16];
405 int rv, eno;
406
407 af = scm_to_int (family);
408 SCM_ASSERT_RANGE (1, family, af == AF_INET || af == AF_INET6);
409 src = scm_to_locale_string (address);
410 rv = inet_pton (af, src, dst);
411 eno = errno;
412 free (src);
413 errno = eno;
414 if (rv == -1)
415 SCM_SYSERROR;
416 else if (rv == 0)
417 SCM_MISC_ERROR ("Bad address", SCM_EOL);
418 if (af == AF_INET)
419 return scm_from_ulong (ntohl (*(scm_t_uint32 *) dst));
420 else
421 return scm_from_ipv6 ((char *) dst);
422 }
423 #undef FUNC_NAME
424 #endif
425
426 #ifdef HAVE_INET_NTOP
427 SCM_DEFINE (scm_inet_ntop, "inet-ntop", 2, 0, 0,
428 (SCM family, SCM address),
429 "Convert a network address into a printable string.\n"
430 "Note that unlike the C version of this function,\n"
431 "the input is an integer with normal host byte ordering.\n"
432 "@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g.,\n\n"
433 "@lisp\n"
434 "(inet-ntop AF_INET 2130706433) @result{} \"127.0.0.1\"\n"
435 "(inet-ntop AF_INET6 (- (expt 2 128) 1)) @result{}\n"
436 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\n"
437 "@end lisp")
438 #define FUNC_NAME s_scm_inet_ntop
439 {
440 int af;
441 #ifdef INET6_ADDRSTRLEN
442 char dst[INET6_ADDRSTRLEN];
443 #else
444 char dst[46];
445 #endif
446 char addr6[16];
447
448 af = scm_to_int (family);
449 SCM_ASSERT_RANGE (1, family, af == AF_INET || af == AF_INET6);
450 if (af == AF_INET)
451 *(scm_t_uint32 *) addr6 = htonl (SCM_NUM2ULONG (2, address));
452 else
453 scm_to_ipv6 (addr6, address);
454 if (inet_ntop (af, &addr6, dst, sizeof dst) == NULL)
455 SCM_SYSERROR;
456 return scm_makfrom0str (dst);
457 }
458 #undef FUNC_NAME
459 #endif
460
461 #endif /* HAVE_IPV6 */
462
463 SCM_SYMBOL (sym_socket, "socket");
464
465 #define SCM_SOCK_FD_TO_PORT(fd) scm_fdes_to_port (fd, "r+0", sym_socket)
466
467 SCM_DEFINE (scm_socket, "socket", 3, 0, 0,
468 (SCM family, SCM style, SCM proto),
469 "Return a new socket port of the type specified by @var{family},\n"
470 "@var{style} and @var{proto}. All three parameters are\n"
471 "integers. Supported values for @var{family} are\n"
472 "@code{AF_UNIX}, @code{AF_INET} and @code{AF_INET6}.\n"
473 "Typical values for @var{style} are @code{SOCK_STREAM},\n"
474 "@code{SOCK_DGRAM} and @code{SOCK_RAW}.\n\n"
475 "@var{proto} can be obtained from a protocol name using\n"
476 "@code{getprotobyname}. A value of zero specifies the default\n"
477 "protocol, which is usually right.\n\n"
478 "A single socket port cannot by used for communication until it\n"
479 "has been connected to another socket.")
480 #define FUNC_NAME s_scm_socket
481 {
482 int fd;
483
484 fd = socket (scm_to_int (family),
485 scm_to_int (style),
486 scm_to_int (proto));
487 if (fd == -1)
488 SCM_SYSERROR;
489 return SCM_SOCK_FD_TO_PORT (fd);
490 }
491 #undef FUNC_NAME
492
493 #ifdef HAVE_SOCKETPAIR
494 SCM_DEFINE (scm_socketpair, "socketpair", 3, 0, 0,
495 (SCM family, SCM style, SCM proto),
496 "Return a pair of connected (but unnamed) socket ports of the\n"
497 "type specified by @var{family}, @var{style} and @var{proto}.\n"
498 "Many systems support only socket pairs of the @code{AF_UNIX}\n"
499 "family. Zero is likely to be the only meaningful value for\n"
500 "@var{proto}.")
501 #define FUNC_NAME s_scm_socketpair
502 {
503 int fam;
504 int fd[2];
505
506 fam = scm_to_int (family);
507
508 if (socketpair (fam, scm_to_int (style), scm_to_int (proto), fd) == -1)
509 SCM_SYSERROR;
510
511 return scm_cons (SCM_SOCK_FD_TO_PORT (fd[0]), SCM_SOCK_FD_TO_PORT (fd[1]));
512 }
513 #undef FUNC_NAME
514 #endif
515
516 SCM_DEFINE (scm_getsockopt, "getsockopt", 3, 0, 0,
517 (SCM sock, SCM level, SCM optname),
518 "Return the value of a particular socket option for the socket\n"
519 "port @var{sock}. @var{level} is an integer code for type of\n"
520 "option being requested, e.g., @code{SOL_SOCKET} for\n"
521 "socket-level options. @var{optname} is an integer code for the\n"
522 "option required and should be specified using one of the\n"
523 "symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc.\n\n"
524 "The returned value is typically an integer but @code{SO_LINGER}\n"
525 "returns a pair of integers.")
526 #define FUNC_NAME s_scm_getsockopt
527 {
528 int fd;
529 /* size of optval is the largest supported option. */
530 #ifdef HAVE_STRUCT_LINGER
531 char optval[sizeof (struct linger)];
532 int optlen = sizeof (struct linger);
533 #else
534 char optval[sizeof (size_t)];
535 int optlen = sizeof (size_t);
536 #endif
537 int ilevel;
538 int ioptname;
539
540 sock = SCM_COERCE_OUTPORT (sock);
541 SCM_VALIDATE_OPFPORT (1, sock);
542 ilevel = scm_to_int (level);
543 ioptname = scm_to_int (optname);
544
545 fd = SCM_FPORT_FDES (sock);
546 if (getsockopt (fd, ilevel, ioptname, (void *) optval, &optlen) == -1)
547 SCM_SYSERROR;
548
549 if (ilevel == SOL_SOCKET)
550 {
551 #ifdef SO_LINGER
552 if (ioptname == SO_LINGER)
553 {
554 #ifdef HAVE_STRUCT_LINGER
555 struct linger *ling = (struct linger *) optval;
556
557 return scm_cons (scm_from_long (ling->l_onoff),
558 scm_from_long (ling->l_linger));
559 #else
560 return scm_cons (scm_from_long (*(int *) optval),
561 scm_from_int (0));
562 #endif
563 }
564 else
565 #endif
566 if (0
567 #ifdef SO_SNDBUF
568 || ioptname == SO_SNDBUF
569 #endif
570 #ifdef SO_RCVBUF
571 || ioptname == SO_RCVBUF
572 #endif
573 )
574 {
575 return scm_from_size_t (*(size_t *) optval);
576 }
577 }
578 return scm_from_int (*(int *) optval);
579 }
580 #undef FUNC_NAME
581
582 SCM_DEFINE (scm_setsockopt, "setsockopt", 4, 0, 0,
583 (SCM sock, SCM level, SCM optname, SCM value),
584 "Set the value of a particular socket option for the socket\n"
585 "port @var{sock}. @var{level} is an integer code for type of option\n"
586 "being set, e.g., @code{SOL_SOCKET} for socket-level options.\n"
587 "@var{optname} is an\n"
588 "integer code for the option to set and should be specified using one of\n"
589 "the symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc.\n"
590 "@var{value} is the value to which the option should be set. For\n"
591 "most options this must be an integer, but for @code{SO_LINGER} it must\n"
592 "be a pair.\n\n"
593 "The return value is unspecified.")
594 #define FUNC_NAME s_scm_setsockopt
595 {
596 int fd;
597 int optlen = -1;
598 /* size of optval is the largest supported option. */
599 #ifdef HAVE_STRUCT_LINGER
600 char optval[sizeof (struct linger)];
601 #else
602 char optval[sizeof (size_t)];
603 #endif
604 int ilevel, ioptname;
605
606 sock = SCM_COERCE_OUTPORT (sock);
607
608 SCM_VALIDATE_OPFPORT (1, sock);
609 ilevel = scm_to_int (level);
610 ioptname = scm_to_int (optname);
611
612 fd = SCM_FPORT_FDES (sock);
613
614 if (ilevel == SOL_SOCKET)
615 {
616 #ifdef SO_LINGER
617 if (ioptname == SO_LINGER)
618 {
619 #ifdef HAVE_STRUCT_LINGER
620 struct linger ling;
621 long lv;
622
623 SCM_ASSERT (SCM_CONSP (value), value, SCM_ARG4, FUNC_NAME);
624 lv = SCM_NUM2LONG (4, SCM_CAR (value));
625 ling.l_onoff = (int) lv;
626 SCM_ASSERT_RANGE (SCM_ARG4, value, ling.l_onoff == lv);
627 lv = SCM_NUM2LONG (4, SCM_CDR (value));
628 ling.l_linger = (int) lv;
629 SCM_ASSERT_RANGE (SCM_ARG4, value, ling.l_linger == lv);
630 optlen = (int) sizeof (struct linger);
631 memcpy (optval, (void *) &ling, optlen);
632 #else
633 int ling;
634 long lv;
635
636 SCM_ASSERT (SCM_CONSP (value), value, SCM_ARG4, FUNC_NAME);
637 /* timeout is ignored, but may as well validate it. */
638 lv = SCM_NUM2LONG (4, SCM_CDR (value));
639 ling = (int) lv;
640 SCM_ASSERT_RANGE (SCM_ARG4, value, ling == lv);
641 lv = SCM_NUM2LONG (4, SCM_CAR (value));
642 ling = (int) lv;
643 SCM_ASSERT_RANGE (SCM_ARG4, value, ling == lv);
644 optlen = (int) sizeof (int);
645 (*(int *) optval) = ling;
646 #endif
647 }
648 else
649 #endif
650 if (0
651 #ifdef SO_SNDBUF
652 || ioptname == SO_SNDBUF
653 #endif
654 #ifdef SO_RCVBUF
655 || ioptname == SO_RCVBUF
656 #endif
657 )
658 {
659 long lv = SCM_NUM2LONG (4, value);
660
661 optlen = (int) sizeof (size_t);
662 (*(size_t *) optval) = (size_t) lv;
663 }
664 }
665 if (optlen == -1)
666 {
667 /* Most options take an int. */
668 long lv = SCM_NUM2LONG (4, value);
669 int val = (int) lv;
670
671 SCM_ASSERT_RANGE (SCM_ARG4, value, val == lv);
672 optlen = (int) sizeof (int);
673 (*(int *) optval) = val;
674 }
675 if (setsockopt (fd, ilevel, ioptname, (void *) optval, optlen) == -1)
676 SCM_SYSERROR;
677 return SCM_UNSPECIFIED;
678 }
679 #undef FUNC_NAME
680
681 SCM_DEFINE (scm_shutdown, "shutdown", 2, 0, 0,
682 (SCM sock, SCM how),
683 "Sockets can be closed simply by using @code{close-port}. The\n"
684 "@code{shutdown} procedure allows reception or transmission on a\n"
685 "connection to be shut down individually, according to the parameter\n"
686 "@var{how}:\n\n"
687 "@table @asis\n"
688 "@item 0\n"
689 "Stop receiving data for this socket. If further data arrives, reject it.\n"
690 "@item 1\n"
691 "Stop trying to transmit data from this socket. Discard any\n"
692 "data waiting to be sent. Stop looking for acknowledgement of\n"
693 "data already sent; don't retransmit it if it is lost.\n"
694 "@item 2\n"
695 "Stop both reception and transmission.\n"
696 "@end table\n\n"
697 "The return value is unspecified.")
698 #define FUNC_NAME s_scm_shutdown
699 {
700 int fd;
701 sock = SCM_COERCE_OUTPORT (sock);
702 SCM_VALIDATE_OPFPORT (1, sock);
703 fd = SCM_FPORT_FDES (sock);
704 if (shutdown (fd, scm_to_signed_integer (how, 0, 2)) == -1)
705 SCM_SYSERROR;
706 return SCM_UNSPECIFIED;
707 }
708 #undef FUNC_NAME
709
710 /* convert fam/address/args into a sockaddr of the appropriate type.
711 args is modified by removing the arguments actually used.
712 which_arg and proc are used when reporting errors:
713 which_arg is the position of address in the original argument list.
714 proc is the name of the original procedure.
715 size returns the size of the structure allocated. */
716
717 static struct sockaddr *
718 scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
719 const char *proc, int *size)
720 #define FUNC_NAME proc
721 {
722 switch (fam)
723 {
724 case AF_INET:
725 {
726 struct sockaddr_in *soka;
727 unsigned long addr;
728 int port;
729
730 SCM_VALIDATE_ULONG_COPY (which_arg, address, addr);
731 SCM_VALIDATE_CONS (which_arg + 1, *args);
732 port = scm_to_int (SCM_CAR (*args));
733 *args = SCM_CDR (*args);
734 soka = (struct sockaddr_in *) scm_malloc (sizeof (struct sockaddr_in));
735 if (!soka)
736 scm_memory_error (proc);
737 /* 4.4BSD-style interface includes sin_len member and defines SIN_LEN,
738 4.3BSD does not. */
739 #ifdef SIN_LEN
740 soka->sin_len = sizeof (struct sockaddr_in);
741 #endif
742 soka->sin_family = AF_INET;
743 soka->sin_addr.s_addr = htonl (addr);
744 soka->sin_port = htons (port);
745 *size = sizeof (struct sockaddr_in);
746 return (struct sockaddr *) soka;
747 }
748 #ifdef HAVE_IPV6
749 case AF_INET6:
750 {
751 /* see RFC2553. */
752 int port;
753 struct sockaddr_in6 *soka;
754 unsigned long flowinfo = 0;
755 unsigned long scope_id = 0;
756
757 SCM_VALIDATE_CONS (which_arg + 1, *args);
758 port = scm_to_int (SCM_CAR (*args));
759 *args = SCM_CDR (*args);
760 if (SCM_CONSP (*args))
761 {
762 SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
763 *args = SCM_CDR (*args);
764 if (SCM_CONSP (*args))
765 {
766 SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
767 scope_id);
768 *args = SCM_CDR (*args);
769 }
770 }
771 soka = (struct sockaddr_in6 *) scm_malloc (sizeof (struct sockaddr_in6));
772 if (!soka)
773 scm_memory_error (proc);
774 #ifdef SIN_LEN6
775 soka->sin6_len = sizeof (struct sockaddr_in6);
776 #endif
777 soka->sin6_family = AF_INET6;
778 scm_to_ipv6 (soka->sin6_addr.s6_addr, address);
779 soka->sin6_port = htons (port);
780 soka->sin6_flowinfo = flowinfo;
781 #ifdef HAVE_SIN6_SCOPE_ID
782 soka->sin6_scope_id = scope_id;
783 #endif
784 *size = sizeof (struct sockaddr_in6);
785 return (struct sockaddr *) soka;
786 }
787 #endif
788 #ifdef HAVE_UNIX_DOMAIN_SOCKETS
789 case AF_UNIX:
790 {
791 struct sockaddr_un *soka;
792 int addr_size;
793 char *c_address;
794
795 scm_frame_begin (0);
796
797 c_address = scm_to_locale_string (address);
798 scm_frame_free (c_address);
799
800 /* the static buffer size in sockaddr_un seems to be arbitrary
801 and not necessarily a hard limit. e.g., the glibc manual
802 suggests it may be possible to declare it size 0. let's
803 ignore it. if the O/S doesn't like the size it will cause
804 connect/bind etc., to fail. sun_path is always the last
805 member of the structure. */
806 addr_size = sizeof (struct sockaddr_un)
807 + max (0, strlen (c_address) + 1 - (sizeof soka->sun_path));
808 soka = (struct sockaddr_un *) scm_malloc (addr_size);
809 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
810 soka->sun_family = AF_UNIX;
811 strcpy (soka->sun_path, c_address);
812 *size = SUN_LEN (soka);
813
814 scm_frame_end ();
815 return (struct sockaddr *) soka;
816 }
817 #endif
818 default:
819 scm_out_of_range (proc, scm_from_int (fam));
820 }
821 }
822 #undef FUNC_NAME
823
824 SCM_DEFINE (scm_connect, "connect", 3, 0, 1,
825 (SCM sock, SCM fam, SCM address, SCM args),
826 "Initiate a connection from a socket using a specified address\n"
827 "family to the address\n"
828 "specified by @var{address} and possibly @var{args}.\n"
829 "The format required for @var{address}\n"
830 "and @var{args} depends on the family of the socket.\n\n"
831 "For a socket of family @code{AF_UNIX},\n"
832 "only @var{address} is specified and must be a string with the\n"
833 "filename where the socket is to be created.\n\n"
834 "For a socket of family @code{AF_INET},\n"
835 "@var{address} must be an integer IPv4 host address and\n"
836 "@var{args} must be a single integer port number.\n\n"
837 "For a socket of family @code{AF_INET6},\n"
838 "@var{address} must be an integer IPv6 host address and\n"
839 "@var{args} may be up to three integers:\n"
840 "port [flowinfo] [scope_id],\n"
841 "where flowinfo and scope_id default to zero.\n\n"
842 "The return value is unspecified.")
843 #define FUNC_NAME s_scm_connect
844 {
845 int fd;
846 struct sockaddr *soka;
847 int size;
848
849 sock = SCM_COERCE_OUTPORT (sock);
850 SCM_VALIDATE_OPFPORT (1, sock);
851 fd = SCM_FPORT_FDES (sock);
852 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args, 3, FUNC_NAME,
853 &size);
854 if (connect (fd, soka, size) == -1)
855 {
856 int save_errno = errno;
857
858 free (soka);
859 errno = save_errno;
860 SCM_SYSERROR;
861 }
862 free (soka);
863 return SCM_UNSPECIFIED;
864 }
865 #undef FUNC_NAME
866
867 SCM_DEFINE (scm_bind, "bind", 3, 0, 1,
868 (SCM sock, SCM fam, SCM address, SCM args),
869 "Assign an address to the socket port @var{sock}.\n"
870 "Generally this only needs to be done for server sockets,\n"
871 "so they know where to look for incoming connections. A socket\n"
872 "without an address will be assigned one automatically when it\n"
873 "starts communicating.\n\n"
874 "The format of @var{address} and @var{args} depends\n"
875 "on the family of the socket.\n\n"
876 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
877 "is specified and must be a string with the filename where\n"
878 "the socket is to be created.\n\n"
879 "For a socket of family @code{AF_INET}, @var{address}\n"
880 "must be an integer IPv4 address and @var{args}\n"
881 "must be a single integer port number.\n\n"
882 "The values of the following variables can also be used for\n"
883 "@var{address}:\n\n"
884 "@defvar INADDR_ANY\n"
885 "Allow connections from any address.\n"
886 "@end defvar\n\n"
887 "@defvar INADDR_LOOPBACK\n"
888 "The address of the local host using the loopback device.\n"
889 "@end defvar\n\n"
890 "@defvar INADDR_BROADCAST\n"
891 "The broadcast address on the local network.\n"
892 "@end defvar\n\n"
893 "@defvar INADDR_NONE\n"
894 "No address.\n"
895 "@end defvar\n\n"
896 "For a socket of family @code{AF_INET6}, @var{address}\n"
897 "must be an integer IPv6 address and @var{args}\n"
898 "may be up to three integers:\n"
899 "port [flowinfo] [scope_id],\n"
900 "where flowinfo and scope_id default to zero.\n\n"
901 "The return value is unspecified.")
902 #define FUNC_NAME s_scm_bind
903 {
904 struct sockaddr *soka;
905 int size;
906 int fd;
907
908 sock = SCM_COERCE_OUTPORT (sock);
909 SCM_VALIDATE_OPFPORT (1, sock);
910 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args, 3, FUNC_NAME,
911 &size);
912 fd = SCM_FPORT_FDES (sock);
913 if (bind (fd, soka, size) == -1)
914 {
915 int save_errno = errno;
916
917 free (soka);
918 errno = save_errno;
919 SCM_SYSERROR;
920 }
921 free (soka);
922 return SCM_UNSPECIFIED;
923 }
924 #undef FUNC_NAME
925
926 SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
927 (SCM sock, SCM backlog),
928 "Enable @var{sock} to accept connection\n"
929 "requests. @var{backlog} is an integer specifying\n"
930 "the maximum length of the queue for pending connections.\n"
931 "If the queue fills, new clients will fail to connect until\n"
932 "the server calls @code{accept} to accept a connection from\n"
933 "the queue.\n\n"
934 "The return value is unspecified.")
935 #define FUNC_NAME s_scm_listen
936 {
937 int fd;
938 sock = SCM_COERCE_OUTPORT (sock);
939 SCM_VALIDATE_OPFPORT (1, sock);
940 fd = SCM_FPORT_FDES (sock);
941 if (listen (fd, scm_to_int (backlog)) == -1)
942 SCM_SYSERROR;
943 return SCM_UNSPECIFIED;
944 }
945 #undef FUNC_NAME
946
947 /* Put the components of a sockaddr into a new SCM vector. */
948 static SCM
949 scm_addr_vector (const struct sockaddr *address, int addr_size,
950 const char *proc)
951 {
952 short int fam = address->sa_family;
953 SCM result =SCM_EOL;
954
955
956 switch (fam)
957 {
958 case AF_INET:
959 {
960 const struct sockaddr_in *nad = (struct sockaddr_in *) address;
961
962 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
963
964 SCM_VECTOR_SET(result, 0,
965 scm_from_short (fam));
966 SCM_VECTOR_SET(result, 1,
967 scm_from_ulong (ntohl (nad->sin_addr.s_addr)));
968 SCM_VECTOR_SET(result, 2,
969 scm_from_ushort (ntohs (nad->sin_port)));
970 }
971 break;
972 #ifdef HAVE_IPV6
973 case AF_INET6:
974 {
975 const struct sockaddr_in6 *nad = (struct sockaddr_in6 *) address;
976
977 result = scm_c_make_vector (5, SCM_UNSPECIFIED);
978 SCM_VECTOR_SET(result, 0, scm_from_short (fam));
979 SCM_VECTOR_SET(result, 1, scm_from_ipv6 (nad->sin6_addr.s6_addr));
980 SCM_VECTOR_SET(result, 2, scm_from_ushort (ntohs (nad->sin6_port)));
981 SCM_VECTOR_SET(result, 3, scm_from_uint32 (nad->sin6_flowinfo));
982 #ifdef HAVE_SIN6_SCOPE_ID
983 SCM_VECTOR_SET(result, 4, scm_from_ulong (nad->sin6_scope_id));
984 #else
985 SCM_VECTOR_SET(result, 4, SCM_INUM0);
986 #endif
987 }
988 break;
989 #endif
990 #ifdef HAVE_UNIX_DOMAIN_SOCKETS
991 case AF_UNIX:
992 {
993 const struct sockaddr_un *nad = (struct sockaddr_un *) address;
994
995 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
996
997 SCM_VECTOR_SET(result, 0, scm_from_short (fam));
998 /* When addr_size is not enough to cover sun_path, do not try
999 to access it. */
1000 if (addr_size <= offsetof (struct sockaddr_un, sun_path))
1001 SCM_VECTOR_SET(result, 1, SCM_BOOL_F);
1002 else
1003 SCM_VECTOR_SET(result, 1, scm_mem2string (nad->sun_path,
1004 strlen (nad->sun_path)));
1005 }
1006 break;
1007 #endif
1008 default:
1009 scm_misc_error (proc, "Unrecognised address family: ~A",
1010 scm_list_1 (scm_from_int (fam)));
1011 }
1012 return result;
1013 }
1014
1015 /* calculate the size of a buffer large enough to hold any supported
1016 sockaddr type. if the buffer isn't large enough, certain system
1017 calls will return a truncated address. */
1018
1019 #if defined (HAVE_UNIX_DOMAIN_SOCKETS)
1020 #define MAX_SIZE_UN sizeof (struct sockaddr_un)
1021 #else
1022 #define MAX_SIZE_UN 0
1023 #endif
1024
1025 #if defined (HAVE_IPV6)
1026 #define MAX_SIZE_IN6 sizeof (struct sockaddr_in6)
1027 #else
1028 #define MAX_SIZE_IN6 0
1029 #endif
1030
1031 #define MAX_ADDR_SIZE max (max (sizeof (struct sockaddr_in), MAX_SIZE_IN6),\
1032 MAX_SIZE_UN)
1033
1034 SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1035 (SCM sock),
1036 "Accept a connection on a bound, listening socket.\n"
1037 "If there\n"
1038 "are no pending connections in the queue, wait until\n"
1039 "one is available unless the non-blocking option has been\n"
1040 "set on the socket.\n\n"
1041 "The return value is a\n"
1042 "pair in which the @emph{car} is a new socket port for the\n"
1043 "connection and\n"
1044 "the @emph{cdr} is an object with address information about the\n"
1045 "client which initiated the connection.\n\n"
1046 "@var{sock} does not become part of the\n"
1047 "connection and will continue to accept new requests.")
1048 #define FUNC_NAME s_scm_accept
1049 {
1050 int fd;
1051 int newfd;
1052 SCM address;
1053 SCM newsock;
1054 int addr_size = MAX_ADDR_SIZE;
1055 char max_addr[MAX_ADDR_SIZE];
1056 struct sockaddr *addr = (struct sockaddr *) max_addr;
1057
1058 sock = SCM_COERCE_OUTPORT (sock);
1059 SCM_VALIDATE_OPFPORT (1, sock);
1060 fd = SCM_FPORT_FDES (sock);
1061 newfd = accept (fd, addr, &addr_size);
1062 if (newfd == -1)
1063 SCM_SYSERROR;
1064 newsock = SCM_SOCK_FD_TO_PORT (newfd);
1065 address = scm_addr_vector (addr, addr_size, FUNC_NAME);
1066 return scm_cons (newsock, address);
1067 }
1068 #undef FUNC_NAME
1069
1070 SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1071 (SCM sock),
1072 "Return the address of @var{sock}, in the same form as the\n"
1073 "object returned by @code{accept}. On many systems the address\n"
1074 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1075 #define FUNC_NAME s_scm_getsockname
1076 {
1077 int fd;
1078 int addr_size = MAX_ADDR_SIZE;
1079 char max_addr[MAX_ADDR_SIZE];
1080 struct sockaddr *addr = (struct sockaddr *) max_addr;
1081
1082 sock = SCM_COERCE_OUTPORT (sock);
1083 SCM_VALIDATE_OPFPORT (1, sock);
1084 fd = SCM_FPORT_FDES (sock);
1085 if (getsockname (fd, addr, &addr_size) == -1)
1086 SCM_SYSERROR;
1087 return scm_addr_vector (addr, addr_size, FUNC_NAME);
1088 }
1089 #undef FUNC_NAME
1090
1091 SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1092 (SCM sock),
1093 "Return the address that @var{sock}\n"
1094 "is connected to, in the same form as the object returned by\n"
1095 "@code{accept}. On many systems the address of a socket in the\n"
1096 "@code{AF_FILE} namespace cannot be read.")
1097 #define FUNC_NAME s_scm_getpeername
1098 {
1099 int fd;
1100 int addr_size = MAX_ADDR_SIZE;
1101 char max_addr[MAX_ADDR_SIZE];
1102 struct sockaddr *addr = (struct sockaddr *) max_addr;
1103
1104 sock = SCM_COERCE_OUTPORT (sock);
1105 SCM_VALIDATE_OPFPORT (1, sock);
1106 fd = SCM_FPORT_FDES (sock);
1107 if (getpeername (fd, addr, &addr_size) == -1)
1108 SCM_SYSERROR;
1109 return scm_addr_vector (addr, addr_size, FUNC_NAME);
1110 }
1111 #undef FUNC_NAME
1112
1113 SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1114 (SCM sock, SCM buf, SCM flags),
1115 "Receive data from a socket port.\n"
1116 "@var{sock} must already\n"
1117 "be bound to the address from which data is to be received.\n"
1118 "@var{buf} is a string into which\n"
1119 "the data will be written. The size of @var{buf} limits\n"
1120 "the amount of\n"
1121 "data which can be received: in the case of packet\n"
1122 "protocols, if a packet larger than this limit is encountered\n"
1123 "then some data\n"
1124 "will be irrevocably lost.\n\n"
1125 "The optional @var{flags} argument is a value or\n"
1126 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
1127 "The value returned is the number of bytes read from the\n"
1128 "socket.\n\n"
1129 "Note that the data is read directly from the socket file\n"
1130 "descriptor:\n"
1131 "any unread buffered port data is ignored.")
1132 #define FUNC_NAME s_scm_recv
1133 {
1134 int rv;
1135 int fd;
1136 int flg;
1137
1138 SCM_VALIDATE_OPFPORT (1, sock);
1139 SCM_VALIDATE_STRING (2, buf);
1140 if (SCM_UNBNDP (flags))
1141 flg = 0;
1142 else
1143 flg = scm_to_int (flags);
1144 fd = SCM_FPORT_FDES (sock);
1145
1146 SCM_SYSCALL (rv = recv (fd,
1147 SCM_I_STRING_CHARS (buf), SCM_I_STRING_LENGTH (buf),
1148 flg));
1149 if (rv == -1)
1150 SCM_SYSERROR;
1151
1152 scm_remember_upto_here_1 (buf);
1153 return scm_from_int (rv);
1154 }
1155 #undef FUNC_NAME
1156
1157 SCM_DEFINE (scm_send, "send", 2, 1, 0,
1158 (SCM sock, SCM message, SCM flags),
1159 "Transmit the string @var{message} on a socket port @var{sock}.\n"
1160 "@var{sock} must already be bound to a destination address. The\n"
1161 "value returned is the number of bytes transmitted --\n"
1162 "it's possible for\n"
1163 "this to be less than the length of @var{message}\n"
1164 "if the socket is\n"
1165 "set to be non-blocking. The optional @var{flags} argument\n"
1166 "is a value or\n"
1167 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
1168 "Note that the data is written directly to the socket\n"
1169 "file descriptor:\n"
1170 "any unflushed buffered port data is ignored.")
1171 #define FUNC_NAME s_scm_send
1172 {
1173 int rv;
1174 int fd;
1175 int flg;
1176
1177 sock = SCM_COERCE_OUTPORT (sock);
1178 SCM_VALIDATE_OPFPORT (1, sock);
1179 SCM_VALIDATE_STRING (2, message);
1180 if (SCM_UNBNDP (flags))
1181 flg = 0;
1182 else
1183 flg = scm_to_int (flags);
1184 fd = SCM_FPORT_FDES (sock);
1185
1186 SCM_SYSCALL (rv = send (fd,
1187 SCM_I_STRING_CHARS (message),
1188 SCM_I_STRING_LENGTH (message),
1189 flg));
1190 if (rv == -1)
1191 SCM_SYSERROR;
1192
1193 scm_remember_upto_here_1 (message);
1194 return scm_from_int (rv);
1195 }
1196 #undef FUNC_NAME
1197
1198 SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
1199 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
1200 "Return data from the socket port @var{sock} and also\n"
1201 "information about where the data was received from.\n"
1202 "@var{sock} must already be bound to the address from which\n"
1203 "data is to be received. @code{str}, is a string into which the\n"
1204 "data will be written. The size of @var{str} limits the amount\n"
1205 "of data which can be received: in the case of packet protocols,\n"
1206 "if a packet larger than this limit is encountered then some\n"
1207 "data will be irrevocably lost.\n\n"
1208 "The optional @var{flags} argument is a value or bitwise OR of\n"
1209 "@code{MSG_OOB}, @code{MSG_PEEK}, @code{MSG_DONTROUTE} etc.\n\n"
1210 "The value returned is a pair: the @emph{car} is the number of\n"
1211 "bytes read from the socket and the @emph{cdr} an address object\n"
1212 "in the same form as returned by @code{accept}. The address\n"
1213 "will given as @code{#f} if not available, as is usually the\n"
1214 "case for stream sockets.\n\n"
1215 "The @var{start} and @var{end} arguments specify a substring of\n"
1216 "@var{str} to which the data should be written.\n\n"
1217 "Note that the data is read directly from the socket file\n"
1218 "descriptor: any unread buffered port data is ignored.")
1219 #define FUNC_NAME s_scm_recvfrom
1220 {
1221 int rv;
1222 int fd;
1223 int flg;
1224 char *buf;
1225 size_t offset;
1226 size_t cend;
1227 SCM address;
1228 int addr_size = MAX_ADDR_SIZE;
1229 char max_addr[MAX_ADDR_SIZE];
1230 struct sockaddr *addr = (struct sockaddr *) max_addr;
1231
1232 SCM_VALIDATE_OPFPORT (1, sock);
1233 fd = SCM_FPORT_FDES (sock);
1234
1235 SCM_VALIDATE_STRING (2, str);
1236 buf = SCM_I_STRING_CHARS (str);
1237 scm_i_get_substring_spec (SCM_I_STRING_LENGTH (str),
1238 start, &offset, end, &cend);
1239
1240 if (SCM_UNBNDP (flags))
1241 flg = 0;
1242 else
1243 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
1244
1245 /* recvfrom will not necessarily return an address. usually nothing
1246 is returned for stream sockets. */
1247 addr->sa_family = AF_UNSPEC;
1248 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
1249 cend - offset, flg,
1250 addr, &addr_size));
1251 if (rv == -1)
1252 SCM_SYSERROR;
1253 if (addr->sa_family != AF_UNSPEC)
1254 address = scm_addr_vector (addr, addr_size, FUNC_NAME);
1255 else
1256 address = SCM_BOOL_F;
1257
1258 scm_remember_upto_here_1 (str);
1259 return scm_cons (scm_from_int (rv), address);
1260 }
1261 #undef FUNC_NAME
1262
1263 SCM_DEFINE (scm_sendto, "sendto", 4, 0, 1,
1264 (SCM sock, SCM message, SCM fam, SCM address, SCM args_and_flags),
1265 "Transmit the string @var{message} on the socket port\n"
1266 "@var{sock}. The\n"
1267 "destination address is specified using the @var{fam},\n"
1268 "@var{address} and\n"
1269 "@var{args_and_flags} arguments, in a similar way to the\n"
1270 "@code{connect} procedure. @var{args_and_flags} contains\n"
1271 "the usual connection arguments optionally followed by\n"
1272 "a flags argument, which is a value or\n"
1273 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
1274 "The value returned is the number of bytes transmitted --\n"
1275 "it's possible for\n"
1276 "this to be less than the length of @var{message} if the\n"
1277 "socket is\n"
1278 "set to be non-blocking.\n"
1279 "Note that the data is written directly to the socket\n"
1280 "file descriptor:\n"
1281 "any unflushed buffered port data is ignored.")
1282 #define FUNC_NAME s_scm_sendto
1283 {
1284 int rv;
1285 int fd;
1286 int flg;
1287 struct sockaddr *soka;
1288 int size;
1289
1290 sock = SCM_COERCE_OUTPORT (sock);
1291 SCM_VALIDATE_FPORT (1, sock);
1292 SCM_VALIDATE_STRING (2, message);
1293 fd = SCM_FPORT_FDES (sock);
1294 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args_and_flags, 4,
1295 FUNC_NAME, &size);
1296 if (SCM_NULLP (args_and_flags))
1297 flg = 0;
1298 else
1299 {
1300 SCM_VALIDATE_CONS (5, args_and_flags);
1301 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
1302 }
1303 SCM_SYSCALL (rv = sendto (fd,
1304 SCM_I_STRING_CHARS (message),
1305 SCM_I_STRING_LENGTH (message),
1306 flg, soka, size));
1307 if (rv == -1)
1308 {
1309 int save_errno = errno;
1310 free (soka);
1311 errno = save_errno;
1312 SCM_SYSERROR;
1313 }
1314 free (soka);
1315
1316 scm_remember_upto_here_1 (message);
1317 return scm_from_int (rv);
1318 }
1319 #undef FUNC_NAME
1320 \f
1321
1322
1323 void
1324 scm_init_socket ()
1325 {
1326 /* protocol families. */
1327 #ifdef AF_UNSPEC
1328 scm_c_define ("AF_UNSPEC", scm_from_int (AF_UNSPEC));
1329 #endif
1330 #ifdef AF_UNIX
1331 scm_c_define ("AF_UNIX", scm_from_int (AF_UNIX));
1332 #endif
1333 #ifdef AF_INET
1334 scm_c_define ("AF_INET", scm_from_int (AF_INET));
1335 #endif
1336 #ifdef AF_INET6
1337 scm_c_define ("AF_INET6", scm_from_int (AF_INET6));
1338 #endif
1339
1340 #ifdef PF_UNSPEC
1341 scm_c_define ("PF_UNSPEC", scm_from_int (PF_UNSPEC));
1342 #endif
1343 #ifdef PF_UNIX
1344 scm_c_define ("PF_UNIX", scm_from_int (PF_UNIX));
1345 #endif
1346 #ifdef PF_INET
1347 scm_c_define ("PF_INET", scm_from_int (PF_INET));
1348 #endif
1349 #ifdef PF_INET6
1350 scm_c_define ("PF_INET6", scm_from_int (PF_INET6));
1351 #endif
1352
1353 /* standard addresses. */
1354 #ifdef INADDR_ANY
1355 scm_c_define ("INADDR_ANY", scm_from_ulong (INADDR_ANY));
1356 #endif
1357 #ifdef INADDR_BROADCAST
1358 scm_c_define ("INADDR_BROADCAST", scm_from_ulong (INADDR_BROADCAST));
1359 #endif
1360 #ifdef INADDR_NONE
1361 scm_c_define ("INADDR_NONE", scm_from_ulong (INADDR_NONE));
1362 #endif
1363 #ifdef INADDR_LOOPBACK
1364 scm_c_define ("INADDR_LOOPBACK", scm_from_ulong (INADDR_LOOPBACK));
1365 #endif
1366
1367 /* socket types.
1368
1369 SOCK_PACKET is deliberately omitted, the GNU/Linux socket(2) and
1370 packet(7) advise that it's obsolete and strongly deprecated. */
1371
1372 #ifdef SOCK_STREAM
1373 scm_c_define ("SOCK_STREAM", scm_from_int (SOCK_STREAM));
1374 #endif
1375 #ifdef SOCK_DGRAM
1376 scm_c_define ("SOCK_DGRAM", scm_from_int (SOCK_DGRAM));
1377 #endif
1378 #ifdef SOCK_SEQPACKET
1379 scm_c_define ("SOCK_SEQPACKET", scm_from_int (SOCK_SEQPACKET));
1380 #endif
1381 #ifdef SOCK_RAW
1382 scm_c_define ("SOCK_RAW", scm_from_int (SOCK_RAW));
1383 #endif
1384 #ifdef SOCK_RDM
1385 scm_c_define ("SOCK_RDM", scm_from_int (SOCK_RDM));
1386 #endif
1387
1388 /* setsockopt level. */
1389 #ifdef SOL_SOCKET
1390 scm_c_define ("SOL_SOCKET", scm_from_int (SOL_SOCKET));
1391 #endif
1392 #ifdef SOL_IP
1393 scm_c_define ("SOL_IP", scm_from_int (SOL_IP));
1394 #endif
1395 #ifdef SOL_TCP
1396 scm_c_define ("SOL_TCP", scm_from_int (SOL_TCP));
1397 #endif
1398 #ifdef SOL_UDP
1399 scm_c_define ("SOL_UDP", scm_from_int (SOL_UDP));
1400 #endif
1401
1402 /* setsockopt names. */
1403 #ifdef SO_DEBUG
1404 scm_c_define ("SO_DEBUG", scm_from_int (SO_DEBUG));
1405 #endif
1406 #ifdef SO_REUSEADDR
1407 scm_c_define ("SO_REUSEADDR", scm_from_int (SO_REUSEADDR));
1408 #endif
1409 #ifdef SO_STYLE
1410 scm_c_define ("SO_STYLE", scm_from_int (SO_STYLE));
1411 #endif
1412 #ifdef SO_TYPE
1413 scm_c_define ("SO_TYPE", scm_from_int (SO_TYPE));
1414 #endif
1415 #ifdef SO_ERROR
1416 scm_c_define ("SO_ERROR", scm_from_int (SO_ERROR));
1417 #endif
1418 #ifdef SO_DONTROUTE
1419 scm_c_define ("SO_DONTROUTE", scm_from_int (SO_DONTROUTE));
1420 #endif
1421 #ifdef SO_BROADCAST
1422 scm_c_define ("SO_BROADCAST", scm_from_int (SO_BROADCAST));
1423 #endif
1424 #ifdef SO_SNDBUF
1425 scm_c_define ("SO_SNDBUF", scm_from_int (SO_SNDBUF));
1426 #endif
1427 #ifdef SO_RCVBUF
1428 scm_c_define ("SO_RCVBUF", scm_from_int (SO_RCVBUF));
1429 #endif
1430 #ifdef SO_KEEPALIVE
1431 scm_c_define ("SO_KEEPALIVE", scm_from_int (SO_KEEPALIVE));
1432 #endif
1433 #ifdef SO_OOBINLINE
1434 scm_c_define ("SO_OOBINLINE", scm_from_int (SO_OOBINLINE));
1435 #endif
1436 #ifdef SO_NO_CHECK
1437 scm_c_define ("SO_NO_CHECK", scm_from_int (SO_NO_CHECK));
1438 #endif
1439 #ifdef SO_PRIORITY
1440 scm_c_define ("SO_PRIORITY", scm_from_int (SO_PRIORITY));
1441 #endif
1442 #ifdef SO_LINGER
1443 scm_c_define ("SO_LINGER", scm_from_int (SO_LINGER));
1444 #endif
1445
1446 /* recv/send options. */
1447 #ifdef MSG_OOB
1448 scm_c_define ("MSG_OOB", scm_from_int (MSG_OOB));
1449 #endif
1450 #ifdef MSG_PEEK
1451 scm_c_define ("MSG_PEEK", scm_from_int (MSG_PEEK));
1452 #endif
1453 #ifdef MSG_DONTROUTE
1454 scm_c_define ("MSG_DONTROUTE", scm_from_int (MSG_DONTROUTE));
1455 #endif
1456
1457 #ifdef __MINGW32__
1458 scm_i_init_socket_Win32 ();
1459 #endif
1460
1461 scm_add_feature ("socket");
1462
1463 #include "libguile/socket.x"
1464 }
1465
1466
1467 /*
1468 Local Variables:
1469 c-file-style: "gnu"
1470 End:
1471 */