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