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