News for scm_call_N and scm_apply_N.
[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
00120130
GH
79#if !defined (HAVE_UINT32_T)
80#if SIZEOF_INT == 4
81typedef unsigned int uint32_t;
82#elif SIZEOF_LONG == 4
83typedef unsigned long uint32_t;
84#else
85#error can not define uint32_t
86#endif
87#endif
88
439006bf
GH
89/* we are not currently using socklen_t. it's not defined on all systems,
90 so would need to be checked by configure. in the meantime, plain
91 int is the best alternative. */
92
0f2d19dd
JB
93\f
94
a1ec6916 95SCM_DEFINE (scm_htons, "htons", 1, 0, 0,
eefae538
GH
96 (SCM value),
97 "Convert a 16 bit quantity from host to network byte ordering.\n"
98 "@var{value} is packed into 2 bytes, which are then converted\n"
99 "and returned as a new integer.")
1bbd0b84 100#define FUNC_NAME s_scm_htons
5c11cc9d
GH
101{
102 unsigned short c_in;
103
eefae538
GH
104 SCM_VALIDATE_INUM_COPY (1, value, c_in);
105 if (c_in != SCM_INUM (value))
106 SCM_OUT_OF_RANGE (1, value);
5c11cc9d
GH
107
108 return SCM_MAKINUM (htons (c_in));
109}
1bbd0b84 110#undef FUNC_NAME
5c11cc9d 111
a1ec6916 112SCM_DEFINE (scm_ntohs, "ntohs", 1, 0, 0,
eefae538
GH
113 (SCM value),
114 "Convert a 16 bit quantity from network to host byte ordering.\n"
115 "@var{value} is packed into 2 bytes, which are then converted\n"
116 "and returned as a new integer.")
1bbd0b84 117#define FUNC_NAME s_scm_ntohs
5c11cc9d
GH
118{
119 unsigned short c_in;
120
eefae538
GH
121 SCM_VALIDATE_INUM_COPY (1, value, c_in);
122 if (c_in != SCM_INUM (value))
123 SCM_OUT_OF_RANGE (1, value);
5c11cc9d
GH
124
125 return SCM_MAKINUM (ntohs (c_in));
126}
1bbd0b84 127#undef FUNC_NAME
5c11cc9d 128
a1ec6916 129SCM_DEFINE (scm_htonl, "htonl", 1, 0, 0,
eefae538
GH
130 (SCM value),
131 "Convert a 32 bit quantity from host to network byte ordering.\n"
132 "@var{value} is packed into 4 bytes, which are then converted\n"
133 "and returned as a new integer.")
1bbd0b84 134#define FUNC_NAME s_scm_htonl
5c11cc9d 135{
eefae538 136 uint32_t c_in = SCM_NUM2ULONG (1, value);
66c73b76 137
5c11cc9d
GH
138 return scm_ulong2num (htonl (c_in));
139}
1bbd0b84 140#undef FUNC_NAME
5c11cc9d 141
a1ec6916 142SCM_DEFINE (scm_ntohl, "ntohl", 1, 0, 0,
eefae538
GH
143 (SCM value),
144 "Convert a 32 bit quantity from network to host byte ordering.\n"
145 "@var{value} is packed into 4 bytes, which are then converted\n"
146 "and returned as a new integer.")
1bbd0b84 147#define FUNC_NAME s_scm_ntohl
5c11cc9d 148{
eefae538 149 uint32_t c_in = SCM_NUM2ULONG (1, value);
66c73b76 150
5c11cc9d
GH
151 return scm_ulong2num (ntohl (c_in));
152}
1bbd0b84 153#undef FUNC_NAME
5c11cc9d 154
66c73b76
GH
155#ifndef HAVE_INET_ATON
156/* for our definition in inet_aton.c, not usually needed. */
157extern int inet_aton ();
158#endif
159
160SCM_DEFINE (scm_inet_aton, "inet-aton", 1, 0, 0,
161 (SCM address),
eefae538
GH
162 "Convert an IPv4 Internet address from printable string\n"
163 "(dotted decimal notation) to an integer. E.g.,\n\n"
66c73b76
GH
164 "@lisp\n"
165 "(inet-aton \"127.0.0.1\") @result{} 2130706433\n"
166 "@end lisp")
167#define FUNC_NAME s_scm_inet_aton
168{
169 struct in_addr soka;
170
171 SCM_VALIDATE_STRING (1, address);
172 SCM_STRING_COERCE_0TERMINATION_X (address);
173 if (inet_aton (SCM_STRING_CHARS (address), &soka) == 0)
174 SCM_MISC_ERROR ("bad address", SCM_EOL);
175 return scm_ulong2num (ntohl (soka.s_addr));
176}
177#undef FUNC_NAME
178
179
180SCM_DEFINE (scm_inet_ntoa, "inet-ntoa", 1, 0, 0,
181 (SCM inetid),
eefae538
GH
182 "Convert an IPv4 Internet address to a printable\n"
183 "(dotted decimal notation) string. E.g.,\n\n"
66c73b76
GH
184 "@lisp\n"
185 "(inet-ntoa 2130706433) @result{} \"127.0.0.1\"\n"
186 "@end lisp")
187#define FUNC_NAME s_scm_inet_ntoa
188{
189 struct in_addr addr;
190 char *s;
191 SCM answer;
192 addr.s_addr = htonl (SCM_NUM2ULONG (1, inetid));
193 s = inet_ntoa (addr);
36284627 194 answer = scm_mem2string (s, strlen (s));
66c73b76
GH
195 return answer;
196}
197#undef FUNC_NAME
198
199#ifdef HAVE_INET_NETOF
200SCM_DEFINE (scm_inet_netof, "inet-netof", 1, 0, 0,
201 (SCM address),
eefae538
GH
202 "Return the network number part of the given IPv4\n"
203 "Internet address. E.g.,\n\n"
66c73b76
GH
204 "@lisp\n"
205 "(inet-netof 2130706433) @result{} 127\n"
206 "@end lisp")
207#define FUNC_NAME s_scm_inet_netof
208{
209 struct in_addr addr;
210 addr.s_addr = htonl (SCM_NUM2ULONG (1, address));
211 return scm_ulong2num ((unsigned long) inet_netof (addr));
212}
213#undef FUNC_NAME
214#endif
215
216#ifdef HAVE_INET_LNAOF
217SCM_DEFINE (scm_lnaof, "inet-lnaof", 1, 0, 0,
218 (SCM address),
219 "Return the local-address-with-network part of the given\n"
eefae538
GH
220 "IPv4 Internet address, using the obsolete class A/B/C system.\n"
221 "E.g.,\n\n"
66c73b76
GH
222 "@lisp\n"
223 "(inet-lnaof 2130706433) @result{} 1\n"
224 "@end lisp")
225#define FUNC_NAME s_scm_lnaof
226{
227 struct in_addr addr;
228 addr.s_addr = htonl (SCM_NUM2ULONG (1, address));
229 return scm_ulong2num ((unsigned long) inet_lnaof (addr));
230}
231#undef FUNC_NAME
232#endif
233
234#ifdef HAVE_INET_MAKEADDR
235SCM_DEFINE (scm_inet_makeaddr, "inet-makeaddr", 2, 0, 0,
236 (SCM net, SCM lna),
eefae538 237 "Make an IPv4 Internet address by combining the network number\n"
66c73b76 238 "@var{net} with the local-address-within-network number\n"
eefae538 239 "@var{lna}. E.g.,\n\n"
66c73b76
GH
240 "@lisp\n"
241 "(inet-makeaddr 127 1) @result{} 2130706433\n"
242 "@end lisp")
243#define FUNC_NAME s_scm_inet_makeaddr
244{
245 struct in_addr addr;
246 unsigned long netnum;
247 unsigned long lnanum;
248
249 netnum = SCM_NUM2ULONG (1, net);
250 lnanum = SCM_NUM2ULONG (2, lna);
251 addr = inet_makeaddr (netnum, lnanum);
252 return scm_ulong2num (ntohl (addr.s_addr));
253}
254#undef FUNC_NAME
255#endif
256
a57a0b1e 257#ifdef HAVE_IPV6
eefae538 258
66c73b76
GH
259/* flip a 128 bit IPv6 address between host and network order. */
260#ifdef WORDS_BIGENDIAN
261#define FLIP_NET_HOST_128(addr)
262#else
263#define FLIP_NET_HOST_128(addr)\
264{\
265 int i;\
266 \
267 for (i = 0; i < 8; i++)\
268 {\
269 char c = (addr)[i];\
270 \
271 (addr)[i] = (addr)[15 - i];\
272 (addr)[15 - i] = c;\
273 }\
274}
275#endif
276
277/* convert a 128 bit IPv6 address in network order to a host ordered
278 SCM integer. */
279static SCM ipv6_net_to_num (const char *src)
280{
281 int big_digits = 128 / SCM_BITSPERDIG;
282 const int bytes_per_dig = SCM_BITSPERDIG / 8;
283 char addr[16];
284 char *ptr = addr;
285 SCM result;
286
287 memcpy (addr, src, 16);
288 /* get rid of leading zeros. */
289 while (big_digits > 0)
290 {
291 long test = 0;
292
293 memcpy (&test, ptr, bytes_per_dig);
294 if (test != 0)
295 break;
296 ptr += bytes_per_dig;
297 big_digits--;
298 }
299 FLIP_NET_HOST_128 (addr);
300 if (big_digits * bytes_per_dig <= sizeof (unsigned long))
301 {
302 /* this is just so that we use INUM where possible. */
303 unsigned long l_addr;
304
305 memcpy (&l_addr, addr, sizeof (unsigned long));
306 result = scm_ulong2num (l_addr);
307 }
308 else
309 {
1be6b49c 310 result = scm_i_mkbig (big_digits, 0);
66c73b76
GH
311 memcpy (SCM_BDIGITS (result), addr, big_digits * bytes_per_dig);
312 }
313 return result;
314}
315
316/* convert a host ordered SCM integer to a 128 bit IPv6 address in
317 network order. */
318static void ipv6_num_to_net (SCM src, char *dst)
319{
320 if (SCM_INUMP (src))
321 {
322 uint32_t addr = htonl (SCM_INUM (src));
323
324 memset (dst, 0, 12);
325 memcpy (dst + 12, &addr, 4);
326 }
327 else
328 {
329 memset (dst, 0, 16);
330 memcpy (dst, SCM_BDIGITS (src),
331 SCM_NUMDIGS (src) * (SCM_BITSPERDIG / 8));
332 FLIP_NET_HOST_128 (dst);
333 }
334}
335
336/* check that an SCM variable contains an IPv6 integer address. */
337#define VALIDATE_INET6(which_arg, address)\
338 if (SCM_INUMP (address))\
339 SCM_ASSERT_RANGE (which_arg, address, SCM_INUM (address) >= 0);\
340 else\
341 {\
342 SCM_VALIDATE_BIGINT (which_arg, address);\
343 SCM_ASSERT_RANGE (which_arg, address,\
344 !SCM_BIGSIGN (address)\
345 && (SCM_BITSPERDIG\
346 * SCM_NUMDIGS (address) <= 128));\
347 }
348
349#ifdef HAVE_INET_PTON
350SCM_DEFINE (scm_inet_pton, "inet-pton", 2, 0, 0,
351 (SCM family, SCM address),
eefae538
GH
352 "Convert a string containing a printable network address to\n"
353 "an integer address. Note that unlike the C version of this\n"
354 "function,\n"
66c73b76 355 "the result is an integer with normal host byte ordering.\n"
eefae538 356 "@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g.,\n\n"
66c73b76 357 "@lisp\n"
dd85ce47
ML
358 "(inet-pton AF_INET \"127.0.0.1\") @result{} 2130706433\n"
359 "(inet-pton AF_INET6 \"::1\") @result{} 1\n"
66c73b76
GH
360 "@end lisp")
361#define FUNC_NAME s_scm_inet_pton
362{
363 int af;
364 char *src;
365 char dst[16];
366 int rv;
367
368 SCM_VALIDATE_INUM_COPY (1, family, af);
369 SCM_ASSERT_RANGE (1, family, af == AF_INET || af == AF_INET6);
370 SCM_VALIDATE_STRING_COPY (2, address, src);
371 rv = inet_pton (af, src, dst);
372 if (rv == -1)
373 SCM_SYSERROR;
374 else if (rv == 0)
375 SCM_MISC_ERROR ("Bad address", SCM_EOL);
376 if (af == AF_INET)
377 return scm_ulong2num (ntohl (*(uint32_t *) dst));
378 else
379 return ipv6_net_to_num ((char *) dst);
380}
381#undef FUNC_NAME
382#endif
383
384#ifdef HAVE_INET_NTOP
385SCM_DEFINE (scm_inet_ntop, "inet-ntop", 2, 0, 0,
386 (SCM family, SCM address),
eefae538 387 "Convert a network address into a printable string.\n"
66c73b76
GH
388 "Note that unlike the C version of this function,\n"
389 "the input is an integer with normal host byte ordering.\n"
eefae538 390 "@var{family} can be @code{AF_INET} or @code{AF_INET6}. E.g.,\n\n"
66c73b76 391 "@lisp\n"
dd85ce47 392 "(inet-ntop AF_INET 2130706433) @result{} \"127.0.0.1\"\n"
66c73b76
GH
393 "(inet-ntop AF_INET6 (- (expt 2 128) 1)) @result{}\n"
394 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\n"
395 "@end lisp")
396#define FUNC_NAME s_scm_inet_ntop
397{
398 int af;
399#ifdef INET6_ADDRSTRLEN
400 char dst[INET6_ADDRSTRLEN];
401#else
402 char dst[46];
403#endif
404 char addr6[16];
405
406 SCM_VALIDATE_INUM_COPY (1, family, af);
407 SCM_ASSERT_RANGE (1, family, af == AF_INET || af == AF_INET6);
408 if (af == AF_INET)
409 *(uint32_t *) addr6 = htonl (SCM_NUM2ULONG (2, address));
410 else
411 {
412 VALIDATE_INET6 (2, address);
413 ipv6_num_to_net (address, addr6);
414 }
415 if (inet_ntop (af, &addr6, dst, sizeof dst) == NULL)
416 SCM_SYSERROR;
417 return scm_makfrom0str (dst);
418}
419#undef FUNC_NAME
420#endif
421
a57a0b1e 422#endif /* HAVE_IPV6 */
eefae538 423
bc45012d 424SCM_SYMBOL (sym_socket, "socket");
82ddea4e 425
439006bf 426#define SCM_SOCK_FD_TO_PORT(fd) scm_fdes_to_port (fd, "r+0", sym_socket)
1bbd0b84 427
a1ec6916 428SCM_DEFINE (scm_socket, "socket", 3, 0, 0,
1bbd0b84 429 (SCM family, SCM style, SCM proto),
1e6808ea 430 "Return a new socket port of the type specified by @var{family},\n"
eefae538 431 "@var{style} and @var{proto}. All three parameters are\n"
3453619b
GH
432 "integers. Supported values for @var{family} are\n"
433 "@code{AF_UNIX}, @code{AF_INET} and @code{AF_INET6}.\n"
434 "Typical values for @var{style} are @code{SOCK_STREAM},\n"
eefae538
GH
435 "@code{SOCK_DGRAM} and @code{SOCK_RAW}.\n\n"
436 "@var{proto} can be obtained from a protocol name using\n"
1e6808ea 437 "@code{getprotobyname}. A value of zero specifies the default\n"
eefae538 438 "protocol, which is usually right.\n\n"
1e6808ea
MG
439 "A single socket port cannot by used for communication until it\n"
440 "has been connected to another socket.")
1bbd0b84 441#define FUNC_NAME s_scm_socket
0f2d19dd 442{
370312ae 443 int fd;
370312ae 444
439006bf
GH
445 SCM_VALIDATE_INUM (1, family);
446 SCM_VALIDATE_INUM (2, style);
447 SCM_VALIDATE_INUM (3, proto);
370312ae 448 fd = socket (SCM_INUM (family), SCM_INUM (style), SCM_INUM (proto));
439006bf
GH
449 if (fd == -1)
450 SCM_SYSERROR;
451 return SCM_SOCK_FD_TO_PORT (fd);
0f2d19dd 452}
1bbd0b84 453#undef FUNC_NAME
0f2d19dd 454
0e958795 455#ifdef HAVE_SOCKETPAIR
a1ec6916 456SCM_DEFINE (scm_socketpair, "socketpair", 3, 0, 0,
1bbd0b84 457 (SCM family, SCM style, SCM proto),
1e6808ea 458 "Return a pair of connected (but unnamed) socket ports of the\n"
eefae538 459 "type specified by @var{family}, @var{style} and @var{proto}.\n"
1e6808ea
MG
460 "Many systems support only socket pairs of the @code{AF_UNIX}\n"
461 "family. Zero is likely to be the only meaningful value for\n"
eefae538 462 "@var{proto}.")
1bbd0b84 463#define FUNC_NAME s_scm_socketpair
0f2d19dd 464{
370312ae
GH
465 int fam;
466 int fd[2];
370312ae 467
3b3b36dd
GB
468 SCM_VALIDATE_INUM (1,family);
469 SCM_VALIDATE_INUM (2,style);
470 SCM_VALIDATE_INUM (3,proto);
370312ae
GH
471
472 fam = SCM_INUM (family);
473
370312ae 474 if (socketpair (fam, SCM_INUM (style), SCM_INUM (proto), fd) == -1)
1bbd0b84 475 SCM_SYSERROR;
370312ae 476
439006bf 477 return scm_cons (SCM_SOCK_FD_TO_PORT (fd[0]), SCM_SOCK_FD_TO_PORT (fd[1]));
0f2d19dd 478}
1bbd0b84 479#undef FUNC_NAME
0e958795 480#endif
0f2d19dd 481
a1ec6916 482SCM_DEFINE (scm_getsockopt, "getsockopt", 3, 0, 0,
1bbd0b84 483 (SCM sock, SCM level, SCM optname),
1e6808ea 484 "Return the value of a particular socket option for the socket\n"
eefae538 485 "port @var{sock}. @var{level} is an integer code for type of\n"
1e6808ea
MG
486 "option being requested, e.g., @code{SOL_SOCKET} for\n"
487 "socket-level options. @var{optname} is an integer code for the\n"
488 "option required and should be specified using one of the\n"
eefae538 489 "symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc.\n\n"
1e6808ea
MG
490 "The returned value is typically an integer but @code{SO_LINGER}\n"
491 "returns a pair of integers.")
1bbd0b84 492#define FUNC_NAME s_scm_getsockopt
0f2d19dd 493{
370312ae 494 int fd;
439006bf 495 /* size of optval is the largest supported option. */
370312ae
GH
496#ifdef HAVE_STRUCT_LINGER
497 char optval[sizeof (struct linger)];
439006bf 498 int optlen = sizeof (struct linger);
370312ae 499#else
1be6b49c
ML
500 char optval[sizeof (size_t)];
501 int optlen = sizeof (size_t);
370312ae
GH
502#endif
503 int ilevel;
504 int ioptname;
0f2d19dd 505
78446828 506 sock = SCM_COERCE_OUTPORT (sock);
2cf6d014
MD
507 SCM_VALIDATE_OPFPORT (1, sock);
508 SCM_VALIDATE_INUM_COPY (2, level, ilevel);
509 SCM_VALIDATE_INUM_COPY (3, optname, ioptname);
0f2d19dd 510
ee149d03 511 fd = SCM_FPORT_FDES (sock);
370312ae 512 if (getsockopt (fd, ilevel, ioptname, (void *) optval, &optlen) == -1)
1bbd0b84 513 SCM_SYSERROR;
1cc91f1b 514
439006bf 515 if (ilevel == SOL_SOCKET)
0f2d19dd 516 {
439006bf
GH
517#ifdef SO_LINGER
518 if (ioptname == SO_LINGER)
519 {
370312ae 520#ifdef HAVE_STRUCT_LINGER
439006bf
GH
521 struct linger *ling = (struct linger *) optval;
522
523 return scm_cons (scm_long2num (ling->l_onoff),
524 scm_long2num (ling->l_linger));
370312ae 525#else
439006bf
GH
526 return scm_cons (scm_long2num (*(int *) optval)
527 SCM_MAKINUM (0));
0f2d19dd 528#endif
439006bf
GH
529 }
530 else
370312ae 531#endif
439006bf 532 if (0
370312ae 533#ifdef SO_SNDBUF
439006bf 534 || ioptname == SO_SNDBUF
370312ae
GH
535#endif
536#ifdef SO_RCVBUF
439006bf 537 || ioptname == SO_RCVBUF
370312ae 538#endif
439006bf
GH
539 )
540 {
1be6b49c 541 return scm_long2num (*(size_t *) optval);
439006bf
GH
542 }
543 }
544 return scm_long2num (*(int *) optval);
0f2d19dd 545}
1bbd0b84 546#undef FUNC_NAME
0f2d19dd 547
a1ec6916 548SCM_DEFINE (scm_setsockopt, "setsockopt", 4, 0, 0,
1bbd0b84 549 (SCM sock, SCM level, SCM optname, SCM value),
eefae538
GH
550 "Set the value of a particular socket option for the socket\n"
551 "port @var{sock}. @var{level} is an integer code for type of option\n"
b380b885
MD
552 "being set, e.g., @code{SOL_SOCKET} for socket-level options.\n"
553 "@var{optname} is an\n"
554 "integer code for the option to set and should be specified using one of\n"
555 "the symbols @code{SO_DEBUG}, @code{SO_REUSEADDR} etc.\n"
556 "@var{value} is the value to which the option should be set. For\n"
557 "most options this must be an integer, but for @code{SO_LINGER} it must\n"
558 "be a pair.\n\n"
559 "The return value is unspecified.")
1bbd0b84 560#define FUNC_NAME s_scm_setsockopt
0f2d19dd 561{
370312ae 562 int fd;
439006bf
GH
563 int optlen = -1;
564 /* size of optval is the largest supported option. */
370312ae 565#ifdef HAVE_STRUCT_LINGER
439006bf 566 char optval[sizeof (struct linger)];
370312ae 567#else
1be6b49c 568 char optval[sizeof (size_t)];
370312ae
GH
569#endif
570 int ilevel, ioptname;
439006bf 571
78446828 572 sock = SCM_COERCE_OUTPORT (sock);
439006bf
GH
573
574 SCM_VALIDATE_OPFPORT (1, sock);
575 SCM_VALIDATE_INUM_COPY (2, level, ilevel);
576 SCM_VALIDATE_INUM_COPY (3, optname, ioptname);
577
ee149d03 578 fd = SCM_FPORT_FDES (sock);
439006bf
GH
579
580 if (ilevel == SOL_SOCKET)
370312ae 581 {
439006bf
GH
582#ifdef SO_LINGER
583 if (ioptname == SO_LINGER)
584 {
370312ae 585#ifdef HAVE_STRUCT_LINGER
439006bf
GH
586 struct linger ling;
587 long lv;
588
589 SCM_ASSERT (SCM_CONSP (value), value, SCM_ARG4, FUNC_NAME);
590 lv = SCM_NUM2LONG (4, SCM_CAR (value));
591 ling.l_onoff = (int) lv;
592 SCM_ASSERT_RANGE (SCM_ARG4, value, ling.l_onoff == lv);
593 lv = SCM_NUM2LONG (4, SCM_CDR (value));
594 ling.l_linger = (int) lv;
595 SCM_ASSERT_RANGE (SCM_ARG4, value, ling.l_linger == lv);
596 optlen = (int) sizeof (struct linger);
597 memcpy (optval, (void *) &ling, optlen);
370312ae 598#else
439006bf
GH
599 int ling;
600 long lv;
601
602 SCM_ASSERT (SCM_CONSP (value), value, SCM_ARG4, FUNC_NAME);
603 /* timeout is ignored, but may as well validate it. */
604 lv = SCM_NUM2LONG (4, SCM_CDR (value));
605 ling = (int) lv;
606 SCM_ASSERT_RANGE (SCM_ARG4, value, ling == lv);
607 lv = SCM_NUM2LONG (4, SCM_CAR (value));
608 ling = (int) lv;
609 SCM_ASSERT_RANGE (SCM_ARG4, value, ling == lv);
610 optlen = (int) sizeof (int);
611 (*(int *) optval) = ling;
612#endif
613 }
614 else
615#endif
616 if (0
370312ae 617#ifdef SO_SNDBUF
439006bf 618 || ioptname == SO_SNDBUF
370312ae
GH
619#endif
620#ifdef SO_RCVBUF
439006bf 621 || ioptname == SO_RCVBUF
370312ae 622#endif
439006bf
GH
623 )
624 {
625 long lv = SCM_NUM2LONG (4, value);
626
1be6b49c
ML
627 optlen = (int) sizeof (size_t);
628 (*(size_t *) optval) = (size_t) lv;
439006bf
GH
629 }
630 }
631 if (optlen == -1)
0f2d19dd 632 {
439006bf
GH
633 /* Most options take an int. */
634 long lv = SCM_NUM2LONG (4, value);
635 int val = (int) lv;
636
637 SCM_ASSERT_RANGE (SCM_ARG4, value, val == lv);
370312ae 638 optlen = (int) sizeof (int);
439006bf 639 (*(int *) optval) = val;
0f2d19dd 640 }
370312ae 641 if (setsockopt (fd, ilevel, ioptname, (void *) optval, optlen) == -1)
1bbd0b84 642 SCM_SYSERROR;
370312ae 643 return SCM_UNSPECIFIED;
0f2d19dd 644}
1bbd0b84 645#undef FUNC_NAME
0f2d19dd 646
a1ec6916 647SCM_DEFINE (scm_shutdown, "shutdown", 2, 0, 0,
1bbd0b84 648 (SCM sock, SCM how),
b380b885
MD
649 "Sockets can be closed simply by using @code{close-port}. The\n"
650 "@code{shutdown} procedure allows reception or tranmission on a\n"
651 "connection to be shut down individually, according to the parameter\n"
652 "@var{how}:\n\n"
653 "@table @asis\n"
654 "@item 0\n"
655 "Stop receiving data for this socket. If further data arrives, reject it.\n"
656 "@item 1\n"
657 "Stop trying to transmit data from this socket. Discard any\n"
658 "data waiting to be sent. Stop looking for acknowledgement of\n"
659 "data already sent; don't retransmit it if it is lost.\n"
660 "@item 2\n"
661 "Stop both reception and transmission.\n"
662 "@end table\n\n"
663 "The return value is unspecified.")
1bbd0b84 664#define FUNC_NAME s_scm_shutdown
0f2d19dd 665{
370312ae 666 int fd;
78446828 667 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd
GB
668 SCM_VALIDATE_OPFPORT (1,sock);
669 SCM_VALIDATE_INUM (2,how);
1bbd0b84 670 SCM_ASSERT_RANGE(2,how,0 <= SCM_INUM (how) && 2 >= SCM_INUM (how));
ee149d03 671 fd = SCM_FPORT_FDES (sock);
370312ae 672 if (shutdown (fd, SCM_INUM (how)) == -1)
1bbd0b84 673 SCM_SYSERROR;
370312ae
GH
674 return SCM_UNSPECIFIED;
675}
1bbd0b84 676#undef FUNC_NAME
0f2d19dd 677
370312ae
GH
678/* convert fam/address/args into a sockaddr of the appropriate type.
679 args is modified by removing the arguments actually used.
680 which_arg and proc are used when reporting errors:
681 which_arg is the position of address in the original argument list.
682 proc is the name of the original procedure.
683 size returns the size of the structure allocated. */
684
370312ae 685static struct sockaddr *
439006bf
GH
686scm_fill_sockaddr (int fam, SCM address, SCM *args, int which_arg,
687 const char *proc, int *size)
3453619b 688#define FUNC_NAME proc
370312ae
GH
689{
690 switch (fam)
0f2d19dd 691 {
370312ae
GH
692 case AF_INET:
693 {
370312ae 694 struct sockaddr_in *soka;
3453619b
GH
695 unsigned long addr;
696 int port;
370312ae 697
3453619b
GH
698 SCM_VALIDATE_ULONG_COPY (which_arg, address, addr);
699 SCM_VALIDATE_CONS (which_arg + 1, *args);
700 SCM_VALIDATE_INUM_COPY (which_arg + 1, SCM_CAR (*args), port);
701 *args = SCM_CDR (*args);
439006bf
GH
702 soka = (struct sockaddr_in *) malloc (sizeof (struct sockaddr_in));
703 if (!soka)
704 scm_memory_error (proc);
3453619b
GH
705 /* 4.4BSD-style interface includes sin_len member and defines SIN_LEN,
706 4.3BSD does not. */
707#ifdef SIN_LEN
708 soka->sin_len = sizeof (struct sockaddr_in);
709#endif
370312ae 710 soka->sin_family = AF_INET;
3453619b
GH
711 soka->sin_addr.s_addr = htonl (addr);
712 soka->sin_port = htons (port);
370312ae
GH
713 *size = sizeof (struct sockaddr_in);
714 return (struct sockaddr *) soka;
715 }
a57a0b1e 716#ifdef HAVE_IPV6
3453619b
GH
717 case AF_INET6:
718 {
719 /* see RFC2553. */
720 int port;
721 struct sockaddr_in6 *soka;
722 unsigned long flowinfo = 0;
723 unsigned long scope_id = 0;
724
66c73b76 725 VALIDATE_INET6 (which_arg, address);
3453619b
GH
726 SCM_VALIDATE_CONS (which_arg + 1, *args);
727 SCM_VALIDATE_INUM_COPY (which_arg + 1, SCM_CAR (*args), port);
728 *args = SCM_CDR (*args);
729 if (SCM_CONSP (*args))
730 {
731 SCM_VALIDATE_ULONG_COPY (which_arg + 2, SCM_CAR (*args), flowinfo);
732 *args = SCM_CDR (*args);
733 if (SCM_CONSP (*args))
734 {
735 SCM_VALIDATE_ULONG_COPY (which_arg + 3, SCM_CAR (*args),
736 scope_id);
737 *args = SCM_CDR (*args);
738 }
739 }
740 soka = (struct sockaddr_in6 *) malloc (sizeof (struct sockaddr_in6));
741 if (!soka)
742 scm_memory_error (proc);
743#ifdef SIN_LEN6
744 soka->sin6_len = sizeof (struct sockaddr_in6);
745#endif
746 soka->sin6_family = AF_INET6;
66c73b76 747 ipv6_num_to_net (address, soka->sin6_addr.s6_addr);
5a525b84 748 soka->sin6_port = htons (port);
3453619b 749 soka->sin6_flowinfo = flowinfo;
5a525b84 750#ifdef HAVE_SIN6_SCOPE_ID
3453619b 751 soka->sin6_scope_id = scope_id;
5a525b84 752#endif
3453619b
GH
753 *size = sizeof (struct sockaddr_in6);
754 return (struct sockaddr *) soka;
755 }
756#endif
1ba8c23a 757#ifdef HAVE_UNIX_DOMAIN_SOCKETS
370312ae
GH
758 case AF_UNIX:
759 {
760 struct sockaddr_un *soka;
439006bf 761 int addr_size;
370312ae 762
a6d9e5ab 763 SCM_ASSERT (SCM_STRINGP (address), address, which_arg, proc);
439006bf
GH
764 /* the static buffer size in sockaddr_un seems to be arbitrary
765 and not necessarily a hard limit. e.g., the glibc manual
766 suggests it may be possible to declare it size 0. let's
767 ignore it. if the O/S doesn't like the size it will cause
768 connect/bind etc., to fail. sun_path is always the last
769 member of the structure. */
770 addr_size = sizeof (struct sockaddr_un)
771 + max (0, SCM_STRING_LENGTH (address) + 1 - (sizeof soka->sun_path));
772 soka = (struct sockaddr_un *) malloc (addr_size);
773 if (!soka)
774 scm_memory_error (proc);
775 memset (soka, 0, addr_size); /* for sun_len: see sin_len above. */
776 soka->sun_family = AF_UNIX;
34f0f2b8 777 memcpy (soka->sun_path, SCM_STRING_CHARS (address),
439006bf
GH
778 SCM_STRING_LENGTH (address));
779 *size = SUN_LEN (soka);
370312ae
GH
780 return (struct sockaddr *) soka;
781 }
0e958795 782#endif
370312ae
GH
783 default:
784 scm_out_of_range (proc, SCM_MAKINUM (fam));
0f2d19dd 785 }
0f2d19dd 786}
3453619b 787#undef FUNC_NAME
370312ae 788
a1ec6916 789SCM_DEFINE (scm_connect, "connect", 3, 0, 1,
1bbd0b84 790 (SCM sock, SCM fam, SCM address, SCM args),
eefae538 791 "Initiate a connection from a socket using a specified address\n"
3453619b
GH
792 "family to the address\n"
793 "specified by @var{address} and possibly @var{args}.\n"
794 "The format required for @var{address}\n"
795 "and @var{args} depends on the family of the socket.\n\n"
b380b885 796 "For a socket of family @code{AF_UNIX},\n"
3453619b 797 "only @var{address} is specified and must be a string with the\n"
b380b885
MD
798 "filename where the socket is to be created.\n\n"
799 "For a socket of family @code{AF_INET},\n"
3453619b
GH
800 "@var{address} must be an integer IPv4 host address and\n"
801 "@var{args} must be a single integer port number.\n\n"
802 "For a socket of family @code{AF_INET6},\n"
803 "@var{address} must be an integer IPv6 host address and\n"
804 "@var{args} may be up to three integers:\n"
805 "port [flowinfo] [scope_id],\n"
806 "where flowinfo and scope_id default to zero.\n\n"
b380b885 807 "The return value is unspecified.")
1bbd0b84 808#define FUNC_NAME s_scm_connect
0f2d19dd 809{
370312ae
GH
810 int fd;
811 struct sockaddr *soka;
439006bf 812 int size;
0f2d19dd 813
78446828 814 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd
GB
815 SCM_VALIDATE_OPFPORT (1,sock);
816 SCM_VALIDATE_INUM (2,fam);
ee149d03 817 fd = SCM_FPORT_FDES (sock);
439006bf
GH
818 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args, 3, FUNC_NAME,
819 &size);
370312ae 820 if (connect (fd, soka, size) == -1)
439006bf
GH
821 {
822 int save_errno = errno;
823
824 free (soka);
825 errno = save_errno;
826 SCM_SYSERROR;
827 }
828 free (soka);
370312ae 829 return SCM_UNSPECIFIED;
0f2d19dd 830}
1bbd0b84 831#undef FUNC_NAME
0f2d19dd 832
a1ec6916 833SCM_DEFINE (scm_bind, "bind", 3, 0, 1,
1bbd0b84 834 (SCM sock, SCM fam, SCM address, SCM args),
eefae538 835 "Assign an address to the socket port @var{sock}.\n"
b380b885
MD
836 "Generally this only needs to be done for server sockets,\n"
837 "so they know where to look for incoming connections. A socket\n"
838 "without an address will be assigned one automatically when it\n"
839 "starts communicating.\n\n"
eefae538
GH
840 "The format of @var{address} and @var{args} depends\n"
841 "on the family of the socket.\n\n"
b380b885 842 "For a socket of family @code{AF_UNIX}, only @var{address}\n"
eefae538
GH
843 "is specified and must be a string with the filename where\n"
844 "the socket is to be created.\n\n"
845 "For a socket of family @code{AF_INET}, @var{address}\n"
846 "must be an integer IPv4 address and @var{args}\n"
847 "must be a single integer port number.\n\n"
848 "The values of the following variables can also be used for\n"
849 "@var{address}:\n\n"
b380b885
MD
850 "@defvar INADDR_ANY\n"
851 "Allow connections from any address.\n"
852 "@end defvar\n\n"
853 "@defvar INADDR_LOOPBACK\n"
854 "The address of the local host using the loopback device.\n"
855 "@end defvar\n\n"
856 "@defvar INADDR_BROADCAST\n"
857 "The broadcast address on the local network.\n"
858 "@end defvar\n\n"
859 "@defvar INADDR_NONE\n"
860 "No address.\n"
861 "@end defvar\n\n"
eefae538
GH
862 "For a socket of family @code{AF_INET6}, @var{address}\n"
863 "must be an integer IPv6 address and @var{args}\n"
864 "may be up to three integers:\n"
865 "port [flowinfo] [scope_id],\n"
866 "where flowinfo and scope_id default to zero.\n\n"
b380b885 867 "The return value is unspecified.")
1bbd0b84 868#define FUNC_NAME s_scm_bind
370312ae 869{
370312ae 870 struct sockaddr *soka;
439006bf 871 int size;
370312ae
GH
872 int fd;
873
78446828 874 sock = SCM_COERCE_OUTPORT (sock);
439006bf
GH
875 SCM_VALIDATE_OPFPORT (1, sock);
876 SCM_VALIDATE_INUM (2, fam);
877 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args, 3, FUNC_NAME,
878 &size);
ee149d03 879 fd = SCM_FPORT_FDES (sock);
439006bf
GH
880 if (bind (fd, soka, size) == -1)
881 {
882 int save_errno = errno;
883
884 free (soka);
885 errno = save_errno;
1bbd0b84 886 SCM_SYSERROR;
439006bf
GH
887 }
888 free (soka);
370312ae
GH
889 return SCM_UNSPECIFIED;
890}
1bbd0b84 891#undef FUNC_NAME
370312ae 892
a1ec6916 893SCM_DEFINE (scm_listen, "listen", 2, 0, 0,
1bbd0b84 894 (SCM sock, SCM backlog),
eefae538 895 "Enable @var{sock} to accept connection\n"
b380b885
MD
896 "requests. @var{backlog} is an integer specifying\n"
897 "the maximum length of the queue for pending connections.\n"
eefae538
GH
898 "If the queue fills, new clients will fail to connect until\n"
899 "the server calls @code{accept} to accept a connection from\n"
900 "the queue.\n\n"
b380b885 901 "The return value is unspecified.")
1bbd0b84 902#define FUNC_NAME s_scm_listen
370312ae
GH
903{
904 int fd;
78446828 905 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd
GB
906 SCM_VALIDATE_OPFPORT (1,sock);
907 SCM_VALIDATE_INUM (2,backlog);
ee149d03 908 fd = SCM_FPORT_FDES (sock);
370312ae 909 if (listen (fd, SCM_INUM (backlog)) == -1)
1bbd0b84 910 SCM_SYSERROR;
370312ae
GH
911 return SCM_UNSPECIFIED;
912}
1bbd0b84 913#undef FUNC_NAME
370312ae
GH
914
915/* Put the components of a sockaddr into a new SCM vector. */
370312ae 916static SCM
e1368a8d 917scm_addr_vector (const struct sockaddr *address, const char *proc)
0f2d19dd 918{
370312ae
GH
919 short int fam = address->sa_family;
920 SCM result;
921 SCM *ve;
439006bf 922
5a525b84 923 switch (fam)
0f2d19dd 924 {
5a525b84
GH
925 case AF_INET:
926 {
e1368a8d 927 const struct sockaddr_in *nad = (struct sockaddr_in *) address;
439006bf 928
5a525b84
GH
929 result = scm_c_make_vector (3, SCM_UNSPECIFIED);
930 ve = SCM_VELTS (result);
931 ve[0] = scm_ulong2num ((unsigned long) fam);
932 ve[1] = scm_ulong2num (ntohl (nad->sin_addr.s_addr));
933 ve[2] = scm_ulong2num ((unsigned long) ntohs (nad->sin_port));
934 }
935 break;
a57a0b1e 936#ifdef HAVE_IPV6
5a525b84
GH
937 case AF_INET6:
938 {
e1368a8d 939 const struct sockaddr_in6 *nad = (struct sockaddr_in6 *) address;
5a525b84
GH
940
941 result = scm_c_make_vector (5, SCM_UNSPECIFIED);
942 ve = SCM_VELTS (result);
943 ve[0] = scm_ulong2num ((unsigned long) fam);
66c73b76 944 ve[1] = ipv6_net_to_num (nad->sin6_addr.s6_addr);
5a525b84
GH
945 ve[2] = scm_ulong2num ((unsigned long) ntohs (nad->sin6_port));
946 ve[3] = scm_ulong2num ((unsigned long) nad->sin6_flowinfo);
947#ifdef HAVE_SIN6_SCOPE_ID
948 ve[4] = scm_ulong2num ((unsigned long) nad->sin6_scope_id);
949#else
950 ve[4] = SCM_INUM0;
0e958795 951#endif
5a525b84
GH
952 }
953 break;
954#endif
955#ifdef HAVE_UNIX_DOMAIN_SOCKETS
956 case AF_UNIX:
957 {
e1368a8d 958 const struct sockaddr_un *nad = (struct sockaddr_un *) address;
439006bf 959
5a525b84
GH
960 result = scm_c_make_vector (2, SCM_UNSPECIFIED);
961 ve = SCM_VELTS (result);
962 ve[0] = scm_ulong2num ((unsigned long) fam);
36284627 963 ve[1] = scm_mem2string (nad->sun_path, strlen (nad->sun_path));
5a525b84
GH
964 }
965 break;
966#endif
967 default:
968 scm_misc_error (proc, "Unrecognised address family: ~A",
969 SCM_LIST1 (SCM_MAKINUM (fam)));
0f2d19dd 970 }
370312ae
GH
971 return result;
972}
973
439006bf
GH
974/* calculate the size of a buffer large enough to hold any supported
975 sockaddr type. if the buffer isn't large enough, certain system
976 calls will return a truncated address. */
370312ae 977
439006bf
GH
978#if defined (HAVE_UNIX_DOMAIN_SOCKETS)
979#define MAX_SIZE_UN sizeof (struct sockaddr_un)
0e958795 980#else
439006bf 981#define MAX_SIZE_UN 0
0e958795 982#endif
439006bf 983
a57a0b1e 984#if defined (HAVE_IPV6)
5a525b84
GH
985#define MAX_SIZE_IN6 sizeof (struct sockaddr_in6)
986#else
987#define MAX_SIZE_IN6 0
988#endif
989
990#define MAX_ADDR_SIZE max (max (sizeof (struct sockaddr_in), MAX_SIZE_IN6),\
991 MAX_SIZE_UN)
0f2d19dd 992
a1ec6916 993SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
1bbd0b84 994 (SCM sock),
eefae538
GH
995 "Accept a connection on a bound, listening socket.\n"
996 "If there\n"
997 "are no pending connections in the queue, wait until\n"
998 "one is available unless the non-blocking option has been\n"
999 "set on the socket.\n\n"
b380b885 1000 "The return value is a\n"
eefae538
GH
1001 "pair in which the @emph{car} is a new socket port for the\n"
1002 "connection and\n"
1003 "the @emph{cdr} is an object with address information about the\n"
1004 "client which initiated the connection.\n\n"
1005 "@var{sock} does not become part of the\n"
b380b885 1006 "connection and will continue to accept new requests.")
1bbd0b84 1007#define FUNC_NAME s_scm_accept
0f2d19dd 1008{
370312ae
GH
1009 int fd;
1010 int newfd;
1011 SCM address;
1012 SCM newsock;
439006bf
GH
1013 int addr_size = MAX_ADDR_SIZE;
1014 char max_addr[MAX_ADDR_SIZE];
1015 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 1016
78446828 1017 sock = SCM_COERCE_OUTPORT (sock);
439006bf 1018 SCM_VALIDATE_OPFPORT (1, sock);
ee149d03 1019 fd = SCM_FPORT_FDES (sock);
439006bf
GH
1020 newfd = accept (fd, addr, &addr_size);
1021 if (newfd == -1)
1022 SCM_SYSERROR;
1023 newsock = SCM_SOCK_FD_TO_PORT (newfd);
eefae538 1024 address = scm_addr_vector (addr, FUNC_NAME);
370312ae 1025 return scm_cons (newsock, address);
0f2d19dd 1026}
1bbd0b84 1027#undef FUNC_NAME
0f2d19dd 1028
a1ec6916 1029SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
1bbd0b84 1030 (SCM sock),
eefae538 1031 "Return the address of @var{sock}, in the same form as the\n"
1e6808ea
MG
1032 "object returned by @code{accept}. On many systems the address\n"
1033 "of a socket in the @code{AF_FILE} namespace cannot be read.")
1bbd0b84 1034#define FUNC_NAME s_scm_getsockname
0f2d19dd 1035{
370312ae 1036 int fd;
439006bf
GH
1037 int addr_size = MAX_ADDR_SIZE;
1038 char max_addr[MAX_ADDR_SIZE];
1039 struct sockaddr *addr = (struct sockaddr *) max_addr;
1040
78446828 1041 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd 1042 SCM_VALIDATE_OPFPORT (1,sock);
ee149d03 1043 fd = SCM_FPORT_FDES (sock);
439006bf 1044 if (getsockname (fd, addr, &addr_size) == -1)
1bbd0b84 1045 SCM_SYSERROR;
eefae538 1046 return scm_addr_vector (addr, FUNC_NAME);
0f2d19dd 1047}
1bbd0b84 1048#undef FUNC_NAME
0f2d19dd 1049
a1ec6916 1050SCM_DEFINE (scm_getpeername, "getpeername", 1, 0, 0,
1bbd0b84 1051 (SCM sock),
eefae538 1052 "Return the address that @var{sock}\n"
1e6808ea
MG
1053 "is connected to, in the same form as the object returned by\n"
1054 "@code{accept}. On many systems the address of a socket in the\n"
1055 "@code{AF_FILE} namespace cannot be read.")
1bbd0b84 1056#define FUNC_NAME s_scm_getpeername
0f2d19dd 1057{
370312ae 1058 int fd;
439006bf
GH
1059 int addr_size = MAX_ADDR_SIZE;
1060 char max_addr[MAX_ADDR_SIZE];
1061 struct sockaddr *addr = (struct sockaddr *) max_addr;
1062
78446828 1063 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd 1064 SCM_VALIDATE_OPFPORT (1,sock);
ee149d03 1065 fd = SCM_FPORT_FDES (sock);
439006bf 1066 if (getpeername (fd, addr, &addr_size) == -1)
1bbd0b84 1067 SCM_SYSERROR;
eefae538 1068 return scm_addr_vector (addr, FUNC_NAME);
0f2d19dd 1069}
1bbd0b84 1070#undef FUNC_NAME
0f2d19dd 1071
a1ec6916 1072SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
1bbd0b84 1073 (SCM sock, SCM buf, SCM flags),
eefae538
GH
1074 "Receive data from a socket port.\n"
1075 "@var{sock} must already\n"
b380b885
MD
1076 "be bound to the address from which data is to be received.\n"
1077 "@var{buf} is a string into which\n"
eefae538
GH
1078 "the data will be written. The size of @var{buf} limits\n"
1079 "the amount of\n"
b380b885 1080 "data which can be received: in the case of packet\n"
eefae538
GH
1081 "protocols, if a packet larger than this limit is encountered\n"
1082 "then some data\n"
b380b885
MD
1083 "will be irrevocably lost.\n\n"
1084 "The optional @var{flags} argument is a value or\n"
1085 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1086 "The value returned is the number of bytes read from the\n"
1087 "socket.\n\n"
1088 "Note that the data is read directly from the socket file\n"
1089 "descriptor:\n"
09831f94 1090 "any unread buffered port data is ignored.")
1bbd0b84 1091#define FUNC_NAME s_scm_recv
0f2d19dd 1092{
370312ae
GH
1093 int rv;
1094 int fd;
1095 int flg;
370312ae 1096
3b3b36dd
GB
1097 SCM_VALIDATE_OPFPORT (1,sock);
1098 SCM_VALIDATE_STRING (2,buf);
1099 SCM_VALIDATE_INUM_DEF_COPY (3,flags,0,flg);
ee149d03 1100 fd = SCM_FPORT_FDES (sock);
370312ae 1101
bfa974f0 1102 SCM_SYSCALL (rv = recv (fd, SCM_STRING_CHARS (buf), SCM_STRING_LENGTH (buf), flg));
370312ae 1103 if (rv == -1)
1bbd0b84 1104 SCM_SYSERROR;
370312ae 1105
1146b6cd 1106 return SCM_MAKINUM (rv);
370312ae 1107}
1bbd0b84 1108#undef FUNC_NAME
370312ae 1109
a1ec6916 1110SCM_DEFINE (scm_send, "send", 2, 1, 0,
1bbd0b84 1111 (SCM sock, SCM message, SCM flags),
eefae538
GH
1112 "Transmit the string @var{message} on a socket port @var{sock}.\n"
1113 "@var{sock} must already be bound to a destination address. The\n"
1114 "value returned is the number of bytes transmitted --\n"
1115 "it's possible for\n"
1116 "this to be less than the length of @var{message}\n"
1117 "if the socket is\n"
1118 "set to be non-blocking. The optional @var{flags} argument\n"
1119 "is a value or\n"
b380b885 1120 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1121 "Note that the data is written directly to the socket\n"
1122 "file descriptor:\n"
b380b885 1123 "any unflushed buffered port data is ignored.")
1bbd0b84 1124#define FUNC_NAME s_scm_send
370312ae
GH
1125{
1126 int rv;
1127 int fd;
1128 int flg;
1129
78446828 1130 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd 1131 SCM_VALIDATE_OPFPORT (1,sock);
a6d9e5ab 1132 SCM_VALIDATE_STRING (2, message);
3b3b36dd 1133 SCM_VALIDATE_INUM_DEF_COPY (3,flags,0,flg);
ee149d03 1134 fd = SCM_FPORT_FDES (sock);
370312ae 1135
34f0f2b8 1136 SCM_SYSCALL (rv = send (fd, SCM_STRING_CHARS (message), SCM_STRING_LENGTH (message), flg));
370312ae 1137 if (rv == -1)
1bbd0b84 1138 SCM_SYSERROR;
370312ae
GH
1139 return SCM_MAKINUM (rv);
1140}
1bbd0b84 1141#undef FUNC_NAME
370312ae 1142
a1ec6916 1143SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
60d02d09 1144 (SCM sock, SCM str, SCM flags, SCM start, SCM end),
eefae538 1145 "Return data from the socket port @var{sock} and also\n"
1e6808ea 1146 "information about where the data was received from.\n"
eefae538 1147 "@var{sock} must already be bound to the address from which\n"
1e6808ea
MG
1148 "data is to be received. @code{str}, is a string into which the\n"
1149 "data will be written. The size of @var{str} limits the amount\n"
1150 "of data which can be received: in the case of packet protocols,\n"
1151 "if a packet larger than this limit is encountered then some\n"
eefae538 1152 "data will be irrevocably lost.\n\n"
1e6808ea 1153 "The optional @var{flags} argument is a value or bitwise OR of\n"
eefae538 1154 "@code{MSG_OOB}, @code{MSG_PEEK}, @code{MSG_DONTROUTE} etc.\n\n"
1e6808ea
MG
1155 "The value returned is a pair: the @emph{car} is the number of\n"
1156 "bytes read from the socket and the @emph{cdr} an address object\n"
eefae538
GH
1157 "in the same form as returned by @code{accept}. The address\n"
1158 "will given as @code{#f} if not available, as is usually the\n"
1159 "case for stream sockets.\n\n"
1e6808ea 1160 "The @var{start} and @var{end} arguments specify a substring of\n"
eefae538 1161 "@var{str} to which the data should be written.\n\n"
1e6808ea
MG
1162 "Note that the data is read directly from the socket file\n"
1163 "descriptor: any unread buffered port data is ignored.")
1bbd0b84 1164#define FUNC_NAME s_scm_recvfrom
370312ae
GH
1165{
1166 int rv;
1167 int fd;
1168 int flg;
60d02d09
GH
1169 char *buf;
1170 int offset;
1146b6cd 1171 int cend;
370312ae 1172 SCM address;
439006bf
GH
1173 int addr_size = MAX_ADDR_SIZE;
1174 char max_addr[MAX_ADDR_SIZE];
1175 struct sockaddr *addr = (struct sockaddr *) max_addr;
370312ae 1176
3b3b36dd 1177 SCM_VALIDATE_OPFPORT (1,sock);
60d02d09
GH
1178 fd = SCM_FPORT_FDES (sock);
1179 SCM_VALIDATE_SUBSTRING_SPEC_COPY (2, str, buf, 4, start, offset,
1180 5, end, cend);
1146b6cd
GH
1181 if (SCM_UNBNDP (flags))
1182 flg = 0;
370312ae 1183 else
60d02d09 1184 SCM_VALIDATE_ULONG_COPY (3, flags, flg);
370312ae 1185
97d0e20b
GH
1186 /* recvfrom will not necessarily return an address. usually nothing
1187 is returned for stream sockets. */
439006bf 1188 addr->sa_family = AF_UNSPEC;
60d02d09 1189 SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
1146b6cd 1190 cend - offset, flg,
439006bf 1191 addr, &addr_size));
370312ae 1192 if (rv == -1)
1bbd0b84 1193 SCM_SYSERROR;
eefae538 1194 if (addr->sa_family != AF_UNSPEC)
439006bf 1195 address = scm_addr_vector (addr, FUNC_NAME);
370312ae
GH
1196 else
1197 address = SCM_BOOL_F;
1198
1146b6cd 1199 return scm_cons (SCM_MAKINUM (rv), address);
0f2d19dd 1200}
1bbd0b84 1201#undef FUNC_NAME
0f2d19dd 1202
a1ec6916 1203SCM_DEFINE (scm_sendto, "sendto", 4, 0, 1,
1bbd0b84 1204 (SCM sock, SCM message, SCM fam, SCM address, SCM args_and_flags),
eefae538
GH
1205 "Transmit the string @var{message} on the socket port\n"
1206 "@var{sock}. The\n"
1207 "destination address is specified using the @var{fam},\n"
1208 "@var{address} and\n"
1209 "@var{args_and_flags} arguments, in a similar way to the\n"
1210 "@code{connect} procedure. @var{args_and_flags} contains\n"
1211 "the usual connection arguments optionally followed by\n"
1212 "a flags argument, which is a value or\n"
b380b885 1213 "bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.\n\n"
eefae538
GH
1214 "The value returned is the number of bytes transmitted --\n"
1215 "it's possible for\n"
1216 "this to be less than the length of @var{message} if the\n"
1217 "socket is\n"
1218 "set to be non-blocking.\n"
1219 "Note that the data is written directly to the socket\n"
1220 "file descriptor:\n"
b380b885 1221 "any unflushed buffered port data is ignored.")
1bbd0b84 1222#define FUNC_NAME s_scm_sendto
370312ae
GH
1223{
1224 int rv;
1225 int fd;
1226 int flg;
1227 struct sockaddr *soka;
439006bf 1228 int size;
370312ae 1229
78446828 1230 sock = SCM_COERCE_OUTPORT (sock);
3b3b36dd 1231 SCM_VALIDATE_FPORT (1,sock);
a6d9e5ab 1232 SCM_VALIDATE_STRING (2, message);
3b3b36dd 1233 SCM_VALIDATE_INUM (3,fam);
ee149d03 1234 fd = SCM_FPORT_FDES (sock);
370312ae 1235 soka = scm_fill_sockaddr (SCM_INUM (fam), address, &args_and_flags, 4,
1bbd0b84 1236 FUNC_NAME, &size);
370312ae
GH
1237 if (SCM_NULLP (args_and_flags))
1238 flg = 0;
1239 else
1240 {
3b3b36dd 1241 SCM_VALIDATE_CONS (5,args_and_flags);
e4b265d8 1242 flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
370312ae 1243 }
439006bf
GH
1244 SCM_SYSCALL (rv = sendto (fd, SCM_STRING_CHARS (message),
1245 SCM_STRING_LENGTH (message),
ae2fa5bc 1246 flg, soka, size));
370312ae 1247 if (rv == -1)
439006bf
GH
1248 {
1249 int save_errno = errno;
1250 free (soka);
1251 errno = save_errno;
1252 SCM_SYSERROR;
1253 }
1254 free (soka);
370312ae
GH
1255 return SCM_MAKINUM (rv);
1256}
1bbd0b84 1257#undef FUNC_NAME
370312ae
GH
1258\f
1259
1260
1261void
0f2d19dd 1262scm_init_socket ()
0f2d19dd 1263{
370312ae
GH
1264 /* protocol families. */
1265#ifdef AF_UNSPEC
86d31dfe 1266 scm_c_define ("AF_UNSPEC", SCM_MAKINUM (AF_UNSPEC));
370312ae
GH
1267#endif
1268#ifdef AF_UNIX
86d31dfe 1269 scm_c_define ("AF_UNIX", SCM_MAKINUM (AF_UNIX));
370312ae
GH
1270#endif
1271#ifdef AF_INET
86d31dfe 1272 scm_c_define ("AF_INET", SCM_MAKINUM (AF_INET));
370312ae 1273#endif
3453619b 1274#ifdef AF_INET6
86d31dfe 1275 scm_c_define ("AF_INET6", SCM_MAKINUM (AF_INET6));
3453619b 1276#endif
370312ae
GH
1277
1278#ifdef PF_UNSPEC
86d31dfe 1279 scm_c_define ("PF_UNSPEC", SCM_MAKINUM (PF_UNSPEC));
370312ae
GH
1280#endif
1281#ifdef PF_UNIX
86d31dfe 1282 scm_c_define ("PF_UNIX", SCM_MAKINUM (PF_UNIX));
370312ae
GH
1283#endif
1284#ifdef PF_INET
86d31dfe 1285 scm_c_define ("PF_INET", SCM_MAKINUM (PF_INET));
370312ae 1286#endif
3453619b 1287#ifdef PF_INET6
86d31dfe 1288 scm_c_define ("PF_INET6", SCM_MAKINUM (PF_INET6));
3453619b 1289#endif
370312ae 1290
66c73b76
GH
1291 /* standard addresses. */
1292#ifdef INADDR_ANY
86d31dfe 1293 scm_c_define ("INADDR_ANY", scm_ulong2num (INADDR_ANY));
66c73b76
GH
1294#endif
1295#ifdef INADDR_BROADCAST
86d31dfe 1296 scm_c_define ("INADDR_BROADCAST", scm_ulong2num (INADDR_BROADCAST));
66c73b76
GH
1297#endif
1298#ifdef INADDR_NONE
86d31dfe 1299 scm_c_define ("INADDR_NONE", scm_ulong2num (INADDR_NONE));
66c73b76
GH
1300#endif
1301#ifdef INADDR_LOOPBACK
86d31dfe 1302 scm_c_define ("INADDR_LOOPBACK", scm_ulong2num (INADDR_LOOPBACK));
66c73b76
GH
1303#endif
1304
370312ae
GH
1305 /* socket types. */
1306#ifdef SOCK_STREAM
86d31dfe 1307 scm_c_define ("SOCK_STREAM", SCM_MAKINUM (SOCK_STREAM));
370312ae
GH
1308#endif
1309#ifdef SOCK_DGRAM
86d31dfe 1310 scm_c_define ("SOCK_DGRAM", SCM_MAKINUM (SOCK_DGRAM));
370312ae
GH
1311#endif
1312#ifdef SOCK_RAW
86d31dfe 1313 scm_c_define ("SOCK_RAW", SCM_MAKINUM (SOCK_RAW));
370312ae
GH
1314#endif
1315
1316 /* setsockopt level. */
1317#ifdef SOL_SOCKET
86d31dfe 1318 scm_c_define ("SOL_SOCKET", SCM_MAKINUM (SOL_SOCKET));
370312ae
GH
1319#endif
1320#ifdef SOL_IP
86d31dfe 1321 scm_c_define ("SOL_IP", SCM_MAKINUM (SOL_IP));
370312ae
GH
1322#endif
1323#ifdef SOL_TCP
86d31dfe 1324 scm_c_define ("SOL_TCP", SCM_MAKINUM (SOL_TCP));
370312ae
GH
1325#endif
1326#ifdef SOL_UDP
86d31dfe 1327 scm_c_define ("SOL_UDP", SCM_MAKINUM (SOL_UDP));
370312ae
GH
1328#endif
1329
1330 /* setsockopt names. */
1331#ifdef SO_DEBUG
86d31dfe 1332 scm_c_define ("SO_DEBUG", SCM_MAKINUM (SO_DEBUG));
370312ae
GH
1333#endif
1334#ifdef SO_REUSEADDR
86d31dfe 1335 scm_c_define ("SO_REUSEADDR", SCM_MAKINUM (SO_REUSEADDR));
370312ae
GH
1336#endif
1337#ifdef SO_STYLE
86d31dfe 1338 scm_c_define ("SO_STYLE", SCM_MAKINUM (SO_STYLE));
370312ae
GH
1339#endif
1340#ifdef SO_TYPE
86d31dfe 1341 scm_c_define ("SO_TYPE", SCM_MAKINUM (SO_TYPE));
370312ae
GH
1342#endif
1343#ifdef SO_ERROR
86d31dfe 1344 scm_c_define ("SO_ERROR", SCM_MAKINUM (SO_ERROR));
370312ae
GH
1345#endif
1346#ifdef SO_DONTROUTE
86d31dfe 1347 scm_c_define ("SO_DONTROUTE", SCM_MAKINUM (SO_DONTROUTE));
370312ae
GH
1348#endif
1349#ifdef SO_BROADCAST
86d31dfe 1350 scm_c_define ("SO_BROADCAST", SCM_MAKINUM (SO_BROADCAST));
370312ae
GH
1351#endif
1352#ifdef SO_SNDBUF
86d31dfe 1353 scm_c_define ("SO_SNDBUF", SCM_MAKINUM (SO_SNDBUF));
370312ae
GH
1354#endif
1355#ifdef SO_RCVBUF
86d31dfe 1356 scm_c_define ("SO_RCVBUF", SCM_MAKINUM (SO_RCVBUF));
370312ae
GH
1357#endif
1358#ifdef SO_KEEPALIVE
86d31dfe 1359 scm_c_define ("SO_KEEPALIVE", SCM_MAKINUM (SO_KEEPALIVE));
370312ae
GH
1360#endif
1361#ifdef SO_OOBINLINE
86d31dfe 1362 scm_c_define ("SO_OOBINLINE", SCM_MAKINUM (SO_OOBINLINE));
370312ae
GH
1363#endif
1364#ifdef SO_NO_CHECK
86d31dfe 1365 scm_c_define ("SO_NO_CHECK", SCM_MAKINUM (SO_NO_CHECK));
370312ae
GH
1366#endif
1367#ifdef SO_PRIORITY
86d31dfe 1368 scm_c_define ("SO_PRIORITY", SCM_MAKINUM (SO_PRIORITY));
370312ae
GH
1369#endif
1370#ifdef SO_LINGER
86d31dfe 1371 scm_c_define ("SO_LINGER", SCM_MAKINUM (SO_LINGER));
370312ae
GH
1372#endif
1373
1374 /* recv/send options. */
1375#ifdef MSG_OOB
86d31dfe 1376 scm_c_define ("MSG_OOB", SCM_MAKINUM (MSG_OOB));
370312ae
GH
1377#endif
1378#ifdef MSG_PEEK
86d31dfe 1379 scm_c_define ("MSG_PEEK", SCM_MAKINUM (MSG_PEEK));
370312ae
GH
1380#endif
1381#ifdef MSG_DONTROUTE
86d31dfe 1382 scm_c_define ("MSG_DONTROUTE", SCM_MAKINUM (MSG_DONTROUTE));
370312ae
GH
1383#endif
1384
0f2d19dd 1385 scm_add_feature ("socket");
370312ae 1386
8dc9439f 1387#ifndef SCM_MAGIC_SNARFER
a0599745 1388#include "libguile/socket.x"
8dc9439f 1389#endif
0f2d19dd
JB
1390}
1391
89e00824
ML
1392
1393/*
1394 Local Variables:
1395 c-file-style: "gnu"
1396 End:
1397*/