From: Jarkko Hietaniemi Date: Sat, 8 Sep 2001 20:09:07 +0000 (+0000) Subject: Retract the portability changes since they X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=fbf77aee4423df41bab4335ba003d27a32454c43;p=p5sagit%2Fp5-mst-13.2.git Retract the portability changes since they seem to have opened a can of worms... will go back to UNICOS/mk and do the bare minimum required to get the tests working. p4raw-id: //depot/perl@11950 --- diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs index 938d8ae..b048e59 100644 --- a/ext/Socket/Socket.xs +++ b/ext/Socket/Socket.xs @@ -181,36 +181,6 @@ not_here(char *s) #include "constants.c" -#define PERL_IN_ADDR_S_ADDR_SIZE 4 - -/* - * Bad assumptions possible here. - * - * Bad Assumption 1: struct in_addr has no other fields - * than the s_addr (which is the field we care about - * in here, really). However, we can be fed either 4-byte - * addresses (from pack("N", ...), or va.b.c.d, or ...), - * or full struct in_addrs (from e.g. pack_sockaddr_in()), - * which may or may not be 4 bytes in size. - * - * Bad Assumption 2: the s_addr field is a simple type - * (such as an int, u_int32_t). It can be a bit field, - * in which case using & (address-of) on it or taking sizeof() - * wouldn't go over too well. (Those are not attempted - * now but in case someone thinks to change the below code - * to use addr.s_addr instead of addr, you have been warned.) - * - * Bad Assumption 3: the s_addr is the first field in - * an in_addr, or that its bytes are the first bytes in - * an in_addr. - * - * These bad assumptions are wrong in UNICOS which has - * struct in_addr { struct { u_long st_addr:32; } s_da }; - * #define s_addr s_da.st_addr - * and u_long is 64 bits. - * - * --jhi */ - MODULE = Socket PACKAGE = Socket INCLUDE: constants.xs @@ -220,26 +190,18 @@ inet_aton(host) char * host CODE: { - struct in_addr addr; - char saddr[PERL_IN_ADDR_S_ADDR_SIZE]; + struct in_addr ip_address; struct hostent * phe; - int ok; + int ok = inet_aton(host, &ip_address); - ok = inet_aton(host, &addr); - if (ok) { - saddr[0] = (addr.s_addr >> 24) & 0xFF; - saddr[1] = (addr.s_addr >> 16) & 0xFF; - saddr[2] = (addr.s_addr >> 8) & 0xFF; - saddr[3] = (addr.s_addr ) & 0xFF; - } - else if (phe = gethostbyname(host)) { - Copy( phe->h_addr, saddr, phe->h_length, char ); + if (!ok && (phe = gethostbyname(host))) { + Copy( phe->h_addr, &ip_address, phe->h_length, char ); ok = 1; } ST(0) = sv_newmortal(); if (ok) { - sv_setpvn( ST(0), saddr, PERL_IN_ADDR_S_ADDR_SIZE); + sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address ); } } @@ -254,39 +216,15 @@ inet_ntoa(ip_address_sv) 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); - if (addrlen == PERL_IN_ADDR_S_ADDR_SIZE) { - /* It must be (better be) a network-order 32-bit integer. - * We can't use any fancy casting of ip_address to pointer ofn - * some type (int or long) and the dereferencing that sincen - * neither int not long is guaranteed to be 32 bits. */ - addr.s_addr = (ip_address[0] & 0xFF) << 24; - addr.s_addr |= (ip_address[1] & 0xFF) << 16; - addr.s_addr |= (ip_address[2] & 0xFF) << 8; - addr.s_addr |= (ip_address[3] & 0xFF); + ip_address = SvPV(ip_address_sv,addrlen); + if (addrlen != sizeof(addr)) { + croak("Bad arg length for %s, length is %d, should be %d", + "Socket::inet_ntoa", + addrlen, sizeof(addr)); } - else { - /* It could be a struct in_addr that is not 32 bits. */ - - if (addrlen == sizeof(addr)) - /* This branch could be optimized away if we knew - * during compile time what size is struct in_addr. - * If it's four, the above code should have worked. */ - Copy( ip_address, &addr, sizeof addr, char ); - else { - if (PERL_IN_ADDR_S_ADDR_SIZE == sizeof(addr)) - croak("Bad arg length for %s, length is %d, should be %d", - "Socket::inet_ntoa", - addrlen, PERL_IN_ADDR_S_ADDR_SIZE); - else - croak("Bad arg length for %s, length is %d, should be %d or %d", - "Socket::inet_ntoa", - addrlen, PERL_IN_ADDR_S_ADDR_SIZE, 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. */ + Copy( ip_address, &addr, sizeof addr, char ); +#if defined(__hpux) && defined(__GNUC__) && defined(USE_64_BIT_INT) + /* GCC on HP_UX breaks the call to inet_ntoa --sky */ New(1138, addr_str, 4 * 3 + 3 + 1, char); sprintf(addr_str, "%d.%d.%d.%d", ((addr.s_addr >> 24) & 0xFF), @@ -295,6 +233,10 @@ inet_ntoa(ip_address_sv) ( addr.s_addr & 0xFF)); ST(0) = sv_2mortal(newSVpvn(addr_str, strlen(addr_str))); Safefree(addr_str); +#else + addr_str = inet_ntoa(addr); + ST(0) = sv_2mortal(newSVpvn(addr_str, strlen(addr_str))); +#endif } void @@ -406,7 +348,6 @@ unpack_sockaddr_in(sin_sv) struct sockaddr_in addr; unsigned short port; struct in_addr ip_address; - char saddr[PERL_IN_ADDR_S_ADDR_SIZE]; char * sin = SvPV(sin_sv,sockaddrlen); if (sockaddrlen != sizeof(addr)) { croak("Bad arg length for %s, length is %d, should be %d", @@ -422,12 +363,8 @@ unpack_sockaddr_in(sin_sv) } port = ntohs(addr.sin_port); ip_address = addr.sin_addr; - saddr[0] = (ip_address.s_addr >> 24) & 0xFF; - saddr[1] = (ip_address.s_addr >> 16) & 0xFF; - saddr[2] = (ip_address.s_addr >> 8) & 0xFF; - saddr[3] = (ip_address.s_addr ) & 0xFF; EXTEND(SP, 2); PUSHs(sv_2mortal(newSViv((IV) port))); - PUSHs(sv_2mortal(newSVpvn(saddr, PERL_IN_ADDR_S_ADDR_SIZE))); + PUSHs(sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address))); }