1 /* "net_db.c" network database support
2 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2006, 2009,
3 * 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 3 of
8 * the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 /* Written in 1994 by Aubrey Jaffer.
24 * Thanks to Hallvard.Tretteberg@si.sintef.no for inspiration and discussion.
25 * Rewritten by Gary Houston to be a closer interface to the C socket library.
26 * Split into net_db.c and socket.c.
41 #include <sys/types.h>
43 #include <sys/socket.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
48 #include "libguile/_scm.h"
49 #include "libguile/feature.h"
50 #include "libguile/strings.h"
51 #include "libguile/vectors.h"
52 #include "libguile/dynwind.h"
54 #include "libguile/validate.h"
55 #include "libguile/net_db.h"
56 #include "libguile/socket.h"
59 #if defined (HAVE_H_ERRNO)
60 /* Only wrap gethostbyname / gethostbyaddr if h_errno is available. */
62 #if defined HAVE_HSTRERROR && !HAVE_DECL_HSTRERROR
63 /* Some OSes, such as Tru64 5.1b, lack a declaration for hstrerror(3). */
64 extern const char *hstrerror (int);
67 SCM_SYMBOL (scm_host_not_found_key
, "host-not-found");
68 SCM_SYMBOL (scm_try_again_key
, "try-again");
69 SCM_SYMBOL (scm_no_recovery_key
, "no-recovery");
70 SCM_SYMBOL (scm_no_data_key
, "no-data");
72 static void scm_resolv_error (const char *subr
, SCM bad_value
)
75 if (h_errno
== NETDB_INTERNAL
)
77 /* errno supposedly contains a useful value. */
89 key
= scm_host_not_found_key
;
90 errmsg
= "Unknown host";
93 key
= scm_try_again_key
;
94 errmsg
= "Host name lookup failure";
97 key
= scm_no_recovery_key
;
98 errmsg
= "Unknown server error";
101 key
= scm_no_data_key
;
102 errmsg
= "No address associated with name";
105 scm_misc_error (subr
, "Unknown resolver error", SCM_EOL
);
109 #ifdef HAVE_HSTRERROR
110 errmsg
= (const char *) hstrerror (h_errno
);
112 scm_error (key
, subr
, errmsg
, SCM_BOOL_F
, SCM_EOL
);
116 /* Should take an extra arg for address format (will be needed for IPv6).
117 Should use reentrant facilities if available.
120 SCM_DEFINE (scm_gethost
, "gethost", 0, 1, 0,
122 "@deffnx {Scheme Procedure} gethostbyname hostname\n"
123 "@deffnx {Scheme Procedure} gethostbyaddr address\n"
124 "Look up a host by name or address, returning a host object. The\n"
125 "@code{gethost} procedure will accept either a string name or an integer\n"
126 "address; if given no arguments, it behaves like @code{gethostent} (see\n"
127 "below). If a name or address is supplied but the address can not be\n"
128 "found, an error will be thrown to one of the keys:\n"
129 "@code{host-not-found}, @code{try-again}, @code{no-recovery} or\n"
130 "@code{no-data}, corresponding to the equivalent @code{h_error} values.\n"
131 "Unusual conditions may result in errors thrown to the\n"
132 "@code{system-error} or @code{misc_error} keys.")
133 #define FUNC_NAME s_scm_gethost
135 SCM result
= scm_c_make_vector (5, SCM_UNSPECIFIED
);
137 struct hostent
*entry
;
142 if (SCM_UNBNDP (host
))
144 #ifdef HAVE_GETHOSTENT
145 entry
= gethostent ();
151 /* As far as I can tell, there's no good way to tell whether
152 zero means an error or end-of-file. The trick of
153 clearing errno before calling gethostent and checking it
154 afterwards doesn't cut it, because, on Linux, it seems to
155 try to contact some other server (YP?) and fails, which
156 is a benign failure. */
160 else if (scm_is_string (host
))
162 char *str
= scm_to_locale_string (host
);
163 entry
= gethostbyname (str
);
168 inad
.s_addr
= htonl (scm_to_ulong (host
));
169 entry
= gethostbyaddr ((char *) &inad
, sizeof (inad
), AF_INET
);
173 scm_resolv_error (FUNC_NAME
, host
);
175 SCM_SIMPLE_VECTOR_SET(result
, 0, scm_from_locale_string (entry
->h_name
));
176 SCM_SIMPLE_VECTOR_SET(result
, 1, scm_makfromstrs (-1, entry
->h_aliases
));
177 SCM_SIMPLE_VECTOR_SET(result
, 2, scm_from_int (entry
->h_addrtype
));
178 SCM_SIMPLE_VECTOR_SET(result
, 3, scm_from_int (entry
->h_length
));
179 if (sizeof (struct in_addr
) != entry
->h_length
)
181 SCM_SIMPLE_VECTOR_SET(result
, 4, SCM_BOOL_F
);
184 for (argv
= entry
->h_addr_list
; argv
[i
]; i
++);
187 inad
= *(struct in_addr
*) argv
[i
];
188 lst
= scm_cons (scm_from_ulong (ntohl (inad
.s_addr
)), lst
);
190 SCM_SIMPLE_VECTOR_SET(result
, 4, lst
);
195 #endif /* HAVE_H_ERRNO */
198 /* In all subsequent getMUMBLE functions, when we're called with no
199 arguments, we're supposed to traverse the tables entry by entry.
200 However, there doesn't seem to be any documented way to distinguish
201 between end-of-table and an error; in both cases the functions
202 return zero. Gotta love Unix. For the time being, we clear errno,
203 and if we get a zero and errno is set, we signal an error. This
204 doesn't seem quite right (what if errno gets set as part of healthy
205 operation?), but it seems to work okay. We'll see. */
207 #if defined(HAVE_GETNETENT) && defined(HAVE_GETNETBYNAME) && defined(HAVE_GETNETBYADDR)
208 SCM_DEFINE (scm_getnet
, "getnet", 0, 1, 0,
210 "@deffnx {Scheme Procedure} getnetbyname net-name\n"
211 "@deffnx {Scheme Procedure} getnetbyaddr net-number\n"
212 "Look up a network by name or net number in the network database. The\n"
213 "@var{net-name} argument must be a string, and the @var{net-number}\n"
214 "argument must be an integer. @code{getnet} will accept either type of\n"
215 "argument, behaving like @code{getnetent} (see below) if no arguments are\n"
217 #define FUNC_NAME s_scm_getnet
219 SCM result
= scm_c_make_vector (4, SCM_UNSPECIFIED
);
220 struct netent
*entry
;
223 if (SCM_UNBNDP (net
))
225 entry
= getnetent ();
228 /* There's no good way to tell whether zero means an error
229 or end-of-file, so we always return #f. See `gethost'
234 else if (scm_is_string (net
))
236 char *str
= scm_to_locale_string (net
);
237 entry
= getnetbyname (str
);
243 unsigned long netnum
= scm_to_ulong (net
);
244 entry
= getnetbyaddr (netnum
, AF_INET
);
249 SCM_SYSERROR_MSG ("no such network ~A", scm_list_1 (net
), eno
);
251 SCM_SIMPLE_VECTOR_SET(result
, 0, scm_from_locale_string (entry
->n_name
));
252 SCM_SIMPLE_VECTOR_SET(result
, 1, scm_makfromstrs (-1, entry
->n_aliases
));
253 SCM_SIMPLE_VECTOR_SET(result
, 2, scm_from_int (entry
->n_addrtype
));
254 SCM_SIMPLE_VECTOR_SET(result
, 3, scm_from_ulong (entry
->n_net
));
260 #if defined (HAVE_GETPROTOENT)
261 SCM_DEFINE (scm_getproto
, "getproto", 0, 1, 0,
263 "@deffnx {Scheme Procedure} getprotobyname name\n"
264 "@deffnx {Scheme Procedure} getprotobynumber number\n"
265 "Look up a network protocol by name or by number. @code{getprotobyname}\n"
266 "takes a string argument, and @code{getprotobynumber} takes an integer\n"
267 "argument. @code{getproto} will accept either type, behaving like\n"
268 "@code{getprotoent} (see below) if no arguments are supplied.")
269 #define FUNC_NAME s_scm_getproto
271 SCM result
= scm_c_make_vector (3, SCM_UNSPECIFIED
);
272 struct protoent
*entry
;
275 if (SCM_UNBNDP (protocol
))
277 entry
= getprotoent ();
280 /* There's no good way to tell whether zero means an error
281 or end-of-file, so we always return #f. See `gethost'
286 else if (scm_is_string (protocol
))
288 char *str
= scm_to_locale_string (protocol
);
289 entry
= getprotobyname (str
);
295 unsigned long protonum
= scm_to_ulong (protocol
);
296 entry
= getprotobynumber (protonum
);
301 SCM_SYSERROR_MSG ("no such protocol ~A", scm_list_1 (protocol
), eno
);
303 SCM_SIMPLE_VECTOR_SET(result
, 0, scm_from_locale_string (entry
->p_name
));
304 SCM_SIMPLE_VECTOR_SET(result
, 1, scm_makfromstrs (-1, entry
->p_aliases
));
305 SCM_SIMPLE_VECTOR_SET(result
, 2, scm_from_int (entry
->p_proto
));
311 #if defined (HAVE_GETSERVENT)
313 scm_return_entry (struct servent
*entry
)
315 SCM result
= scm_c_make_vector (4, SCM_UNSPECIFIED
);
317 SCM_SIMPLE_VECTOR_SET(result
, 0, scm_from_locale_string (entry
->s_name
));
318 SCM_SIMPLE_VECTOR_SET(result
, 1, scm_makfromstrs (-1, entry
->s_aliases
));
319 SCM_SIMPLE_VECTOR_SET(result
, 2, scm_from_uint16 (ntohs (entry
->s_port
)));
320 SCM_SIMPLE_VECTOR_SET(result
, 3, scm_from_locale_string (entry
->s_proto
));
324 SCM_DEFINE (scm_getserv
, "getserv", 0, 2, 0,
325 (SCM name
, SCM protocol
),
326 "@deffnx {Scheme Procedure} getservbyname name protocol\n"
327 "@deffnx {Scheme Procedure} getservbyport port protocol\n"
328 "Look up a network service by name or by service number, and return a\n"
329 "network service object. The @var{protocol} argument specifies the name\n"
330 "of the desired protocol; if the protocol found in the network service\n"
331 "database does not match this name, a system error is signalled.\n\n"
332 "The @code{getserv} procedure will take either a service name or number\n"
333 "as its first argument; if given no arguments, it behaves like\n"
334 "@code{getservent} (see below).")
335 #define FUNC_NAME s_scm_getserv
337 struct servent
*entry
;
341 if (SCM_UNBNDP (name
))
343 entry
= getservent ();
346 /* There's no good way to tell whether zero means an error
347 or end-of-file, so we always return #f. See `gethost'
351 return scm_return_entry (entry
);
354 scm_dynwind_begin (0);
356 protoname
= scm_to_locale_string (protocol
);
357 scm_dynwind_free (protoname
);
359 if (scm_is_string (name
))
361 char *str
= scm_to_locale_string (name
);
362 entry
= getservbyname (str
, protoname
);
368 entry
= getservbyport (htons (scm_to_int (name
)), protoname
);
373 SCM_SYSERROR_MSG("no such service ~A", scm_list_1 (name
), eno
);
376 return scm_return_entry (entry
);
381 #if defined(HAVE_SETHOSTENT) && defined(HAVE_ENDHOSTENT)
382 SCM_DEFINE (scm_sethost
, "sethost", 0, 1, 0,
384 "If @var{stayopen} is omitted, this is equivalent to @code{endhostent}.\n"
385 "Otherwise it is equivalent to @code{sethostent stayopen}.")
386 #define FUNC_NAME s_scm_sethost
388 if (SCM_UNBNDP (stayopen
))
391 sethostent (scm_is_true (stayopen
));
392 return SCM_UNSPECIFIED
;
397 #if defined(HAVE_SETNETENT) && defined(HAVE_ENDNETENT)
398 SCM_DEFINE (scm_setnet
, "setnet", 0, 1, 0,
400 "If @var{stayopen} is omitted, this is equivalent to @code{endnetent}.\n"
401 "Otherwise it is equivalent to @code{setnetent stayopen}.")
402 #define FUNC_NAME s_scm_setnet
404 if (SCM_UNBNDP (stayopen
))
407 setnetent (scm_is_true (stayopen
));
408 return SCM_UNSPECIFIED
;
413 #if defined (HAVE_SETPROTOENT) && defined (HAVE_ENDPROTOENT)
414 SCM_DEFINE (scm_setproto
, "setproto", 0, 1, 0,
416 "If @var{stayopen} is omitted, this is equivalent to @code{endprotoent}.\n"
417 "Otherwise it is equivalent to @code{setprotoent stayopen}.")
418 #define FUNC_NAME s_scm_setproto
420 if (SCM_UNBNDP (stayopen
))
423 setprotoent (scm_is_true (stayopen
));
424 return SCM_UNSPECIFIED
;
429 #if defined (HAVE_SETSERVENT) && defined (HAVE_ENDSERVENT)
430 SCM_DEFINE (scm_setserv
, "setserv", 0, 1, 0,
432 "If @var{stayopen} is omitted, this is equivalent to @code{endservent}.\n"
433 "Otherwise it is equivalent to @code{setservent stayopen}.")
434 #define FUNC_NAME s_scm_setserv
436 if (SCM_UNBNDP (stayopen
))
439 setservent (scm_is_true (stayopen
));
440 return SCM_UNSPECIFIED
;
446 /* Protocol-independent name resolution with getaddrinfo(3) & co. */
448 SCM_SYMBOL (sym_getaddrinfo_error
, "getaddrinfo-error");
450 /* Make sure the `AI_*' flags can be stored as INUMs. */
451 verify (AI_ALL
< SCM_MOST_POSITIVE_FIXNUM
);
453 /* Valid values for the `ai_flags' to `struct addrinfo'. */
454 SCM_VARIABLE_INIT (sym_ai_passive
, "AI_PASSIVE",
455 SCM_I_MAKINUM (AI_PASSIVE
));
456 SCM_VARIABLE_INIT (sym_ai_canonname
, "AI_CANONNAME",
457 SCM_I_MAKINUM (AI_CANONNAME
));
458 SCM_VARIABLE_INIT (sym_ai_numerichost
, "AI_NUMERICHOST",
459 SCM_I_MAKINUM (AI_NUMERICHOST
));
460 SCM_VARIABLE_INIT (sym_ai_numericserv
, "AI_NUMERICSERV",
461 SCM_I_MAKINUM (AI_NUMERICSERV
));
462 SCM_VARIABLE_INIT (sym_ai_v4mapped
, "AI_V4MAPPED",
463 SCM_I_MAKINUM (AI_V4MAPPED
));
464 SCM_VARIABLE_INIT (sym_ai_all
, "AI_ALL",
465 SCM_I_MAKINUM (AI_ALL
));
466 SCM_VARIABLE_INIT (sym_ai_addrconfig
, "AI_ADDRCONFIG",
467 SCM_I_MAKINUM (AI_ADDRCONFIG
));
469 /* Return a Scheme vector whose elements correspond to the fields of C_AI,
470 ignoring the `ai_next' field. This function is not exported because the
471 definition of `struct addrinfo' is provided by Gnulib. */
473 scm_from_addrinfo (const struct addrinfo
*c_ai
)
477 /* Note: The indices here must be kept synchronized with those used by the
478 `addrinfo:' procedures in `networking.scm'. */
480 ai
= scm_c_make_vector (6, SCM_UNDEFINED
);
481 SCM_SIMPLE_VECTOR_SET (ai
, 0, scm_from_int (c_ai
->ai_flags
));
482 SCM_SIMPLE_VECTOR_SET (ai
, 1, scm_from_int (c_ai
->ai_family
));
483 SCM_SIMPLE_VECTOR_SET (ai
, 2, scm_from_int (c_ai
->ai_socktype
));
484 SCM_SIMPLE_VECTOR_SET (ai
, 3, scm_from_int (c_ai
->ai_protocol
));
485 SCM_SIMPLE_VECTOR_SET (ai
, 4,
486 scm_from_sockaddr (c_ai
->ai_addr
, c_ai
->ai_addrlen
));
487 SCM_SIMPLE_VECTOR_SET (ai
, 5,
488 c_ai
->ai_canonname
!= NULL
489 ? scm_from_locale_string (c_ai
->ai_canonname
)
495 SCM_DEFINE (scm_getaddrinfo
, "getaddrinfo", 1, 5, 0,
496 (SCM name
, SCM service
, SCM hint_flags
, SCM hint_family
,
497 SCM hint_socktype
, SCM hint_protocol
),
498 "Return a list of @code{addrinfo} structures containing "
499 "a socket address and associated information for host @var{name} "
500 "and/or @var{service} to be used in creating a socket with "
501 "which to address the specified service.\n\n"
503 "(let* ((ai (car (getaddrinfo \"www.gnu.org\" \"http\")))\n"
504 " (s (socket (addrinfo:fam ai) (addrinfo:socktype ai)\n"
505 " (addrinfo:protocol ai))))\n"
506 " (connect s (addrinfo:addr ai))\n"
509 "When @var{service} is omitted or is @code{#f}, return "
510 "network-level addresses for @var{name}. When @var{name} "
511 "is @code{#f} @var{service} must be provided and service "
512 "locations local to the caller are returned.\n"
514 "Additional hints can be provided. When specified, "
515 "@var{hint_flags} should be a bitwise-or of zero or more "
516 "constants among the following:\n\n"
519 "Socket address is intended for @code{bind}.\n\n"
520 "@item AI_CANONNAME\n"
521 "Request for canonical host name, available via "
522 "@code{addrinfo:canonname}. This makes sense mainly when "
523 "DNS lookups are involved.\n\n"
524 "@item AI_NUMERICHOST\n"
525 "Specifies that @var{name} is a numeric host address string "
526 "(e.g., @code{\"127.0.0.1\"}), meaning that name resolution "
527 "will not be used.\n\n"
528 "@item AI_NUMERICSERV\n"
529 "Likewise, specifies that @var{service} is a numeric port "
530 "string (e.g., @code{\"80\"}).\n\n"
531 "@item AI_ADDRCONFIG\n"
532 "Return only addresses configured on the local system. It is "
533 "highly recommended to provide this flag when the returned "
534 "socket addresses are to be used to make connections; "
535 "otherwise, some of the returned addresses could be unreachable "
536 "or use a protocol that is not supported.\n\n"
537 "@item AI_V4MAPPED\n"
538 "When looking up IPv6 addresses, return mapped "
539 "IPv4 addresses if there is no IPv6 address available at all.\n\n"
541 "If this flag is set along with @code{AI_V4MAPPED} when looking "
542 "up IPv6 addresses, return all IPv6 addresses "
543 "as well as all IPv4 addresses, the latter mapped to IPv6 "
546 "When given, @var{hint_family} should specify the requested "
547 "address family, e.g., @code{AF_INET6}. Similarly, "
548 "@var{hint_socktype} should specify the requested socket type "
549 "(e.g., @code{SOCK_DGRAM}), and @var{hint_protocol} should "
550 "specify the requested protocol (its value is interpretered "
551 "as in calls to @code{socket}).\n"
553 "On error, an exception with key @code{getaddrinfo-error} is "
554 "thrown, with an error code (an integer) as its argument:\n\n"
556 "(catch 'getaddrinfo-error\n"
558 " (getaddrinfo \"www.gnu.org\" \"gopher\"))\n"
559 " (lambda (key errcode)\n"
560 " (cond ((= errcode EAI_SERVICE)\n"
561 " (display \"doesn't know about Gopher!\\n\"))\n"
562 " ((= errcode EAI_NONAME)\n"
563 " (display \"www.gnu.org not found\\n\"))\n"
565 " (format #t \"something wrong: ~a\\n\"\n"
566 " (gai-strerror errcode))))))\n"
569 "Error codes are:\n\n"
572 "The name or service could not be resolved at this time. Future "
573 "attempts may succeed.\n\n"
574 "@item EAI_BADFLAGS\n"
575 "@var{hint_flags} contains an invalid value.\n\n"
577 "A non-recoverable error occurred when attempting to "
578 "resolve the name.\n\n"
580 "@var{hint_family} was not recognized.\n\n"
582 "Either @var{name} does not resolve for the supplied parameters, "
583 "or neither @var{name} nor @var{service} were supplied.\n\n"
585 /* See `sysdeps/posix/getaddrinfo.c' in the GNU libc, and
586 <http://www.opensource.apple.com/source/Libinfo/Libinfo-324.1/lookup.subproj/netdb.h>,
587 for details on EAI_NODATA. */
589 "This non-POSIX error code can be returned on some systems (GNU "
590 "and Darwin, at least), for example when @var{name} is known "
591 "but requests that were made turned out no data. Error handling\n"
592 "code should be prepared to handle it when it is defined.\n\n"
593 "@item EAI_SERVICE\n"
594 "@var{service} was not recognized for the specified socket type.\n\n"
595 "@item EAI_SOCKTYPE\n"
596 "@var{hint_socktype} was not recognized.\n\n"
598 "A system error occurred. In C, the error code can be found in "
599 "@code{errno}; this value is not accessible from Scheme, but in\n"
600 "practice it provides little information about the actual error "
601 "cause.\n\n" /* see <http://bugs.gnu.org/13958>. */
604 "Users are encouraged to read the "
605 "@url{http://www.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html,"
606 "POSIX specification} for more details.\n")
607 #define FUNC_NAME s_scm_getaddrinfo
610 char *c_name
, *c_service
;
611 struct addrinfo c_hints
, *c_result
;
612 SCM result
= SCM_EOL
;
614 if (scm_is_true (name
))
615 SCM_VALIDATE_STRING (SCM_ARG1
, name
);
617 if (!SCM_UNBNDP (service
) && scm_is_true (service
))
618 SCM_VALIDATE_STRING (SCM_ARG2
, service
);
620 scm_dynwind_begin (0);
622 if (scm_is_string (name
))
624 c_name
= scm_to_locale_string (name
);
625 scm_dynwind_free (c_name
);
630 if (scm_is_string (service
))
632 c_service
= scm_to_locale_string (service
);
633 scm_dynwind_free (c_service
);
638 memset (&c_hints
, 0, sizeof (c_hints
));
639 if (!SCM_UNBNDP (hint_flags
))
641 c_hints
.ai_flags
= scm_to_int (hint_flags
);
642 if (!SCM_UNBNDP (hint_family
))
644 c_hints
.ai_family
= scm_to_int (hint_family
);
645 if (!SCM_UNBNDP (hint_socktype
))
647 c_hints
.ai_socktype
= scm_to_int (hint_socktype
);
648 if (!SCM_UNBNDP (hint_family
))
649 c_hints
.ai_family
= scm_to_int (hint_family
);
654 err
= getaddrinfo (c_name
, c_service
, &c_hints
, &c_result
);
660 for (prev_addr
= &result
, a
= c_result
;
662 a
= a
->ai_next
, prev_addr
= SCM_CDRLOC (*prev_addr
))
663 *prev_addr
= scm_list_1 (scm_from_addrinfo (a
));
665 freeaddrinfo (c_result
);
668 scm_throw (sym_getaddrinfo_error
, scm_list_1 (scm_from_int (err
)));
676 /* Make sure the `EAI_*' flags can be stored as INUMs. */
677 verify (EAI_BADFLAGS
< SCM_MOST_POSITIVE_FIXNUM
);
679 /* Error codes returned by `getaddrinfo'. */
680 SCM_VARIABLE_INIT (sym_eai_badflags
, "EAI_BADFLAGS",
681 SCM_I_MAKINUM (EAI_BADFLAGS
));
682 SCM_VARIABLE_INIT (sym_eai_noname
, "EAI_NONAME",
683 SCM_I_MAKINUM (EAI_NONAME
));
684 SCM_VARIABLE_INIT (sym_eai_again
, "EAI_AGAIN",
685 SCM_I_MAKINUM (EAI_AGAIN
));
686 SCM_VARIABLE_INIT (sym_eai_fail
, "EAI_FAIL",
687 SCM_I_MAKINUM (EAI_FAIL
));
688 SCM_VARIABLE_INIT (sym_eai_family
, "EAI_FAMILY",
689 SCM_I_MAKINUM (EAI_FAMILY
));
690 SCM_VARIABLE_INIT (sym_eai_socktype
, "EAI_SOCKTYPE",
691 SCM_I_MAKINUM (EAI_SOCKTYPE
));
692 SCM_VARIABLE_INIT (sym_eai_service
, "EAI_SERVICE",
693 SCM_I_MAKINUM (EAI_SERVICE
));
694 SCM_VARIABLE_INIT (sym_eai_memory
, "EAI_MEMORY",
695 SCM_I_MAKINUM (EAI_MEMORY
));
696 SCM_VARIABLE_INIT (sym_eai_system
, "EAI_SYSTEM",
697 SCM_I_MAKINUM (EAI_SYSTEM
));
698 SCM_VARIABLE_INIT (sym_eai_overflow
, "EAI_OVERFLOW",
699 SCM_I_MAKINUM (EAI_OVERFLOW
));
701 /* The following values are GNU extensions. */
703 SCM_VARIABLE_INIT (sym_eai_nodata
, "EAI_NODATA",
704 SCM_I_MAKINUM (EAI_NODATA
));
706 #ifdef EAI_ADDRFAMILY
707 SCM_VARIABLE_INIT (sym_eai_addrfamily
, "EAI_ADDRFAMILY",
708 SCM_I_MAKINUM (EAI_ADDRFAMILY
));
710 #ifdef EAI_INPROGRESS
711 SCM_VARIABLE_INIT (sym_eai_inprogress
, "EAI_INPROGRESS",
712 SCM_I_MAKINUM (EAI_INPROGRESS
));
715 SCM_VARIABLE_INIT (sym_eai_canceled
, "EAI_CANCELED",
716 SCM_I_MAKINUM (EAI_CANCELED
));
718 #ifdef EAI_NOTCANCELED
719 SCM_VARIABLE_INIT (sym_eai_notcanceled
, "EAI_NOTCANCELED",
720 SCM_I_MAKINUM (EAI_NOTCANCELED
));
723 SCM_VARIABLE_INIT (sym_eai_alldone
, "EAI_ALLDONE",
724 SCM_I_MAKINUM (EAI_ALLDONE
));
727 SCM_VARIABLE_INIT (sym_eai_intr
, "EAI_INTR",
728 SCM_I_MAKINUM (EAI_INTR
));
730 #ifdef EAI_IDN_ENCODE
731 SCM_VARIABLE_INIT (sym_eai_idn_encode
, "EAI_IDN_ENCODE",
732 SCM_I_MAKINUM (EAI_IDN_ENCODE
));
735 SCM_DEFINE (scm_gai_strerror
, "gai-strerror", 1, 0, 0,
737 "Return a string describing @var{error}, an integer error code "
738 "returned by @code{getaddrinfo}.")
739 #define FUNC_NAME s_scm_gai_strerror
741 return scm_from_locale_string (gai_strerror (scm_to_int (error
)));
745 /* TODO: Add a getnameinfo(3) wrapper. */
751 scm_add_feature ("net-db");
752 #include "libguile/net_db.x"