#include "perl.h"
#include "XSUB.h"
+#include <stddef.h>
+
#ifndef VMS
# ifdef I_SYS_TYPES
# include <sys/types.h>
# endif
-# include <sys/socket.h>
+# if !defined(ultrix) /* Avoid double definition. */
+# include <sys/socket.h>
+# endif
# if defined(USE_SOCKS) && defined(I_SOCKS)
# include <socks.h>
# endif
# if defined(NeXT) || defined(__NeXT__)
# include <netinet/in_systm.h>
# endif
-# ifdef I_NETINET_IN
+# if defined(__sgi) && !defined(AF_LINK) && defined(PF_LINK) && PF_LINK == AF_LNK
+# undef PF_LINK
+# endif
+# if defined(I_NETINET_IN) || defined(__ultrix__)
# include <netinet/in.h>
# endif
# ifdef I_NETDB
-# include <netdb.h>
+# if !defined(ultrix) /* Avoid double definition. */
+# include <netdb.h>
+# endif
# endif
# ifdef I_ARPA_INET
# include <arpa/inet.h>
*
* --jhi */
-#include "constants.c"
+#include "const-c.inc"
MODULE = Socket PACKAGE = Socket
-INCLUDE: constants.xs
+INCLUDE: const-xs.inc
void
inet_aton(host)
char * ip_address;
if (DO_UTF8(ip_address_sv) && !sv_utf8_downgrade(ip_address_sv, 1))
croak("Wide character in Socket::inet_ntoa");
- ip_address = SvPV(ip_address_sv, addrlen);
+ ip_address = SvPVbyte(ip_address_sv, addrlen);
if (addrlen == sizeof(addr) || addrlen == 4)
addr.s_addr =
(ip_address[0] & 0xFF) << 24 |
addrlen, sizeof(addr));
/* We could use inet_ntoa() but that is broken
* in HP-UX + GCC + 64bitint (returns "0.0.0.0"),
- * so let's use this sprintf() workaround everywhere. */
- New(1138, addr_str, 4 * 3 + 3 + 1, char);
+ * so let's use this sprintf() workaround everywhere.
+ * This is also more threadsafe than using inet_ntoa(). */
+ New(1138, addr_str, 4 * 3 + 3 + 1, char); /* IPv6? */
sprintf(addr_str, "%d.%d.%d.%d",
((addr.s_addr >> 24) & 0xFF),
((addr.s_addr >> 16) & 0xFF),
}
void
+sockaddr_family(sockaddr)
+ SV * sockaddr
+ PREINIT:
+ STRLEN sockaddr_len;
+ char *sockaddr_pv = SvPVbyte(sockaddr, sockaddr_len);
+ CODE:
+ if (sockaddr_len < offsetof(struct sockaddr, sa_data)) {
+ croak("Bad arg length for %s, length is %d, should be at least %d",
+ "Socket::sockaddr_family", sockaddr_len,
+ offsetof(struct sockaddr, sa_data));
+ }
+ ST(0) = sv_2mortal(newSViv(((struct sockaddr*)sockaddr_pv)->sa_family));
+
+void
pack_sockaddr_un(pathname)
char * pathname
CODE:
#ifdef I_SYS_UN
struct sockaddr_un addr;
STRLEN sockaddrlen;
- char * sun_ad = SvPV(sun_sv,sockaddrlen);
+ char * sun_ad = SvPVbyte(sun_sv,sockaddrlen);
char * e;
# ifndef __linux__
/* On Linux sockaddrlen on sockets returned by accept, recvfrom,
addr.sun_family,
AF_UNIX);
}
- e = addr.sun_path;
- while (*e && e < addr.sun_path + sizeof addr.sun_path)
+ e = (char*)addr.sun_path;
+ while (*e && e < (char*)addr.sun_path + sizeof addr.sun_path)
++e;
- ST(0) = sv_2mortal(newSVpvn(addr.sun_path, e - addr.sun_path));
+ ST(0) = sv_2mortal(newSVpvn(addr.sun_path, e - (char*)addr.sun_path));
#else
ST(0) = (SV *) not_here("unpack_sockaddr_un");
#endif
char * ip_address;
if (DO_UTF8(ip_address_sv) && !sv_utf8_downgrade(ip_address_sv, 1))
croak("Wide character in Socket::pack_sockaddr_in");
- ip_address = SvPV(ip_address_sv, addrlen);
+ ip_address = SvPVbyte(ip_address_sv, addrlen);
if (addrlen == sizeof(addr) || addrlen == 4)
addr.s_addr =
(ip_address[0] & 0xFF) << 24 |
struct sockaddr_in addr;
unsigned short port;
struct in_addr ip_address;
- char * sin = SvPV(sin_sv,sockaddrlen);
+ char * sin = SvPVbyte(sin_sv,sockaddrlen);
if (sockaddrlen != sizeof(addr)) {
croak("Bad arg length for %s, length is %d, should be %d",
"Socket::unpack_sockaddr_in",