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