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