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