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