Some tweaks for invocations and for networking.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25140 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2007-05-11 08:26:59 +00:00
parent 1855046feb
commit 7c633ab823
6 changed files with 355 additions and 29 deletions

View file

@ -1,3 +1,14 @@
2007-05-11 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSStream.m:
* Source/unix/NSStream.m:
* Source/win32/NSStreamWin32.m:
* Headers/Foundation/NSStream.h:
First hack at extensions to get address and port properties for
network streams.
* Source/GSFFIInvocation.m:
Attempt to use forward2 if available.
2007-05-11 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSURLResponse.m:

View file

@ -329,6 +329,15 @@ GS_EXPORT NSString * const NSStreamSOCKSProxyVersion4;
GS_EXPORT NSString * const NSStreamSOCKSProxyVersion5;
GS_EXPORT NSString * const NSStreamSOCKSProxyVersionKey;
/** May be used to read the local IP address of a tcp/ip network stream. */
GS_EXPORT NSString * const GSStreamLocalAddressKey;
/** May be used to read the local port of a tcp/ip network stream. */
GS_EXPORT NSString * const GSStreamLocalPortKey;
/** May be used to read the remote IP address of a tcp/ip network stream. */
GS_EXPORT NSString * const GSStreamRemoteAddressKey;
/** May be used to read the remote port of a tcp/ip network stream. */
GS_EXPORT NSString * const GSStreamRemotePortKey;
/**
* Informal protocol for delegates of instance of the [NSStream] class.
*/

View file

@ -141,37 +141,40 @@ gs_find_by_receiver_best_typed_sel (id receiver, SEL sel)
@implementation GSFFIInvocation
static IMP gs_objc_msg_forward (SEL sel)
static IMP gs_objc_msg_forward2 (id receiver, SEL sel)
{
const char *sel_type;
cifframe_t *cframe;
ffi_closure *cclosure;
NSMethodSignature *sig;
/* Determine the method types so we can construct the frame. We may not
get the right one, though. What to do then? Perhaps it can be fixed up
in the callback, but only under limited circumstances.
*/
sel_type = sel_get_type (sel);
sig = nil;
sig = [receiver methodSignatureForSelector: sel];
if (sel_type)
if (sig == nil)
{
sig = [NSMethodSignature signatureWithObjCTypes: sel_type];
}
else
{
static NSMethodSignature *def = nil;
const char *sel_type;
/*
* Default signature is for a method returning an object.
/* Determine the method types so we can construct the frame. We may not
get the right one, though. What to do then? Perhaps it can be fixed up
in the callback, but only under limited circumstances.
*/
if (def == nil)
sel_type = sel_get_type (sel);
if (sel_type)
{
def = RETAIN([NSMethodSignature signatureWithObjCTypes: "@@:"]);
sig = [NSMethodSignature signatureWithObjCTypes: sel_type];
}
else
{
static NSMethodSignature *def = nil;
/*
* Default signature is for a method returning an object.
*/
if (def == nil)
{
def = RETAIN([NSMethodSignature signatureWithObjCTypes: "@@:"]);
}
sig = def;
}
sig = def;
}
NSCAssert1(sig, @"No signature for selector %@", NSStringFromSelector(sel));
@ -188,7 +191,7 @@ static IMP gs_objc_msg_forward (SEL sel)
[NSException raise: NSMallocException format: @"Allocating closure"];
}
if (ffi_prep_closure(cclosure, &(cframe->cif),
GSFFIInvocationCallback, cframe) != FFI_OK)
GSFFIInvocationCallback, cframe) != FFI_OK)
{
[NSException raise: NSGenericException format: @"Preping closure"];
}
@ -196,9 +199,18 @@ static IMP gs_objc_msg_forward (SEL sel)
return (IMP)cclosure;
}
static IMP gs_objc_msg_forward (SEL sel)
{
return gs_objc_msg_forward2 (nil, sel);
}
+ (void) load
{
#if HAVE_FORWARD2
__objc_msg_forward2 = gs_objc_msg_forward2;
#else
__objc_msg_forward = gs_objc_msg_forward;
#endif
}
- (id) initWithArgframe: (arglist_t)frame selector: (SEL)aSelector
@ -522,7 +534,7 @@ GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user)
not the invocation so it will be demallocd at the end of this call
*/
if ([sig methodReturnType] && *[sig methodReturnType] == _C_ID
&& ((NSInvocation_t *)invocation)->_validReturn == YES)
&& ((NSInvocation_t *)invocation)->_validReturn == YES)
{
AUTORELEASE(*(id *)retp);
((NSInvocation_t *)invocation)->_validReturn = NO;

View file

@ -73,6 +73,15 @@ NSString * const NSStreamSOCKSProxyVersion5
NSString * const NSStreamSOCKSProxyVersionKey
= @"NSStreamSOCKSProxyVersionKey";
NSString * const GSStreamLocalAddressKey
= @"GSStreamLocalAddressKey";
NSString * const GSStreamLocalPortKey
= @"GSStreamLocalPortKey";
NSString * const GSStreamRemoteAddressKey
= @"GSStreamRemoteAddressKey";
NSString * const GSStreamRemotePortKey
= @"GSStreamRemotePortKey";
/*
* Determine the type of event to use when adding a stream to the run loop.

View file

@ -31,6 +31,7 @@
#include <Foundation/NSError.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSHost.h>
#include <Foundation/NSByteOrder.h>
#include "../GSStream.h"
@ -54,6 +55,99 @@
#define socklen_t uint32_t
#endif
static id propertyForInet4Stream(int descriptor, NSString *key)
{
struct sockaddr_in sin;
unsigned size = sizeof(sin);
id result = nil;
if ([key isEqualToString: GSStreamLocalAddressKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithUTF8String:
(char*)inet_ntoa(sin.sin_addr)];
}
}
else if ([key isEqualToString: GSStreamLocalPortKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin_port)];
}
}
else if ([key isEqualToString: GSStreamRemoteAddressKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithUTF8String:
(char*)inet_ntoa(sin.sin_addr)];
}
}
else if ([key isEqualToString: GSStreamRemotePortKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin_port)];
}
}
return result;
}
#if defined(AF_INET6)
static id propertyForInet6Stream(int descriptor, NSString *key)
{
struct sockaddr_in6 sin;
unsigned size = sizeof(sin);
id result = nil;
if ([key isEqualToString: GSStreamLocalAddressKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
char buf[INET6_ADDRSTRLEN+1];
if (inet_ntop(AF_INET6, &(sin.sin6_addr), buf, INET6_ADDRSTRLEN) == 0)
{
buf[INET6_ADDRSTRLEN] = '\0';
result = [NSString stringWithUTF8String: buf];
}
}
}
else if ([key isEqualToString: GSStreamLocalPortKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin6_port)];
}
}
else if ([key isEqualToString: GSStreamRemoteAddressKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
char buf[INET6_ADDRSTRLEN+1];
if (inet_ntop(AF_INET6, &(sin.sin6_addr), buf, INET6_ADDRSTRLEN) == 0)
{
buf[INET6_ADDRSTRLEN] = '\0';
result = [NSString stringWithUTF8String: buf];
}
}
}
else if ([key isEqualToString: GSStreamRemotePortKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin6_port)];
}
}
return result;
}
#endif
/**
* The concrete subclass of NSInputStream that reads from a file
*/
@ -80,7 +174,7 @@
- (socklen_t) sockLen;
/**
* get the sockaddr
* get the remote sockaddr
*/
- (struct sockaddr*) peerAddr;
@ -626,7 +720,7 @@ static void setNonblocking(int fd)
if ((self = [super init]) != nil)
{
_peerAddr.sin_family = AF_INET;
_peerAddr.sin_port = htons(port);
_peerAddr.sin_port = GSSwapHostI16ToBig(port);
ptonReturn = inet_pton(AF_INET, addr_c, &(_peerAddr.sin_addr));
if (ptonReturn == 0) // error
{
@ -636,6 +730,17 @@ static void setNonblocking(int fd)
return self;
}
- (id) propertyForKey: (NSString *)key
{
id result = propertyForInet4Stream((intptr_t)_loopID, key);
if (result == nil)
{
result = [super propertyForKey: key];
}
return result;
}
@end
@implementation GSInet6InputStream
@ -658,7 +763,7 @@ static void setNonblocking(int fd)
if ((self = [super init]) != nil)
{
_peerAddr.sin6_family = AF_INET6;
_peerAddr.sin6_port = htons(port);
_peerAddr.sin6_port = GSSwapHostI16ToBig(port);
ptonReturn = inet_pton(AF_INET6, addr_c, &(_peerAddr.sin6_addr));
if (ptonReturn == 0) // error
{
@ -667,6 +772,18 @@ static void setNonblocking(int fd)
}
return self;
}
- (id) propertyForKey: (NSString *)key
{
id result = propertyForInet6Stream((intptr_t)_loopID, key);
if (result == nil)
{
result = [super propertyForKey: key];
}
return result;
}
#else
- (id) initToAddr: (NSString*)addr port: (int)port
{
@ -1038,7 +1155,7 @@ static void setNonblocking(int fd)
if ((self = [super init]) != nil)
{
_peerAddr.sin_family = AF_INET;
_peerAddr.sin_port = htons(port);
_peerAddr.sin_port = GSSwapHostI16ToBig(port);
ptonReturn = inet_pton(AF_INET, addr_c, &(_peerAddr.sin_addr));
if (ptonReturn == 0) // error
{
@ -1048,6 +1165,17 @@ static void setNonblocking(int fd)
return self;
}
- (id) propertyForKey: (NSString *)key
{
id result = propertyForInet4Stream((intptr_t)_loopID, key);
if (result == nil)
{
result = [super propertyForKey: key];
}
return result;
}
@end
@implementation GSInet6OutputStream
@ -1070,7 +1198,7 @@ static void setNonblocking(int fd)
if ((self = [super init]) != nil)
{
_peerAddr.sin6_family = AF_INET6;
_peerAddr.sin6_port = htons(port);
_peerAddr.sin6_port = GSSwapHostI16ToBig(port);
ptonReturn = inet_pton(AF_INET6, addr_c, &(_peerAddr.sin6_addr));
if (ptonReturn == 0) // error
{
@ -1079,6 +1207,18 @@ static void setNonblocking(int fd)
}
return self;
}
- (id) propertyForKey: (NSString *)key
{
id result = propertyForInet6Stream((intptr_t)_loopID, key);
if (result == nil)
{
result = [super propertyForKey: key];
}
return result;
}
#else
- (id) initToAddr: (NSString*)addr port: (int)port
{
@ -1585,7 +1725,7 @@ static void setNonblocking(int fd)
[super init];
_serverAddr.sin_family = AF_INET;
_serverAddr.sin_port = htons(port);
_serverAddr.sin_port = GSSwapHostI16ToBig(port);
ptonReturn = inet_pton(AF_INET, addr_c, &(_serverAddr.sin_addr));
_loopID = (void*)(intptr_t)socket(AF_INET, SOCK_STREAM, 0);
if (ptonReturn == 0 || _loopID < 0) // error
@ -1628,7 +1768,7 @@ static void setNonblocking(int fd)
[super init];
_serverAddr.sin6_family = AF_INET6;
_serverAddr.sin6_port = htons(port);
_serverAddr.sin6_port = GSSwapHostI16ToBig(port);
ptonReturn = inet_pton(AF_INET6, addr_c, &(_serverAddr.sin6_addr));
_loopID = (void*)(intptr_t)socket(AF_INET6, SOCK_STREAM, 0);
if (ptonReturn == 0 || _loopID < 0) // error

View file

@ -42,6 +42,7 @@
#include <Foundation/NSHost.h>
#include <Foundation/NSProcessInfo.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSByteOrder.h>
#include "../GSStream.h"
#include "../GSPrivate.h"
@ -50,6 +51,47 @@
typedef int socklen_t;
static id propertyForInet4Stream(int descriptor, NSString *key)
{
struct sockaddr_in sin;
unsigned size = sizeof(sin);
id result = nil;
if ([key isEqualToString: GSStreamLocalAddressKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithUTF8String:
(char*)inet_ntoa(sin.sin_addr)];
}
}
else if ([key isEqualToString: GSStreamLocalPortKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin_port)];
}
}
else if ([key isEqualToString: GSStreamRemoteAddressKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithUTF8String:
(char*)inet_ntoa(sin.sin_addr)];
}
}
else if ([key isEqualToString: GSStreamRemotePortKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin_port)];
}
}
return result;
}
/**
* The concrete subclass of NSInputStream that reads from a file
*/
@ -1030,6 +1072,98 @@ static void setNonblocking(SOCKET fd)
return self;
}
static id propertyForInet4Stream(int descriptor, NSString *key)
{
struct sockaddr_in sin;
unsigned size = sizeof(sin);
id result = nil;
if ([key isEqualToString: GSStreamLocalAddressKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithUTF8String:
(char*)inet_ntoa(sin.sin_addr)];
}
}
else if ([key isEqualToString: GSStreamLocalPortKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin_port)];
}
}
else if ([key isEqualToString: GSStreamRemoteAddressKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithUTF8String:
(char*)inet_ntoa(sin.sin_addr)];
}
}
else if ([key isEqualToString: GSStreamRemotePortKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin_port)];
}
}
return result;
}
#if defined(AF_INET6)
static id propertyForInet6Stream(int descriptor, NSString *key)
{
struct sockaddr_in6 sin;
unsigned size = sizeof(sin);
id result = nil;
if ([key isEqualToString: GSStreamLocalAddressKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
char buf[INET6_ADDRSTRLEN+1];
if (inet_ntop(AF_INET6, &(sin.sin6_addr), buf, INET6_ADDRSTRLEN) == 0)
{
buf[INET6_ADDRSTRLEN] = '\0';
result = [NSString stringWithUTF8String: buf];
}
}
}
else if ([key isEqualToString: GSStreamLocalPortKey])
{
if (getsockname(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin6_port)];
}
}
else if ([key isEqualToString: GSStreamRemoteAddressKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
char buf[INET6_ADDRSTRLEN+1];
if (inet_ntop(AF_INET6, &(sin.sin6_addr), buf, INET6_ADDRSTRLEN) == 0)
{
buf[INET6_ADDRSTRLEN] = '\0';
result = [NSString stringWithUTF8String: buf];
}
}
}
else if ([key isEqualToString: GSStreamRemotePortKey])
{
if (getpeername(descriptor, (struct sockaddr*)&sin, &size) != -1)
{
result = [NSString stringWithFormat: @"%d",
(int)GSSwapBigI16ToHost(sin.sin6_port)];
}
}
return result;
}
#endif
@end
@implementation GSFileOutputStream
@ -1772,6 +1906,17 @@ static void setNonblocking(SOCKET fd)
return self;
}
- (id) propertyForKey: (NSString *)key
{
id result = propertyForInet4Stream((intptr_t)_loopID, key);
if (result == nil)
{
result = [super propertyForKey: key];
}
return result;
}
@end
@implementation NSStream