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