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