mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Name server updates.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3144 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e7d231a0ba
commit
3cc0e06afd
6 changed files with 1126 additions and 234 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
Thu Oct 29 13:30:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* src/UnixFileHandle.m: Improved handling of error conditions on
|
||||
background connection operations. Disable SIGPIPE to avoid abort
|
||||
when we attempt to write to a socket that's closed by the other end.
|
||||
* src/TCPPort.m: Modified to use NSPortNameServer, also changed to
|
||||
disable SIGPIPE on initialisation only, not on every write.
|
||||
* src/include/NSPortNameServer.h: new class.
|
||||
* src/NSPortNameServer.m: new class.
|
||||
* src/GNUmakefile: Added NSPortNameServer.
|
||||
|
||||
Wed Oct 28 14:30:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Tools/gdomap.c: Added command-line options to lookup, register, and
|
||||
|
|
47
Headers/gnustep/base/NSPortNameServer.h
Normal file
47
Headers/gnustep/base/NSPortNameServer.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* Interface of NSPortNameServer class for Distributed Objects
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
Created: October 1998
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __NSPortNameServer_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __NSPortNameServer_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
|
||||
@class NSPort, NSString, NSMutableData, NSFileHandle;
|
||||
|
||||
@interface NSPortNameServer : NSObject
|
||||
{
|
||||
NSFileHandle *handle; /* File handle to talk to gdomap. */
|
||||
NSMutableData *data; /* Where to accumulated incoming data. */
|
||||
unsigned expecting; /* Length of data we want. */
|
||||
}
|
||||
+ (id) defaultPortNameServer;
|
||||
- (NSPort*) portForName: (NSString*)name;
|
||||
- (NSPort*) portForName: (NSString*)name
|
||||
onHost: (NSString*)host;
|
||||
- (BOOL) registerPort: (NSPort*)port
|
||||
forName: (NSString*)name;
|
||||
- (void) removePortForName: (NSString*)name;
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
@ -340,6 +340,7 @@ NSPipe.m \
|
|||
NSPort.m \
|
||||
NSPortCoder.m \
|
||||
NSPortMessage.m \
|
||||
NSPortNameServer.m \
|
||||
NSProcessInfo.m \
|
||||
NSProtocolChecker.m \
|
||||
NSProxy.m \
|
||||
|
@ -433,6 +434,7 @@ Foundation/NSPathUtilities.h \
|
|||
Foundation/NSPort.h \
|
||||
Foundation/NSPortCoder.h \
|
||||
Foundation/NSPortMessage.h \
|
||||
Foundation/NSPortNameServer.h \
|
||||
Foundation/NSProcessInfo.h \
|
||||
Foundation/NSProtocolChecker.h \
|
||||
Foundation/NSProxy.h \
|
||||
|
|
765
Source/NSPortNameServer.m
Normal file
765
Source/NSPortNameServer.m
Normal file
|
@ -0,0 +1,765 @@
|
|||
/* Implementation of NSPortNameServer class for Distributed Objects
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
Created: October 1998
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSByteOrder.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <Foundation/NSLock.h>
|
||||
#include <Foundation/NSFileHandle.h>
|
||||
#include <Foundation/NSRunLoop.h>
|
||||
#include <Foundation/NSNotificationQueue.h>
|
||||
#include <Foundation/NSPort.h>
|
||||
#include <Foundation/NSPortNameServer.h>
|
||||
#include <gnustep/base/TcpPort.h>
|
||||
|
||||
/*
|
||||
* Protocol definition stuff for talking to gdomap process.
|
||||
*/
|
||||
#include "../Tools/gdomap.h"
|
||||
|
||||
/*
|
||||
* Macros to build text to start name server and to give an error
|
||||
* message about it - they include installation path information.
|
||||
*/
|
||||
#define stringify_it(X) #X
|
||||
#define make_gdomap_cmd(X) stringify_it(X) "/Tools/"GNUSTEP_TARGET_DIR"/gdomap &"
|
||||
#define make_gdomap_err(X) "check that " stringify_it(X) "/Tools/"GNUSTEP_TARGET_DIR"/gdomap is running and owned by root."
|
||||
|
||||
/*
|
||||
* Private methods for internal use only.
|
||||
*/
|
||||
@interface NSPortNameServer (Private)
|
||||
- (void) _close;
|
||||
- (void) _didConnect: (NSNotification*)notification;
|
||||
- (void) _didRead: (NSNotification*)notification;
|
||||
- (void) _didWrite: (NSNotification*)notification;
|
||||
- (void) _open: (NSString*)host;
|
||||
- (void) _retry;
|
||||
@end
|
||||
|
||||
@implementation NSPortNameServer
|
||||
|
||||
static NSTimeInterval writeTimeout = 5.0;
|
||||
static NSTimeInterval readTimeout = 15.0;
|
||||
static NSTimeInterval connectTimeout = 20.0;
|
||||
static NSString *serverPort = @"gdomap";
|
||||
static NSString *mode = @"NSPortServerLookupMode";
|
||||
static NSArray *modes = nil;
|
||||
static NSRecursiveLock *serverLock = nil;
|
||||
static NSPortNameServer *defaultServer = nil;
|
||||
|
||||
+ (id) allocWithZone: (NSZone*)aZone
|
||||
{
|
||||
[NSException raise: NSGenericException
|
||||
format: @"attempt to create extra port name server"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSPortNameServer class])
|
||||
{
|
||||
serverLock = [NSRecursiveLock new];
|
||||
[serverLock lock];
|
||||
if (modes == nil)
|
||||
{
|
||||
modes = [[NSArray alloc] initWithObjects: &mode count: 1];
|
||||
}
|
||||
[serverLock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
+ (id) defaultPortNameServer
|
||||
{
|
||||
if (defaultServer == nil)
|
||||
{
|
||||
NSPortNameServer *s;
|
||||
|
||||
[serverLock lock];
|
||||
if (defaultServer)
|
||||
{
|
||||
[serverLock unlock];
|
||||
return defaultServer;
|
||||
}
|
||||
s = (NSPortNameServer*)NSAllocateObject(self, 0, NSDefaultMallocZone());
|
||||
s->data = [NSMutableData new];
|
||||
defaultServer = s;
|
||||
[serverLock unlock];
|
||||
}
|
||||
return defaultServer;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[NSException raise: NSGenericException
|
||||
format: @"attempt to deallocate default port name server"];
|
||||
}
|
||||
|
||||
- (NSPort*) portForName: (NSString*)name
|
||||
{
|
||||
return [self portForName: name onHost: nil];
|
||||
}
|
||||
|
||||
- (NSPort*) portForName: (NSString*)name
|
||||
onHost: (NSString*)host
|
||||
{
|
||||
gdo_req msg; /* Message structure. */
|
||||
NSMutableData *dat; /* Hold message here. */
|
||||
unsigned len;
|
||||
NSRunLoop *loop = [NSRunLoop currentRunLoop];
|
||||
struct in_addr singleServer;
|
||||
struct in_addr *svrs = &singleServer;
|
||||
unsigned numSvrs;
|
||||
unsigned count;
|
||||
unsigned portNum = 0;
|
||||
|
||||
if (name == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"attempt to register port with nil name"];
|
||||
}
|
||||
|
||||
len = [name cStringLength];
|
||||
if (len == 0)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"attempt to register port with no name"];
|
||||
}
|
||||
if (len > GDO_NAME_MAX_LEN)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"name of port is too long (max %d) bytes",
|
||||
GDO_NAME_MAX_LEN];
|
||||
}
|
||||
|
||||
if (host != nil && [host isEqual: @"*"])
|
||||
{
|
||||
NSMutableData *tmp;
|
||||
unsigned bufsiz;
|
||||
unsigned length;
|
||||
|
||||
msg.rtype = GDO_SERVERS; /* Get a list of name servers. */
|
||||
msg.ptype = GDO_TCP_GDO; /* Port is TCP port for GNU DO */
|
||||
msg.nsize = 0;
|
||||
msg.port = 0;
|
||||
dat = [NSMutableData dataWithBytes: (void*)&msg length: sizeof(msg)];
|
||||
|
||||
[serverLock lock];
|
||||
NS_DURING
|
||||
{
|
||||
[self _open: nil];
|
||||
expecting = sizeof(msg);
|
||||
[handle writeInBackgroundAndNotify: dat
|
||||
forModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow: writeTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSPortTimeoutException
|
||||
format: @"timed out writing to gdomap"];
|
||||
}
|
||||
|
||||
expecting = sizeof(unsigned);
|
||||
[data setLength: 0];
|
||||
[handle readInBackgroundAndNotifyForModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow: readTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSPortTimeoutException
|
||||
format: @"timed out reading from gdomap"];
|
||||
}
|
||||
numSvrs = NSSwapBigIntToHost(*(unsigned*)[data bytes]);
|
||||
if (numSvrs == 0)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"failed to get list of name servers on net"];
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate size of buffer for server internet addresses and
|
||||
* allocate a buffer to store them in.
|
||||
*/
|
||||
bufsiz = numSvrs * sizeof(struct in_addr);
|
||||
tmp = [NSMutableData dataWithLength: bufsiz];
|
||||
svrs = (struct in_addr*)[tmp mutableBytes];
|
||||
|
||||
/*
|
||||
* Read the addresses from the name server if necessary
|
||||
* and copy them to our newly allocated buffer.
|
||||
* We may already have some/all of the data, in which case
|
||||
* we don't need to do a read.
|
||||
*/
|
||||
length = [data length] - sizeof(unsigned);
|
||||
if (length > 0)
|
||||
{
|
||||
void *bytes = [data mutableBytes];
|
||||
|
||||
memcpy(bytes, bytes+sizeof(unsigned), length);
|
||||
[data setLength: length];
|
||||
}
|
||||
else
|
||||
{
|
||||
[data setLength: 0];
|
||||
}
|
||||
|
||||
if (length < bufsiz)
|
||||
{
|
||||
expecting = bufsiz;
|
||||
[handle readInBackgroundAndNotifyForModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow:
|
||||
readTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSPortTimeoutException
|
||||
format: @"timed out reading from gdomap"];
|
||||
}
|
||||
}
|
||||
|
||||
[data getBytes: (void*)svrs length: bufsiz];
|
||||
[self _close];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
/*
|
||||
* If we had a problem - unlock before continueing.
|
||||
*/
|
||||
[serverLock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[serverLock unlock];
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Query a single nameserver - on the local host.
|
||||
*/
|
||||
numSvrs = 1;
|
||||
#ifndef HAVE_INET_ATON
|
||||
svrs->s_addr = inet_addr("127.0.0.1");
|
||||
#else
|
||||
inet_aton("127.0.0.1", &svrs->s_addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
[serverLock lock];
|
||||
NS_DURING
|
||||
{
|
||||
for (count = 0; count < numSvrs; count++)
|
||||
{
|
||||
NSString *addr;
|
||||
|
||||
msg.rtype = GDO_LOOKUP; /* Find the named port. */
|
||||
msg.ptype = GDO_TCP_GDO; /* Port is TCP port for GNU DO */
|
||||
msg.port = 0;
|
||||
msg.nsize = len;
|
||||
[name getCString: msg.name];
|
||||
dat = [NSMutableData dataWithBytes: (void*)&msg length: sizeof(msg)];
|
||||
|
||||
addr = [NSString stringWithCString: (char*)inet_ntoa(svrs[count])];
|
||||
[self _open: addr];
|
||||
expecting = sizeof(msg);
|
||||
[handle writeInBackgroundAndNotify: dat
|
||||
forModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow: writeTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
[self _close];
|
||||
}
|
||||
else
|
||||
{
|
||||
expecting = sizeof(unsigned);
|
||||
[data setLength: 0];
|
||||
[handle readInBackgroundAndNotifyForModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow:
|
||||
readTimeout]];
|
||||
[self _close];
|
||||
if (expecting == 0)
|
||||
{
|
||||
portNum = NSSwapBigIntToHost(*(unsigned*)[data bytes]);
|
||||
if (portNum != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
/*
|
||||
* If we had a problem - unlock before continueing.
|
||||
*/
|
||||
[serverLock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[serverLock unlock];
|
||||
|
||||
if (portNum)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
NSPort *p;
|
||||
unsigned short n;
|
||||
|
||||
memset(&sin, '\0', sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
/*
|
||||
* The returned port is an unsigned int - so we have to
|
||||
* convert to a short in network byte order (big endian).
|
||||
*/
|
||||
n = (unsigned short)portNum;
|
||||
sin.sin_port = NSSwapHostShortToBig(n);
|
||||
|
||||
/*
|
||||
* The host addresses are given to us in network byte order
|
||||
* so we just copy the address into place.
|
||||
*/
|
||||
sin.sin_addr.s_addr = svrs[count].s_addr;
|
||||
|
||||
p = [TcpOutPort newForSendingToSockaddr: &sin
|
||||
withAcceptedSocket: 0
|
||||
pollingInPort: nil];
|
||||
return [p autorelease];
|
||||
}
|
||||
else
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) registerPort: (NSPort*)port
|
||||
forName: (NSString*)name
|
||||
{
|
||||
gdo_req msg; /* Message structure. */
|
||||
NSMutableData *dat; /* Hold message here. */
|
||||
unsigned len;
|
||||
NSRunLoop *loop = [NSRunLoop currentRunLoop];
|
||||
|
||||
if (name == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"attempt to register port with nil name"];
|
||||
}
|
||||
if (port == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"attempt to register nil port"];
|
||||
}
|
||||
|
||||
len = [name cStringLength];
|
||||
if (len == 0)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"attempt to register port with no name"];
|
||||
}
|
||||
if (len > GDO_NAME_MAX_LEN)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"name of port is too long (max %d) bytes",
|
||||
GDO_NAME_MAX_LEN];
|
||||
}
|
||||
|
||||
msg.rtype = GDO_REGISTER; /* Register a port. */
|
||||
msg.ptype = GDO_TCP_GDO; /* Port is TCP port for GNU DO */
|
||||
msg.nsize = len;
|
||||
[name getCString: msg.name];
|
||||
msg.port = NSSwapHostIntToBig((unsigned)[(TcpInPort*)port portNumber]);
|
||||
dat = [NSMutableData dataWithBytes: (void*)&msg length: sizeof(msg)];
|
||||
|
||||
/*
|
||||
* Lock out other threads while doing I/O to gdomap
|
||||
*/
|
||||
[serverLock lock];
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
[self _open: nil];
|
||||
|
||||
/*
|
||||
* Queue a write request in our own run mode then run until the
|
||||
* timeout period or until the write completes.
|
||||
*/
|
||||
expecting = sizeof(msg);
|
||||
[handle writeInBackgroundAndNotify: dat
|
||||
forModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow: writeTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSPortTimeoutException
|
||||
format: @"timed out writing to gdomap"];
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue a read request in our own run mode then run until the
|
||||
* timoeut period or until the read completes.
|
||||
*/
|
||||
expecting = sizeof(unsigned);
|
||||
[data setLength: 0];
|
||||
[handle readInBackgroundAndNotifyForModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow: readTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSPortTimeoutException
|
||||
format: @"timed out reading from gdomap"];
|
||||
}
|
||||
|
||||
/*
|
||||
* Finished with server - so close connection.
|
||||
*/
|
||||
[self _close];
|
||||
|
||||
if ([data length] != sizeof(unsigned))
|
||||
{
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"too much data read from gdomap"];
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned result = NSSwapBigIntToHost(*(unsigned*)[data bytes]);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
NSLog(@"NSPortNameServer unable to register '%@'\n", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
/*
|
||||
* If we had a problem - unlock before continueing.
|
||||
*/
|
||||
[serverLock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[serverLock unlock];
|
||||
}
|
||||
|
||||
- (void) removePortForName: (NSString*)name
|
||||
{
|
||||
gdo_req msg; /* Message structure. */
|
||||
NSMutableData *dat; /* Hold message here. */
|
||||
unsigned len;
|
||||
NSRunLoop *loop = [NSRunLoop currentRunLoop];
|
||||
|
||||
if (name == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"attempt to remove port with nil name"];
|
||||
}
|
||||
|
||||
len = [name cStringLength];
|
||||
if (len == 0)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"attempt to remove port with no name"];
|
||||
}
|
||||
if (len > GDO_NAME_MAX_LEN)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"name of port is too long (max %d) bytes",
|
||||
GDO_NAME_MAX_LEN];
|
||||
}
|
||||
|
||||
msg.rtype = GDO_UNREG; /* Unregister a port. */
|
||||
msg.ptype = GDO_TCP_GDO; /* Port is TCP port for GNU DO */
|
||||
msg.nsize = len;
|
||||
[name getCString: msg.name];
|
||||
msg.port = 0;
|
||||
dat = [NSMutableData dataWithBytes: (void*)&msg length: sizeof(msg)];
|
||||
|
||||
/*
|
||||
* Lock out other threads while doing I/O to gdomap
|
||||
*/
|
||||
[serverLock lock];
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
[self _open: nil];
|
||||
|
||||
/*
|
||||
* Queue a write request in our own run mode then run until the
|
||||
* timeout period or until the write completes.
|
||||
*/
|
||||
expecting = sizeof(msg);
|
||||
[handle writeInBackgroundAndNotify: dat
|
||||
forModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow: writeTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSPortTimeoutException
|
||||
format: @"timed out writing to gdomap"];
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue a read request in our own run mode then run until the
|
||||
* timeout period or until the read completes.
|
||||
*/
|
||||
expecting = sizeof(unsigned);
|
||||
[data setLength: 0];
|
||||
[handle readInBackgroundAndNotifyForModes: modes];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow: readTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSPortTimeoutException
|
||||
format: @"timed out reading from gdomap"];
|
||||
}
|
||||
|
||||
/*
|
||||
* Finished with server - so close connection.
|
||||
*/
|
||||
[self _close];
|
||||
|
||||
if ([data length] != sizeof(unsigned))
|
||||
{
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"too much data read from gdomap"];
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned result = NSSwapBigIntToHost(*(unsigned*)[data bytes]);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
NSLog(@"NSPortNameServer unable to unregister '%@'\n", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
/*
|
||||
* If we had a problem - unlock before continueing.
|
||||
*/
|
||||
[serverLock unlock];
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[serverLock unlock];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSPortNameServer (Private)
|
||||
- (void) _close
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
[NSNotificationCenter removeObserver: self
|
||||
name: GSFileHandleConnectCompletionNotification
|
||||
object: handle];
|
||||
[NSNotificationCenter removeObserver: self
|
||||
name: NSFileHandleReadCompletionNotification
|
||||
object: handle];
|
||||
[NSNotificationCenter removeObserver: self
|
||||
name: GSFileHandleWriteCompletionNotification
|
||||
object: handle];
|
||||
[handle closeFile];
|
||||
[handle release];
|
||||
handle = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _didConnect: (NSNotification*)notification
|
||||
{
|
||||
NSDictionary *userInfo = [notification userInfo];
|
||||
NSString *e;
|
||||
|
||||
e = [userInfo objectForKey:GSFileHandleNotificationError];
|
||||
if (e)
|
||||
{
|
||||
NSLog(@"NSPortNameServer failed connect to gdomap - %@", e);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* There should now be nothing for the runloop to do so
|
||||
* control should return to the method that started the connection.
|
||||
* Set 'expecting' to zero to show that the connection worked and
|
||||
* stop watching for connection completion.
|
||||
*/
|
||||
expecting = 0;
|
||||
[NSNotificationCenter removeObserver: self
|
||||
name: GSFileHandleConnectCompletionNotification
|
||||
object: handle];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _didRead: (NSNotification*)notification
|
||||
{
|
||||
NSDictionary *userInfo = [notification userInfo];
|
||||
NSData *d;
|
||||
|
||||
d = [userInfo objectForKey:NSFileHandleNotificationDataItem];
|
||||
|
||||
if (d == nil || [d length] == 0)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSGenericException
|
||||
format: @"NSPortNameServer lost connection to gdomap"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[data appendData: d];
|
||||
if ([data length] < expecting)
|
||||
{
|
||||
/*
|
||||
* Not enough data read yet - go read some more.
|
||||
*/
|
||||
[handle readInBackgroundAndNotifyForModes: modes];
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* There should now be nothing for the runloop to do so
|
||||
* control should return to the method that started the read.
|
||||
* Set 'expecting' to zero to show that the data was read.
|
||||
*/
|
||||
expecting = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _didWrite: (NSNotification*)notification
|
||||
{
|
||||
NSDictionary *userInfo = [notification userInfo];
|
||||
NSString *e;
|
||||
|
||||
e = [userInfo objectForKey:GSFileHandleNotificationError];
|
||||
if (e)
|
||||
{
|
||||
[self _close];
|
||||
[NSException raise: NSGenericException
|
||||
format: @"NSPortNameServer failed write to gdomap - %@", e];
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* There should now be nothing for the runloop to do so
|
||||
* control should return to the method that started the write.
|
||||
* Set 'expecting' to zero to show that the data was written.
|
||||
*/
|
||||
expecting = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _open: (NSString*)host
|
||||
{
|
||||
NSRunLoop *loop;
|
||||
NSString *hostname = host;
|
||||
|
||||
if (handle)
|
||||
{
|
||||
return; /* Connection already open. */
|
||||
}
|
||||
if (hostname == nil)
|
||||
{
|
||||
hostname = @"localhost";
|
||||
}
|
||||
|
||||
expecting = 1;
|
||||
handle = [NSFileHandle fileHandleAsClientInBackgroundAtAddress: host
|
||||
service: serverPort
|
||||
protocol: @"tcp"
|
||||
forModes: modes];
|
||||
|
||||
if (handle == nil)
|
||||
{
|
||||
[NSException raise: NSGenericException
|
||||
format: @"failed to create file handle to gdomap on %@",
|
||||
hostname];
|
||||
}
|
||||
|
||||
[handle retain];
|
||||
[NSNotificationCenter addObserver: self
|
||||
selector: @selector(_didConnect:)
|
||||
name: GSFileHandleConnectCompletionNotification
|
||||
object: handle];
|
||||
[NSNotificationCenter addObserver: self
|
||||
selector: @selector(_didRead:)
|
||||
name: NSFileHandleReadCompletionNotification
|
||||
object: handle];
|
||||
[NSNotificationCenter addObserver: self
|
||||
selector: @selector(_didWrite:)
|
||||
name: GSFileHandleWriteCompletionNotification
|
||||
object: handle];
|
||||
loop = [NSRunLoop currentRunLoop];
|
||||
[loop runMode: mode
|
||||
beforeDate: [NSDate dateWithTimeIntervalSinceNow: connectTimeout]];
|
||||
if (expecting)
|
||||
{
|
||||
static BOOL retrying = NO;
|
||||
|
||||
[self _close];
|
||||
if (retrying == NO)
|
||||
{
|
||||
retrying = YES;
|
||||
NS_DURING
|
||||
{
|
||||
[self _retry];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
retrying = NO;
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
retrying = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"NSPortNameServer failed to connect to gdomap - %s",
|
||||
make_gdomap_err(GNUSTEP_INSTALL_PREFIX));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _retry
|
||||
{
|
||||
NSLog(@"NSPortNameServer attempting to start gdomap on local host");
|
||||
system(make_gdomap_cmd(GNUSTEP_INSTALL_PREFIX));
|
||||
sleep(5);
|
||||
NSLog(@"NSPortNameServer retrying connection attempt to gdomap");
|
||||
[self _open: nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
#include <gnustep/base/Invocation.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSDate.h>
|
||||
#include <Foundation/NSPortNameServer.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
@ -68,6 +69,7 @@
|
|||
#define NBLK_OPT FNDELAY
|
||||
#endif
|
||||
|
||||
#define NSPORTNAMESERVER 1
|
||||
#define GDOMAP 1 /* 1 = Use name server. */
|
||||
#define stringify_it(X) #X
|
||||
#define make_gdomap_cmd(X) stringify_it(X) "/Tools/"GNUSTEP_TARGET_DIR"/gdomap &"
|
||||
|
@ -317,15 +319,7 @@ tryWrite(int desc, int tim, unsigned char* dat, int len)
|
|||
return(-1); /* Error in select. */
|
||||
}
|
||||
else if (len > 0) {
|
||||
void (*ifun)();
|
||||
|
||||
/*
|
||||
* Should be able to write this short a message immediately, but
|
||||
* if the connection is lost we will get a signal we must trap.
|
||||
*/
|
||||
ifun = signal(SIGPIPE, (void(*)(int))SIG_IGN);
|
||||
rval = write(desc, &dat[pos], len - pos);
|
||||
signal(SIGPIPE, ifun);
|
||||
|
||||
if (rval <= 0) {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
|
@ -745,10 +739,17 @@ static NSMapTable* port_number_2_port;
|
|||
+ (void) initialize
|
||||
{
|
||||
if (self == [TcpInPort class])
|
||||
port_number_2_port =
|
||||
NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
init_port_socket_2_port ();
|
||||
{
|
||||
port_number_2_port =
|
||||
NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
init_port_socket_2_port ();
|
||||
/*
|
||||
* If SIGPIPE is not ignored, we will abort on any attempt to
|
||||
* write to a pipe/socket that has been closed by the other end!
|
||||
*/
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is the designated initializer.
|
||||
|
@ -919,12 +920,17 @@ static NSMapTable* port_number_2_port;
|
|||
struct sockaddr_in sin;
|
||||
|
||||
if (p) {
|
||||
#if NSPORTNAMESERVER
|
||||
[[NSPortNameServer defaultPortNameServer] registerPort: p
|
||||
forName: name];
|
||||
#else
|
||||
int port = [p portNumber];
|
||||
|
||||
if (nameServer([name cString], 0, GDO_REGISTER, &sin, port, 1) == 0) {
|
||||
[p release];
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return p;
|
||||
#else
|
||||
|
@ -1390,6 +1396,11 @@ static NSMapTable *out_port_bag = NULL;
|
|||
init_port_socket_2_port ();
|
||||
out_port_bag = NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
/*
|
||||
* If SIGPIPE is not ignored, we will abort on any attempt to
|
||||
* write to a pipe/socket that has been closed by the other end!
|
||||
*/
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1647,6 +1658,13 @@ static NSMapTable *out_port_bag = NULL;
|
|||
onHost: (NSString*)hostname
|
||||
{
|
||||
#ifdef GDOMAP
|
||||
#if NSPORTNAMESERVER
|
||||
id c;
|
||||
|
||||
c = [[NSPortNameServer defaultPortNameServer] portForName: name
|
||||
onHost: hostname];
|
||||
return [c retain];
|
||||
#else
|
||||
struct sockaddr_in sin[100];
|
||||
int found;
|
||||
int i;
|
||||
|
@ -1661,6 +1679,7 @@ static NSMapTable *out_port_bag = NULL;
|
|||
pollingInPort: nil];
|
||||
}
|
||||
return c;
|
||||
#endif
|
||||
#else
|
||||
return [self newForSendingToPortNumber:
|
||||
name_2_port_number ([name cString]) onHost: hostname];;
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <signal.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include <sys/file.h>
|
||||
|
@ -101,7 +102,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
*/
|
||||
if (name)
|
||||
{
|
||||
NSHost* host = [NSHost hostWithName:name];
|
||||
NSHost* host = [NSHost hostWithName: name];
|
||||
|
||||
if (host)
|
||||
name = [host address];
|
||||
|
@ -146,12 +147,24 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
}
|
||||
|
||||
+ allocWithZone:(NSZone*)z
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [UnixFileHandle class])
|
||||
{
|
||||
/*
|
||||
* If SIGPIPE is not ignored, we will abort on any attempt to
|
||||
* write to a pipe/socket that has been closed by the other end!
|
||||
*/
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
}
|
||||
}
|
||||
|
||||
+ (id) allocWithZone: (NSZone*)z
|
||||
{
|
||||
return NSAllocateObject ([self class], 0, z);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
- (void) dealloc
|
||||
{
|
||||
[address release];
|
||||
[service release];
|
||||
|
@ -186,12 +199,12 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithNullDevice];
|
||||
return [self initWithNullDevice];
|
||||
}
|
||||
|
||||
- (id)initAsClientAtAddress:a
|
||||
service:s
|
||||
protocol:p
|
||||
- (id)initAsClientAtAddress: a
|
||||
service: s
|
||||
protocol: p
|
||||
{
|
||||
int net;
|
||||
struct sockaddr_in sin;
|
||||
|
@ -217,7 +230,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return nil;
|
||||
}
|
||||
|
||||
self = [self initWithFileDescriptor:net closeOnDealloc:YES];
|
||||
self = [self initWithFileDescriptor: net closeOnDealloc: YES];
|
||||
if (self)
|
||||
{
|
||||
if (connect(net, (struct sockaddr*)&sin, sizeof(sin)) < 0)
|
||||
|
@ -234,10 +247,10 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id)initAsClientInBackgroundAtAddress:a
|
||||
service:s
|
||||
protocol:p
|
||||
forModes:modes
|
||||
- (id)initAsClientInBackgroundAtAddress: a
|
||||
service: s
|
||||
protocol: p
|
||||
forModes: modes
|
||||
{
|
||||
int net;
|
||||
struct sockaddr_in sin;
|
||||
|
@ -263,7 +276,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return nil;
|
||||
}
|
||||
|
||||
self = [self initWithFileDescriptor:net closeOnDealloc:YES];
|
||||
self = [self initWithFileDescriptor: net closeOnDealloc: YES];
|
||||
if (self)
|
||||
{
|
||||
NSMutableDictionary* info;
|
||||
|
@ -277,13 +290,13 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return nil;
|
||||
}
|
||||
|
||||
info = [[NSMutableDictionary dictionaryWithCapacity:4] retain];
|
||||
[info setObject:address forKey:NSFileHandleNotificationDataItem];
|
||||
[info setObject:GSFileHandleConnectCompletionNotification
|
||||
forKey:NotificationKey];
|
||||
info = [[NSMutableDictionary dictionaryWithCapacity: 4] retain];
|
||||
[info setObject: address forKey: NSFileHandleNotificationDataItem];
|
||||
[info setObject: GSFileHandleConnectCompletionNotification
|
||||
forKey: NotificationKey];
|
||||
if (modes)
|
||||
[info setObject:modes forKey:NSFileHandleNotificationMonitorModes];
|
||||
[writeInfo addObject:info];
|
||||
[info setObject: modes forKey: NSFileHandleNotificationMonitorModes];
|
||||
[writeInfo addObject: info];
|
||||
[info release];
|
||||
[self watchWriteDescriptor];
|
||||
connectOK = YES;
|
||||
|
@ -293,9 +306,9 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id)initAsServerAtAddress:a
|
||||
service:s
|
||||
protocol:p
|
||||
- (id)initAsServerAtAddress: a
|
||||
service: s
|
||||
protocol: p
|
||||
{
|
||||
int status = 1;
|
||||
int net;
|
||||
|
@ -342,7 +355,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return nil;
|
||||
}
|
||||
|
||||
self = [self initWithFileDescriptor:net closeOnDealloc:YES];
|
||||
self = [self initWithFileDescriptor: net closeOnDealloc: YES];
|
||||
if (self)
|
||||
{
|
||||
acceptOK = YES;
|
||||
|
@ -353,7 +366,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id)initForReadingAtPath:(NSString*)path
|
||||
- (id)initForReadingAtPath: (NSString*)path
|
||||
{
|
||||
int d = open([path fileSystemRepresentation], O_RDONLY);
|
||||
|
||||
|
@ -364,14 +377,14 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
else
|
||||
{
|
||||
self = [self initWithFileDescriptor:d closeOnDealloc:YES];
|
||||
self = [self initWithFileDescriptor: d closeOnDealloc: YES];
|
||||
if (self)
|
||||
writeOK = NO;
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
- (id)initForWritingAtPath:(NSString*)path
|
||||
- (id)initForWritingAtPath: (NSString*)path
|
||||
{
|
||||
int d = open([path fileSystemRepresentation], O_WRONLY);
|
||||
|
||||
|
@ -382,14 +395,14 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
else
|
||||
{
|
||||
self = [self initWithFileDescriptor:d closeOnDealloc:YES];
|
||||
self = [self initWithFileDescriptor: d closeOnDealloc: YES];
|
||||
if (self)
|
||||
readOK = NO;
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
- (id)initForUpdatingAtPath:(NSString*)path
|
||||
- (id)initForUpdatingAtPath: (NSString*)path
|
||||
{
|
||||
int d = open([path fileSystemRepresentation], O_RDWR);
|
||||
|
||||
|
@ -400,7 +413,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
else
|
||||
{
|
||||
return [self initWithFileDescriptor:d closeOnDealloc:YES];
|
||||
return [self initWithFileDescriptor: d closeOnDealloc: YES];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -413,7 +426,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
else
|
||||
{
|
||||
[self initWithFileDescriptor:2 closeOnDealloc:NO];
|
||||
[self initWithFileDescriptor: 2 closeOnDealloc: NO];
|
||||
fh_stderr = self;
|
||||
}
|
||||
self = fh_stderr;
|
||||
|
@ -431,7 +444,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
else
|
||||
{
|
||||
[self initWithFileDescriptor:0 closeOnDealloc:NO];
|
||||
[self initWithFileDescriptor: 0 closeOnDealloc: NO];
|
||||
fh_stdin = self;
|
||||
}
|
||||
self = fh_stdin;
|
||||
|
@ -449,7 +462,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
else
|
||||
{
|
||||
[self initWithFileDescriptor:1 closeOnDealloc:NO];
|
||||
[self initWithFileDescriptor: 1 closeOnDealloc: NO];
|
||||
fh_stdout = self;
|
||||
}
|
||||
self = fh_stdout;
|
||||
|
@ -460,15 +473,15 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
- (id)initWithNullDevice
|
||||
{
|
||||
self = [self initWithFileDescriptor:open("/dev/null", O_RDWR)
|
||||
closeOnDealloc:YES];
|
||||
self = [self initWithFileDescriptor: open("/dev/null", O_RDWR)
|
||||
closeOnDealloc: YES];
|
||||
if (self) {
|
||||
isNullDevice = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithFileDescriptor:(int)desc closeOnDealloc:(BOOL)flag
|
||||
- (id)initWithFileDescriptor: (int)desc closeOnDealloc: (BOOL)flag
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
|
@ -506,14 +519,14 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithNativeHandle:(void*)hdl
|
||||
- (id)initWithNativeHandle: (void*)hdl
|
||||
{
|
||||
return [self initWithFileDescriptor:(int)hdl closeOnDealloc:NO];
|
||||
return [self initWithFileDescriptor: (int)hdl closeOnDealloc: NO];
|
||||
}
|
||||
|
||||
- (id)initWithNativeHandle:(void*)hdl closeOnDealloc:(BOOL)flag
|
||||
- (id)initWithNativeHandle: (void*)hdl closeOnDealloc: (BOOL)flag
|
||||
{
|
||||
return [self initWithFileDescriptor:(int)hdl closeOnDealloc:flag];
|
||||
return [self initWithFileDescriptor: (int)hdl closeOnDealloc: flag];
|
||||
}
|
||||
|
||||
- (void)checkAccept
|
||||
|
@ -525,7 +538,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
if (readInfo)
|
||||
{
|
||||
id operation = [readInfo objectForKey:NotificationKey];
|
||||
id operation = [readInfo objectForKey: NotificationKey];
|
||||
|
||||
if (operation == NSFileHandleConnectionAcceptedNotification)
|
||||
{
|
||||
|
@ -549,8 +562,8 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
if ([writeInfo count] > 0)
|
||||
{
|
||||
id info = [writeInfo objectAtIndex:0];
|
||||
id operation = [info objectForKey:NotificationKey];
|
||||
id info = [writeInfo objectAtIndex: 0];
|
||||
id operation = [info objectForKey: NotificationKey];
|
||||
|
||||
if (operation == GSFileHandleConnectCompletionNotification)
|
||||
{
|
||||
|
@ -574,7 +587,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
if (readInfo)
|
||||
{
|
||||
id operation = [readInfo objectForKey:NotificationKey];
|
||||
id operation = [readInfo objectForKey: NotificationKey];
|
||||
|
||||
if (operation == NSFileHandleConnectionAcceptedNotification)
|
||||
{
|
||||
|
@ -598,8 +611,8 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
if ([writeInfo count] > 0)
|
||||
{
|
||||
id info = [writeInfo objectAtIndex:0];
|
||||
id operation = [info objectForKey:NotificationKey];
|
||||
id info = [writeInfo objectAtIndex: 0];
|
||||
id operation = [info objectForKey: NotificationKey];
|
||||
|
||||
if (operation == GSFileHandleConnectCompletionNotification)
|
||||
{
|
||||
|
@ -634,12 +647,12 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
[self checkRead];
|
||||
if (isNonBlocking == YES)
|
||||
[self setNonBlocking: NO];
|
||||
d = [NSMutableData dataWithCapacity:0];
|
||||
d = [NSMutableData dataWithCapacity: 0];
|
||||
if (isStandardFile)
|
||||
{
|
||||
while ((len = read(descriptor, buf, sizeof(buf))) > 0)
|
||||
{
|
||||
[d appendBytes:buf length:len];
|
||||
[d appendBytes: buf length: len];
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -668,7 +681,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
if ((len = read(descriptor, buf, count)) > 0)
|
||||
{
|
||||
[d appendBytes:buf length:len];
|
||||
[d appendBytes: buf length: len];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -690,10 +703,10 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
[self checkRead];
|
||||
if (isNonBlocking == YES)
|
||||
[self setNonBlocking: NO];
|
||||
d = [NSMutableData dataWithCapacity:0];
|
||||
d = [NSMutableData dataWithCapacity: 0];
|
||||
while ((len = read(descriptor, buf, sizeof(buf))) > 0)
|
||||
{
|
||||
[d appendBytes:buf length:len];
|
||||
[d appendBytes: buf length: len];
|
||||
}
|
||||
if (len < 0)
|
||||
{
|
||||
|
@ -704,7 +717,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return d;
|
||||
}
|
||||
|
||||
- (NSData*)readDataOfLength:(unsigned int)len
|
||||
- (NSData*)readDataOfLength: (unsigned int)len
|
||||
{
|
||||
NSMutableData* d;
|
||||
int pos;
|
||||
|
@ -721,11 +734,11 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
format: @"unable to read from descriptor - %s",
|
||||
strerror(errno)];
|
||||
}
|
||||
[d setLength:pos];
|
||||
[d setLength: pos];
|
||||
return d;
|
||||
}
|
||||
|
||||
- (void)writeData:(NSData*)item
|
||||
- (void)writeData: (NSData*)item
|
||||
{
|
||||
int rval = 0;
|
||||
const void* ptr = [item bytes];
|
||||
|
@ -757,74 +770,74 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
// Asynchronous I/O operations
|
||||
|
||||
- (void)acceptConnectionInBackgroundAndNotifyForModes:(NSArray*)modes
|
||||
- (void)acceptConnectionInBackgroundAndNotifyForModes: (NSArray*)modes
|
||||
{
|
||||
[self checkAccept];
|
||||
readPos = 0;
|
||||
[readInfo release];
|
||||
readInfo = [[NSMutableDictionary dictionaryWithCapacity:4] retain];
|
||||
[readInfo setObject:NSFileHandleConnectionAcceptedNotification
|
||||
forKey:NotificationKey];
|
||||
[self watchReadDescriptorForModes:modes];
|
||||
readInfo = [[NSMutableDictionary dictionaryWithCapacity: 4] retain];
|
||||
[readInfo setObject: NSFileHandleConnectionAcceptedNotification
|
||||
forKey: NotificationKey];
|
||||
[self watchReadDescriptorForModes: modes];
|
||||
}
|
||||
|
||||
- (void)acceptConnectionInBackgroundAndNotify
|
||||
{
|
||||
[self acceptConnectionInBackgroundAndNotifyForModes:nil];
|
||||
[self acceptConnectionInBackgroundAndNotifyForModes: nil];
|
||||
}
|
||||
|
||||
- (void)readInBackgroundAndNotifyForModes:(NSArray*)modes
|
||||
- (void)readInBackgroundAndNotifyForModes: (NSArray*)modes
|
||||
{
|
||||
[self checkRead];
|
||||
readPos = 0;
|
||||
[readInfo release];
|
||||
readInfo = [[NSMutableDictionary dictionaryWithCapacity:4] retain];
|
||||
[readInfo setObject:NSFileHandleReadCompletionNotification
|
||||
forKey:NotificationKey];
|
||||
[readInfo setObject:[NSMutableData dataWithCapacity:0]
|
||||
forKey:NSFileHandleNotificationDataItem];
|
||||
[self watchReadDescriptorForModes:modes];
|
||||
readInfo = [[NSMutableDictionary dictionaryWithCapacity: 4] retain];
|
||||
[readInfo setObject: NSFileHandleReadCompletionNotification
|
||||
forKey: NotificationKey];
|
||||
[readInfo setObject: [NSMutableData dataWithCapacity: 0]
|
||||
forKey: NSFileHandleNotificationDataItem];
|
||||
[self watchReadDescriptorForModes: modes];
|
||||
}
|
||||
|
||||
- (void)readInBackgroundAndNotify
|
||||
{
|
||||
return [self readInBackgroundAndNotifyForModes:nil];
|
||||
return [self readInBackgroundAndNotifyForModes: nil];
|
||||
}
|
||||
|
||||
- (void)readToEndOfFileInBackgroundAndNotifyForModes:(NSArray*)modes
|
||||
- (void)readToEndOfFileInBackgroundAndNotifyForModes: (NSArray*)modes
|
||||
{
|
||||
[self checkRead];
|
||||
readPos = 0;
|
||||
[readInfo release];
|
||||
readInfo = [[NSMutableDictionary dictionaryWithCapacity:4] retain];
|
||||
[readInfo setObject:NSFileHandleReadToEndOfFileCompletionNotification
|
||||
forKey:NotificationKey];
|
||||
[readInfo setObject:[NSMutableData dataWithCapacity:0]
|
||||
forKey:NSFileHandleNotificationDataItem];
|
||||
[self watchReadDescriptorForModes:modes];
|
||||
readInfo = [[NSMutableDictionary dictionaryWithCapacity: 4] retain];
|
||||
[readInfo setObject: NSFileHandleReadToEndOfFileCompletionNotification
|
||||
forKey: NotificationKey];
|
||||
[readInfo setObject: [NSMutableData dataWithCapacity: 0]
|
||||
forKey: NSFileHandleNotificationDataItem];
|
||||
[self watchReadDescriptorForModes: modes];
|
||||
}
|
||||
|
||||
- (void)readToEndOfFileInBackgroundAndNotify
|
||||
{
|
||||
return [self readToEndOfFileInBackgroundAndNotifyForModes:nil];
|
||||
return [self readToEndOfFileInBackgroundAndNotifyForModes: nil];
|
||||
}
|
||||
|
||||
- (void)waitForDataInBackgroundAndNotifyForModes:(NSArray*)modes
|
||||
- (void)waitForDataInBackgroundAndNotifyForModes: (NSArray*)modes
|
||||
{
|
||||
[self checkRead];
|
||||
readPos = 0;
|
||||
[readInfo release];
|
||||
readInfo = [[NSMutableDictionary dictionaryWithCapacity:4] retain];
|
||||
[readInfo setObject:NSFileHandleDataAvailableNotification
|
||||
forKey:NotificationKey];
|
||||
[readInfo setObject:[NSMutableData dataWithCapacity:0]
|
||||
forKey:NSFileHandleNotificationDataItem];
|
||||
[self watchReadDescriptorForModes:modes];
|
||||
readInfo = [[NSMutableDictionary dictionaryWithCapacity: 4] retain];
|
||||
[readInfo setObject: NSFileHandleDataAvailableNotification
|
||||
forKey: NotificationKey];
|
||||
[readInfo setObject: [NSMutableData dataWithCapacity: 0]
|
||||
forKey: NSFileHandleNotificationDataItem];
|
||||
[self watchReadDescriptorForModes: modes];
|
||||
}
|
||||
|
||||
- (void)waitForDataInBackgroundAndNotify
|
||||
{
|
||||
return [self waitForDataInBackgroundAndNotifyForModes:nil];
|
||||
return [self waitForDataInBackgroundAndNotifyForModes: nil];
|
||||
}
|
||||
|
||||
// Seeking within a file
|
||||
|
@ -859,7 +872,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return (unsigned long long)result;
|
||||
}
|
||||
|
||||
- (void)seekToFileOffset:(unsigned long long)pos
|
||||
- (void)seekToFileOffset: (unsigned long long)pos
|
||||
{
|
||||
off_t result = -1;
|
||||
|
||||
|
@ -903,34 +916,34 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
(void)sync();
|
||||
}
|
||||
|
||||
- (void)truncateFileAtOffset:(unsigned long long)pos
|
||||
- (void)truncateFileAtOffset: (unsigned long long)pos
|
||||
{
|
||||
if (isStandardFile && descriptor >= 0)
|
||||
(void)ftruncate(descriptor, pos);
|
||||
[self seekToFileOffset:pos];
|
||||
[self seekToFileOffset: pos];
|
||||
}
|
||||
|
||||
- (void)writeInBackgroundAndNotify:(NSData*)item forModes:(NSArray*)modes
|
||||
- (void)writeInBackgroundAndNotify: (NSData*)item forModes: (NSArray*)modes
|
||||
{
|
||||
NSMutableDictionary* info;
|
||||
|
||||
[self checkWrite];
|
||||
|
||||
info = [[NSMutableDictionary dictionaryWithCapacity:4] retain];
|
||||
[info setObject:item forKey:NSFileHandleNotificationDataItem];
|
||||
[info setObject:GSFileHandleWriteCompletionNotification
|
||||
forKey:NotificationKey];
|
||||
info = [[NSMutableDictionary dictionaryWithCapacity: 4] retain];
|
||||
[info setObject: item forKey: NSFileHandleNotificationDataItem];
|
||||
[info setObject: GSFileHandleWriteCompletionNotification
|
||||
forKey: NotificationKey];
|
||||
if (modes)
|
||||
[info setObject:modes forKey:NSFileHandleNotificationMonitorModes];
|
||||
[info setObject: modes forKey: NSFileHandleNotificationMonitorModes];
|
||||
|
||||
[writeInfo addObject:info];
|
||||
[writeInfo addObject: info];
|
||||
[info release];
|
||||
[self watchWriteDescriptor];
|
||||
}
|
||||
|
||||
- (void)writeInBackgroundAndNotify:(NSData*)item;
|
||||
- (void)writeInBackgroundAndNotify: (NSData*)item;
|
||||
{
|
||||
[self writeInBackgroundAndNotify:item forModes:nil];
|
||||
[self writeInBackgroundAndNotify: item forModes: nil];
|
||||
}
|
||||
|
||||
- (void)postReadNotification
|
||||
|
@ -942,39 +955,39 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
[self ignoreReadDescriptor];
|
||||
readInfo = nil;
|
||||
modes = (NSArray*)[info objectForKey:NSFileHandleNotificationMonitorModes];
|
||||
name = (NSString*)[info objectForKey:NotificationKey];
|
||||
modes = (NSArray*)[info objectForKey: NSFileHandleNotificationMonitorModes];
|
||||
name = (NSString*)[info objectForKey: NotificationKey];
|
||||
|
||||
n = [NSNotification notificationWithName:name object:self userInfo:info];
|
||||
n = [NSNotification notificationWithName: name object: self userInfo: info];
|
||||
|
||||
[info release]; /* Retained by the notification. */
|
||||
|
||||
[[NSNotificationQueue defaultQueue] enqueueNotification:n
|
||||
postingStyle:NSPostASAP
|
||||
coalesceMask:NSNotificationNoCoalescing
|
||||
forModes:modes];
|
||||
[[NSNotificationQueue defaultQueue] enqueueNotification: n
|
||||
postingStyle: NSPostASAP
|
||||
coalesceMask: NSNotificationNoCoalescing
|
||||
forModes: modes];
|
||||
}
|
||||
|
||||
- (void)postWriteNotification
|
||||
{
|
||||
NSMutableDictionary* info = [writeInfo objectAtIndex:0];
|
||||
NSMutableDictionary* info = [writeInfo objectAtIndex: 0];
|
||||
NSNotification* n;
|
||||
NSArray* modes;
|
||||
NSString* name;
|
||||
|
||||
[self ignoreWriteDescriptor];
|
||||
modes = (NSArray*)[info objectForKey:NSFileHandleNotificationMonitorModes];
|
||||
name = (NSString*)[info objectForKey:NotificationKey];
|
||||
modes = (NSArray*)[info objectForKey: NSFileHandleNotificationMonitorModes];
|
||||
name = (NSString*)[info objectForKey: NotificationKey];
|
||||
|
||||
n = [NSNotification notificationWithName:name object:self userInfo:info];
|
||||
n = [NSNotification notificationWithName: name object: self userInfo: info];
|
||||
|
||||
writePos = 0;
|
||||
[writeInfo removeObjectAtIndex:0]; /* Retained by notification. */
|
||||
[writeInfo removeObjectAtIndex: 0]; /* Retained by notification. */
|
||||
|
||||
[[NSNotificationQueue defaultQueue] enqueueNotification:n
|
||||
postingStyle:NSPostASAP
|
||||
coalesceMask:NSNotificationNoCoalescing
|
||||
forModes:modes];
|
||||
[[NSNotificationQueue defaultQueue] enqueueNotification: n
|
||||
postingStyle: NSPostASAP
|
||||
coalesceMask: NSNotificationNoCoalescing
|
||||
forModes: modes];
|
||||
[self watchWriteDescriptor]; /* In case of queued writes. */
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1017,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
modes = nil;
|
||||
|
||||
if (readInfo)
|
||||
modes = (NSArray*)[readInfo objectForKey:NSFileHandleNotificationMonitorModes];
|
||||
modes = (NSArray*)[readInfo objectForKey: NSFileHandleNotificationMonitorModes];
|
||||
|
||||
if (modes && [modes count])
|
||||
{
|
||||
|
@ -1014,7 +1027,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
{
|
||||
[l removeEvent: (void*)descriptor
|
||||
type: ET_RDESC
|
||||
forMode: [modes objectAtIndex:i]
|
||||
forMode: [modes objectAtIndex: i]
|
||||
all: YES];
|
||||
}
|
||||
}
|
||||
|
@ -1038,9 +1051,9 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
if ([writeInfo count] > 0)
|
||||
{
|
||||
NSMutableDictionary* info = [writeInfo objectAtIndex:0];
|
||||
NSMutableDictionary* info = [writeInfo objectAtIndex: 0];
|
||||
|
||||
modes=(NSArray*)[info objectForKey:NSFileHandleNotificationMonitorModes];
|
||||
modes=(NSArray*)[info objectForKey: NSFileHandleNotificationMonitorModes];
|
||||
}
|
||||
|
||||
if (modes && [modes count])
|
||||
|
@ -1051,7 +1064,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
{
|
||||
[l removeEvent: (void*)descriptor
|
||||
type: ET_WDESC
|
||||
forMode: [modes objectAtIndex:i]
|
||||
forMode: [modes objectAtIndex: i]
|
||||
all: YES];
|
||||
}
|
||||
}
|
||||
|
@ -1062,7 +1075,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
all: YES];
|
||||
}
|
||||
|
||||
- (void)watchReadDescriptorForModes:(NSArray*)modes;
|
||||
- (void)watchReadDescriptorForModes: (NSArray*)modes;
|
||||
{
|
||||
NSRunLoop *l;
|
||||
|
||||
|
@ -1080,9 +1093,9 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
[l addEvent: (void*)descriptor
|
||||
type: ET_RDESC
|
||||
watcher: self
|
||||
forMode: [modes objectAtIndex:i]];
|
||||
forMode: [modes objectAtIndex: i]];
|
||||
}
|
||||
[readInfo setObject:modes forKey:NSFileHandleNotificationMonitorModes];
|
||||
[readInfo setObject: modes forKey: NSFileHandleNotificationMonitorModes];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1100,14 +1113,14 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
if ([writeInfo count] > 0)
|
||||
{
|
||||
NSMutableDictionary* info = [writeInfo objectAtIndex:0];
|
||||
NSMutableDictionary* info = [writeInfo objectAtIndex: 0];
|
||||
NSRunLoop* l = [NSRunLoop currentRunLoop];
|
||||
NSArray* modes = nil;
|
||||
|
||||
|
||||
modes = [info objectForKey:NSFileHandleNotificationMonitorModes];
|
||||
modes = [info objectForKey: NSFileHandleNotificationMonitorModes];
|
||||
|
||||
[self setNonBlocking:YES];
|
||||
[self setNonBlocking: YES];
|
||||
if (modes && [modes count])
|
||||
{
|
||||
int i;
|
||||
|
@ -1117,7 +1130,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
[l addEvent: (void*)descriptor
|
||||
type: ET_WDESC
|
||||
watcher: self
|
||||
forMode: [modes objectAtIndex:i]];
|
||||
forMode: [modes objectAtIndex: i]];
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1139,131 +1152,166 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
if (isNonBlocking == NO)
|
||||
[self setNonBlocking: YES];
|
||||
if (type == ET_RDESC) {
|
||||
operation = [readInfo objectForKey:NotificationKey];
|
||||
if (operation == NSFileHandleConnectionAcceptedNotification) {
|
||||
struct sockaddr_in buf;
|
||||
int desc;
|
||||
int blen = sizeof(buf);
|
||||
NSFileHandle* hdl;
|
||||
if (type == ET_RDESC)
|
||||
{
|
||||
operation = [readInfo objectForKey: NotificationKey];
|
||||
if (operation == NSFileHandleConnectionAcceptedNotification)
|
||||
{
|
||||
struct sockaddr_in buf;
|
||||
int desc;
|
||||
int blen = sizeof(buf);
|
||||
NSFileHandle* hdl;
|
||||
|
||||
desc = accept(descriptor, (struct sockaddr*)&buf, &blen);
|
||||
if (desc < 0) {
|
||||
NSString* s;
|
||||
desc = accept(descriptor, (struct sockaddr*)&buf, &blen);
|
||||
if (desc < 0)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat:@"Accept attempt failed - %s",
|
||||
s = [NSString stringWithFormat: @"Accept attempt failed - %s",
|
||||
strerror(errno)];
|
||||
[readInfo setObject:s forKey:GSFileHandleNotificationError];
|
||||
}
|
||||
else { // Accept attempt completed.
|
||||
UnixFileHandle *h;
|
||||
struct sockaddr_in sin;
|
||||
int size = sizeof(sin);
|
||||
[readInfo setObject: s forKey: GSFileHandleNotificationError];
|
||||
}
|
||||
else
|
||||
{ // Accept attempt completed.
|
||||
UnixFileHandle *h;
|
||||
struct sockaddr_in sin;
|
||||
int size = sizeof(sin);
|
||||
|
||||
h = [[UnixFileHandle alloc] initWithFileDescriptor:desc];
|
||||
getpeername(desc, (struct sockaddr*)&sin, &size);
|
||||
[h setAddr: &sin];
|
||||
[readInfo setObject: h forKey: NSFileHandleNotificationFileHandleItem];
|
||||
[h release];
|
||||
}
|
||||
[self postReadNotification];
|
||||
}
|
||||
else if (operation == NSFileHandleDataAvailableNotification) {
|
||||
[self postReadNotification];
|
||||
}
|
||||
else {
|
||||
NSMutableData* item;
|
||||
int length;
|
||||
int received = 0;
|
||||
char buf[NETBUF_SIZE];
|
||||
h = [[UnixFileHandle alloc] initWithFileDescriptor: desc];
|
||||
getpeername(desc, (struct sockaddr*)&sin, &size);
|
||||
[h setAddr: &sin];
|
||||
[readInfo setObject: h
|
||||
forKey: NSFileHandleNotificationFileHandleItem];
|
||||
[h release];
|
||||
}
|
||||
[self postReadNotification];
|
||||
}
|
||||
else if (operation == NSFileHandleDataAvailableNotification)
|
||||
{
|
||||
[self postReadNotification];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMutableData *item;
|
||||
int length;
|
||||
int received = 0;
|
||||
char buf[NETBUF_SIZE];
|
||||
|
||||
item = [readInfo objectForKey:NSFileHandleNotificationDataItem];
|
||||
length = [item length];
|
||||
item = [readInfo objectForKey: NSFileHandleNotificationDataItem];
|
||||
length = [item length];
|
||||
|
||||
received = read(descriptor, buf, sizeof(buf));
|
||||
if (received == 0) { // Read up to end of file.
|
||||
[self postReadNotification];
|
||||
}
|
||||
else if (received < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
NSString* s;
|
||||
received = read(descriptor, buf, sizeof(buf));
|
||||
if (received == 0)
|
||||
{ // Read up to end of file.
|
||||
[self postReadNotification];
|
||||
}
|
||||
else if (received < 0)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat:@"Read attempt failed - %s",
|
||||
s = [NSString stringWithFormat: @"Read attempt failed - %s",
|
||||
strerror(errno)];
|
||||
[readInfo setObject:s forKey:GSFileHandleNotificationError];
|
||||
[self postReadNotification];
|
||||
[readInfo setObject: s forKey: GSFileHandleNotificationError];
|
||||
[self postReadNotification];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[item appendBytes: buf length: received];
|
||||
if (operation == NSFileHandleReadCompletionNotification)
|
||||
{
|
||||
// Read a single chunk of data
|
||||
[self postReadNotification];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
[item appendBytes:buf length:received];
|
||||
if (operation == NSFileHandleReadCompletionNotification) {
|
||||
// Read a single chunk of data
|
||||
[self postReadNotification];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == ET_WDESC) {
|
||||
NSMutableDictionary* info;
|
||||
else if (type == ET_WDESC)
|
||||
{
|
||||
NSMutableDictionary *info;
|
||||
|
||||
info = [writeInfo objectAtIndex:0];
|
||||
operation = [info objectForKey:NotificationKey];
|
||||
if (operation == GSFileHandleWriteCompletionNotification) {
|
||||
NSData* item;
|
||||
int length;
|
||||
const void* ptr;
|
||||
info = [writeInfo objectAtIndex: 0];
|
||||
operation = [info objectForKey: NotificationKey];
|
||||
if (operation == GSFileHandleWriteCompletionNotification)
|
||||
{
|
||||
NSData *item;
|
||||
int length;
|
||||
const void *ptr;
|
||||
|
||||
item = [info objectForKey:NSFileHandleNotificationDataItem];
|
||||
length = [item length];
|
||||
ptr = [item bytes];
|
||||
if (writePos < length) {
|
||||
int written;
|
||||
item = [info objectForKey: NSFileHandleNotificationDataItem];
|
||||
length = [item length];
|
||||
ptr = [item bytes];
|
||||
if (writePos < length)
|
||||
{
|
||||
int written;
|
||||
|
||||
written = write(descriptor, (char*)ptr+writePos, length - writePos);
|
||||
if (written <= 0) {
|
||||
if (errno != EAGAIN) {
|
||||
NSString* s;
|
||||
written = write(descriptor, (char*)ptr+writePos, length-writePos);
|
||||
if (written <= 0)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat:@"Write attempt failed - %s",
|
||||
strerror(errno)];
|
||||
[info setObject:s forKey:GSFileHandleNotificationError];
|
||||
[self postWriteNotification];
|
||||
}
|
||||
s = [NSString stringWithFormat:
|
||||
@"Write attempt failed - %s", strerror(errno)];
|
||||
[info setObject: s forKey: GSFileHandleNotificationError];
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writePos += written;
|
||||
}
|
||||
}
|
||||
if (writePos >= length)
|
||||
{ // Write operation completed.
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
else {
|
||||
writePos += written;
|
||||
else
|
||||
{ // Connection attempt completed.
|
||||
int result;
|
||||
int len = sizeof(result);
|
||||
|
||||
if (getsockopt(descriptor, SOL_SOCKET, SO_ERROR,
|
||||
(char*)&result, &len) == 0 && result != 0)
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [NSString stringWithFormat: @"Connect attempt failed - %s",
|
||||
strerror(result)];
|
||||
[info setObject: s forKey: GSFileHandleNotificationError];
|
||||
}
|
||||
else
|
||||
{
|
||||
readOK = YES;
|
||||
writeOK = YES;
|
||||
}
|
||||
connectOK = NO;
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
if (writePos >= length) { // Write operation completed.
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
else { // Connection attempt completed.
|
||||
connectOK = NO;
|
||||
readOK = YES;
|
||||
writeOK = YES;
|
||||
[self postWriteNotification];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDate*)timedOutEvent: (void*)data
|
||||
type: (RunLoopEventType)type
|
||||
forMode: (NSString*)mode
|
||||
{
|
||||
return nil; /* Don't restart timed out events */
|
||||
return nil; /* Don't restart timed out events */
|
||||
}
|
||||
|
||||
- (void) setAddr: (struct sockaddr_in *)sin
|
||||
{
|
||||
address = [NSString stringWithCString: (char*)inet_ntoa(sin->sin_addr)];
|
||||
[address retain];
|
||||
service = [NSString stringWithFormat: @"%d", (int)ntohs(sin->sin_port)];
|
||||
[service retain];
|
||||
protocol = @"tcp";
|
||||
address = [NSString stringWithCString: (char*)inet_ntoa(sin->sin_addr)];
|
||||
[address retain];
|
||||
service = [NSString stringWithFormat: @"%d", (int)ntohs(sin->sin_port)];
|
||||
[service retain];
|
||||
protocol = @"tcp";
|
||||
}
|
||||
|
||||
- (void)setNonBlocking:(BOOL)flag
|
||||
- (void)setNonBlocking: (BOOL)flag
|
||||
{
|
||||
int e;
|
||||
|
||||
|
@ -1294,17 +1342,17 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
- (NSString*) socketAddress
|
||||
{
|
||||
return address;
|
||||
return address;
|
||||
}
|
||||
|
||||
- (NSString*) socketProtocol
|
||||
{
|
||||
return protocol;
|
||||
return protocol;
|
||||
}
|
||||
|
||||
- (NSString*) socketService
|
||||
{
|
||||
return service;
|
||||
return service;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue