mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
Apply modified patch to support windows native event handling
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@20785 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
0e7313bb94
commit
2a9f4ec7c0
24 changed files with 2735 additions and 1640 deletions
|
@ -109,6 +109,11 @@ static GSFileHandle* fh_stderr = nil;
|
|||
// Key to info dictionary for operation mode.
|
||||
static NSString* NotificationKey = @"NSFileHandleNotificationKey";
|
||||
|
||||
@interface GSFileHandle(private)
|
||||
- (void) receivedEventRead;
|
||||
- (void) receivedEventWrite;
|
||||
@end
|
||||
|
||||
@implementation GSFileHandle
|
||||
|
||||
/**
|
||||
|
@ -299,6 +304,8 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
if (isSocket)
|
||||
{
|
||||
closesocket((SOCKET)_get_osfhandle(descriptor));
|
||||
WSACloseEvent(event);
|
||||
event = WSA_INVALID_EVENT;
|
||||
}
|
||||
#endif
|
||||
close(descriptor);
|
||||
|
@ -1221,6 +1228,22 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
writeOK = YES;
|
||||
acceptOK = YES;
|
||||
connectOK = YES;
|
||||
#ifdef __MINGW32__
|
||||
if (isSocket)
|
||||
{
|
||||
event = CreateEvent(NULL, NO, NO, NULL);
|
||||
if (event == WSA_INVALID_EVENT)
|
||||
{
|
||||
NSLog(@"Invalid Event - '%d'", WSAGetLastError());
|
||||
return nil;
|
||||
}
|
||||
WSAEventSelect(_get_osfhandle(descriptor), event, FD_ALL_EVENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
event = WSA_INVALID_EVENT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -1492,7 +1515,12 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
rval = [self write: (char*)ptr+pos length: toWrite];
|
||||
if (rval < 0)
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
if (WSAGetLastError()== WSAEINTR ||
|
||||
WSAGetLastError()== WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
#endif
|
||||
{
|
||||
rval = 0;
|
||||
}
|
||||
|
@ -1702,6 +1730,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
if (isSocket)
|
||||
{
|
||||
(void)closesocket((SOCKET)_get_osfhandle(descriptor));
|
||||
WSACloseEvent(event);
|
||||
event = WSA_INVALID_EVENT;
|
||||
}
|
||||
#endif
|
||||
(void)close(descriptor);
|
||||
|
@ -1796,6 +1826,10 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
modes = (NSArray*)[info objectForKey: NSFileHandleNotificationMonitorModes];
|
||||
name = (NSString*)[info objectForKey: NotificationKey];
|
||||
|
||||
if (name == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
n = [NSNotification notificationWithName: name object: self userInfo: info];
|
||||
|
||||
RELEASE(info); /* Retained by the notification. */
|
||||
|
@ -1877,9 +1911,9 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
|
||||
for (i = 0; i < [modes count]; i++)
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
[l removeEvent: (void*)(gsaddr)(SOCKET)_get_osfhandle(descriptor)
|
||||
type: ET_RDESC
|
||||
#ifdef __MINGW32__
|
||||
[l removeEvent: (void*)(gsaddr)event
|
||||
type: ET_HANDLE
|
||||
forMode: [modes objectAtIndex: i]
|
||||
all: YES];
|
||||
#else
|
||||
|
@ -1892,11 +1926,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
}
|
||||
else
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
[l removeEvent: (void*)(gsaddr)(SOCKET)_get_osfhandle(descriptor)
|
||||
type: ET_RDESC
|
||||
#ifdef __MINGW32__
|
||||
[l removeEvent: (void*)(gsaddr)event
|
||||
type: ET_HANDLE
|
||||
forMode: NSDefaultRunLoopMode
|
||||
all: YES];
|
||||
all: YES];
|
||||
#else
|
||||
[l removeEvent: (void*)(gsaddr)descriptor
|
||||
type: ET_RDESC
|
||||
|
@ -1931,11 +1965,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
|
||||
for (i = 0; i < [modes count]; i++)
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
[l removeEvent: (void*)(gsaddr)(SOCKET)_get_osfhandle(descriptor)
|
||||
type: ET_WDESC
|
||||
forMode: [modes objectAtIndex: i]
|
||||
all: YES];
|
||||
#ifdef __MINGW32__
|
||||
[l removeEvent: (void*)(gsaddr)event
|
||||
type: ET_HANDLE
|
||||
forMode: [modes objectAtIndex: i]
|
||||
all: YES];
|
||||
#else
|
||||
[l removeEvent: (void*)(gsaddr)descriptor
|
||||
type: ET_WDESC
|
||||
|
@ -1946,11 +1980,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
}
|
||||
else
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
[l removeEvent: (void*)(gsaddr)(SOCKET)_get_osfhandle(descriptor)
|
||||
type: ET_WDESC
|
||||
#ifdef __MINGW32__
|
||||
[l removeEvent: (void*)(gsaddr)event
|
||||
type: ET_HANDLE
|
||||
forMode: NSDefaultRunLoopMode
|
||||
all: YES];
|
||||
all: YES];
|
||||
#else
|
||||
[l removeEvent: (void*)(gsaddr)descriptor
|
||||
type: ET_WDESC
|
||||
|
@ -1968,6 +2002,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
l = [NSRunLoop currentRunLoop];
|
||||
[self setNonBlocking: YES];
|
||||
if (modes && [modes count])
|
||||
|
@ -1976,9 +2011,9 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
|
||||
for (i = 0; i < [modes count]; i++)
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
[l addEvent: (void*)(gsaddr)(SOCKET)_get_osfhandle(descriptor)
|
||||
type: ET_RDESC
|
||||
#ifdef __MINGW32__
|
||||
[l addEvent: (void*)(gsaddr)event
|
||||
type: ET_HANDLE
|
||||
watcher: self
|
||||
forMode: [modes objectAtIndex: i]];
|
||||
#else
|
||||
|
@ -1992,9 +2027,9 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
}
|
||||
else
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
[l addEvent: (void*)(gsaddr)(SOCKET)_get_osfhandle(descriptor)
|
||||
type: ET_RDESC
|
||||
#ifdef __MINGW32__
|
||||
[l addEvent: (void*)(gsaddr)event
|
||||
type: ET_HANDLE
|
||||
watcher: self
|
||||
forMode: NSDefaultRunLoopMode];
|
||||
#else
|
||||
|
@ -2027,9 +2062,9 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
|
||||
for (i = 0; i < [modes count]; i++)
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
[l addEvent: (void*)(gsaddr)(SOCKET)_get_osfhandle(descriptor)
|
||||
type: ET_WDESC
|
||||
#ifdef __MINGW32__
|
||||
[l addEvent: (void*)(gsaddr)event
|
||||
type: ET_HANDLE
|
||||
watcher: self
|
||||
forMode: [modes objectAtIndex: i]];
|
||||
#else
|
||||
|
@ -2042,9 +2077,9 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
}
|
||||
else
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
[l addEvent: (void*)(gsaddr)(SOCKET)_get_osfhandle(descriptor)
|
||||
type: ET_WDESC
|
||||
#ifdef __MINGW32__
|
||||
[l addEvent: (void*)(gsaddr)event
|
||||
type: ET_HANDLE
|
||||
watcher: self
|
||||
forMode: NSDefaultRunLoopMode];
|
||||
#else
|
||||
|
@ -2057,12 +2092,205 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
}
|
||||
}
|
||||
|
||||
- (void) receivedEventRead
|
||||
{
|
||||
NSString *operation;
|
||||
|
||||
operation = [readInfo objectForKey: NotificationKey];
|
||||
if (operation == NSFileHandleConnectionAcceptedNotification)
|
||||
{
|
||||
struct sockaddr_in buf;
|
||||
#if defined(__MINGW__)
|
||||
SOCKET desc;
|
||||
#else
|
||||
int desc;
|
||||
#endif
|
||||
int blen = sizeof(buf);
|
||||
|
||||
#if defined(__MINGW__)
|
||||
desc = accept((SOCKET)_get_osfhandle(descriptor), (struct sockaddr*)&buf, &blen);
|
||||
#else
|
||||
desc = accept(descriptor, (struct sockaddr*)&buf, &blen);
|
||||
#endif
|
||||
if (desc == INVALID_SOCKET)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat: @"Accept attempt failed - %s",
|
||||
GSLastErrorStr(errno)];
|
||||
[readInfo setObject: s forKey: GSFileHandleNotificationError];
|
||||
}
|
||||
else
|
||||
{ // Accept attempt completed.
|
||||
GSFileHandle *h;
|
||||
struct sockaddr_in sin;
|
||||
int size = sizeof(sin);
|
||||
|
||||
#if defined(__MINGW__)
|
||||
h = [[[self class] alloc] initWithNativeHandle: (void*)desc
|
||||
closeOnDealloc: YES];
|
||||
#else
|
||||
h = [[[self class] alloc] initWithFileDescriptor: desc
|
||||
closeOnDealloc: YES];
|
||||
#endif
|
||||
h->isSocket = YES;
|
||||
getpeername(desc, (struct sockaddr*)&sin, &size);
|
||||
[h setAddr: &sin];
|
||||
[readInfo setObject: h
|
||||
forKey: NSFileHandleNotificationFileHandleItem];
|
||||
RELEASE(h);
|
||||
}
|
||||
[self postReadNotification];
|
||||
}
|
||||
else if (operation == NSFileHandleDataAvailableNotification)
|
||||
{
|
||||
[self postReadNotification];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMutableData *item;
|
||||
int length;
|
||||
int received = 0;
|
||||
char buf[NETBUF_SIZE];
|
||||
|
||||
item = [readInfo objectForKey: NSFileHandleNotificationDataItem];
|
||||
/*
|
||||
* We may have a maximum data size set...
|
||||
*/
|
||||
if (readMax > 0)
|
||||
{
|
||||
length = (unsigned int)readMax - [item length];
|
||||
if (length > (int)sizeof(buf))
|
||||
{
|
||||
length = sizeof(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = sizeof(buf);
|
||||
}
|
||||
|
||||
received = [self read: buf length: length];
|
||||
if (received == 0)
|
||||
{ // Read up to end of file.
|
||||
[self postReadNotification];
|
||||
}
|
||||
else if (received < 0)
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
if (WSAGetLastError() != WSAEINTR
|
||||
&& WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (errno != EAGAIN && errno != EINTR)
|
||||
#endif
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat: @"Read attempt failed - %s",
|
||||
GSLastErrorStr(errno)];
|
||||
[readInfo setObject: s forKey: GSFileHandleNotificationError];
|
||||
[self postReadNotification];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[item appendBytes: buf length: received];
|
||||
if (readMax < 0 || (readMax > 0 && (int)[item length] == readMax))
|
||||
{
|
||||
// Read a single chunk of data
|
||||
[self postReadNotification];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) receivedEventWrite
|
||||
{
|
||||
NSString *operation;
|
||||
NSMutableDictionary *info;
|
||||
|
||||
info = [writeInfo objectAtIndex: 0];
|
||||
operation = [info objectForKey: NotificationKey];
|
||||
if (operation == GSFileHandleConnectCompletionNotification
|
||||
|| operation == GSSOCKSConnect)
|
||||
{ // Connection attempt completed.
|
||||
int result;
|
||||
int len = sizeof(result);
|
||||
|
||||
#if defined(__MINGW__)
|
||||
if (getsockopt((SOCKET)_get_osfhandle(descriptor), SOL_SOCKET, SO_ERROR,
|
||||
(char*)&result, &len) == 0 && result != 0)
|
||||
#else
|
||||
if (getsockopt(descriptor, SOL_SOCKET, SO_ERROR,
|
||||
(char*)&result, &len) == 0 && result != 0)
|
||||
#endif
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat: @"Connect attempt failed - %s",
|
||||
GSLastErrorStr(result)];
|
||||
[info setObject: s forKey: GSFileHandleNotificationError];
|
||||
}
|
||||
else
|
||||
{
|
||||
readOK = YES;
|
||||
writeOK = YES;
|
||||
}
|
||||
connectOK = NO;
|
||||
[self postWriteNotification];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSData *item;
|
||||
int length;
|
||||
const void *ptr;
|
||||
|
||||
item = [info objectForKey: NSFileHandleNotificationDataItem];
|
||||
length = [item length];
|
||||
ptr = [item bytes];
|
||||
if (writePos < length)
|
||||
{
|
||||
int written;
|
||||
|
||||
written = [self write: (char*)ptr+writePos
|
||||
length: length-writePos];
|
||||
if (written <= 0)
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
if (written < 0 && WSAGetLastError()!= WSAEINTR
|
||||
&& WSAGetLastError()!= WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (written < 0 && errno != EAGAIN && errno != EINTR)
|
||||
#endif
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat:
|
||||
@"Write attempt failed - %s", GSLastErrorStr(errno)];
|
||||
[info setObject: s forKey: GSFileHandleNotificationError];
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writePos += written;
|
||||
}
|
||||
}
|
||||
if (writePos >= length)
|
||||
{ // Write operation completed.
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) receivedEvent: (void*)data
|
||||
type: (RunLoopEventType)type
|
||||
extra: (void*)extra
|
||||
forMode: (NSString*)mode
|
||||
{
|
||||
NSString *operation;
|
||||
#ifdef __MINGW32__
|
||||
WSANETWORKEVENTS ocurredEvents;
|
||||
#endif
|
||||
|
||||
NSDebugMLLog(@"NSFileHandle", @"%@ event: %d", self, type);
|
||||
|
||||
|
@ -2070,183 +2298,77 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
|
|||
{
|
||||
[self setNonBlocking: YES];
|
||||
}
|
||||
|
||||
if (type == ET_RDESC)
|
||||
#ifdef __MINGW32__
|
||||
if (WSAEnumNetworkEvents((SOCKET)_get_osfhandle(descriptor),
|
||||
event, &ocurredEvents) == SOCKET_ERROR)
|
||||
{
|
||||
operation = [readInfo objectForKey: NotificationKey];
|
||||
if (operation == NSFileHandleConnectionAcceptedNotification)
|
||||
NSLog(@"Error getting event type %d", WSAGetLastError());
|
||||
abort();
|
||||
}
|
||||
if (ocurredEvents.lNetworkEvents & FD_CONNECT)
|
||||
{
|
||||
NSDebugMLLog(@"NSFileHandle", @"Connect on %x", extra);
|
||||
ocurredEvents.lNetworkEvents ^= FD_CONNECT;
|
||||
[self receivedEventWrite];
|
||||
GSNotifyASAP();
|
||||
}
|
||||
if (ocurredEvents.lNetworkEvents & FD_ACCEPT)
|
||||
{
|
||||
NSDebugMLLog(@"NSFileHandle", @"Accept on %x", extra);
|
||||
ocurredEvents.lNetworkEvents ^= FD_ACCEPT;
|
||||
[self receivedEventRead];
|
||||
GSNotifyASAP();
|
||||
}
|
||||
if (ocurredEvents.lNetworkEvents & FD_WRITE)
|
||||
{
|
||||
NSDebugMLLog(@"NSFileHandle", @"Write on %x", extra);
|
||||
ocurredEvents.lNetworkEvents ^= FD_WRITE;
|
||||
[self receivedEventWrite];
|
||||
GSNotifyASAP();
|
||||
}
|
||||
if (ocurredEvents.lNetworkEvents & FD_READ)
|
||||
{
|
||||
NSDebugMLLog(@"NSFileHandle", @"Read on %x", extra);
|
||||
ocurredEvents.lNetworkEvents ^= FD_READ;
|
||||
[self receivedEventRead];
|
||||
GSNotifyASAP();
|
||||
}
|
||||
if (ocurredEvents.lNetworkEvents & FD_OOB)
|
||||
{
|
||||
NSDebugMLLog(@"NSFileHandle", @"OOB on %x", extra);
|
||||
ocurredEvents.lNetworkEvents ^= FD_OOB;
|
||||
[self receivedEventRead];
|
||||
GSNotifyASAP();
|
||||
}
|
||||
if (ocurredEvents.lNetworkEvents & FD_CLOSE)
|
||||
{
|
||||
NSDebugMLLog(@"NSFileHandle", @"Close on %x", extra);
|
||||
ocurredEvents.lNetworkEvents ^= FD_CLOSE;
|
||||
if ([writeInfo count] > 0)
|
||||
{
|
||||
struct sockaddr_in buf;
|
||||
#if defined(__MINGW__)
|
||||
SOCKET desc;
|
||||
#else
|
||||
int desc;
|
||||
#endif
|
||||
int blen = sizeof(buf);
|
||||
|
||||
#if defined(__MINGW__)
|
||||
desc = accept((SOCKET)_get_osfhandle(descriptor), (struct sockaddr*)&buf, &blen);
|
||||
#else
|
||||
desc = accept(descriptor, (struct sockaddr*)&buf, &blen);
|
||||
#endif
|
||||
if (desc == INVALID_SOCKET)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat: @"Accept attempt failed - %s",
|
||||
GSLastErrorStr(errno)];
|
||||
[readInfo setObject: s forKey: GSFileHandleNotificationError];
|
||||
}
|
||||
else
|
||||
{ // Accept attempt completed.
|
||||
GSFileHandle *h;
|
||||
struct sockaddr_in sin;
|
||||
int size = sizeof(sin);
|
||||
|
||||
#if defined(__MINGW__)
|
||||
h = [[[self class] alloc] initWithNativeHandle: (void*)desc
|
||||
closeOnDealloc: YES];
|
||||
#else
|
||||
h = [[[self class] alloc] initWithFileDescriptor: desc
|
||||
closeOnDealloc: YES];
|
||||
#endif
|
||||
h->isSocket = YES;
|
||||
getpeername(desc, (struct sockaddr*)&sin, &size);
|
||||
[h setAddr: &sin];
|
||||
[readInfo setObject: h
|
||||
forKey: NSFileHandleNotificationFileHandleItem];
|
||||
RELEASE(h);
|
||||
}
|
||||
[self postReadNotification];
|
||||
}
|
||||
else if (operation == NSFileHandleDataAvailableNotification)
|
||||
{
|
||||
[self postReadNotification];
|
||||
[self receivedEventWrite];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMutableData *item;
|
||||
int length;
|
||||
int received = 0;
|
||||
char buf[NETBUF_SIZE];
|
||||
|
||||
item = [readInfo objectForKey: NSFileHandleNotificationDataItem];
|
||||
/*
|
||||
* We may have a maximum data size set...
|
||||
*/
|
||||
if (readMax > 0)
|
||||
{
|
||||
length = (unsigned int)readMax - [item length];
|
||||
if (length > (int)sizeof(buf))
|
||||
{
|
||||
length = sizeof(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = sizeof(buf);
|
||||
}
|
||||
|
||||
received = [self read: buf length: length];
|
||||
if (received == 0)
|
||||
{ // Read up to end of file.
|
||||
[self postReadNotification];
|
||||
}
|
||||
else if (received < 0)
|
||||
{
|
||||
if (errno != EAGAIN && errno != EINTR)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat: @"Read attempt failed - %s",
|
||||
GSLastErrorStr(errno)];
|
||||
[readInfo setObject: s forKey: GSFileHandleNotificationError];
|
||||
[self postReadNotification];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[item appendBytes: buf length: received];
|
||||
if (readMax < 0 || (readMax > 0 && (int)[item length] == readMax))
|
||||
{
|
||||
// Read a single chunk of data
|
||||
[self postReadNotification];
|
||||
}
|
||||
}
|
||||
[self receivedEventRead];
|
||||
}
|
||||
GSNotifyASAP();
|
||||
}
|
||||
if (ocurredEvents.lNetworkEvents)
|
||||
{
|
||||
NSLog(@"Event not get %d", ocurredEvents.lNetworkEvents);
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
if (type == ET_RDESC)
|
||||
{
|
||||
[self receivedEventRead];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMutableDictionary *info;
|
||||
|
||||
info = [writeInfo objectAtIndex: 0];
|
||||
operation = [info objectForKey: NotificationKey];
|
||||
if (operation == GSFileHandleConnectCompletionNotification
|
||||
|| operation == GSSOCKSConnect)
|
||||
{ // Connection attempt completed.
|
||||
int result;
|
||||
int len = sizeof(result);
|
||||
|
||||
#if defined(__MINGW__)
|
||||
if (getsockopt((SOCKET)_get_osfhandle(descriptor), SOL_SOCKET, SO_ERROR,
|
||||
(char*)&result, &len) == 0 && result != 0)
|
||||
#else
|
||||
if (getsockopt(descriptor, SOL_SOCKET, SO_ERROR,
|
||||
(char*)&result, &len) == 0 && result != 0)
|
||||
#endif
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat: @"Connect attempt failed - %s",
|
||||
GSLastErrorStr(result)];
|
||||
[info setObject: s forKey: GSFileHandleNotificationError];
|
||||
}
|
||||
else
|
||||
{
|
||||
readOK = YES;
|
||||
writeOK = YES;
|
||||
}
|
||||
connectOK = NO;
|
||||
[self postWriteNotification];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSData *item;
|
||||
int length;
|
||||
const void *ptr;
|
||||
|
||||
item = [info objectForKey: NSFileHandleNotificationDataItem];
|
||||
length = [item length];
|
||||
ptr = [item bytes];
|
||||
if (writePos < length)
|
||||
{
|
||||
int written;
|
||||
|
||||
written = [self write: (char*)ptr+writePos
|
||||
length: length-writePos];
|
||||
if (written <= 0)
|
||||
{
|
||||
if (written < 0 && errno != EAGAIN && errno != EINTR)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat:
|
||||
@"Write attempt failed - %s", GSLastErrorStr(errno)];
|
||||
[info setObject: s forKey: GSFileHandleNotificationError];
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writePos += written;
|
||||
}
|
||||
}
|
||||
if (writePos >= length)
|
||||
{ // Write operation completed.
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
[self receivedEventWrite];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSDate*) timedOutEvent: (void*)data
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue