(scm_fill_sockaddr): Use HAVE_STRUCT_SOCKADDR_SIN_LEN and
[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_from_locale_string (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_from_locale_string (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 #if HAVE_STRUCT_SOCKADDR_SIN_LEN
738 soka->sin_len = sizeof (struct sockaddr_in);
739 #endif
740 soka->sin_family = AF_INET;
741 soka->sin_addr.s_addr = htonl (addr);
742 soka->sin_port = htons (port);
743 *size = sizeof (struct sockaddr_in);
744 return (struct sockaddr *) soka;
745 }
746 #ifdef HAVE_IPV6
747 case AF_INET6:
748 {
749 /* see RFC2553. */
750 int port;
751 struct sockaddr_in6 *soka;
752 unsigned long flowinfo = 0;
753 unsigned long scope_id = 0;
754
755 SCM_VALIDATE_CONS (which_arg + 1, *args);
756 port = scm_to_int (SCM_CAR (*args));
757 *args = SCM_CDR (*args);
758 if (SCM_CONSP (*args))
759 {
760 SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
761 *args = SCM_CDR (*args);
762 if (SCM_CONSP (*args))
763 {
764 SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
765 scope_id);
766 *args = SCM_CDR (*args);
767 }
768 }
769 soka = (struct sockaddr_in6 *) scm_malloc (sizeof (struct sockaddr_in6));
770 if (!soka)
771 scm_memory_error (proc);
772 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
773 soka->sin6_len = sizeof (struct sockaddr_in6);
774 #endif
775 soka->sin6_family = AF_INET6;
776 scm_to_ipv6 (soka->sin6_addr.s6_addr, address);
777 soka->sin6_port = htons (port);
778 soka->sin6_flowinfo = flowinfo;
779 #ifdef HAVE_SIN6_SCOPE_ID
780 soka->sin6_scope_id = scope_id;
781 #endif
782 *size = sizeof (struct sockaddr_in6);
783 return (struct sockaddr *) soka;
784 }
785 #endif
786 #ifdef HAVE_UNIX_DOMAIN_SOCKETS
787 case AF_UNIX:
788 {
789 struct sockaddr_un *soka;
790 int addr_size;
791 char *c_address;
792
793 scm_frame_begin (0);
794
795 c_address = scm_to_locale_string (address);
796 scm_frame_free (c_address);
797
798 /* the static buffer size in sockaddr_un seems to be arbitrary
799 and not necessarily a hard limit. e.g., the glibc manual
800 suggests it may be possible to declare it size 0. let's
801 ignore it. if the O/S doesn't like the size it will cause
802 connect/bind etc., to fail. sun_path is always the last
803 member of the structure. */
804 addr_size = sizeof (struct sockaddr_un)
805 + max (0, strlen (c_address) + 1 - (sizeof soka->sun_path));
806 soka = (struct sockaddr_un *) scm_malloc (addr_size);
807 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
808 soka->sun_family = AF_UNIX;
809 strcpy (soka->sun_path, c_address);
810 *size = SUN_LEN (soka);
811
812 scm_frame_end ();
813 return (struct sockaddr *) soka;
814 }
815 #endif
816 default:
817 scm_out_of_range (proc, scm_from_int (fam));
818 }
819 }
820 #undef FUNC_NAME
821
822 SCM_DEFINE (scm_connect, "connect", 3, 0, 1,
823 (SCM sock, SCM fam, SCM address, SCM args),
824 "Initiate a connection from a socket using a specified address\n"
825 "family to the address\n"
826 "specified by @var{address} and possibly @var{args}.\n"
827 "The format required for @var{address}\n"
828 "and @var{args} depends on the family of the socket.\n\n"
829 "For a socket of family @code{AF_UNIX},\n"
830 "only @var{address} is specified and must be a string with the\n"
831 "filename where the socket is to be created.\n\n"
832 "For a socket of family @code{AF_INET},\n"
833 "@var{address} must be an integer IPv4 host address and\n"
834 "@var{args} must be a single integer port number.\n\n"
835 "For a socket of family @code{AF_INET6},\n"
836 "@var{address} must be an integer IPv6 host address and\n"
837 "@var{args} may be up to three integers:\n"
838 "port [flowinfo] [scope_id],\n"
839 "where flowinfo and scope_id default to zero.\n\n"
840 "The return value is unspecified.")
841 #define FUNC_NAME s_scm_connect
842 {
843 int fd;
844 struct sockaddr *soka;
845 int size;
846
847 sock = SCM_COERCE_OUTPORT (sock);
848 SCM_VALIDATE_OPFPORT (1, sock);
849 fd = SCM_FPORT_FDES (sock);
850 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args, 3, FUNC_NAME,
851 &size);
852 if (connect (fd, soka, size) == -1)
853 {
854 int save_errno = errno;
855
856 free (soka);
857 errno = save_errno;
858 SCM_SYSERROR;
859 }
860 free (soka);
861 return SCM_UNSPECIFIED;
862 }
863 #undef FUNC_NAME
864
865 SCM_DEFINE (scm_bind, "bind", 3, 0, 1,
866 (SCM sock, SCM fam, SCM address, SCM args),
867 "Assign an address to the socket port @var{sock}.\n"
868 "Generally this only needs to be done for server sockets,\n"
869 "so they know where to look for incoming connections. A socket\n"
870 "without an address will be assigned one automatically when it\n"
871 "starts communicating.\n\n"
872 "The format of @var{address} and @var{args} depends\n"
873 "on the family of the socket.\n\n"
874 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
875 "is specified and must be a string with the filename where\n"
876 "the socket is to be created.\n\n"
877 "For a socket of family @code{AF_INET}, @var{address}\n"
878 "must be an integer IPv4 address and @var{args}\n"
879 "must be a single integer port number.\n\n"
880 "The values of the following variables can also be used for\n"
881 "@var{address}:\n\n"
882 "@defvar INADDR_ANY\n"
883 "Allow connections from any address.\n"
884 "@end defvar\n\n"
885 "@defvar INADDR_LOOPBACK\n"
886 "The address of the local host using the loopback device.\n"
887 "@end defvar\n\n"
888 "@defvar INADDR_BROADCAST\n"
889 "The broadcast address on the local network.\n"
890 "@end defvar\n\n"
891 "@defvar INADDR_NONE\n"
892 "No address.\n"
893 "@end defvar\n\n"
894 "For a socket of family @code{AF_INET6}, @var{address}\n"
895 "must be an integer IPv6 address and @var{args}\n"
896 "may be up to three integers:\n"
897 "port [flowinfo] [scope_id],\n"
898 "where flowinfo and scope_id default to zero.\n\n"
899 "The return value is unspecified.")
900 #define FUNC_NAME s_scm_bind
901 {
902 struct sockaddr *soka;
903 int size;
904 int fd;
905
906 sock = SCM_COERCE_OUTPORT (sock);
907 SCM_VALIDATE_OPFPORT (1, sock);
908 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args, 3, FUNC_NAME,
909 &size);
910 fd = SCM_FPORT_FDES (sock);
911 if (bind (fd, soka, size) == -1)
912 {
913 int save_errno = errno;
914
915 free (soka);
916 errno = save_errno;
917 SCM_SYSERROR;
918 }
919 free (soka);
920 return SCM_UNSPECIFIED;
921 }
922 #undef FUNC_NAME
923
924 SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
925 (SCM sock, SCM backlog),
926 "Enable @var{sock} to accept connection\n"
927 "requests. @var{backlog} is an integer specifying\n"
928 "the maximum length of the queue for pending connections.\n"
929 "If the queue fills, new clients will fail to connect until\n"
930 "the server calls @code{accept} to accept a connection from\n"
931 "the queue.\n\n"
932 "The return value is unspecified.")
933 #define FUNC_NAME s_scm_listen
934 {
935 int fd;
936 sock = SCM_COERCE_OUTPORT (sock);
937 SCM_VALIDATE_OPFPORT (1, sock);
938 fd = SCM_FPORT_FDES (sock);
939 if (listen (fd, scm_to_int (backlog)) == -1)
940 SCM_SYSERROR;
941 return SCM_UNSPECIFIED;
942 }
943 #undef FUNC_NAME
944
945 /* Put the components of a sockaddr into a new SCM vector. */
946 static SCM
947 scm_addr_vector (const struct sockaddr *address, int addr_size,
948 const char *proc)
949 {
950 short int fam = address->sa_family;
951 SCM result =SCM_EOL;
952
953
954 switch (fam)
955 {
956 case AF_INET:
957 {
958 const struct sockaddr_in *nad = (struct sockaddr_in *) address;
959
960 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
961
962 SCM_VECTOR_SET(result, 0,
963 scm_from_short (fam));
964 SCM_VECTOR_SET(result, 1,
965 scm_from_ulong (ntohl (nad->sin_addr.s_addr)));
966 SCM_VECTOR_SET(result, 2,
967 scm_from_ushort (ntohs (nad->sin_port)));
968 }
969 break;
970 #ifdef HAVE_IPV6
971 case AF_INET6:
972 {
973 const struct sockaddr_in6 *nad = (struct sockaddr_in6 *) address;
974
975 result = scm_c_make_vector (5, SCM_UNSPECIFIED);
976 SCM_VECTOR_SET(result, 0, scm_from_short (fam));
977 SCM_VECTOR_SET(result, 1, scm_from_ipv6 (nad->sin6_addr.s6_addr));
978 SCM_VECTOR_SET(result, 2, scm_from_ushort (ntohs (nad->sin6_port)));
979 SCM_VECTOR_SET(result, 3, scm_from_uint32 (nad->sin6_flowinfo));
980 #ifdef HAVE_SIN6_SCOPE_ID
981 SCM_VECTOR_SET(result, 4, scm_from_ulong (nad->sin6_scope_id));
982 #else
983 SCM_VECTOR_SET(result, 4, SCM_INUM0);
984 #endif
985 }
986 break;
987 #endif
988 #ifdef HAVE_UNIX_DOMAIN_SOCKETS
989 case AF_UNIX:
990 {
991 const struct sockaddr_un *nad = (struct sockaddr_un *) address;
992
993 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
994
995 SCM_VECTOR_SET(result, 0, scm_from_short (fam));
996 /* When addr_size is not enough to cover sun_path, do not try
997 to access it. */
998 if (addr_size <= offsetof (struct sockaddr_un, sun_path))
999 SCM_VECTOR_SET(result, 1, SCM_BOOL_F);
1000 else
1001 SCM_VECTOR_SET(result, 1, scm_from_locale_string (nad->sun_path));
1002 }
1003 break;
1004 #endif
1005 default:
1006 scm_misc_error (proc, "Unrecognised address family: ~A",
1007 scm_list_1 (scm_from_int (fam)));
1008 }
1009 return result;
1010 }
1011
1012 /* calculate the size of a buffer large enough to hold any supported
1013 sockaddr type. if the buffer isn't large enough, certain system
1014 calls will return a truncated address. */
1015
1016 #if defined (HAVE_UNIX_DOMAIN_SOCKETS)
1017 #define MAX_SIZE_UN sizeof (struct sockaddr_un)
1018 #else
1019 #define MAX_SIZE_UN 0
1020 #endif
1021
1022 #if defined (HAVE_IPV6)
1023 #define MAX_SIZE_IN6 sizeof (struct sockaddr_in6)
1024 #else
1025 #define MAX_SIZE_IN6 0
1026 #endif
1027
1028 #define MAX_ADDR_SIZE max (max (sizeof (struct sockaddr_in), MAX_SIZE_IN6),\
1029 MAX_SIZE_UN)
1030
1031 SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1032 (SCM sock),
1033 "Accept a connection on a bound, listening socket.\n"
1034 "If there\n"
1035 "are no pending connections in the queue, wait until\n"
1036 "one is available unless the non-blocking option has been\n"
1037 "set on the socket.\n\n"
1038 "The return value is a\n"
1039 "pair in which the @emph{car} is a new socket port for the\n"
1040 "connection and\n"
1041 "the @emph{cdr} is an object with address information about the\n"
1042 "client which initiated the connection.\n\n"
1043 "@var{sock} does not become part of the\n"
1044 "connection and will continue to accept new requests.")
1045 #define FUNC_NAME s_scm_accept
1046 {
1047 int fd;
1048 int newfd;
1049 SCM address;
1050 SCM newsock;
1051 int addr_size = MAX_ADDR_SIZE;
1052 char max_addr[MAX_ADDR_SIZE];
1053 struct sockaddr *addr = (struct sockaddr *) max_addr;
1054
1055 sock = SCM_COERCE_OUTPORT (sock);
1056 SCM_VALIDATE_OPFPORT (1, sock);
1057 fd = SCM_FPORT_FDES (sock);
1058 newfd = accept (fd, addr, &addr_size);
1059 if (newfd == -1)
1060 SCM_SYSERROR;
1061 newsock = SCM_SOCK_FD_TO_PORT (newfd);
1062 address = scm_addr_vector (addr, addr_size, FUNC_NAME);
1063 return scm_cons (newsock, address);
1064 }
1065 #undef FUNC_NAME
1066
1067 SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1068 (SCM sock),
1069 "Return the address of @var{sock}, in the same form as the\n"
1070 "object returned by @code{accept}. On many systems the address\n"
1071 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1072 #define FUNC_NAME s_scm_getsockname
1073 {
1074 int fd;
1075 int addr_size = MAX_ADDR_SIZE;
1076 char max_addr[MAX_ADDR_SIZE];
1077 struct sockaddr *addr = (struct sockaddr *) max_addr;
1078
1079 sock = SCM_COERCE_OUTPORT (sock);
1080 SCM_VALIDATE_OPFPORT (1, sock);
1081 fd = SCM_FPORT_FDES (sock);
1082 if (getsockname (fd, addr, &addr_size) == -1)
1083 SCM_SYSERROR;
1084 return scm_addr_vector (addr, addr_size, FUNC_NAME);
1085 }
1086 #undef FUNC_NAME
1087
1088 SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1089 (SCM sock),
1090 "Return the address that @var{sock}\n"
1091 "is connected to, in the same form as the object returned by\n"
1092 "@code{accept}. On many systems the address of a socket in the\n"
1093 "@code{AF_FILE} namespace cannot be read.")
1094 #define FUNC_NAME s_scm_getpeername
1095 {
1096 int fd;
1097 int addr_size = MAX_ADDR_SIZE;
1098 char max_addr[MAX_ADDR_SIZE];
1099 struct sockaddr *addr = (struct sockaddr *) max_addr;
1100
1101 sock = SCM_COERCE_OUTPORT (sock);
1102 SCM_VALIDATE_OPFPORT (1, sock);
1103 fd = SCM_FPORT_FDES (sock);
1104 if (getpeername (fd, addr, &addr_size) == -1)
1105 SCM_SYSERROR;
1106 return scm_addr_vector (addr, addr_size, FUNC_NAME);
1107 }
1108 #undef FUNC_NAME
1109
1110 SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1111 (SCM sock, SCM buf, SCM flags),
1112 "Receive data from a socket port.\n"
1113 "@var{sock} must already\n"
1114 "be bound to the address from which data is to be received.\n"
1115 "@var{buf} is a string into which\n"
1116 "the data will be written. The size of @var{buf} limits\n"
1117 "the amount of\n"
1118 "data which can be received: in the case of packet\n"
1119 "protocols, if a packet larger than this limit is encountered\n"
1120 "then some data\n"
1121 "will be irrevocably lost.\n\n"
1122 "The optional @var{flags} argument is a value or\n"
1123 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
1124 "The value returned is the number of bytes read from the\n"
1125 "socket.\n\n"
1126 "Note that the data is read directly from the socket file\n"
1127 "descriptor:\n"
1128 "any unread buffered port data is ignored.")
1129 #define FUNC_NAME s_scm_recv
1130 {
1131 int rv;
1132 int fd;
1133 int flg;
1134 char *dest;
1135 size_t len;
1136
1137 SCM_VALIDATE_OPFPORT (1, sock);
1138 SCM_VALIDATE_STRING (2, buf);
1139 if (SCM_UNBNDP (flags))
1140 flg = 0;
1141 else
1142 flg = scm_to_int (flags);
1143 fd = SCM_FPORT_FDES (sock);
1144
1145 len = scm_i_string_length (buf);
1146 dest = scm_i_string_writable_chars (buf);
1147 SCM_SYSCALL (rv = recv (fd, dest, len, flg));
1148 scm_i_string_stop_writing ();
1149
1150 if (rv == -1)
1151 SCM_SYSERROR;
1152
1153 scm_remember_upto_here_1 (buf);
1154 return scm_from_int (rv);
1155 }
1156 #undef FUNC_NAME
1157
1158 SCM_DEFINE (scm_send, "send", 2, 1, 0,
1159 (SCM sock, SCM message, SCM flags),
1160 "Transmit the string @var{message} on a socket port @var{sock}.\n"
1161 "@var{sock} must already be bound to a destination address. The\n"
1162 "value returned is the number of bytes transmitted --\n"
1163 "it's possible for\n"
1164 "this to be less than the length of @var{message}\n"
1165 "if the socket is\n"
1166 "set to be non-blocking. The optional @var{flags} argument\n"
1167 "is a value or\n"
1168 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
1169 "Note that the data is written directly to the socket\n"
1170 "file descriptor:\n"
1171 "any unflushed buffered port data is ignored.")
1172 #define FUNC_NAME s_scm_send
1173 {
1174 int rv;
1175 int fd;
1176 int flg;
1177 const char *src;
1178 size_t len;
1179
1180 sock = SCM_COERCE_OUTPORT (sock);
1181 SCM_VALIDATE_OPFPORT (1, sock);
1182 SCM_VALIDATE_STRING (2, message);
1183 if (SCM_UNBNDP (flags))
1184 flg = 0;
1185 else
1186 flg = scm_to_int (flags);
1187 fd = SCM_FPORT_FDES (sock);
1188
1189 len = scm_i_string_length (message);
1190 src = scm_i_string_writable_chars (message);
1191 SCM_SYSCALL (rv = send (fd, src, len, flg));
1192 scm_i_string_stop_writing ();
1193
1194 if (rv == -1)
1195 SCM_SYSERROR;
1196
1197 scm_remember_upto_here_1 (message);
1198 return scm_from_int (rv);
1199 }
1200 #undef FUNC_NAME
1201
1202 SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
1203 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
1204 "Return data from the socket port @var{sock} and also\n"
1205 "information about where the data was received from.\n"
1206 "@var{sock} must already be bound to the address from which\n"
1207 "data is to be received. @code{str}, is a string into which the\n"
1208 "data will be written. The size of @var{str} limits the amount\n"
1209 "of data which can be received: in the case of packet protocols,\n"
1210 "if a packet larger than this limit is encountered then some\n"
1211 "data will be irrevocably lost.\n\n"
1212 "The optional @var{flags} argument is a value or bitwise OR of\n"
1213 "@code{MSG_OOB}, @code{MSG_PEEK}, @code{MSG_DONTROUTE} etc.\n\n"
1214 "The value returned is a pair: the @emph{car} is the number of\n"
1215 "bytes read from the socket and the @emph{cdr} an address object\n"
1216 "in the same form as returned by @code{accept}. The address\n"
1217 "will given as @code{#f} if not available, as is usually the\n"
1218 "case for stream sockets.\n\n"
1219 "The @var{start} and @var{end} arguments specify a substring of\n"
1220 "@var{str} to which the data should be written.\n\n"
1221 "Note that the data is read directly from the socket file\n"
1222 "descriptor: any unread buffered port data is ignored.")
1223 #define FUNC_NAME s_scm_recvfrom
1224 {
1225 int rv;
1226 int fd;
1227 int flg;
1228 char *buf;
1229 size_t offset;
1230 size_t cend;
1231 SCM address;
1232 int addr_size = MAX_ADDR_SIZE;
1233 char max_addr[MAX_ADDR_SIZE];
1234 struct sockaddr *addr = (struct sockaddr *) max_addr;
1235
1236 SCM_VALIDATE_OPFPORT (1, sock);
1237 fd = SCM_FPORT_FDES (sock);
1238
1239 SCM_VALIDATE_STRING (2, str);
1240 scm_i_get_substring_spec (scm_i_string_length (str),
1241 start, &offset, end, &cend);
1242
1243 if (SCM_UNBNDP (flags))
1244 flg = 0;
1245 else
1246 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
1247
1248 /* recvfrom will not necessarily return an address. usually nothing
1249 is returned for stream sockets. */
1250 buf = scm_i_string_writable_chars (str);
1251 addr->sa_family = AF_UNSPEC;
1252 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
1253 cend - offset, flg,
1254 addr, &addr_size));
1255 scm_i_string_stop_writing ();
1256
1257 if (rv == -1)
1258 SCM_SYSERROR;
1259 if (addr->sa_family != AF_UNSPEC)
1260 address = scm_addr_vector (addr, addr_size, FUNC_NAME);
1261 else
1262 address = SCM_BOOL_F;
1263
1264 scm_remember_upto_here_1 (str);
1265 return scm_cons (scm_from_int (rv), address);
1266 }
1267 #undef FUNC_NAME
1268
1269 SCM_DEFINE (scm_sendto, "sendto", 4, 0, 1,
1270 (SCM sock, SCM message, SCM fam, SCM address, SCM args_and_flags),
1271 "Transmit the string @var{message} on the socket port\n"
1272 "@var{sock}. The\n"
1273 "destination address is specified using the @var{fam},\n"
1274 "@var{address} and\n"
1275 "@var{args_and_flags} arguments, in a similar way to the\n"
1276 "@code{connect} procedure. @var{args_and_flags} contains\n"
1277 "the usual connection arguments optionally followed by\n"
1278 "a flags argument, which is a value or\n"
1279 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
1280 "The value returned is the number of bytes transmitted --\n"
1281 "it's possible for\n"
1282 "this to be less than the length of @var{message} if the\n"
1283 "socket is\n"
1284 "set to be non-blocking.\n"
1285 "Note that the data is written directly to the socket\n"
1286 "file descriptor:\n"
1287 "any unflushed buffered port data is ignored.")
1288 #define FUNC_NAME s_scm_sendto
1289 {
1290 int rv;
1291 int fd;
1292 int flg;
1293 struct sockaddr *soka;
1294 int size;
1295
1296 sock = SCM_COERCE_OUTPORT (sock);
1297 SCM_VALIDATE_FPORT (1, sock);
1298 SCM_VALIDATE_STRING (2, message);
1299 fd = SCM_FPORT_FDES (sock);
1300 soka = scm_fill_sockaddr (scm_to_int (fam), address, &args_and_flags, 4,
1301 FUNC_NAME, &size);
1302 if (SCM_NULLP (args_and_flags))
1303 flg = 0;
1304 else
1305 {
1306 SCM_VALIDATE_CONS (5, args_and_flags);
1307 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
1308 }
1309 SCM_SYSCALL (rv = sendto (fd,
1310 scm_i_string_chars (message),
1311 scm_i_string_length (message),
1312 flg, soka, size));
1313 if (rv == -1)
1314 {
1315 int save_errno = errno;
1316 free (soka);
1317 errno = save_errno;
1318 SCM_SYSERROR;
1319 }
1320 free (soka);
1321
1322 scm_remember_upto_here_1 (message);
1323 return scm_from_int (rv);
1324 }
1325 #undef FUNC_NAME
1326 \f
1327
1328
1329 void
1330 scm_init_socket ()
1331 {
1332 /* protocol families. */
1333 #ifdef AF_UNSPEC
1334 scm_c_define ("AF_UNSPEC", scm_from_int (AF_UNSPEC));
1335 #endif
1336 #ifdef AF_UNIX
1337 scm_c_define ("AF_UNIX", scm_from_int (AF_UNIX));
1338 #endif
1339 #ifdef AF_INET
1340 scm_c_define ("AF_INET", scm_from_int (AF_INET));
1341 #endif
1342 #ifdef AF_INET6
1343 scm_c_define ("AF_INET6", scm_from_int (AF_INET6));
1344 #endif
1345
1346 #ifdef PF_UNSPEC
1347 scm_c_define ("PF_UNSPEC", scm_from_int (PF_UNSPEC));
1348 #endif
1349 #ifdef PF_UNIX
1350 scm_c_define ("PF_UNIX", scm_from_int (PF_UNIX));
1351 #endif
1352 #ifdef PF_INET
1353 scm_c_define ("PF_INET", scm_from_int (PF_INET));
1354 #endif
1355 #ifdef PF_INET6
1356 scm_c_define ("PF_INET6", scm_from_int (PF_INET6));
1357 #endif
1358
1359 /* standard addresses. */
1360 #ifdef INADDR_ANY
1361 scm_c_define ("INADDR_ANY", scm_from_ulong (INADDR_ANY));
1362 #endif
1363 #ifdef INADDR_BROADCAST
1364 scm_c_define ("INADDR_BROADCAST", scm_from_ulong (INADDR_BROADCAST));
1365 #endif
1366 #ifdef INADDR_NONE
1367 scm_c_define ("INADDR_NONE", scm_from_ulong (INADDR_NONE));
1368 #endif
1369 #ifdef INADDR_LOOPBACK
1370 scm_c_define ("INADDR_LOOPBACK", scm_from_ulong (INADDR_LOOPBACK));
1371 #endif
1372
1373 /* socket types.
1374
1375 SOCK_PACKET is deliberately omitted, the GNU/Linux socket(2) and
1376 packet(7) advise that it's obsolete and strongly deprecated. */
1377
1378 #ifdef SOCK_STREAM
1379 scm_c_define ("SOCK_STREAM", scm_from_int (SOCK_STREAM));
1380 #endif
1381 #ifdef SOCK_DGRAM
1382 scm_c_define ("SOCK_DGRAM", scm_from_int (SOCK_DGRAM));
1383 #endif
1384 #ifdef SOCK_SEQPACKET
1385 scm_c_define ("SOCK_SEQPACKET", scm_from_int (SOCK_SEQPACKET));
1386 #endif
1387 #ifdef SOCK_RAW
1388 scm_c_define ("SOCK_RAW", scm_from_int (SOCK_RAW));
1389 #endif
1390 #ifdef SOCK_RDM
1391 scm_c_define ("SOCK_RDM", scm_from_int (SOCK_RDM));
1392 #endif
1393
1394 /* setsockopt level. */
1395 #ifdef SOL_SOCKET
1396 scm_c_define ("SOL_SOCKET", scm_from_int (SOL_SOCKET));
1397 #endif
1398 #ifdef SOL_IP
1399 scm_c_define ("SOL_IP", scm_from_int (SOL_IP));
1400 #endif
1401 #ifdef SOL_TCP
1402 scm_c_define ("SOL_TCP", scm_from_int (SOL_TCP));
1403 #endif
1404 #ifdef SOL_UDP
1405 scm_c_define ("SOL_UDP", scm_from_int (SOL_UDP));
1406 #endif
1407
1408 /* setsockopt names. */
1409 #ifdef SO_DEBUG
1410 scm_c_define ("SO_DEBUG", scm_from_int (SO_DEBUG));
1411 #endif
1412 #ifdef SO_REUSEADDR
1413 scm_c_define ("SO_REUSEADDR", scm_from_int (SO_REUSEADDR));
1414 #endif
1415 #ifdef SO_STYLE
1416 scm_c_define ("SO_STYLE", scm_from_int (SO_STYLE));
1417 #endif
1418 #ifdef SO_TYPE
1419 scm_c_define ("SO_TYPE", scm_from_int (SO_TYPE));
1420 #endif
1421 #ifdef SO_ERROR
1422 scm_c_define ("SO_ERROR", scm_from_int (SO_ERROR));
1423 #endif
1424 #ifdef SO_DONTROUTE
1425 scm_c_define ("SO_DONTROUTE", scm_from_int (SO_DONTROUTE));
1426 #endif
1427 #ifdef SO_BROADCAST
1428 scm_c_define ("SO_BROADCAST", scm_from_int (SO_BROADCAST));
1429 #endif
1430 #ifdef SO_SNDBUF
1431 scm_c_define ("SO_SNDBUF", scm_from_int (SO_SNDBUF));
1432 #endif
1433 #ifdef SO_RCVBUF
1434 scm_c_define ("SO_RCVBUF", scm_from_int (SO_RCVBUF));
1435 #endif
1436 #ifdef SO_KEEPALIVE
1437 scm_c_define ("SO_KEEPALIVE", scm_from_int (SO_KEEPALIVE));
1438 #endif
1439 #ifdef SO_OOBINLINE
1440 scm_c_define ("SO_OOBINLINE", scm_from_int (SO_OOBINLINE));
1441 #endif
1442 #ifdef SO_NO_CHECK
1443 scm_c_define ("SO_NO_CHECK", scm_from_int (SO_NO_CHECK));
1444 #endif
1445 #ifdef SO_PRIORITY
1446 scm_c_define ("SO_PRIORITY", scm_from_int (SO_PRIORITY));
1447 #endif
1448 #ifdef SO_LINGER
1449 scm_c_define ("SO_LINGER", scm_from_int (SO_LINGER));
1450 #endif
1451
1452 /* recv/send options. */
1453 #ifdef MSG_OOB
1454 scm_c_define ("MSG_OOB", scm_from_int (MSG_OOB));
1455 #endif
1456 #ifdef MSG_PEEK
1457 scm_c_define ("MSG_PEEK", scm_from_int (MSG_PEEK));
1458 #endif
1459 #ifdef MSG_DONTROUTE
1460 scm_c_define ("MSG_DONTROUTE", scm_from_int (MSG_DONTROUTE));
1461 #endif
1462
1463 #ifdef __MINGW32__
1464 scm_i_init_socket_Win32 ();
1465 #endif
1466
1467 scm_add_feature ("socket");
1468
1469 #include "libguile/socket.x"
1470 }
1471
1472
1473 /*
1474 Local Variables:
1475 c-file-style: "gnu"
1476 End:
1477 */