* validate.h (SCM_VALIDATE_OPOUTSTRPORT): New macro.
[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 #include <sys/socket.h>
67 #ifdef HAVE_UNIX_DOMAIN_SOCKETS
68 #include <sys/un.h>
69 #endif
70 #include <netinet/in.h>
71 #include <netdb.h>
72 #include <arpa/inet.h>
73
74 #if defined (HAVE_UNIX_DOMAIN_SOCKETS) && !defined (SUN_LEN)
75 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
76 + strlen ((ptr)->sun_path))
77 #endif
78
79 /* we are not currently using socklen_t. it's not defined on all systems,
80 so would need to be checked by configure. in the meantime, plain
81 int is the best alternative. */
82
83 \f
84
85 SCM_DEFINE (scm_htons, "htons", 1, 0, 0,
86 (SCM in),
87 "Returns a new integer from @var{value} by converting from host to\n"
88 "network order. @var{value} must be within the range of a C unsigned\n"
89 "short integer.")
90 #define FUNC_NAME s_scm_htons
91 {
92 unsigned short c_in;
93
94 SCM_VALIDATE_INUM_COPY (1,in,c_in);
95 if (c_in != SCM_INUM (in))
96 SCM_OUT_OF_RANGE (1,in);
97
98 return SCM_MAKINUM (htons (c_in));
99 }
100 #undef FUNC_NAME
101
102 SCM_DEFINE (scm_ntohs, "ntohs", 1, 0, 0,
103 (SCM in),
104 "Returns a new integer from @var{value} by converting from network to\n"
105 "host order. @var{value} must be within the range of a C unsigned short\n"
106 "integer.")
107 #define FUNC_NAME s_scm_ntohs
108 {
109 unsigned short c_in;
110
111 SCM_VALIDATE_INUM_COPY (1,in,c_in);
112 if (c_in != SCM_INUM (in))
113 SCM_OUT_OF_RANGE (1,in);
114
115 return SCM_MAKINUM (ntohs (c_in));
116 }
117 #undef FUNC_NAME
118
119 SCM_DEFINE (scm_htonl, "htonl", 1, 0, 0,
120 (SCM in),
121 "Returns a new integer from @var{value} by converting from host to\n"
122 "network order. @var{value} must be within the range of a C unsigned\n"
123 "long integer.")
124 #define FUNC_NAME s_scm_htonl
125 {
126 unsigned long c_in = SCM_NUM2ULONG (1,in);
127 return scm_ulong2num (htonl (c_in));
128 }
129 #undef FUNC_NAME
130
131 SCM_DEFINE (scm_ntohl, "ntohl", 1, 0, 0,
132 (SCM in),
133 "Returns a new integer from @var{value} by converting from network to\n"
134 "host order. @var{value} must be within the range of a C unsigned\n"
135 "long integer.")
136 #define FUNC_NAME s_scm_ntohl
137 {
138 unsigned long c_in = SCM_NUM2ULONG (1,in);
139 return scm_ulong2num (ntohl (c_in));
140 }
141 #undef FUNC_NAME
142
143 SCM_SYMBOL (sym_socket, "socket");
144
145 #define SCM_SOCK_FD_TO_PORT(fd) scm_fdes_to_port (fd, "r+0", sym_socket)
146
147 SCM_DEFINE (scm_socket, "socket", 3, 0, 0,
148 (SCM family, SCM style, SCM proto),
149 "Returns a new socket port of the type specified by @var{family}, @var{style}\n"
150 "and @var{protocol}. All three parameters are integers. Typical values\n"
151 "for @var{family} are the values of @code{AF_UNIX}\n"
152 "and @code{AF_INET}. Typical values for @var{style} are\n"
153 "the values of @code{SOCK_STREAM}, @code{SOCK_DGRAM} and @code{SOCK_RAW}.\n\n"
154 "@var{protocol} can be obtained from a protocol name using\n"
155 "@code{getprotobyname}. A value of\n"
156 "zero specifies the default protocol, which is usually right.\n\n"
157 "A single socket port cannot by used for communication until\n"
158 "it has been connected to another socket.")
159 #define FUNC_NAME s_scm_socket
160 {
161 int fd;
162
163 SCM_VALIDATE_INUM (1, family);
164 SCM_VALIDATE_INUM (2, style);
165 SCM_VALIDATE_INUM (3, proto);
166 fd = socket (SCM_INUM (family), SCM_INUM (style), SCM_INUM (proto));
167 if (fd == -1)
168 SCM_SYSERROR;
169 return SCM_SOCK_FD_TO_PORT (fd);
170 }
171 #undef FUNC_NAME
172
173 #ifdef HAVE_SOCKETPAIR
174 SCM_DEFINE (scm_socketpair, "socketpair", 3, 0, 0,
175 (SCM family, SCM style, SCM proto),
176 "Returns a pair of connected (but unnamed) socket ports of the type specified\n"
177 "by @var{family}, @var{style} and @var{protocol}.\n"
178 "Many systems support only\n"
179 "socket pairs of the @code{AF_UNIX} family. Zero is likely to be\n"
180 "the only meaningful value for @var{protocol}.")
181 #define FUNC_NAME s_scm_socketpair
182 {
183 int fam;
184 int fd[2];
185
186 SCM_VALIDATE_INUM (1,family);
187 SCM_VALIDATE_INUM (2,style);
188 SCM_VALIDATE_INUM (3,proto);
189
190 fam = SCM_INUM (family);
191
192 if (socketpair (fam, SCM_INUM (style), SCM_INUM (proto), fd) == -1)
193 SCM_SYSERROR;
194
195 return scm_cons (SCM_SOCK_FD_TO_PORT (fd[0]), SCM_SOCK_FD_TO_PORT (fd[1]));
196 }
197 #undef FUNC_NAME
198 #endif
199
200 SCM_DEFINE (scm_getsockopt, "getsockopt", 3, 0, 0,
201 (SCM sock, SCM level, SCM optname),
202 "Returns the value of a particular socket option for the socket\n"
203 "port @var{socket}. @var{level} is an integer code for type of option\n"
204 "being requested, e.g., @code{SOL_SOCKET} for socket-level options.\n"
205 "@var{optname} is an\n"
206 "integer code for the option required and should be specified using one of\n"
207 "the symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc.\n\n"
208 "The returned value is typically an integer but @code{SO_LINGER} returns a\n"
209 "pair of integers.")
210 #define FUNC_NAME s_scm_getsockopt
211 {
212 int fd;
213 /* size of optval is the largest supported option. */
214 #ifdef HAVE_STRUCT_LINGER
215 char optval[sizeof (struct linger)];
216 int optlen = sizeof (struct linger);
217 #else
218 char optval[sizeof (scm_sizet)];
219 int optlen = sizeof (scm_sizet);
220 #endif
221 int ilevel;
222 int ioptname;
223
224 sock = SCM_COERCE_OUTPORT (sock);
225 SCM_VALIDATE_OPFPORT (1, sock);
226 SCM_VALIDATE_INUM_COPY (2, level, ilevel);
227 SCM_VALIDATE_INUM_COPY (3, optname, ioptname);
228
229 fd = SCM_FPORT_FDES (sock);
230 if (getsockopt (fd, ilevel, ioptname, (void *) optval, &optlen) == -1)
231 SCM_SYSERROR;
232
233 if (ilevel == SOL_SOCKET)
234 {
235 #ifdef SO_LINGER
236 if (ioptname == SO_LINGER)
237 {
238 #ifdef HAVE_STRUCT_LINGER
239 struct linger *ling = (struct linger *) optval;
240
241 return scm_cons (scm_long2num (ling->l_onoff),
242 scm_long2num (ling->l_linger));
243 #else
244 return scm_cons (scm_long2num (*(int *) optval)
245 SCM_MAKINUM (0));
246 #endif
247 }
248 else
249 #endif
250 if (0
251 #ifdef SO_SNDBUF
252 || ioptname == SO_SNDBUF
253 #endif
254 #ifdef SO_RCVBUF
255 || ioptname == SO_RCVBUF
256 #endif
257 )
258 {
259 return scm_long2num (*(scm_sizet *) optval);
260 }
261 }
262 return scm_long2num (*(int *) optval);
263 }
264 #undef FUNC_NAME
265
266 SCM_DEFINE (scm_setsockopt, "setsockopt", 4, 0, 0,
267 (SCM sock, SCM level, SCM optname, SCM value),
268 "Sets the value of a particular socket option for the socket\n"
269 "port @var{socket}. @var{level} is an integer code for type of option\n"
270 "being set, e.g., @code{SOL_SOCKET} for socket-level options.\n"
271 "@var{optname} is an\n"
272 "integer code for the option to set and should be specified using one of\n"
273 "the symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc.\n"
274 "@var{value} is the value to which the option should be set. For\n"
275 "most options this must be an integer, but for @code{SO_LINGER} it must\n"
276 "be a pair.\n\n"
277 "The return value is unspecified.")
278 #define FUNC_NAME s_scm_setsockopt
279 {
280 int fd;
281 int optlen = -1;
282 /* size of optval is the largest supported option. */
283 #ifdef HAVE_STRUCT_LINGER
284 char optval[sizeof (struct linger)];
285 #else
286 char optval[sizeof (scm_sizet)];
287 #endif
288 int ilevel, ioptname;
289
290 sock = SCM_COERCE_OUTPORT (sock);
291
292 SCM_VALIDATE_OPFPORT (1, sock);
293 SCM_VALIDATE_INUM_COPY (2, level, ilevel);
294 SCM_VALIDATE_INUM_COPY (3, optname, ioptname);
295
296 fd = SCM_FPORT_FDES (sock);
297
298 if (ilevel == SOL_SOCKET)
299 {
300 #ifdef SO_LINGER
301 if (ioptname == SO_LINGER)
302 {
303 #ifdef HAVE_STRUCT_LINGER
304 struct linger ling;
305 long lv;
306
307 SCM_ASSERT (SCM_CONSP (value), value, SCM_ARG4, FUNC_NAME);
308 lv = SCM_NUM2LONG (4, SCM_CAR (value));
309 ling.l_onoff = (int) lv;
310 SCM_ASSERT_RANGE (SCM_ARG4, value, ling.l_onoff == lv);
311 lv = SCM_NUM2LONG (4, SCM_CDR (value));
312 ling.l_linger = (int) lv;
313 SCM_ASSERT_RANGE (SCM_ARG4, value, ling.l_linger == lv);
314 optlen = (int) sizeof (struct linger);
315 memcpy (optval, (void *) &ling, optlen);
316 #else
317 int ling;
318 long lv;
319
320 SCM_ASSERT (SCM_CONSP (value), value, SCM_ARG4, FUNC_NAME);
321 /* timeout is ignored, but may as well validate it. */
322 lv = SCM_NUM2LONG (4, SCM_CDR (value));
323 ling = (int) lv;
324 SCM_ASSERT_RANGE (SCM_ARG4, value, ling == lv);
325 lv = SCM_NUM2LONG (4, SCM_CAR (value));
326 ling = (int) lv;
327 SCM_ASSERT_RANGE (SCM_ARG4, value, ling == lv);
328 optlen = (int) sizeof (int);
329 (*(int *) optval) = ling;
330 #endif
331 }
332 else
333 #endif
334 if (0
335 #ifdef SO_SNDBUF
336 || ioptname == SO_SNDBUF
337 #endif
338 #ifdef SO_RCVBUF
339 || ioptname == SO_RCVBUF
340 #endif
341 )
342 {
343 long lv = SCM_NUM2LONG (4, value);
344
345 optlen = (int) sizeof (scm_sizet);
346 (*(scm_sizet *) optval) = (scm_sizet) lv;
347 }
348 }
349 if (optlen == -1)
350 {
351 /* Most options take an int. */
352 long lv = SCM_NUM2LONG (4, value);
353 int val = (int) lv;
354
355 SCM_ASSERT_RANGE (SCM_ARG4, value, val == lv);
356 optlen = (int) sizeof (int);
357 (*(int *) optval) = val;
358 }
359 if (setsockopt (fd, ilevel, ioptname, (void *) optval, optlen) == -1)
360 SCM_SYSERROR;
361 return SCM_UNSPECIFIED;
362 }
363 #undef FUNC_NAME
364
365 SCM_DEFINE (scm_shutdown, "shutdown", 2, 0, 0,
366 (SCM sock, SCM how),
367 "Sockets can be closed simply by using @code{close-port}. The\n"
368 "@code{shutdown} procedure allows reception or tranmission on a\n"
369 "connection to be shut down individually, according to the parameter\n"
370 "@var{how}:\n\n"
371 "@table @asis\n"
372 "@item 0\n"
373 "Stop receiving data for this socket. If further data arrives, reject it.\n"
374 "@item 1\n"
375 "Stop trying to transmit data from this socket. Discard any\n"
376 "data waiting to be sent. Stop looking for acknowledgement of\n"
377 "data already sent; don't retransmit it if it is lost.\n"
378 "@item 2\n"
379 "Stop both reception and transmission.\n"
380 "@end table\n\n"
381 "The return value is unspecified.")
382 #define FUNC_NAME s_scm_shutdown
383 {
384 int fd;
385 sock = SCM_COERCE_OUTPORT (sock);
386 SCM_VALIDATE_OPFPORT (1,sock);
387 SCM_VALIDATE_INUM (2,how);
388 SCM_ASSERT_RANGE(2,how,0 <= SCM_INUM (how) && 2 >= SCM_INUM (how));
389 fd = SCM_FPORT_FDES (sock);
390 if (shutdown (fd, SCM_INUM (how)) == -1)
391 SCM_SYSERROR;
392 return SCM_UNSPECIFIED;
393 }
394 #undef FUNC_NAME
395
396 /* convert fam/address/args into a sockaddr of the appropriate type.
397 args is modified by removing the arguments actually used.
398 which_arg and proc are used when reporting errors:
399 which_arg is the position of address in the original argument list.
400 proc is the name of the original procedure.
401 size returns the size of the structure allocated. */
402
403 static struct sockaddr *
404 scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
405 const char *proc, int *size)
406 {
407 switch (fam)
408 {
409 case AF_INET:
410 {
411 SCM isport;
412 struct sockaddr_in *soka;
413
414 SCM_ASSERT (SCM_CONSP (*args), *args,
415 which_arg + 1, proc);
416 isport = SCM_CAR (*args);
417 SCM_ASSERT (SCM_INUMP (isport), isport, which_arg + 1, proc);
418 soka = (struct sockaddr_in *) malloc (sizeof (struct sockaddr_in));
419 if (!soka)
420 scm_memory_error (proc);
421 /* e.g., for BSDs which don't like invalid sin_len. */
422 memset (soka, 0, sizeof (struct sockaddr_in));
423 soka->sin_family = AF_INET;
424 soka->sin_addr.s_addr =
425 htonl (scm_num2ulong (address, (char *) which_arg, proc));
426 *args = SCM_CDR (*args);
427 soka->sin_port = htons (SCM_INUM (isport));
428 *size = sizeof (struct sockaddr_in);
429 return (struct sockaddr *) soka;
430 }
431 #ifdef HAVE_UNIX_DOMAIN_SOCKETS
432 case AF_UNIX:
433 {
434 struct sockaddr_un *soka;
435 int addr_size;
436
437 SCM_ASSERT (SCM_STRINGP (address), address, which_arg, proc);
438 /* the static buffer size in sockaddr_un seems to be arbitrary
439 and not necessarily a hard limit. e.g., the glibc manual
440 suggests it may be possible to declare it size 0. let's
441 ignore it. if the O/S doesn't like the size it will cause
442 connect/bind etc., to fail. sun_path is always the last
443 member of the structure. */
444 addr_size = sizeof (struct sockaddr_un)
445 + max (0, SCM_STRING_LENGTH (address) + 1 - (sizeof soka->sun_path));
446 soka = (struct sockaddr_un *) malloc (addr_size);
447 if (!soka)
448 scm_memory_error (proc);
449 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
450 soka->sun_family = AF_UNIX;
451 memcpy (soka->sun_path, SCM_STRING_CHARS (address),
452 SCM_STRING_LENGTH (address));
453 *size = SUN_LEN (soka);
454 return (struct sockaddr *) soka;
455 }
456 #endif
457 default:
458 scm_out_of_range (proc, SCM_MAKINUM (fam));
459 }
460 }
461
462 SCM_DEFINE (scm_connect, "connect", 3, 0, 1,
463 (SCM sock, SCM fam, SCM address, SCM args),
464 "Initiates a connection from @var{socket} to the address\n"
465 "specified by @var{address} and possibly @var{arg @dots{}}. The format\n"
466 "required for @var{address}\n"
467 "and @var{arg} @dots{} depends on the family of the socket.\n\n"
468 "For a socket of family @code{AF_UNIX},\n"
469 "only @code{address} is specified and must be a string with the\n"
470 "filename where the socket is to be created.\n\n"
471 "For a socket of family @code{AF_INET},\n"
472 "@code{address} must be an integer Internet host address and @var{arg} @dots{}\n"
473 "must be a single integer port number.\n\n"
474 "The return value is unspecified.")
475 #define FUNC_NAME s_scm_connect
476 {
477 int fd;
478 struct sockaddr *soka;
479 int size;
480
481 sock = SCM_COERCE_OUTPORT (sock);
482 SCM_VALIDATE_OPFPORT (1,sock);
483 SCM_VALIDATE_INUM (2,fam);
484 fd = SCM_FPORT_FDES (sock);
485 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args, 3, FUNC_NAME,
486 &size);
487 if (connect (fd, soka, size) == -1)
488 {
489 int save_errno = errno;
490
491 free (soka);
492 errno = save_errno;
493 SCM_SYSERROR;
494 }
495 free (soka);
496 return SCM_UNSPECIFIED;
497 }
498 #undef FUNC_NAME
499
500 SCM_DEFINE (scm_bind, "bind", 3, 0, 1,
501 (SCM sock, SCM fam, SCM address, SCM args),
502 "Assigns an address to the socket port @var{socket}.\n"
503 "Generally this only needs to be done for server sockets,\n"
504 "so they know where to look for incoming connections. A socket\n"
505 "without an address will be assigned one automatically when it\n"
506 "starts communicating.\n\n"
507 "The format of @var{address} and @var{ARG} @dots{} depends on the family\n"
508 "of the socket.\n\n"
509 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
510 "is specified and must \n"
511 "be a string with the filename where the socket is to be created.\n\n"
512 "For a socket of family @code{AF_INET}, @var{address} must be an integer\n"
513 "Internet host address and @var{arg} @dots{} must be a single integer\n"
514 "port number.\n\n"
515 "The values of the following variables can also be used for @var{address}:\n\n"
516 "@defvar INADDR_ANY\n"
517 "Allow connections from any address.\n"
518 "@end defvar\n\n"
519 "@defvar INADDR_LOOPBACK\n"
520 "The address of the local host using the loopback device.\n"
521 "@end defvar\n\n"
522 "@defvar INADDR_BROADCAST\n"
523 "The broadcast address on the local network.\n"
524 "@end defvar\n\n"
525 "@defvar INADDR_NONE\n"
526 "No address.\n"
527 "@end defvar\n\n"
528 "The return value is unspecified.")
529 #define FUNC_NAME s_scm_bind
530 {
531 struct sockaddr *soka;
532 int size;
533 int fd;
534
535 sock = SCM_COERCE_OUTPORT (sock);
536 SCM_VALIDATE_OPFPORT (1, sock);
537 SCM_VALIDATE_INUM (2, fam);
538 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args, 3, FUNC_NAME,
539 &size);
540 fd = SCM_FPORT_FDES (sock);
541 if (bind (fd, soka, size) == -1)
542 {
543 int save_errno = errno;
544
545 free (soka);
546 errno = save_errno;
547 SCM_SYSERROR;
548 }
549 free (soka);
550 return SCM_UNSPECIFIED;
551 }
552 #undef FUNC_NAME
553
554 SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
555 (SCM sock, SCM backlog),
556 "This procedure enables @var{socket} to accept connection\n"
557 "requests. @var{backlog} is an integer specifying\n"
558 "the maximum length of the queue for pending connections.\n"
559 "If the queue fills, new clients will fail to connect until the\n"
560 "server calls @code{accept} to accept a connection from the queue.\n\n"
561 "The return value is unspecified.")
562 #define FUNC_NAME s_scm_listen
563 {
564 int fd;
565 sock = SCM_COERCE_OUTPORT (sock);
566 SCM_VALIDATE_OPFPORT (1,sock);
567 SCM_VALIDATE_INUM (2,backlog);
568 fd = SCM_FPORT_FDES (sock);
569 if (listen (fd, SCM_INUM (backlog)) == -1)
570 SCM_SYSERROR;
571 return SCM_UNSPECIFIED;
572 }
573 #undef FUNC_NAME
574
575 /* Put the components of a sockaddr into a new SCM vector. */
576 static SCM
577 scm_addr_vector (struct sockaddr *address, const char *proc)
578 {
579 short int fam = address->sa_family;
580 SCM result;
581 SCM *ve;
582
583 #ifdef HAVE_UNIX_DOMAIN_SOCKETS
584 if (fam == AF_UNIX)
585 {
586 struct sockaddr_un *nad = (struct sockaddr_un *) address;
587
588 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
589 ve = SCM_VELTS (result);
590 ve[0] = scm_ulong2num ((unsigned long) fam);
591 ve[1] = scm_makfromstr (nad->sun_path,
592 (scm_sizet) strlen (nad->sun_path), 0);
593 }
594 else
595 #endif
596 if (fam == AF_INET)
597 {
598 struct sockaddr_in *nad = (struct sockaddr_in *) address;
599
600 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
601 ve = SCM_VELTS (result);
602 ve[0] = scm_ulong2num ((unsigned long) fam);
603 ve[1] = scm_ulong2num (ntohl (nad->sin_addr.s_addr));
604 ve[2] = scm_ulong2num ((unsigned long) ntohs (nad->sin_port));
605 }
606 else
607 scm_misc_error (proc, "Unrecognised address family: ~A",
608 SCM_LIST1 (SCM_MAKINUM (fam)));
609
610 return result;
611 }
612
613 /* calculate the size of a buffer large enough to hold any supported
614 sockaddr type. if the buffer isn't large enough, certain system
615 calls will return a truncated address. */
616
617 #if defined (HAVE_UNIX_DOMAIN_SOCKETS)
618 #define MAX_SIZE_UN sizeof (struct sockaddr_un)
619 #else
620 #define MAX_SIZE_UN 0
621 #endif
622
623 #define MAX_ADDR_SIZE max (sizeof (struct sockaddr_in), MAX_SIZE_UN)
624
625 SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
626 (SCM sock),
627 "Accepts a connection on a bound, listening socket @var{socket}. If there\n"
628 "are no pending connections in the queue, it waits until\n"
629 "one is available unless the non-blocking option has been set on the\n"
630 "socket.\n\n"
631 "The return value is a\n"
632 "pair in which the CAR is a new socket port for the connection and\n"
633 "the CDR is an object with address information about the client which\n"
634 "initiated the connection.\n\n"
635 "If the address is not available then the CDR will be an empty vector.\n\n"
636 "@var{socket} does not become part of the\n"
637 "connection and will continue to accept new requests.")
638 #define FUNC_NAME s_scm_accept
639 {
640 int fd;
641 int newfd;
642 SCM address;
643 SCM newsock;
644 int addr_size = MAX_ADDR_SIZE;
645 char max_addr[MAX_ADDR_SIZE];
646 struct sockaddr *addr = (struct sockaddr *) max_addr;
647
648 sock = SCM_COERCE_OUTPORT (sock);
649 SCM_VALIDATE_OPFPORT (1, sock);
650 fd = SCM_FPORT_FDES (sock);
651 newfd = accept (fd, addr, &addr_size);
652 if (newfd == -1)
653 SCM_SYSERROR;
654 newsock = SCM_SOCK_FD_TO_PORT (newfd);
655 if (addr_size > 0)
656 address = scm_addr_vector (addr, FUNC_NAME);
657 else
658 address = SCM_BOOL_F;
659
660 return scm_cons (newsock, address);
661 }
662 #undef FUNC_NAME
663
664 SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
665 (SCM sock),
666 "Returns the address of @var{socket}, in the same form as the object\n"
667 "returned by @code{accept}. On many systems the address of a socket\n"
668 "in the @code{AF_FILE} namespace cannot be read.")
669 #define FUNC_NAME s_scm_getsockname
670 {
671 int fd;
672 SCM result;
673 int addr_size = MAX_ADDR_SIZE;
674 char max_addr[MAX_ADDR_SIZE];
675 struct sockaddr *addr = (struct sockaddr *) max_addr;
676
677 sock = SCM_COERCE_OUTPORT (sock);
678 SCM_VALIDATE_OPFPORT (1,sock);
679 fd = SCM_FPORT_FDES (sock);
680 if (getsockname (fd, addr, &addr_size) == -1)
681 SCM_SYSERROR;
682 if (addr_size > 0)
683 result = scm_addr_vector (addr, FUNC_NAME);
684 else
685 result = SCM_BOOL_F;
686 return result;
687 }
688 #undef FUNC_NAME
689
690 SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
691 (SCM sock),
692 "Returns the address of the socket that the socket @var{socket} is connected to,\n"
693 "in the same form as the object\n"
694 "returned by @code{accept}. On many systems the address of a socket\n"
695 "in the @code{AF_FILE} namespace cannot be read.")
696 #define FUNC_NAME s_scm_getpeername
697 {
698 int fd;
699 SCM result;
700 int addr_size = MAX_ADDR_SIZE;
701 char max_addr[MAX_ADDR_SIZE];
702 struct sockaddr *addr = (struct sockaddr *) max_addr;
703
704 sock = SCM_COERCE_OUTPORT (sock);
705 SCM_VALIDATE_OPFPORT (1,sock);
706 fd = SCM_FPORT_FDES (sock);
707 if (getpeername (fd, addr, &addr_size) == -1)
708 SCM_SYSERROR;
709 if (addr_size > 0)
710 result = scm_addr_vector (addr, FUNC_NAME);
711 else
712 result = SCM_BOOL_F;
713 return result;
714 }
715 #undef FUNC_NAME
716
717 SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
718 (SCM sock, SCM buf, SCM flags),
719 "Receives data from the socket port @var{socket}. @var{socket} must already\n"
720 "be bound to the address from which data is to be received.\n"
721 "@var{buf} is a string into which\n"
722 "the data will be written. The size of @var{buf} limits the amount of\n"
723 "data which can be received: in the case of packet\n"
724 "protocols, if a packet larger than this limit is encountered then some data\n"
725 "will be irrevocably lost.\n\n"
726 "The optional @var{flags} argument is a value or\n"
727 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
728 "The value returned is the number of bytes read from the socket.\n\n"
729 "Note that the data is read directly from the socket file descriptor:\n"
730 "any unread buffered port data is ignored.")
731 #define FUNC_NAME s_scm_recv
732 {
733 int rv;
734 int fd;
735 int flg;
736
737 SCM_VALIDATE_OPFPORT (1,sock);
738 SCM_VALIDATE_STRING (2,buf);
739 SCM_VALIDATE_INUM_DEF_COPY (3,flags,0,flg);
740 fd = SCM_FPORT_FDES (sock);
741
742 SCM_SYSCALL (rv = recv (fd, SCM_STRING_CHARS (buf), SCM_STRING_LENGTH (buf), flg));
743 if (rv == -1)
744 SCM_SYSERROR;
745
746 return SCM_MAKINUM (rv);
747 }
748 #undef FUNC_NAME
749
750 SCM_DEFINE (scm_send, "send", 2, 1, 0,
751 (SCM sock, SCM message, SCM flags),
752 "Transmits the string @var{message} on the socket port @var{socket}. \n"
753 "@var{socket} must already be bound to a destination address. The\n"
754 "value returned is the number of bytes transmitted -- it's possible for\n"
755 "this to be less than the length of @var{message} if the socket is\n"
756 "set to be non-blocking. The optional @var{flags} argument is a value or\n"
757 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
758 "Note that the data is written directly to the socket file descriptor:\n"
759 "any unflushed buffered port data is ignored.")
760 #define FUNC_NAME s_scm_send
761 {
762 int rv;
763 int fd;
764 int flg;
765
766 sock = SCM_COERCE_OUTPORT (sock);
767 SCM_VALIDATE_OPFPORT (1,sock);
768 SCM_VALIDATE_STRING (2, message);
769 SCM_VALIDATE_INUM_DEF_COPY (3,flags,0,flg);
770 fd = SCM_FPORT_FDES (sock);
771
772 SCM_SYSCALL (rv = send (fd, SCM_STRING_CHARS (message), SCM_STRING_LENGTH (message), flg));
773 if (rv == -1)
774 SCM_SYSERROR;
775 return SCM_MAKINUM (rv);
776 }
777 #undef FUNC_NAME
778
779 SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
780 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
781 "Returns data from the socket port @var{socket} and also information about\n"
782 "where the data was received from. @var{socket} must already\n"
783 "be bound to the address from which data is to be received.\n"
784 "@code{str}, is a string into which\n"
785 "the data will be written. The size of @var{str} limits the amount of\n"
786 "data which can be received: in the case of packet\n"
787 "protocols, if a packet larger than this limit is encountered then some data\n"
788 "will be irrevocably lost.\n\n"
789 "The optional @var{flags} argument is a value or\n"
790 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
791 "The value returned is a pair: the CAR is the number of bytes read from\n"
792 "the socket and the CDR an address object in the same form as returned by\n"
793 "@code{accept}.\n\n"
794 "The @var{start} and @var{end} arguments specify a substring of @var{str}\n"
795 "to which the data should be written.\n\n"
796 "Note that the data is read directly from the socket file descriptor:\n"
797 "any unread buffered port data is ignored.")
798 #define FUNC_NAME s_scm_recvfrom
799 {
800 int rv;
801 int fd;
802 int flg;
803 char *buf;
804 int offset;
805 int cend;
806 SCM address;
807 int addr_size = MAX_ADDR_SIZE;
808 char max_addr[MAX_ADDR_SIZE];
809 struct sockaddr *addr = (struct sockaddr *) max_addr;
810
811 SCM_VALIDATE_OPFPORT (1,sock);
812 fd = SCM_FPORT_FDES (sock);
813 SCM_VALIDATE_SUBSTRING_SPEC_COPY (2, str, buf, 4, start, offset,
814 5, end, cend);
815 if (SCM_UNBNDP (flags))
816 flg = 0;
817 else
818 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
819
820 /* recvfrom will not necessarily return an address. usually nothing
821 is returned for stream sockets. */
822 addr->sa_family = AF_UNSPEC;
823 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
824 cend - offset, flg,
825 addr, &addr_size));
826 if (rv == -1)
827 SCM_SYSERROR;
828 if (addr_size > 0 && addr->sa_family != AF_UNSPEC)
829 address = scm_addr_vector (addr, FUNC_NAME);
830 else
831 address = SCM_BOOL_F;
832
833 return scm_cons (SCM_MAKINUM (rv), address);
834 }
835 #undef FUNC_NAME
836
837 SCM_DEFINE (scm_sendto, "sendto", 4, 0, 1,
838 (SCM sock, SCM message, SCM fam, SCM address, SCM args_and_flags),
839 "Transmits the string @var{message} on the socket port @var{socket}. The\n"
840 "destination address is specified using the @var{family}, @var{address} and\n"
841 "@var{arg} arguments, in a similar way to the @code{connect}\n"
842 "procedure. The\n"
843 "value returned is the number of bytes transmitted -- it's possible for\n"
844 "this to be less than the length of @var{message} if the socket is\n"
845 "set to be non-blocking. The optional @var{flags} argument is a value or\n"
846 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
847 "Note that the data is written directly to the socket file descriptor:\n"
848 "any unflushed buffered port data is ignored.")
849 #define FUNC_NAME s_scm_sendto
850 {
851 int rv;
852 int fd;
853 int flg;
854 struct sockaddr *soka;
855 int size;
856
857 sock = SCM_COERCE_OUTPORT (sock);
858 SCM_VALIDATE_FPORT (1,sock);
859 SCM_VALIDATE_STRING (2, message);
860 SCM_VALIDATE_INUM (3,fam);
861 fd = SCM_FPORT_FDES (sock);
862 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args_and_flags, 4,
863 FUNC_NAME, &size);
864 if (SCM_NULLP (args_and_flags))
865 flg = 0;
866 else
867 {
868 SCM_VALIDATE_CONS (5,args_and_flags);
869 flg = SCM_NUM2ULONG (5,SCM_CAR (args_and_flags));
870 }
871 SCM_SYSCALL (rv = sendto (fd, SCM_STRING_CHARS (message),
872 SCM_STRING_LENGTH (message),
873 flg, soka, size));
874 if (rv == -1)
875 {
876 int save_errno = errno;
877 free (soka);
878 errno = save_errno;
879 SCM_SYSERROR;
880 }
881 free (soka);
882 return SCM_MAKINUM (rv);
883 }
884 #undef FUNC_NAME
885 \f
886
887
888 void
889 scm_init_socket ()
890 {
891 /* protocol families. */
892 #ifdef AF_UNSPEC
893 scm_sysintern ("AF_UNSPEC", SCM_MAKINUM (AF_UNSPEC));
894 #endif
895 #ifdef AF_UNIX
896 scm_sysintern ("AF_UNIX", SCM_MAKINUM (AF_UNIX));
897 #endif
898 #ifdef AF_INET
899 scm_sysintern ("AF_INET", SCM_MAKINUM (AF_INET));
900 #endif
901
902 #ifdef PF_UNSPEC
903 scm_sysintern ("PF_UNSPEC", SCM_MAKINUM (PF_UNSPEC));
904 #endif
905 #ifdef PF_UNIX
906 scm_sysintern ("PF_UNIX", SCM_MAKINUM (PF_UNIX));
907 #endif
908 #ifdef PF_INET
909 scm_sysintern ("PF_INET", SCM_MAKINUM (PF_INET));
910 #endif
911
912 /* socket types. */
913 #ifdef SOCK_STREAM
914 scm_sysintern ("SOCK_STREAM", SCM_MAKINUM (SOCK_STREAM));
915 #endif
916 #ifdef SOCK_DGRAM
917 scm_sysintern ("SOCK_DGRAM", SCM_MAKINUM (SOCK_DGRAM));
918 #endif
919 #ifdef SOCK_RAW
920 scm_sysintern ("SOCK_RAW", SCM_MAKINUM (SOCK_RAW));
921 #endif
922
923 /* setsockopt level. */
924 #ifdef SOL_SOCKET
925 scm_sysintern ("SOL_SOCKET", SCM_MAKINUM (SOL_SOCKET));
926 #endif
927 #ifdef SOL_IP
928 scm_sysintern ("SOL_IP", SCM_MAKINUM (SOL_IP));
929 #endif
930 #ifdef SOL_TCP
931 scm_sysintern ("SOL_TCP", SCM_MAKINUM (SOL_TCP));
932 #endif
933 #ifdef SOL_UDP
934 scm_sysintern ("SOL_UDP", SCM_MAKINUM (SOL_UDP));
935 #endif
936
937 /* setsockopt names. */
938 #ifdef SO_DEBUG
939 scm_sysintern ("SO_DEBUG", SCM_MAKINUM (SO_DEBUG));
940 #endif
941 #ifdef SO_REUSEADDR
942 scm_sysintern ("SO_REUSEADDR", SCM_MAKINUM (SO_REUSEADDR));
943 #endif
944 #ifdef SO_STYLE
945 scm_sysintern ("SO_STYLE", SCM_MAKINUM (SO_STYLE));
946 #endif
947 #ifdef SO_TYPE
948 scm_sysintern ("SO_TYPE", SCM_MAKINUM (SO_TYPE));
949 #endif
950 #ifdef SO_ERROR
951 scm_sysintern ("SO_ERROR", SCM_MAKINUM (SO_ERROR));
952 #endif
953 #ifdef SO_DONTROUTE
954 scm_sysintern ("SO_DONTROUTE", SCM_MAKINUM (SO_DONTROUTE));
955 #endif
956 #ifdef SO_BROADCAST
957 scm_sysintern ("SO_BROADCAST", SCM_MAKINUM (SO_BROADCAST));
958 #endif
959 #ifdef SO_SNDBUF
960 scm_sysintern ("SO_SNDBUF", SCM_MAKINUM (SO_SNDBUF));
961 #endif
962 #ifdef SO_RCVBUF
963 scm_sysintern ("SO_RCVBUF", SCM_MAKINUM (SO_RCVBUF));
964 #endif
965 #ifdef SO_KEEPALIVE
966 scm_sysintern ("SO_KEEPALIVE", SCM_MAKINUM (SO_KEEPALIVE));
967 #endif
968 #ifdef SO_OOBINLINE
969 scm_sysintern ("SO_OOBINLINE", SCM_MAKINUM (SO_OOBINLINE));
970 #endif
971 #ifdef SO_NO_CHECK
972 scm_sysintern ("SO_NO_CHECK", SCM_MAKINUM (SO_NO_CHECK));
973 #endif
974 #ifdef SO_PRIORITY
975 scm_sysintern ("SO_PRIORITY", SCM_MAKINUM (SO_PRIORITY));
976 #endif
977 #ifdef SO_LINGER
978 scm_sysintern ("SO_LINGER", SCM_MAKINUM (SO_LINGER));
979 #endif
980
981 /* recv/send options. */
982 #ifdef MSG_OOB
983 scm_sysintern ("MSG_OOB", SCM_MAKINUM (MSG_OOB));
984 #endif
985 #ifdef MSG_PEEK
986 scm_sysintern ("MSG_PEEK", SCM_MAKINUM (MSG_PEEK));
987 #endif
988 #ifdef MSG_DONTROUTE
989 scm_sysintern ("MSG_DONTROUTE", SCM_MAKINUM (MSG_DONTROUTE));
990 #endif
991
992 scm_add_feature ("socket");
993
994 #ifndef SCM_MAGIC_SNARFER
995 #include "libguile/socket.x"
996 #endif
997 }
998
999
1000 /*
1001 Local Variables:
1002 c-file-style: "gnu"
1003 End:
1004 */