Subject: | Socket 2.00x and gai_strerror() |
Date: | Wed, 28 Mar 2012 07:05:44 +1000 |
To: | bug-Socket [...] rt.cpan.org |
From: | NormW <normw [...] gknw.net> |
Hi,
This is NOT a bug report. It notes that at least one OS, NetWare, (maybe
others?) does not have gai_strerr() while having getaddrinfo().
Attached a patch against Socket.xs 2.001 and described here:
The segment beginning at line 45 inserts an external gai_strerror.c (see
below for a sample source) and also disables the 2 'defines' if building
with the later Novell LibC.
The changes starting at line 368 are useful(?) only if it is found that
other OS also lack gai_strerr(). It assumes Socket's Makefile.PL could
test for it, but am unable to confirm as the Win miniperl.exe does not
support dynamic module load and cannot (therefore) actually run the
Makefile.PL.
HTH,
Norm
Show quoted text
> --- Socket.xs.orig 2012-03-27 23:40:53.000000000 +1000
> +++ Socket.xs 2012-03-28 06:13:38.343750000 +1000
> @@ -45,9 +45,15 @@
> #endif
>
> #ifdef NETWARE
> +/* NetWare needs external source for gai_strerror() */
> +#ifndef HAS_GAI_STRERROR
> +# include "gai_strerror.c"
> +#endif
> +#ifndef __NOVELL_LIBC__
> NETDB_DEFINE_CONTEXT
> NETINET_DEFINE_CONTEXT
> #endif
> +#endif
>
> #ifdef I_SYSUIO
> # include <sys/uio.h>
> @@ -368,8 +374,15 @@
> (void) SvUPGRADE(ret, SVt_PVNV);
>
> if(err) {
> +#ifdef HAS_GAI_STRERROR
> const char *error = gai_strerror(err);
> sv_setpv(ret, error);
> +#else
> + /* Report a general getaddrinfo failure plus err */
> + char error = "An error occurred in getaddrinfo(). Error: XXXXXXX";
> + sprintf(&error + 43, "%d", err);
> + sv_setpv(ret, &error);
> +#endif
> }
> else {
> sv_setpv(ret, "");
A sample gai_strerror.c:
Show quoted text> #if defined(HAS_GETADDRINFO) && !defined(HAS_GAI_STRERROR)
> /* getaddrinfo() is available but not gai_strerror(). */
> #include <netdb.h>
>
> static const char *gai_strerror(int err);
>
> static const char *gai_strerror(int err)
> {
> switch (err)
> {
> #ifdef EAI_ADDRFAMILY
> case EAI_ADDRFAMILY:
> return "Address family for hostname is not supported.";
> #endif
> #ifdef EAI_AGAIN
> case EAI_AGAIN:
> return "The name could not be resolved at this time.";
> #endif
> #ifdef EAI_BADFLAGS
> case EAI_BADFLAGS:
> return "The flags parameter has an invalid value.";
> #endif
> #ifdef EAI_FAIL
> case EAI_FAIL:
> return "A non-recoverable error occurred while resolving the name.";
> #endif
> #ifdef EAI_FAMILY
> case EAI_FAMILY:
> return "The address family was not recognized or length is invalid.";
> #endif
> #ifdef EAI_MEMORY
> case EAI_MEMORY:
> return "A memory allocation failure occurred.";
> #endif
> #ifdef EAI_NODATA
> case EAI_NODATA:
> return "No address is associated with the hostname.";
> #endif
> #ifdef EAI_NONAME
> case EAI_NONAME:
> return "The name does not resolve for the supplied parameters.";
> #endif
> #ifdef EAI_OVERFLOW
> case EAI_OVERFLOW:
> return "An argument buffer overflowed.";
> #endif
> #ifdef EAI_SERVICE
> case EAI_SERVICE:
> return "The service parameter was not recognized for the specified socket type.";
> #endif
> #ifdef EAI_SOCKTYPE
> case EAI_SOCKTYPE:
> return "The specified socket type was not recognized.";
> #endif
> #ifdef EAI_SYSTEM
> case EAI_SYSTEM:
> return "A system error occurred - see errno.";
> #endif
> default:
> return "Unknown error in getaddrinfo().";
> }
> /* show now existing. */
> #define HAS_GAI_STRERROR 1
> }
> #endif /* HAS_GETADDRINFO && ! HAS_GAI_STRERROR */
Message body is not shown because sender requested not to inline it.