diff --git a/ChangeLog b/ChangeLog index 0647079bd..106a77a06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-04-22 David Wetzel + + * Source/Additions/Unicode.m: replace objc_malloc with NSZoneMalloc + and objc_free with NSZoneFree + + * Source/Additions/NSFileHandle+GNUstepBase.m: should work with ipv6 + (The old code does fail on Snow Leopard, even with ipv4 addresses.) + + * Source/Additions/GSXML.m: added GSObjCRuntime.h + * Headers/Additions/GNUstepBase/GSObjCRuntime.h: + replace objc_malloc with NSZoneMalloc and objc_free with NSZoneFree + + 2010-04-21 Richard Frith-Macdonald * Source/NSBundle.m: ([mainBundle]) Fix error determining whether diff --git a/Headers/Additions/GNUstepBase/GSObjCRuntime.h b/Headers/Additions/GNUstepBase/GSObjCRuntime.h index 7851ddfb3..a08ceb4b5 100644 --- a/Headers/Additions/GNUstepBase/GSObjCRuntime.h +++ b/Headers/Additions/GNUstepBase/GSObjCRuntime.h @@ -547,7 +547,7 @@ GSLastErrorStr(long error_id) GS_ATTRIB_DEPRECATED; if (__count > __max) \ { \ unsigned int __tmp; \ - __objects = (id*)objc_malloc(__count*sizeof(id)); \ + __objects = (id*)NSZoneMalloc(NSDefaultMallocZone(),__count*sizeof(id)); \ va_start(__ap, firstObject); \ __objects[0] = firstObject; \ for (__tmp = 1; __tmp < __count; __tmp++) \ @@ -557,7 +557,7 @@ GSLastErrorStr(long error_id) GS_ATTRIB_DEPRECATED; va_end(__ap); \ } \ code; \ - if (__objects != __buf) objc_free(__objects); \ + if (__objects != __buf) NSZoneFree (NSDefaultMallocZone(),__objects); \ }) diff --git a/Source/Additions/GSXML.m b/Source/Additions/GSXML.m index 97a405f04..f527a1439 100644 --- a/Source/Additions/GSXML.m +++ b/Source/Additions/GSXML.m @@ -48,6 +48,7 @@ #ifdef HAVE_LIBXML // #undef HAVE_LIBXML_SAX2_H +#import "GNUstepBase/GSObjCRuntime.h" #import "GNUstepBase/GSMime.h" #import "GNUstepBase/GSXML.h" diff --git a/Source/Additions/NSFileHandle+GNUstepBase.m b/Source/Additions/NSFileHandle+GNUstepBase.m index 5e21c83af..8b5422a7f 100644 --- a/Source/Additions/NSFileHandle+GNUstepBase.m +++ b/Source/Additions/NSFileHandle+GNUstepBase.m @@ -38,17 +38,29 @@ // From GSFileHandle.m static BOOL -getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) +getAddr(NSString* name, NSString* svc, NSString* pcl, struct addrinfo **ai, struct addrinfo *hints) { - const char *proto = "tcp"; - struct servent *sp; + const char *cHostn = NULL; + const char *cPortn = NULL; + int e = 0; - if (pcl) - { - proto = [pcl lossyCString]; - } - memset(sin, '\0', sizeof(*sin)); - sin->sin_family = AF_INET; + if (!svc) { + NSLog(@"service is nil."); + + return NO; + } + + hints->ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + hints->ai_protocol = IPPROTO_IP; // accept any + + if (pcl) { + if ([pcl isEqualToString:@"tcp"]) { + hints->ai_protocol = IPPROTO_TCP; + hints->ai_socktype = SOCK_STREAM; + } else if ([pcl isEqualToString:@"udp"]) { + hints->ai_protocol = IPPROTO_UDP; + } + } /* * If we were given a hostname, we use any address for that host. @@ -56,69 +68,31 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) * a null (any address). */ if (name) + { + NSHost* host = [NSHost hostWithName: name]; + + if (host != nil) { - NSHost* host = [NSHost hostWithName: name]; + name = [host address]; + NSLog(@"host address '%@'", name); + cHostn = [name cStringUsingEncoding:NSASCIIStringEncoding]; + } + } + + cPortn = [svc cStringUsingEncoding:NSASCIIStringEncoding]; + + // getaddrinfo() returns zero on success or one of the error codes listed in + // gai_strerror(3) if an error occurs. + NSLog(@"cPortn '%s'", cPortn); + //&ai + e = getaddrinfo (cHostn, cPortn, hints, ai); - if (host != nil) - { - name = [host address]; - } -#ifndef HAVE_INET_ATON - sin->sin_addr.s_addr = inet_addr([name lossyCString]); - if (sin->sin_addr.s_addr == INADDR_NONE) -#else - if (inet_aton([name lossyCString], &sin->sin_addr) == 0) -#endif - { - return NO; - } - } - else - { - sin->sin_addr.s_addr = NSSwapHostIntToBig(INADDR_ANY); - } - if (svc == nil) - { - sin->sin_port = 0; - return YES; - } - else if ((sp = getservbyname([svc lossyCString], proto)) == 0) - { - const char* ptr = [svc lossyCString]; - int val = atoi(ptr); + if (e != 0) { + NSLog(@"getaddrinfo: %s", gai_strerror (e)); + return NO; + } - while (isdigit(*ptr)) - { - ptr++; - } - if (*ptr == '\0' && val <= 0xffff) - { - unsigned short v = val; - - sin->sin_port = NSSwapHostShortToBig(v); - return YES; - } - else if (strcmp(ptr, "gdomap") == 0) - { - unsigned short v; -#ifdef GDOMAP_PORT_OVERRIDE - v = GDOMAP_PORT_OVERRIDE; -#else - v = 538; // IANA allocated port -#endif - sin->sin_port = NSSwapHostShortToBig(v); - return YES; - } - else - { - return NO; - } - } - else - { - sin->sin_port = sp->s_port; - return YES; - } + return YES; } - (id) initAsServerAtAddress: (NSString*)a @@ -129,19 +103,24 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) int status = 1; #endif int net; - struct sockaddr_in sin; - socklen_t size = sizeof(sin); + struct addrinfo *ai; + struct addrinfo hints; + memset (&hints, '\0', sizeof (hints)); - if (getAddr(a, s, p, &sin) == NO) + if (getAddr(a, s, p, &ai, &hints) == NO) { DESTROY(self); NSLog(@"bad address-service-protocol combination"); return nil; } - if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) + if ((net = socket (ai->ai_family, ai->ai_socktype, + ai->ai_protocol)) < 0) { - NSLog(@"unable to create socket - %@", [NSError _last]); + NSLog(@"unable to create socket ai_family: %@ socktype:%@ protocol:%d - %@", (ai->ai_family == PF_INET6 ? @"PF_INET6":@"PF_INET"), + (ai->ai_socktype == SOCK_STREAM ? @"SOCK_STREAM":@"whatever"), + ai->ai_protocol, + [NSError _last]); DESTROY(self); return nil; } @@ -156,34 +135,40 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) setsockopt(net, SOL_SOCKET, SO_REUSEADDR, (char *)&status, sizeof(status)); #endif - if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) < 0) + if (bind(net, ai->ai_addr, ai->ai_addrlen) != 0) { - NSLog(@"unable to bind to port %s:%d - %@", inet_ntoa(sin.sin_addr), - NSSwapBigShortToHost(sin.sin_port), [NSError _last]); - (void) close(net); - DESTROY(self); - return nil; + NSLog(@"unable to bind to port %@", [NSError _last]); + goto cleanup; } if (listen(net, 5) < 0) { NSLog(@"unable to listen on port - %@", [NSError _last]); - (void) close(net); - DESTROY(self); - return nil; + goto cleanup; } - if (getsockname(net, (struct sockaddr*)&sin, &size) < 0) - { - NSLog(@"unable to get socket name - %@", [NSError _last]); - (void) close(net); - DESTROY(self); - return nil; - } + // struct sockaddr_storeage sstore; + // int slen = sizeof(ss); + +// if (getsockname(net,(struct sockaddr *)&sstore, &slen) < 0) +// { +// NSLog(@"unable to get socket name - %@", [NSError _last]); +// goto cleanup; +// } + + freeaddrinfo (ai); + self = [self initWithFileDescriptor: net closeOnDealloc: YES]; return self; + +cleanup: + (void) close(net); + freeaddrinfo (ai); + DESTROY(self); + + return nil; } + (id) fileHandleAsServerAtAddress: (NSString*)address @@ -199,17 +184,49 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) - (NSString*) socketAddress { - struct sockaddr_in sin; - socklen_t size = sizeof(sin); - - if (getsockname([self fileDescriptor], (struct sockaddr*)&sin, &size) < 0) + struct sockaddr_storage sstore; + struct sockaddr *sadr; + + socklen_t size = sizeof(sstore); + + if (getsockname([self fileDescriptor], (struct sockaddr*)&sstore, &size) < 0) + { + NSLog(@"unable to get socket name - %@", [NSError _last]); + return nil; + } + + sadr = (struct sockaddr *) &sstore; + + switch (sadr->sa_family) { + case AF_INET6: { - NSLog(@"unable to get socket name - %@", [NSError _last]); - return nil; + + char straddr[INET6_ADDRSTRLEN]; + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&sstore; + + inet_ntop(AF_INET6, &(addr6->sin6_addr), straddr, + sizeof(straddr)); + + return [NSString stringWithCString:straddr + encoding:NSASCIIStringEncoding]; + break; } - - return [[[NSString alloc] initWithCString: (char*)inet_ntoa(sin.sin_addr)] - autorelease]; + case AF_INET: + { + + struct sockaddr_in * addr4 = (struct sockaddr_in*) &sstore; + + char *address = inet_ntoa(addr4->sin_addr); + + return [NSString stringWithCString:address + encoding:NSASCIIStringEncoding]; + break; + } + default: + break; + } + + return nil; } @end diff --git a/Source/Additions/Unicode.m b/Source/Additions/Unicode.m index baf86dd20..aae5acd43 100644 --- a/Source/Additions/Unicode.m +++ b/Source/Additions/Unicode.m @@ -307,7 +307,7 @@ static void GSSetupEncodingTable(void) } } } - encTable = objc_malloc((encTableSize+1)*sizeof(struct _strenc_ *)); + encTable = NSZoneMalloc(NSDefaultMallocZone(),(encTableSize+1)*sizeof(struct _strenc_ *)); memset(encTable, 0, (encTableSize+1)*sizeof(struct _strenc_ *)); /* @@ -331,13 +331,13 @@ static void GSSetupEncodingTable(void) /* * See if we can do a lossy conversion. */ - lossy = objc_malloc(strlen(entry->iconv) + 12); + lossy = NSZoneMalloc(NSDefaultMallocZone(),strlen(entry->iconv) + 12); strcpy(lossy, entry->iconv); strcat(lossy, "//TRANSLIT"); c = iconv_open(UNICODE_ENC, entry->iconv); if (c == (iconv_t)-1) { - objc_free(lossy); + NSZoneFree(NSDefaultMallocZone(),lossy); } else { @@ -2521,7 +2521,7 @@ GSPrivateAvailableEncodings() * This is also the place where we determine the name we use * for iconv to support unicode. */ - encodings = objc_malloc(sizeof(NSStringEncoding) * (encTableSize+1)); + encodings = NSZoneMalloc(NSDefaultMallocZone(),sizeof(NSStringEncoding) * (encTableSize+1)); pos = 0; for (i = 0; i < encTableSize+1; i++) {