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