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