* configure.in: check for inet_pton and inet_ntop.
[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"
3453619b
GH
151 "integers. Supported values for @var{family} are\n"
152 "@code{AF_UNIX}, @code{AF_INET} and @code{AF_INET6}.\n"
153 "Typical values for @var{style} are @code{SOCK_STREAM},\n"
1e6808ea
MG
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
e1368a8d
GH
369/* flip a 128 bit IPv6 address between host and network order. */
370#ifdef WORDS_BIGENDIAN
371#define FLIP_NET_HOST_128(addr)
372#else
373#define FLIP_NET_HOST_128(addr)\
374{\
375 int i;\
376 \
377 for (i = 0; i < 8; i++)\
378 {\
379 char c = (addr)[i];\
380 \
381 (addr)[i] = (addr)[15 - i];\
382 (addr)[15 - i] = c;\
383 }\
384}
385#endif
386
a1ec6916 387SCM_DEFINE (scm_shutdown, "shutdown", 2, 0, 0,
1bbd0b84 388 (SCM sock, SCM how),
b380b885
MD
389 "Sockets can be closed simply by using @code{close-port}. The\n"
390 "@code{shutdown} procedure allows reception or tranmission on a\n"
391 "connection to be shut down individually, according to the parameter\n"
392 "@var{how}:\n\n"
393 "@table @asis\n"
394 "@item 0\n"
395 "Stop receiving data for this socket. If further data arrives, reject it.\n"
396 "@item 1\n"
397 "Stop trying to transmit data from this socket. Discard any\n"
398 "data waiting to be sent. Stop looking for acknowledgement of\n"
399 "data already sent; don't retransmit it if it is lost.\n"
400 "@item 2\n"
401 "Stop both reception and transmission.\n"
402 "@end table\n\n"
403 "The return value is unspecified.")
1bbd0b84 404#define FUNC_NAME s_scm_shutdown
0f2d19dd 405{
370312ae 406 int fd;
78446828 407 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd
GB
408 SCM_VALIDATE_OPFPORT (1,sock);
409 SCM_VALIDATE_INUM (2,how);
1bbd0b84 410 SCM_ASSERT_RANGE(2,how,0 <= SCM_INUM (how) && 2 >= SCM_INUM (how));
ee149d03 411 fd = SCM_FPORT_FDES (sock);
370312ae 412 if (shutdown (fd, SCM_INUM (how)) == -1)
1bbd0b84 413 SCM_SYSERROR;
370312ae
GH
414 return SCM_UNSPECIFIED;
415}
1bbd0b84 416#undef FUNC_NAME
0f2d19dd 417
370312ae
GH
418/* convert fam/address/args into a sockaddr of the appropriate type.
419 args is modified by removing the arguments actually used.
420 which_arg and proc are used when reporting errors:
421 which_arg is the position of address in the original argument list.
422 proc is the name of the original procedure.
423 size returns the size of the structure allocated. */
424
370312ae 425static struct sockaddr *
439006bf
GH
426scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
427 const char *proc, int *size)
3453619b 428#define FUNC_NAME proc
370312ae
GH
429{
430 switch (fam)
0f2d19dd 431 {
370312ae
GH
432 case AF_INET:
433 {
370312ae 434 struct sockaddr_in *soka;
3453619b
GH
435 unsigned long addr;
436 int port;
370312ae 437
3453619b
GH
438 SCM_VALIDATE_ULONG_COPY (which_arg, address, addr);
439 SCM_VALIDATE_CONS (which_arg + 1, *args);
440 SCM_VALIDATE_INUM_COPY (which_arg + 1, SCM_CAR (*args), port);
441 *args = SCM_CDR (*args);
439006bf
GH
442 soka = (struct sockaddr_in *) malloc (sizeof (struct sockaddr_in));
443 if (!soka)
444 scm_memory_error (proc);
3453619b
GH
445 /* 4.4BSD-style interface includes sin_len member and defines SIN_LEN,
446 4.3BSD does not. */
447#ifdef SIN_LEN
448 soka->sin_len = sizeof (struct sockaddr_in);
449#endif
370312ae 450 soka->sin_family = AF_INET;
3453619b
GH
451 soka->sin_addr.s_addr = htonl (addr);
452 soka->sin_port = htons (port);
370312ae
GH
453 *size = sizeof (struct sockaddr_in);
454 return (struct sockaddr *) soka;
455 }
3453619b
GH
456#ifdef AF_INET6
457 case AF_INET6:
458 {
459 /* see RFC2553. */
460 int port;
461 struct sockaddr_in6 *soka;
462 unsigned long flowinfo = 0;
463 unsigned long scope_id = 0;
464
465 if (SCM_INUMP (address))
466 SCM_ASSERT_RANGE (which_arg, address, SCM_INUM (address) >= 0);
467 else
468 {
469 SCM_VALIDATE_BIGINT (which_arg, address);
470 SCM_ASSERT_RANGE (which_arg, address,
471 !SCM_BIGSIGN (address)
472 && (SCM_BITSPERDIG
473 * SCM_NUMDIGS (address) <= 128));
474 }
475 SCM_VALIDATE_CONS (which_arg + 1, *args);
476 SCM_VALIDATE_INUM_COPY (which_arg + 1, SCM_CAR (*args), port);
477 *args = SCM_CDR (*args);
478 if (SCM_CONSP (*args))
479 {
480 SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
481 *args = SCM_CDR (*args);
482 if (SCM_CONSP (*args))
483 {
484 SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
485 scope_id);
486 *args = SCM_CDR (*args);
487 }
488 }
489 soka = (struct sockaddr_in6 *) malloc (sizeof (struct sockaddr_in6));
490 if (!soka)
491 scm_memory_error (proc);
492#ifdef SIN_LEN6
493 soka->sin6_len = sizeof (struct sockaddr_in6);
494#endif
495 soka->sin6_family = AF_INET6;
496 if (SCM_INUMP (address))
497 {
498 uint32_t addr = htonl (SCM_INUM (address));
499
500 memset (soka->sin6_addr.s6_addr, 0, 12);
501 memcpy (soka->sin6_addr.s6_addr + 12, &addr, 4);
502 }
503 else
504 {
3453619b
GH
505 memset (soka->sin6_addr.s6_addr, 0, 16);
506 memcpy (soka->sin6_addr.s6_addr, SCM_BDIGITS (address),
507 SCM_NUMDIGS (address) * (SCM_BITSPERDIG / 8));
e1368a8d 508 FLIP_NET_HOST_128 (soka->sin6_addr.s6_addr);
3453619b 509 }
5a525b84 510 soka->sin6_port = htons (port);
3453619b 511 soka->sin6_flowinfo = flowinfo;
5a525b84 512#ifdef HAVE_SIN6_SCOPE_ID
3453619b 513 soka->sin6_scope_id = scope_id;
5a525b84 514#endif
3453619b
GH
515 *size = sizeof (struct sockaddr_in6);
516 return (struct sockaddr *) soka;
517 }
518#endif
1ba8c23a 519#ifdef HAVE_UNIX_DOMAIN_SOCKETS
370312ae
GH
520 case AF_UNIX:
521 {
522 struct sockaddr_un *soka;
439006bf 523 int addr_size;
370312ae 524
a6d9e5ab 525 SCM_ASSERT (SCM_STRINGP (address), address, which_arg, proc);
439006bf
GH
526 /* the static buffer size in sockaddr_un seems to be arbitrary
527 and not necessarily a hard limit. e.g., the glibc manual
528 suggests it may be possible to declare it size 0. let's
529 ignore it. if the O/S doesn't like the size it will cause
530 connect/bind etc., to fail. sun_path is always the last
531 member of the structure. */
532 addr_size = sizeof (struct sockaddr_un)
533 + max (0, SCM_STRING_LENGTH (address) + 1 - (sizeof soka->sun_path));
534 soka = (struct sockaddr_un *) malloc (addr_size);
535 if (!soka)
536 scm_memory_error (proc);
537 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
538 soka->sun_family = AF_UNIX;
34f0f2b8 539 memcpy (soka->sun_path, SCM_STRING_CHARS (address),
439006bf
GH
540 SCM_STRING_LENGTH (address));
541 *size = SUN_LEN (soka);
370312ae
GH
542 return (struct sockaddr *) soka;
543 }
0e958795 544#endif
370312ae
GH
545 default:
546 scm_out_of_range (proc, SCM_MAKINUM (fam));
0f2d19dd 547 }
0f2d19dd 548}
3453619b 549#undef FUNC_NAME
370312ae 550
a1ec6916 551SCM_DEFINE (scm_connect, "connect", 3, 0, 1,
1bbd0b84 552 (SCM sock, SCM fam, SCM address, SCM args),
3453619b
GH
553 "Initiates a connection from a socket using a specified address\n"
554 "family to the address\n"
555 "specified by @var{address} and possibly @var{args}.\n"
556 "The format required for @var{address}\n"
557 "and @var{args} depends on the family of the socket.\n\n"
b380b885 558 "For a socket of family @code{AF_UNIX},\n"
3453619b 559 "only @var{address} is specified and must be a string with the\n"
b380b885
MD
560 "filename where the socket is to be created.\n\n"
561 "For a socket of family @code{AF_INET},\n"
3453619b
GH
562 "@var{address} must be an integer IPv4 host address and\n"
563 "@var{args} must be a single integer port number.\n\n"
564 "For a socket of family @code{AF_INET6},\n"
565 "@var{address} must be an integer IPv6 host address and\n"
566 "@var{args} may be up to three integers:\n"
567 "port [flowinfo] [scope_id],\n"
568 "where flowinfo and scope_id default to zero.\n\n"
b380b885 569 "The return value is unspecified.")
1bbd0b84 570#define FUNC_NAME s_scm_connect
0f2d19dd 571{
370312ae
GH
572 int fd;
573 struct sockaddr *soka;
439006bf 574 int size;
0f2d19dd 575
78446828 576 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd
GB
577 SCM_VALIDATE_OPFPORT (1,sock);
578 SCM_VALIDATE_INUM (2,fam);
ee149d03 579 fd = SCM_FPORT_FDES (sock);
439006bf
GH
580 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args, 3, FUNC_NAME,
581 &size);
370312ae 582 if (connect (fd, soka, size) == -1)
439006bf
GH
583 {
584 int save_errno = errno;
585
586 free (soka);
587 errno = save_errno;
588 SCM_SYSERROR;
589 }
590 free (soka);
370312ae 591 return SCM_UNSPECIFIED;
0f2d19dd 592}
1bbd0b84 593#undef FUNC_NAME
0f2d19dd 594
a1ec6916 595SCM_DEFINE (scm_bind, "bind", 3, 0, 1,
1bbd0b84 596 (SCM sock, SCM fam, SCM address, SCM args),
b380b885
MD
597 "Assigns an address to the socket port @var{socket}.\n"
598 "Generally this only needs to be done for server sockets,\n"
599 "so they know where to look for incoming connections. A socket\n"
600 "without an address will be assigned one automatically when it\n"
601 "starts communicating.\n\n"
602 "The format of @var{address} and @var{ARG} @dots{} depends on the family\n"
603 "of the socket.\n\n"
604 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
605 "is specified and must \n"
606 "be a string with the filename where the socket is to be created.\n\n"
607 "For a socket of family @code{AF_INET}, @var{address} must be an integer\n"
608 "Internet host address and @var{arg} @dots{} must be a single integer\n"
609 "port number.\n\n"
610 "The values of the following variables can also be used for @var{address}:\n\n"
611 "@defvar INADDR_ANY\n"
612 "Allow connections from any address.\n"
613 "@end defvar\n\n"
614 "@defvar INADDR_LOOPBACK\n"
615 "The address of the local host using the loopback device.\n"
616 "@end defvar\n\n"
617 "@defvar INADDR_BROADCAST\n"
618 "The broadcast address on the local network.\n"
619 "@end defvar\n\n"
620 "@defvar INADDR_NONE\n"
621 "No address.\n"
622 "@end defvar\n\n"
623 "The return value is unspecified.")
1bbd0b84 624#define FUNC_NAME s_scm_bind
370312ae 625{
370312ae 626 struct sockaddr *soka;
439006bf 627 int size;
370312ae
GH
628 int fd;
629
78446828 630 sock = SCM_COERCE_OUTPORT (sock);
439006bf
GH
631 SCM_VALIDATE_OPFPORT (1, sock);
632 SCM_VALIDATE_INUM (2, fam);
633 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args, 3, FUNC_NAME,
634 &size);
ee149d03 635 fd = SCM_FPORT_FDES (sock);
439006bf
GH
636 if (bind (fd, soka, size) == -1)
637 {
638 int save_errno = errno;
639
640 free (soka);
641 errno = save_errno;
1bbd0b84 642 SCM_SYSERROR;
439006bf
GH
643 }
644 free (soka);
370312ae
GH
645 return SCM_UNSPECIFIED;
646}
1bbd0b84 647#undef FUNC_NAME
370312ae 648
a1ec6916 649SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
1bbd0b84 650 (SCM sock, SCM backlog),
b380b885
MD
651 "This procedure enables @var{socket} to accept connection\n"
652 "requests. @var{backlog} is an integer specifying\n"
653 "the maximum length of the queue for pending connections.\n"
654 "If the queue fills, new clients will fail to connect until the\n"
655 "server calls @code{accept} to accept a connection from the queue.\n\n"
656 "The return value is unspecified.")
1bbd0b84 657#define FUNC_NAME s_scm_listen
370312ae
GH
658{
659 int fd;
78446828 660 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd
GB
661 SCM_VALIDATE_OPFPORT (1,sock);
662 SCM_VALIDATE_INUM (2,backlog);
ee149d03 663 fd = SCM_FPORT_FDES (sock);
370312ae 664 if (listen (fd, SCM_INUM (backlog)) == -1)
1bbd0b84 665 SCM_SYSERROR;
370312ae
GH
666 return SCM_UNSPECIFIED;
667}
1bbd0b84 668#undef FUNC_NAME
370312ae
GH
669
670/* Put the components of a sockaddr into a new SCM vector. */
370312ae 671static SCM
e1368a8d 672scm_addr_vector (const struct sockaddr *address, const char *proc)
0f2d19dd 673{
370312ae
GH
674 short int fam = address->sa_family;
675 SCM result;
676 SCM *ve;
439006bf 677
5a525b84 678 switch (fam)
0f2d19dd 679 {
5a525b84
GH
680 case AF_INET:
681 {
e1368a8d 682 const struct sockaddr_in *nad = (struct sockaddr_in *) address;
439006bf 683
5a525b84
GH
684 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
685 ve = SCM_VELTS (result);
686 ve[0] = scm_ulong2num ((unsigned long) fam);
687 ve[1] = scm_ulong2num (ntohl (nad->sin_addr.s_addr));
688 ve[2] = scm_ulong2num ((unsigned long) ntohs (nad->sin_port));
689 }
690 break;
691#ifdef AF_INET6
692 case AF_INET6:
693 {
e1368a8d
GH
694 const struct sockaddr_in6 *nad = (struct sockaddr_in6 *) address;
695 int big_digits = 128 / SCM_BITSPERDIG;
696 int bytes_per_dig = SCM_BITSPERDIG / 8;
697 char addr[16];
698 char *ptr = addr;
699 SCM scm_addr;
700
701 memcpy (addr, nad->sin6_addr.s6_addr, 16);
702 /* get rid of leading zeros. */
703 while (big_digits > 0)
704 {
705 long test = 0;
706
707 memcpy (&test, ptr, bytes_per_dig);
708 if (test != 0)
709 break;
710 ptr += bytes_per_dig;
711 big_digits--;
712 }
713 FLIP_NET_HOST_128 (addr);
714 if (big_digits * bytes_per_dig <= sizeof (unsigned long))
715 {
716 /* this is just so that we use INUM where possible. */
717 unsigned long l_addr;
718
719 memcpy (&l_addr, addr, sizeof (unsigned long));
720 scm_addr = scm_ulong2num (l_addr);
721 }
722 else
723 {
724 scm_addr = scm_mkbig (big_digits, 0);
725 memcpy (SCM_BDIGITS (scm_addr), addr, big_digits * bytes_per_dig);
726 }
5a525b84
GH
727
728 result = scm_c_make_vector (5, SCM_UNSPECIFIED);
729 ve = SCM_VELTS (result);
730 ve[0] = scm_ulong2num ((unsigned long) fam);
e1368a8d 731 ve[1] = scm_addr;
5a525b84
GH
732 ve[2] = scm_ulong2num ((unsigned long) ntohs (nad->sin6_port));
733 ve[3] = scm_ulong2num ((unsigned long) nad->sin6_flowinfo);
734#ifdef HAVE_SIN6_SCOPE_ID
735 ve[4] = scm_ulong2num ((unsigned long) nad->sin6_scope_id);
736#else
737 ve[4] = SCM_INUM0;
0e958795 738#endif
5a525b84
GH
739 }
740 break;
741#endif
742#ifdef HAVE_UNIX_DOMAIN_SOCKETS
743 case AF_UNIX:
744 {
e1368a8d 745 const struct sockaddr_un *nad = (struct sockaddr_un *) address;
439006bf 746
5a525b84
GH
747 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
748 ve = SCM_VELTS (result);
749 ve[0] = scm_ulong2num ((unsigned long) fam);
750 ve[1] = scm_makfromstr (nad->sun_path,
751 (scm_sizet) strlen (nad->sun_path), 0);
752 }
753 break;
754#endif
755 default:
756 scm_misc_error (proc, "Unrecognised address family: ~A",
757 SCM_LIST1 (SCM_MAKINUM (fam)));
0f2d19dd 758 }
370312ae
GH
759 return result;
760}
761
439006bf
GH
762/* calculate the size of a buffer large enough to hold any supported
763 sockaddr type. if the buffer isn't large enough, certain system
764 calls will return a truncated address. */
370312ae 765
439006bf
GH
766#if defined (HAVE_UNIX_DOMAIN_SOCKETS)
767#define MAX_SIZE_UN sizeof (struct sockaddr_un)
0e958795 768#else
439006bf 769#define MAX_SIZE_UN 0
0e958795 770#endif
439006bf 771
5a525b84
GH
772#if defined (AF_INET6)
773#define MAX_SIZE_IN6 sizeof (struct sockaddr_in6)
774#else
775#define MAX_SIZE_IN6 0
776#endif
777
778#define MAX_ADDR_SIZE max (max (sizeof (struct sockaddr_in), MAX_SIZE_IN6),\
779 MAX_SIZE_UN)
0f2d19dd 780
a1ec6916 781SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1bbd0b84 782 (SCM sock),
b380b885
MD
783 "Accepts a connection on a bound, listening socket @var{socket}. If there\n"
784 "are no pending connections in the queue, it waits until\n"
785 "one is available unless the non-blocking option has been set on the\n"
786 "socket.\n\n"
787 "The return value is a\n"
788 "pair in which the CAR is a new socket port for the connection and\n"
789 "the CDR is an object with address information about the client which\n"
790 "initiated the connection.\n\n"
791 "If the address is not available then the CDR will be an empty vector.\n\n"
792 "@var{socket} does not become part of the\n"
793 "connection and will continue to accept new requests.")
1bbd0b84 794#define FUNC_NAME s_scm_accept
0f2d19dd 795{
370312ae
GH
796 int fd;
797 int newfd;
798 SCM address;
799 SCM newsock;
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
78446828 804 sock = SCM_COERCE_OUTPORT (sock);
439006bf 805 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 806 fd = SCM_FPORT_FDES (sock);
439006bf
GH
807 newfd = accept (fd, addr, &addr_size);
808 if (newfd == -1)
809 SCM_SYSERROR;
810 newsock = SCM_SOCK_FD_TO_PORT (newfd);
811 if (addr_size > 0)
812 address = scm_addr_vector (addr, FUNC_NAME);
0f2d19dd 813 else
370312ae
GH
814 address = SCM_BOOL_F;
815
370312ae 816 return scm_cons (newsock, address);
0f2d19dd 817}
1bbd0b84 818#undef FUNC_NAME
0f2d19dd 819
a1ec6916 820SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1bbd0b84 821 (SCM sock),
1e6808ea
MG
822 "Return the address of @var{socket}, in the same form as the\n"
823 "object returned by @code{accept}. On many systems the address\n"
824 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1bbd0b84 825#define FUNC_NAME s_scm_getsockname
0f2d19dd 826{
370312ae
GH
827 int fd;
828 SCM result;
439006bf
GH
829 int addr_size = MAX_ADDR_SIZE;
830 char max_addr[MAX_ADDR_SIZE];
831 struct sockaddr *addr = (struct sockaddr *) max_addr;
832
78446828 833 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd 834 SCM_VALIDATE_OPFPORT (1,sock);
ee149d03 835 fd = SCM_FPORT_FDES (sock);
439006bf 836 if (getsockname (fd, addr, &addr_size) == -1)
1bbd0b84 837 SCM_SYSERROR;
439006bf
GH
838 if (addr_size > 0)
839 result = scm_addr_vector (addr, FUNC_NAME);
0f2d19dd 840 else
370312ae 841 result = SCM_BOOL_F;
370312ae 842 return result;
0f2d19dd 843}
1bbd0b84 844#undef FUNC_NAME
0f2d19dd 845
a1ec6916 846SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1bbd0b84 847 (SCM sock),
1e6808ea
MG
848 "Return the address of the socket that the socket @var{socket}\n"
849 "is connected to, in the same form as the object returned by\n"
850 "@code{accept}. On many systems the address of a socket in the\n"
851 "@code{AF_FILE} namespace cannot be read.")
1bbd0b84 852#define FUNC_NAME s_scm_getpeername
0f2d19dd 853{
370312ae
GH
854 int fd;
855 SCM result;
439006bf
GH
856 int addr_size = MAX_ADDR_SIZE;
857 char max_addr[MAX_ADDR_SIZE];
858 struct sockaddr *addr = (struct sockaddr *) max_addr;
859
78446828 860 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd 861 SCM_VALIDATE_OPFPORT (1,sock);
ee149d03 862 fd = SCM_FPORT_FDES (sock);
439006bf 863 if (getpeername (fd, addr, &addr_size) == -1)
1bbd0b84 864 SCM_SYSERROR;
439006bf
GH
865 if (addr_size > 0)
866 result = scm_addr_vector (addr, FUNC_NAME);
0f2d19dd 867 else
370312ae 868 result = SCM_BOOL_F;
370312ae 869 return result;
0f2d19dd 870}
1bbd0b84 871#undef FUNC_NAME
0f2d19dd 872
a1ec6916 873SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1bbd0b84 874 (SCM sock, SCM buf, SCM flags),
b380b885
MD
875 "Receives data from the socket port @var{socket}. @var{socket} must already\n"
876 "be bound to the address from which data is to be received.\n"
877 "@var{buf} is a string into which\n"
878 "the data will be written. The size of @var{buf} limits the amount of\n"
879 "data which can be received: in the case of packet\n"
880 "protocols, if a packet larger than this limit is encountered then some data\n"
881 "will be irrevocably lost.\n\n"
882 "The optional @var{flags} argument is a value or\n"
883 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
884 "The value returned is the number of bytes read from the socket.\n\n"
09831f94
NJ
885 "Note that the data is read directly from the socket file descriptor:\n"
886 "any unread buffered port data is ignored.")
1bbd0b84 887#define FUNC_NAME s_scm_recv
0f2d19dd 888{
370312ae
GH
889 int rv;
890 int fd;
891 int flg;
370312ae 892
3b3b36dd
GB
893 SCM_VALIDATE_OPFPORT (1,sock);
894 SCM_VALIDATE_STRING (2,buf);
895 SCM_VALIDATE_INUM_DEF_COPY (3,flags,0,flg);
ee149d03 896 fd = SCM_FPORT_FDES (sock);
370312ae 897
bfa974f0 898 SCM_SYSCALL (rv = recv (fd, SCM_STRING_CHARS (buf), SCM_STRING_LENGTH (buf), flg));
370312ae 899 if (rv == -1)
1bbd0b84 900 SCM_SYSERROR;
370312ae 901
1146b6cd 902 return SCM_MAKINUM (rv);
370312ae 903}
1bbd0b84 904#undef FUNC_NAME
370312ae 905
a1ec6916 906SCM_DEFINE (scm_send, "send", 2, 1, 0,
1bbd0b84 907 (SCM sock, SCM message, SCM flags),
b380b885
MD
908 "Transmits the string @var{message} on the socket port @var{socket}. \n"
909 "@var{socket} must already be bound to a destination address. The\n"
910 "value returned is the number of bytes transmitted -- it's possible for\n"
911 "this to be less than the length of @var{message} if the socket is\n"
912 "set to be non-blocking. The optional @var{flags} argument is a value or\n"
913 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
914 "Note that the data is written directly to the socket file descriptor:\n"
915 "any unflushed buffered port data is ignored.")
1bbd0b84 916#define FUNC_NAME s_scm_send
370312ae
GH
917{
918 int rv;
919 int fd;
920 int flg;
921
78446828 922 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd 923 SCM_VALIDATE_OPFPORT (1,sock);
a6d9e5ab 924 SCM_VALIDATE_STRING (2, message);
3b3b36dd 925 SCM_VALIDATE_INUM_DEF_COPY (3,flags,0,flg);
ee149d03 926 fd = SCM_FPORT_FDES (sock);
370312ae 927
34f0f2b8 928 SCM_SYSCALL (rv = send (fd, SCM_STRING_CHARS (message), SCM_STRING_LENGTH (message), flg));
370312ae 929 if (rv == -1)
1bbd0b84 930 SCM_SYSERROR;
370312ae
GH
931 return SCM_MAKINUM (rv);
932}
1bbd0b84 933#undef FUNC_NAME
370312ae 934
a1ec6916 935SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
60d02d09 936 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
1e6808ea
MG
937 "Return data from the socket port @var{socket} and also\n"
938 "information about where the data was received from.\n"
939 "@var{socket} must already be bound to the address from which\n"
940 "data is to be received. @code{str}, is a string into which the\n"
941 "data will be written. The size of @var{str} limits the amount\n"
942 "of data which can be received: in the case of packet protocols,\n"
943 "if a packet larger than this limit is encountered then some\n"
944 "data will be irrevocably lost.\n"
945 "\n"
946 "The optional @var{flags} argument is a value or bitwise OR of\n"
947 "@code{MSG_OOB}, @code{MSG_PEEK}, @code{MSG_DONTROUTE} etc.\n"
948 "\n"
949 "The value returned is a pair: the @emph{car} is the number of\n"
950 "bytes read from the socket and the @emph{cdr} an address object\n"
951 "in the same form as returned by @code{accept}.\n"
952 "\n"
953 "The @var{start} and @var{end} arguments specify a substring of\n"
954 "@var{str} to which the data should be written.\n"
955 "\n"
956 "Note that the data is read directly from the socket file\n"
957 "descriptor: any unread buffered port data is ignored.")
1bbd0b84 958#define FUNC_NAME s_scm_recvfrom
370312ae
GH
959{
960 int rv;
961 int fd;
962 int flg;
60d02d09
GH
963 char *buf;
964 int offset;
1146b6cd 965 int cend;
370312ae 966 SCM address;
439006bf
GH
967 int addr_size = MAX_ADDR_SIZE;
968 char max_addr[MAX_ADDR_SIZE];
969 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 970
3b3b36dd 971 SCM_VALIDATE_OPFPORT (1,sock);
60d02d09
GH
972 fd = SCM_FPORT_FDES (sock);
973 SCM_VALIDATE_SUBSTRING_SPEC_COPY (2, str, buf, 4, start, offset,
974 5, end, cend);
1146b6cd
GH
975 if (SCM_UNBNDP (flags))
976 flg = 0;
370312ae 977 else
60d02d09 978 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
370312ae 979
97d0e20b
GH
980 /* recvfrom will not necessarily return an address. usually nothing
981 is returned for stream sockets. */
439006bf 982 addr->sa_family = AF_UNSPEC;
60d02d09 983 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
1146b6cd 984 cend - offset, flg,
439006bf 985 addr, &addr_size));
370312ae 986 if (rv == -1)
1bbd0b84 987 SCM_SYSERROR;
439006bf
GH
988 if (addr_size > 0 && addr->sa_family != AF_UNSPEC)
989 address = scm_addr_vector (addr, FUNC_NAME);
370312ae
GH
990 else
991 address = SCM_BOOL_F;
992
1146b6cd 993 return scm_cons (SCM_MAKINUM (rv), address);
0f2d19dd 994}
1bbd0b84 995#undef FUNC_NAME
0f2d19dd 996
a1ec6916 997SCM_DEFINE (scm_sendto, "sendto", 4, 0, 1,
1bbd0b84 998 (SCM sock, SCM message, SCM fam, SCM address, SCM args_and_flags),
b380b885
MD
999 "Transmits the string @var{message} on the socket port @var{socket}. The\n"
1000 "destination address is specified using the @var{family}, @var{address} and\n"
1001 "@var{arg} arguments, in a similar way to the @code{connect}\n"
1002 "procedure. The\n"
1003 "value returned is the number of bytes transmitted -- it's possible for\n"
1004 "this to be less than the length of @var{message} if the socket is\n"
1005 "set to be non-blocking. The optional @var{flags} argument is a value or\n"
1006 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
1007 "Note that the data is written directly to the socket file descriptor:\n"
1008 "any unflushed buffered port data is ignored.")
1bbd0b84 1009#define FUNC_NAME s_scm_sendto
370312ae
GH
1010{
1011 int rv;
1012 int fd;
1013 int flg;
1014 struct sockaddr *soka;
439006bf 1015 int size;
370312ae 1016
78446828 1017 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd 1018 SCM_VALIDATE_FPORT (1,sock);
a6d9e5ab 1019 SCM_VALIDATE_STRING (2, message);
3b3b36dd 1020 SCM_VALIDATE_INUM (3,fam);
ee149d03 1021 fd = SCM_FPORT_FDES (sock);
370312ae 1022 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args_and_flags, 4,
1bbd0b84 1023 FUNC_NAME, &size);
370312ae
GH
1024 if (SCM_NULLP (args_and_flags))
1025 flg = 0;
1026 else
1027 {
3b3b36dd 1028 SCM_VALIDATE_CONS (5,args_and_flags);
e4b265d8 1029 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
370312ae 1030 }
439006bf
GH
1031 SCM_SYSCALL (rv = sendto (fd, SCM_STRING_CHARS (message),
1032 SCM_STRING_LENGTH (message),
ae2fa5bc 1033 flg, soka, size));
370312ae 1034 if (rv == -1)
439006bf
GH
1035 {
1036 int save_errno = errno;
1037 free (soka);
1038 errno = save_errno;
1039 SCM_SYSERROR;
1040 }
1041 free (soka);
370312ae
GH
1042 return SCM_MAKINUM (rv);
1043}
1bbd0b84 1044#undef FUNC_NAME
370312ae
GH
1045\f
1046
1047
1048void
0f2d19dd 1049scm_init_socket ()
0f2d19dd 1050{
370312ae
GH
1051 /* protocol families. */
1052#ifdef AF_UNSPEC
1053 scm_sysintern ("AF_UNSPEC", SCM_MAKINUM (AF_UNSPEC));
1054#endif
1055#ifdef AF_UNIX
1056 scm_sysintern ("AF_UNIX", SCM_MAKINUM (AF_UNIX));
1057#endif
1058#ifdef AF_INET
1059 scm_sysintern ("AF_INET", SCM_MAKINUM (AF_INET));
1060#endif
3453619b
GH
1061#ifdef AF_INET6
1062 scm_sysintern ("AF_INET6", SCM_MAKINUM (AF_INET6));
1063#endif
370312ae
GH
1064
1065#ifdef PF_UNSPEC
1066 scm_sysintern ("PF_UNSPEC", SCM_MAKINUM (PF_UNSPEC));
1067#endif
1068#ifdef PF_UNIX
1069 scm_sysintern ("PF_UNIX", SCM_MAKINUM (PF_UNIX));
1070#endif
1071#ifdef PF_INET
1072 scm_sysintern ("PF_INET", SCM_MAKINUM (PF_INET));
1073#endif
3453619b
GH
1074#ifdef PF_INET6
1075 scm_sysintern ("PF_INET6", SCM_MAKINUM (PF_INET6));
1076#endif
370312ae
GH
1077
1078 /* socket types. */
1079#ifdef SOCK_STREAM
1080 scm_sysintern ("SOCK_STREAM", SCM_MAKINUM (SOCK_STREAM));
1081#endif
1082#ifdef SOCK_DGRAM
1083 scm_sysintern ("SOCK_DGRAM", SCM_MAKINUM (SOCK_DGRAM));
1084#endif
1085#ifdef SOCK_RAW
1086 scm_sysintern ("SOCK_RAW", SCM_MAKINUM (SOCK_RAW));
1087#endif
1088
1089 /* setsockopt level. */
1090#ifdef SOL_SOCKET
1091 scm_sysintern ("SOL_SOCKET", SCM_MAKINUM (SOL_SOCKET));
1092#endif
1093#ifdef SOL_IP
1094 scm_sysintern ("SOL_IP", SCM_MAKINUM (SOL_IP));
1095#endif
1096#ifdef SOL_TCP
1097 scm_sysintern ("SOL_TCP", SCM_MAKINUM (SOL_TCP));
1098#endif
1099#ifdef SOL_UDP
1100 scm_sysintern ("SOL_UDP", SCM_MAKINUM (SOL_UDP));
1101#endif
1102
1103 /* setsockopt names. */
1104#ifdef SO_DEBUG
1105 scm_sysintern ("SO_DEBUG", SCM_MAKINUM (SO_DEBUG));
1106#endif
1107#ifdef SO_REUSEADDR
1108 scm_sysintern ("SO_REUSEADDR", SCM_MAKINUM (SO_REUSEADDR));
1109#endif
1110#ifdef SO_STYLE
1111 scm_sysintern ("SO_STYLE", SCM_MAKINUM (SO_STYLE));
1112#endif
1113#ifdef SO_TYPE
1114 scm_sysintern ("SO_TYPE", SCM_MAKINUM (SO_TYPE));
1115#endif
1116#ifdef SO_ERROR
1117 scm_sysintern ("SO_ERROR", SCM_MAKINUM (SO_ERROR));
1118#endif
1119#ifdef SO_DONTROUTE
1120 scm_sysintern ("SO_DONTROUTE", SCM_MAKINUM (SO_DONTROUTE));
1121#endif
1122#ifdef SO_BROADCAST
1123 scm_sysintern ("SO_BROADCAST", SCM_MAKINUM (SO_BROADCAST));
1124#endif
1125#ifdef SO_SNDBUF
1126 scm_sysintern ("SO_SNDBUF", SCM_MAKINUM (SO_SNDBUF));
1127#endif
1128#ifdef SO_RCVBUF
1129 scm_sysintern ("SO_RCVBUF", SCM_MAKINUM (SO_RCVBUF));
1130#endif
1131#ifdef SO_KEEPALIVE
1132 scm_sysintern ("SO_KEEPALIVE", SCM_MAKINUM (SO_KEEPALIVE));
1133#endif
1134#ifdef SO_OOBINLINE
1135 scm_sysintern ("SO_OOBINLINE", SCM_MAKINUM (SO_OOBINLINE));
1136#endif
1137#ifdef SO_NO_CHECK
1138 scm_sysintern ("SO_NO_CHECK", SCM_MAKINUM (SO_NO_CHECK));
1139#endif
1140#ifdef SO_PRIORITY
1141 scm_sysintern ("SO_PRIORITY", SCM_MAKINUM (SO_PRIORITY));
1142#endif
1143#ifdef SO_LINGER
1144 scm_sysintern ("SO_LINGER", SCM_MAKINUM (SO_LINGER));
1145#endif
1146
1147 /* recv/send options. */
1148#ifdef MSG_OOB
1149 scm_sysintern ("MSG_OOB", SCM_MAKINUM (MSG_OOB));
1150#endif
1151#ifdef MSG_PEEK
1152 scm_sysintern ("MSG_PEEK", SCM_MAKINUM (MSG_PEEK));
1153#endif
1154#ifdef MSG_DONTROUTE
1155 scm_sysintern ("MSG_DONTROUTE", SCM_MAKINUM (MSG_DONTROUTE));
1156#endif
1157
0f2d19dd 1158 scm_add_feature ("socket");
370312ae 1159
8dc9439f 1160#ifndef SCM_MAGIC_SNARFER
a0599745 1161#include "libguile/socket.x"
8dc9439f 1162#endif
0f2d19dd
JB
1163}
1164
89e00824
ML
1165
1166/*
1167 Local Variables:
1168 c-file-style: "gnu"
1169 End:
1170*/