gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(no subject)


From: Andrew Ruder
Subject: (no subject)
Date: Tue, 24 Apr 2007 20:48:12 -0500
User-agent: Mutt/1.5.13 (2006-08-11)

From: Andrew Ruder <address@hidden>
To: address@hidden
Cc: GNUstep Developers <address@hidden>
Subject: [PATCH] Importing original GNUstep NSStream/GSStream
Date: Tue, 24 Apr 2007 20:47:58 -0500
Message-Id: <address@hidden>
X-Mailer: git-send-email 1.5.2.rc0.14.g520d-dirty
In-Reply-To: <address@hidden>
References: <address@hidden>

From: GNUstep Developers <address@hidden>

diff --git a/libs/net/GSStream.h b/libs/net/GSStream.h
index 19a1d36..34792c9 100644
--- a/libs/net/GSStream.h
+++ b/libs/net/GSStream.h
@@ -75,7 +75,6 @@
   NSRunLoop            *_runloop;      /* currently scheduled loop.    */\
   void                  *_loopID;      /* file descriptor etc.         */\
   int                  _events;        /* Signalled events.            */\
-  void *_fd; \
 }
 
 /**
@@ -135,54 +134,14 @@ IVARS
 IVARS
 @end
 
address@hidden GSInputStream (Private)
-- (BOOL) _isOpened;
-- (void) _sendEvent: (NSStreamEvent)event;
-- (void) _setStatus: (NSStreamStatus)newStatus;
-- (void) _setFd: (void*)fd;
-- (void) _recordError; 
address@hidden
-
 @interface GSOutputStream : NSOutputStream
 IVARS
 @end
 
address@hidden GSOutputStream (Private)
-- (BOOL) _isOpened;
-- (void) _sendEvent: (NSStreamEvent)event;
-- (void) _setStatus: (NSStreamStatus)newStatus;
-- (void) _setFd: (void*)fd;
-- (void) _recordError; 
address@hidden
-
 @interface GSAbstractServerStream : GSServerStream
 IVARS
 @end
 
address@hidden GSAbstractServerStream (private)
-- (BOOL) _isOpened;
-- (void) _sendEvent: (NSStreamEvent)event;
-- (void) _setStatus: (NSStreamStatus)newStatus;
-- (void) _setFd: (void*)fd;
-- (void) _recordError; 
address@hidden
-
-/**
- * The concrete subclass of NSInputStream that reads from the memory 
- */
address@hidden GSMemoryInputStream : GSInputStream
-{
address@hidden
-  NSData *_data;
-  unsigned long _pointer;
-}
-
-/**
- * this is the bridge method for asynchronized operation. Do not call.
- */
-- (void) _dispatch;
address@hidden
-
 /**
  * The concrete subclass of NSInputStream that reads from the memory 
  */
@@ -232,23 +191,5 @@ IVARS
 - (void) _dispatch;
 @end
 
-/**
- * The concrete subclass of NSOutputStream that writes to memory
- */
address@hidden GSMemoryOutputStream : GSOutputStream
-{
address@hidden
-  NSMutableData *_data;
-  unsigned long _pointer;
-  BOOL _fixedSize;
-}
-
-/**
- * this is the bridge method for asynchronized operation. Do not call.
- */
-- (void) _dispatch;
address@hidden
-
-
 #endif
 
diff --git a/libs/net/GSStream.m b/libs/net/GSStream.m
index c2023d1..8c1184f 100644
--- a/libs/net/GSStream.m
+++ b/libs/net/GSStream.m
@@ -1,6 +1,9 @@
 /** Implementation for GSStream for GNUStep
    Copyright (C) 2006 Free Software Foundation, Inc.
-   Copyright (C) 2007 Contributors to the Sidestep Project. See AUTHORS file 
for details
+
+   Written by:  Derek Zhou <address@hidden>
+   Written by:  Richard Frith-Macdonald <address@hidden>
+   Date: 2006
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -225,10 +228,7 @@ static RunLoopEventType typeForStream(NSStream *aStream)
     {
       if ([_modes containsObject: mode])
        {
-         if ([self _isOpened])
-           {
-             [_runloop removeStream: self mode: mode];
-           }
+         [_runloop removeStream: self mode: mode];
          [_modes removeObject: mode];
          if ([_modes count] == 0)
            {
@@ -248,6 +248,10 @@ static RunLoopEventType typeForStream(NSStream *aStream)
       mode = [mode copy];
       [_modes addObject: mode];
       RELEASE(mode);
+      /* We only add open streams to the runloop .. subclasses may add
+       * streams when they are in the process of opening if they need
+       * to do so.
+       */
       if ([self _isOpened])
        {
          [_runloop addStream: self mode: mode];
@@ -358,10 +362,9 @@ static RunLoopEventType typeForStream(NSStream *aStream)
 #if    defined(__MINGW32__)
   errno = GetLastError();
 #endif
-  //theError = [NSError errorWithDomain: @"NSPOSIX"
-//                                       code: errno
-//                                   userInfo: nil];
-  theError = nil;
+  theError = [NSError errorWithDomain: NSPOSIXErrorDomain
+                                         code: errno
+                                     userInfo: nil];
   NSLog(@"%@ error(%d): - %@", self, errno, [NSError _last]);
   ASSIGN(_lastError, theError);
   _currentStatus = NSStreamStatusError;
diff --git a/libs/net/unix/NSStream.m b/libs/net/unix/NSStream.m
new file mode 100644
index 0000000..92f6867
--- /dev/null
+++ b/libs/net/unix/NSStream.m
@@ -0,0 +1,1687 @@
+/** Implementation for NSStream for GNUStep
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+   Written by:  Derek Zhou <address@hidden>
+   Written by:  Richard Frith-Macdonald <address@hidden>
+   Date: 2006
+
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02111 USA.
+
+   */
+#include <unistd.h>
+#include <errno.h>
+
+#include <Foundation/NSData.h>
+#include <Foundation/NSArray.h>
+#include <Foundation/NSRunLoop.h>
+#include <Foundation/NSException.h>
+#include <Foundation/NSError.h>
+#include <Foundation/NSValue.h>
+#include <Foundation/NSHost.h>
+
+#include "../GSStream.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifndef        AF_LOCAL
+#define        AF_LOCAL        AF_UNIX
+#endif
+#ifndef        PF_LOCAL
+#define        PF_LOCAL        PF_UNIX
+#endif
+
+#ifndef        socklen_t
+#define        socklen_t       uint32_t
+#endif
+
+/** 
+ * The concrete subclass of NSInputStream that reads from a file
+ */
address@hidden GSFileInputStream : GSInputStream
+{
address@hidden
+  NSString *_path;
+}
address@hidden
+
+/** 
+ * The abstract subclass of NSInputStream that reads from a socket
+ */
address@hidden GSSocketInputStream : GSInputStream
+{
address@hidden
+  GSOutputStream *_sibling;
+  BOOL _passive;              /* YES means already connected */
+}
+
+/** 
+ * get the length of the socket addr
+ */
+- (socklen_t) sockLen;
+
+/**
+ * get the sockaddr
+ */
+- (struct sockaddr*) peerAddr;
+
+/**
+ * setter for sibling
+ */
+- (void) setSibling: (GSOutputStream*)sibling;
+
+/**
+ * setter for passive
+ */
+- (void) setPassive: (BOOL)passive;
+
address@hidden
+
address@hidden GSInetInputStream : GSSocketInputStream
+{
+  @private
+  struct sockaddr_in _peerAddr;
+}
+
+/**
+ * the designated initializer
+ */
+- (id) initToAddr: (NSString*)addr port: (int)port;
+
address@hidden
+
address@hidden GSInet6InputStream : GSSocketInputStream
+{
+  @private
+#if    defined(AF_INET6)
+  struct sockaddr_in6 _peerAddr;
+#endif
+}
+
+/**
+ * the designated initializer
+ */
+- (id) initToAddr: (NSString*)addr port: (int)port;
+
address@hidden
+
address@hidden GSLocalInputStream : GSSocketInputStream
+{
+  @private
+  struct sockaddr_un _peerAddr;
+}
+
+/**
+ * the designated initializer
+ */
+- (id) initToAddr: (NSString*)addr;
+
address@hidden
+
+/**
+ * The concrete subclass of NSOutputStream that writes to a file
+ */
address@hidden GSFileOutputStream : GSOutputStream
+{
address@hidden
+  NSString *_path;
+  BOOL _shouldAppend;
+}
address@hidden
+
+/**
+ * The concrete subclass of NSOutputStream that writes to a socket
+ */
address@hidden GSSocketOutputStream : GSOutputStream
+{
address@hidden
+  GSInputStream *_sibling;
+  BOOL _passive;              /* YES means already connected */
+}
+
+/** 
+ * get the length of the socket addr
+ */
+- (socklen_t) sockLen;
+
+/**
+ * get the sockaddr
+ */
+- (struct sockaddr*) peerAddr;
+
+/**
+ * setter for sibling
+ */
+- (void) setSibling: (GSInputStream*)sibling;
+
+/**
+ * setter for passive
+ */
+- (void) setPassive: (BOOL)passive;
+
address@hidden
+
address@hidden GSInetOutputStream : GSSocketOutputStream
+{
+  @private
+  struct sockaddr_in _peerAddr;
+}
+
+/**
+ * the designated initializer
+ */
+- (id) initToAddr: (NSString*)addr port: (int)port;
+
address@hidden
+
address@hidden GSInet6OutputStream : GSSocketOutputStream
+{
+  @private
+#if    defined(AF_INET6)
+  struct sockaddr_in6 _peerAddr;
+#endif
+}
+
+/**
+ * the designated initializer
+ */
+- (id) initToAddr: (NSString*)addr port: (int)port;
+
address@hidden
+
address@hidden GSLocalOutputStream : GSSocketOutputStream
+{
+  @private
+  struct sockaddr_un _peerAddr;
+}
+
+/**
+ * the designated initializer
+ */
+- (id) initToAddr: (NSString*)addr;
+
address@hidden
+
+/**
+ * The concrete subclass of NSServerStream that accept connection from a socket
+ */
address@hidden GSSocketServerStream : GSAbstractServerStream
+/**
+ * return the class of the inputStream associated with this
+ * type of serverStream.
+ */
+- (Class) _inputStreamClass;
+/**
+ * return the class of the outputStream associated with this
+ * type of serverStream.
+ */
+- (Class) _outputStreamClass;
+/** 
+ * get the length of the socket addr
+ */
+- (socklen_t) sockLen;
+/**
+ * get the sockaddr
+ */
+- (struct sockaddr*) serverAddr;
+
address@hidden
+
address@hidden GSInetServerStream : GSSocketServerStream
+{
+  @private
+  struct sockaddr_in _serverAddr;
+}
address@hidden
+
address@hidden GSInet6ServerStream : GSSocketServerStream
+{
+  @private
+#if    defined(AF_INET6)
+  struct sockaddr_in6 _serverAddr;
+#endif
+}
address@hidden
+
address@hidden GSLocalServerStream : GSSocketServerStream
+{
+  @private
+  struct sockaddr_un _serverAddr;
+}
address@hidden
+
+/**
+ * set the file descriptor to non-blocking
+ */
+static void setNonblocking(int fd)
+{
+  int flags = fcntl(fd, F_GETFL, 0);
+  fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+}
+
address@hidden GSFileInputStream
+
+- (id) initWithFileAtPath: (NSString *)path
+{
+  if ((self = [super init]) != nil)
+    {
+      ASSIGN(_path, path);
+    }
+  return self;
+}
+
+- (void) dealloc
+{
+  if ([self _isOpened])
+    {
+      [self close];
+    }
+  DESTROY(_path);
+  [super dealloc];
+}
+
+- (int) read: (uint8_t *)buffer maxLength: (unsigned int)len
+{
+  int readLen;
+
+  if (buffer == 0)
+    {
+      [NSException raise: NSInvalidArgumentException
+                 format: @"null pointer for buffer"];
+    }
+  if (len == 0)
+    {
+      [NSException raise: NSInvalidArgumentException
+                 format: @"zero byte read write requested"];
+    }
+
+  _events &= ~NSStreamEventHasBytesAvailable;
+
+  if ([self streamStatus] == NSStreamStatusClosed)
+    {
+      return 0;
+    }
+
+  readLen = read((intptr_t)_loopID, buffer, len);
+  if (readLen < 0 && errno != EAGAIN && errno != EINTR)
+    {
+      [self _recordError];
+      readLen = -1;
+    }
+  else if (readLen == 0)
+    {
+      [self _setStatus: NSStreamStatusAtEnd];
+      [self _sendEvent: NSStreamEventEndEncountered];
+    }
+  return readLen;
+}
+
+- (BOOL) getBuffer: (uint8_t **)buffer length: (unsigned int *)len
+{
+  return NO;
+}
+
+- (BOOL) hasBytesAvailable
+{
+  if ([self _isOpened] && [self streamStatus] != NSStreamStatusAtEnd)
+    return YES;
+  return NO;
+}
+
+- (id) propertyForKey: (NSString *)key
+{
+  if ([key isEqualToString: NSStreamFileCurrentOffsetKey])
+    {
+      off_t offset = 0;
+
+      if ([self _isOpened])
+        offset = lseek((intptr_t)_loopID, 0, SEEK_CUR);
+      return [NSNumber numberWithLong: offset];
+    }
+  return [super propertyForKey: key];
+}
+
+- (void) open
+{
+  int fd;
+
+  fd = open([_path fileSystemRepresentation], O_RDONLY|O_NONBLOCK);
+  if (fd < 0)
+    {  
+      [self _recordError];
+      [self _sendEvent: NSStreamEventErrorOccurred];
+      return;
+    }
+  _loopID = (void*)(intptr_t)fd;
+  [super open];
+}
+
+- (void) close
+{
+  int closeReturn = close((intptr_t)_loopID);
+
+  if (closeReturn < 0)
+    [self _recordError];
+  [super close];
+}
+
+- (void) _dispatch
+{
+  if ([self streamStatus] == NSStreamStatusOpen)
+    {
+      [self _sendEvent: NSStreamEventHasBytesAvailable];
+    }
+  else
+    {
+      NSLog(@"_dispatch with unexpected status %d", [self streamStatus]);
+    }
+}
address@hidden
+
address@hidden GSSocketInputStream
+
+- (socklen_t) sockLen
+{
+  [self subclassResponsibility: _cmd];
+  return 0;
+}
+
+- (struct sockaddr*) peerAddr
+{
+  [self subclassResponsibility: _cmd];
+  return NULL;
+}
+
+- (void) setSibling: (GSOutputStream*)sibling
+{
+  _sibling = sibling;
+}
+
+- (void) setPassive: (BOOL)passive
+{
+  _passive = passive;
+}
+
+- (id) init
+{
+  if ((self = [super init]) != nil)
+    {
+      // so that unopened access will fail
+      _sibling = nil;
+      _passive = NO;
+    }
+  return self;
+}
+
+- (void) dealloc
+{
+  if ([self _isOpened])
+    {
+      [self close];
+    }
+  [(GSSocketOutputStream*)_sibling setSibling: nil];
+  _sibling = nil;
+  [super dealloc];
+}
+
+- (void) open
+{
+  // could be opened because of sibling
+  if ([self _isOpened])
+    return;
+  if (_passive || (_sibling && [_sibling _isOpened]))
+    goto open_ok;
+  // check sibling status, avoid double connect
+  if (_sibling && [_sibling streamStatus] == NSStreamStatusOpening)
+    {
+      [self _setStatus: NSStreamStatusOpening];
+      return;
+    }
+  else
+    {
+      int result;
+      
+      if (_runloop)
+       {
+         setNonblocking((intptr_t)_loopID);
+       }
+      result = connect((intptr_t)_loopID, [self peerAddr], [self sockLen]);
+      if (result < 0)
+       {
+         if (errno == EINPROGRESS && _runloop != nil)
+           {
+             unsigned i = [_modes count];
+
+             /*
+              * Need to set the status first, so that the run loop can tell
+              * it needs to add the stream as waiting on writable, as an
+              * indication of opened
+              */
+             [self _setStatus: NSStreamStatusOpening];
+             while (i-- > 0)
+               {
+                 [_runloop addStream: self mode: [_modes objectAtIndex: i]];
+               }
+             return;
+           }
+          [self _recordError];
+          [self _sendEvent: NSStreamEventErrorOccurred];
+          return;
+        }
+    }
+
+ open_ok:
+  // put itself to the runloop
+  [super open];
+  setNonblocking((intptr_t)_loopID);
+}
+
+- (void) close
+{
+  // read shutdown is ignored, because the other side may shutdown first.
+  if (!_sibling || [_sibling streamStatus] == NSStreamStatusClosed)
+    close((intptr_t)_loopID);
+  else
+    shutdown((intptr_t)_loopID, SHUT_RD);
+  [super close];
+}
+
+- (int) read: (uint8_t *)buffer maxLength: (unsigned int)len
+{
+  int readLen;
+
+  if (buffer == 0)
+    {
+      [NSException raise: NSInvalidArgumentException
+                 format: @"null pointer for buffer"];
+    }
+  if (len == 0)
+    {
+      [NSException raise: NSInvalidArgumentException
+                 format: @"zero byte read write requested"];
+    }
+
+  _events &= ~NSStreamEventHasBytesAvailable;
+
+  if ([self streamStatus] == NSStreamStatusClosed)
+    {
+      return 0;
+    }
+
+  readLen = read((intptr_t)_loopID, buffer, len);
+  if (readLen < 0 && errno != EAGAIN && errno != EINTR)
+    {
+      [self _recordError];
+      readLen = -1;
+    }
+  else if (readLen == 0)
+    {
+      [self _setStatus: NSStreamStatusAtEnd];
+      [self _sendEvent: NSStreamEventEndEncountered];
+    }
+  return readLen;
+}
+
+- (BOOL) getBuffer: (uint8_t **)buffer length: (unsigned int *)len
+{
+  return NO;
+}
+
+- (BOOL) hasBytesAvailable
+{
+  if ([self _isOpened] && [self streamStatus] != NSStreamStatusAtEnd)
+    return YES;
+  return NO;
+}
+
+- (void) _dispatch
+{
+  NSStreamEvent myEvent;
+
+  if ([self streamStatus] == NSStreamStatusOpening)
+    {
+      int error;
+      int result;
+      socklen_t len = sizeof(error);
+      unsigned i = [_modes count];
+
+      while (i-- > 0)
+       {
+         [_runloop removeStream: self mode: [_modes objectAtIndex: i]];
+       }
+      result
+       = getsockopt((intptr_t)_loopID, SOL_SOCKET, SO_ERROR, &error, &len);
+
+      if (result >= 0 && !error)
+        { // finish up the opening
+          myEvent = NSStreamEventOpenCompleted;
+          _passive = YES;
+          [self open];
+          // notify sibling
+          [_sibling open];
+          [_sibling _sendEvent: myEvent];
+        }
+      else // must be an error
+        {
+          if (error)
+            errno = error;
+          [self _recordError];
+          myEvent = NSStreamEventErrorOccurred;
+          [_sibling _recordError];
+          [_sibling _sendEvent: myEvent];
+        }
+    }
+  else if ([self streamStatus] == NSStreamStatusAtEnd)
+    {
+      myEvent = NSStreamEventEndEncountered;
+    }
+  else
+    {
+      [self _setStatus: NSStreamStatusOpen];
+      myEvent = NSStreamEventHasBytesAvailable;
+    }
+  [self _sendEvent: myEvent];
+}
+
address@hidden
+
address@hidden GSInetInputStream
+
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_in);
+}
+
+- (struct sockaddr*) peerAddr
+{
+  return (struct sockaddr*)&_peerAddr;
+}
+
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+
+  int ptonReturn;
+  const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
+
+  if ((self = [super init]) != nil)
+    {
+      _peerAddr.sin_family = AF_INET;
+      _peerAddr.sin_port = htons(port);
+      ptonReturn = inet_pton(AF_INET, addr_c, &(_peerAddr.sin_addr));
+      if (ptonReturn == 0)   // error
+       {
+         DESTROY(self);
+       }
+    }
+  return self;
+}
+
address@hidden
+
address@hidden GSInet6InputStream
+#if    defined(AF_INET6)
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_in6);
+}
+
+- (struct sockaddr*) peerAddr
+{
+  return (struct sockaddr*)&_peerAddr;
+}
+
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  int ptonReturn;
+  const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
+
+  if ((self = [super init]) != nil)
+    {
+      _peerAddr.sin6_family = AF_INET6;
+      _peerAddr.sin6_port = htons(port);
+      ptonReturn = inet_pton(AF_INET6, addr_c, &(_peerAddr.sin6_addr));
+      if (ptonReturn == 0)   // error
+       {
+         DESTROY(self);
+       }
+    }
+  return self;
+}
+#else
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  RELEASE(self);
+  return nil;
+}
+#endif
address@hidden
+
address@hidden GSLocalInputStream 
+
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_un);
+}
+
+- (struct sockaddr*) peerAddr
+{
+  return (struct sockaddr*)&_peerAddr;
+}
+
+- (id) initToAddr: (NSString*)addr
+{
+  const char* real_addr = [addr fileSystemRepresentation];
+
+  if ((self = [super init]) != nil)
+    {
+      _peerAddr.sun_family = AF_LOCAL;
+      if (strlen(real_addr)>sizeof(_peerAddr.sun_path)-1) // too long
+       {
+         DESTROY(self);
+       }
+      else
+       {
+         strncpy(_peerAddr.sun_path, real_addr, sizeof(_peerAddr.sun_path)-1);
+       }
+    }
+  return self;
+}
+
address@hidden
+
address@hidden GSFileOutputStream
+
+- (id) initToFileAtPath: (NSString *)path append: (BOOL)shouldAppend
+{
+  if ((self = [super init]) != nil)
+    {
+      ASSIGN(_path, path);
+      // so that unopened access will fail
+      _shouldAppend = shouldAppend;
+    }
+  return self;
+}
+
+- (void) dealloc
+{
+  if ([self _isOpened])
+    {
+      [self close];
+    }
+  RELEASE(_path);
+  [super dealloc];
+}
+
+- (int) write: (const uint8_t *)buffer maxLength: (unsigned int)len
+{
+  int writeLen;
+
+  if (buffer == 0)
+    {
+      [NSException raise: NSInvalidArgumentException
+                 format: @"null pointer for buffer"];
+    }
+  if (len == 0)
+    {
+      [NSException raise: NSInvalidArgumentException
+                 format: @"zero byte length write requested"];
+    }
+
+  _events &= ~NSStreamEventHasSpaceAvailable;
+
+  if ([self streamStatus] == NSStreamStatusClosed)
+    {
+      return 0;
+    }
+
+  writeLen = write((intptr_t)_loopID, buffer, len);
+  if (writeLen < 0 && errno != EAGAIN && errno != EINTR)
+    [self _recordError];
+  return writeLen;
+}
+
+- (BOOL) hasSpaceAvailable
+{
+  if ([self _isOpened])
+    return YES;
+  return NO;
+}
+
+- (void) open
+{
+  int fd;
+  int flag = O_WRONLY | O_NONBLOCK | O_CREAT;
+  mode_t mode = 0666;
+
+  if (_shouldAppend)
+    flag = flag | O_APPEND;
+  else
+    flag = flag | O_TRUNC;
+  fd = open([_path fileSystemRepresentation], flag, mode);
+  if (fd < 0)
+    {  // make an error
+      [self _recordError];
+      [self _sendEvent: NSStreamEventErrorOccurred];
+      return;
+    }
+  _loopID = (void*)(intptr_t)fd;
+  [super open];
+}
+
+- (void) close
+{
+  int closeReturn = close((intptr_t)_loopID);
+  if (closeReturn < 0)
+    [self _recordError];
+  [super close];
+}
+
+- (id) propertyForKey: (NSString *)key
+{
+  if ([key isEqualToString: NSStreamFileCurrentOffsetKey])
+    {
+      off_t offset = 0;
+
+      if ([self _isOpened])
+        offset = lseek((intptr_t)_loopID, 0, SEEK_CUR);
+      return [NSNumber numberWithLong: offset];
+    }
+  return [super propertyForKey: key];
+}
+
+- (void) _dispatch
+{
+  if ([self streamStatus] == NSStreamStatusOpen)
+    {
+      [self _sendEvent: NSStreamEventHasSpaceAvailable];
+    }
+  else
+    {
+      NSLog(@"_dispatch with unexpected status %d", [self streamStatus]);
+    }
+}
address@hidden
+
address@hidden GSSocketOutputStream
+
+- (socklen_t) sockLen
+{
+  [self subclassResponsibility: _cmd];
+  return 0;
+}
+
+- (struct sockaddr*) peerAddr
+{
+  [self subclassResponsibility: _cmd];
+  return NULL;
+}
+
+- (void) setSibling: (GSInputStream*)sibling
+{
+  _sibling = sibling;
+}
+
+- (void) setPassive: (BOOL)passive
+{
+  _passive = passive;
+}
+
+- (id) init
+{
+  if ((self = [super init]) != nil)
+    {
+      _sibling = nil;
+      _passive = NO;
+    }
+  return self;
+}
+
+- (void) dealloc
+{
+  if ([self _isOpened])
+    {
+      [self close];
+    }
+  [(GSSocketInputStream*)_sibling setSibling: nil];
+  _sibling = nil;
+  [super dealloc];
+}
+
+- (int) write: (const uint8_t *)buffer maxLength: (unsigned int)len
+{
+  int writeLen;
+
+  if (buffer == 0)
+    {
+      [NSException raise: NSInvalidArgumentException
+                 format: @"null pointer for buffer"];
+    }
+  if (len == 0)
+    {
+      [NSException raise: NSInvalidArgumentException
+                 format: @"zero byte length write requested"];
+    }
+
+  _events &= ~NSStreamEventHasSpaceAvailable;
+
+  if ([self streamStatus] == NSStreamStatusClosed)
+    {
+      return 0;
+    }
+
+  writeLen = write((intptr_t)_loopID, buffer, len);
+  if (writeLen < 0 && errno != EAGAIN && errno != EINTR)
+    [self _recordError];
+  return writeLen;
+}
+
+- (BOOL) hasSpaceAvailable
+{
+  if ([self _isOpened])
+    return YES;
+  return NO;
+}
+
+- (void) open
+{
+  // could be opened because of sibling
+  if ([self _isOpened])
+    return;
+  if (_passive || (_sibling && [_sibling _isOpened]))
+    goto open_ok;
+  // check sibling status, avoid double connect
+  if (_sibling && [_sibling streamStatus] == NSStreamStatusOpening)
+    {
+      [self _setStatus: NSStreamStatusOpening];
+      return;
+    }
+  else
+    {
+      int result;
+      
+      if (_runloop)
+       {
+         setNonblocking((intptr_t)_loopID);
+       }
+      result = connect((intptr_t)_loopID, [self peerAddr], [self sockLen]);
+      if (result < 0)
+       {
+         if (errno == EINPROGRESS && _runloop != nil)
+           {
+             unsigned i = [_modes count];
+
+             /*
+              * Need to set the status first, so that the run loop can tell
+              * it needs to add the stream as waiting on writable, as an
+              * indication of opened
+              */
+             [self _setStatus: NSStreamStatusOpening];
+             while (i-- > 0)
+               {
+                 [_runloop addStream: self mode: [_modes objectAtIndex: i]];
+               }
+             return;
+           }
+          [self _recordError];
+          [self _sendEvent: NSStreamEventErrorOccurred];
+          return;
+        }
+    }
+
+ open_ok:
+  // put itself to the runloop
+  [super open];
+  setNonblocking((intptr_t)_loopID);
+}
+
+- (void) close
+{
+  // shutdown may fail (broken pipe). Record it.
+  int closeReturn;
+  if (!_sibling || [_sibling streamStatus]==NSStreamStatusClosed)
+    closeReturn = close((intptr_t)_loopID);
+  else
+    closeReturn = shutdown((intptr_t)_loopID, SHUT_WR);
+  if (closeReturn < 0)
+    [self _recordError];
+  [super close];
+}
+
+- (void) _dispatch
+{
+  NSStreamEvent myEvent;
+
+  if ([self streamStatus] == NSStreamStatusOpening)
+    {
+      int error;
+      socklen_t len = sizeof(error);
+      int result;
+      unsigned i = [_modes count];
+
+      while (i-- > 0)
+       {
+         [_runloop removeStream: self mode: [_modes objectAtIndex: i]];
+       }
+      result
+       = getsockopt((intptr_t)_loopID, SOL_SOCKET, SO_ERROR, &error, &len);
+      if (result >= 0 && !error)
+        { // finish up the opening
+          myEvent = NSStreamEventOpenCompleted;
+          _passive = YES;
+          [self open];
+          // notify sibling
+          [_sibling open];
+          [_sibling _sendEvent: myEvent];
+        }
+      else // must be an error
+        {
+          if (error)
+            errno = error;
+          [self _recordError];
+          myEvent = NSStreamEventErrorOccurred;
+          [_sibling _recordError];
+          [_sibling _sendEvent: myEvent];
+        }
+    }
+  else if ([self streamStatus] == NSStreamStatusAtEnd)
+    {
+      myEvent = NSStreamEventEndEncountered;
+    }
+  else
+    {
+      [self _setStatus: NSStreamStatusOpen];
+      myEvent = NSStreamEventHasSpaceAvailable;
+    }
+  [self _sendEvent: myEvent];
+}
+
address@hidden
+
address@hidden GSInetOutputStream
+
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_in);
+}
+
+- (struct sockaddr*) peerAddr
+{
+  return (struct sockaddr*)&_peerAddr;
+}
+
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  int ptonReturn;
+  const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
+
+  if ((self = [super init]) != nil)
+    {
+      _peerAddr.sin_family = AF_INET;
+      _peerAddr.sin_port = htons(port);
+      ptonReturn = inet_pton(AF_INET, addr_c, &(_peerAddr.sin_addr));
+      if (ptonReturn == 0)   // error
+       {
+         DESTROY(self);
+       }
+    }
+  return self;
+}
+
address@hidden
+
address@hidden GSInet6OutputStream
+#if    defined(AF_INET6)
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_in6);
+}
+
+- (struct sockaddr*) peerAddr
+{
+  return (struct sockaddr*)&_peerAddr;
+}
+
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  int ptonReturn;
+  const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
+
+  if ((self = [super init]) != nil)
+    {
+      _peerAddr.sin6_family = AF_INET6;
+      _peerAddr.sin6_port = htons(port);
+      ptonReturn = inet_pton(AF_INET6, addr_c, &(_peerAddr.sin6_addr));
+      if (ptonReturn == 0)   // error
+       {
+         DESTROY(self);
+       }
+    }
+  return self;
+}
+#else
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  RELEASE(self);
+  return nil;
+}
+#endif
address@hidden
+
address@hidden GSLocalOutputStream 
+
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_un);
+}
+
+- (struct sockaddr*) peerAddr
+{
+  return (struct sockaddr*)&_peerAddr;
+}
+
+- (id) initToAddr: (NSString*)addr
+{
+  const char* real_addr = [addr fileSystemRepresentation];
+
+  if ((self = [super init]) != nil)
+    {
+      _peerAddr.sun_family = AF_LOCAL;
+      if (strlen(real_addr) > sizeof(_peerAddr.sun_path)-1) // too long
+       {
+         DESTROY(self);
+       }
+      else
+       {
+         strncpy(_peerAddr.sun_path, real_addr, sizeof(_peerAddr.sun_path)-1);
+       }
+    }
+  return self;
+}
+
address@hidden
+
address@hidden NSStream
+
++ (void) getStreamsToHost: (NSHost *)host 
+                     port: (int)port 
+              inputStream: (NSInputStream **)inputStream 
+             outputStream: (NSOutputStream **)outputStream
+{
+  NSString *address = [host address];
+  GSSocketInputStream *ins = nil;
+  GSSocketOutputStream *outs = nil;
+  int sock;
+
+  // try ipv4 first
+  ins = AUTORELEASE([[GSInetInputStream alloc]
+    initToAddr: address port: port]);
+  outs = AUTORELEASE([[GSInetOutputStream alloc]
+    initToAddr: address port: port]);
+  if (!ins)
+    {
+#if    defined(PF_INET6)
+      ins = [[GSInet6InputStream alloc] initToAddr: address
+                                        port: port];
+      outs = [[GSInet6OutputStream alloc] initToAddr: address
+                                          port: port];
+      sock = socket(PF_INET6, SOCK_STREAM, 0);
+#else
+      sock = -1;
+#endif
+    }  
+  else
+    {
+      sock = socket(PF_INET, SOCK_STREAM, 0);
+    }
+
+  NSAssert(sock >= 0, @"Cannot open socket");
+  [ins _setLoopID: (void*)(intptr_t)sock];
+  [outs _setLoopID: (void*)(intptr_t)sock];
+  if (inputStream)
+    {
+      [ins setSibling: outs];
+      *inputStream = ins;
+    }
+  if (outputStream)
+    {
+      [outs setSibling: ins];
+      *outputStream = outs;
+    }
+  return;
+}
+
++ (void) getLocalStreamsToPath: (NSString *)path 
+                   inputStream: (NSInputStream **)inputStream 
+                  outputStream: (NSOutputStream **)outputStream
+{
+  GSSocketInputStream *ins = nil;
+  GSSocketOutputStream *outs = nil;
+  int sock;
+
+  ins = AUTORELEASE([[GSLocalInputStream alloc] initToAddr: path]);
+  outs = AUTORELEASE([[GSLocalOutputStream alloc] initToAddr: path]);
+  sock = socket(PF_LOCAL, SOCK_STREAM, 0);
+
+  NSAssert(sock >= 0, @"Cannot open socket");
+  [ins _setLoopID: (void*)(intptr_t)sock];
+  [outs _setLoopID: (void*)(intptr_t)sock];
+  if (inputStream)
+    {
+      [ins setSibling: outs];
+      *inputStream = ins;
+    }
+  if (outputStream)
+    {
+      [outs setSibling: ins];
+      *outputStream = outs;
+    }
+  return;
+}
+
++ (void) pipeWithInputStream: (NSInputStream **)inputStream 
+                outputStream: (NSOutputStream **)outputStream
+{
+  GSSocketInputStream *ins = nil;
+  GSSocketOutputStream *outs = nil;
+  int fds[2];
+  int pipeReturn;
+
+  // the type of the stream does not matter, since we are only using the fd
+  ins = AUTORELEASE([GSLocalInputStream new]);
+  outs = AUTORELEASE([GSLocalOutputStream new]);
+  pipeReturn = pipe(fds);
+
+  NSAssert(pipeReturn >= 0, @"Cannot open pipe");
+  [ins _setLoopID: (void*)(intptr_t)fds[0]];
+  [outs _setLoopID: (void*)(intptr_t)fds[1]];
+  // no need to connect
+  [ins setPassive: YES];
+  [outs setPassive: YES];
+  if (inputStream)
+    *inputStream = ins;
+  if (outputStream)
+    *outputStream = outs;
+  return;
+}
+
+- (void) close
+{
+  [self subclassResponsibility: _cmd];
+}
+
+- (void) open
+{
+  [self subclassResponsibility: _cmd];
+}
+
+- (void) setDelegate: (id)delegate
+{
+  [self subclassResponsibility: _cmd];
+}
+
+- (id) delegate
+{
+  [self subclassResponsibility: _cmd];
+  return nil;
+}
+
+- (BOOL) setProperty: (id)property forKey: (NSString *)key
+{
+  [self subclassResponsibility: _cmd];
+  return NO;
+}
+
+- (id) propertyForKey: (NSString *)key
+{
+  [self subclassResponsibility: _cmd];
+  return nil;
+}
+
+- (void) scheduleInRunLoop: (NSRunLoop *)aRunLoop forMode: (NSString *)mode
+{
+  [self subclassResponsibility: _cmd];
+}
+
+- (void) removeFromRunLoop: (NSRunLoop *)aRunLoop forMode: (NSString *)mode;
+{
+  [self subclassResponsibility: _cmd];
+}
+
+- (NSError *) streamError
+{
+  [self subclassResponsibility: _cmd];
+  return nil;
+}
+
+- (NSStreamStatus) streamStatus
+{
+  [self subclassResponsibility: _cmd];
+  return 0;
+}
+
address@hidden
+
address@hidden NSInputStream
+
++ (id) inputStreamWithData: (NSData *)data
+{
+  return AUTORELEASE([[GSDataInputStream alloc] initWithData: data]);
+}
+
++ (id) inputStreamWithFileAtPath: (NSString *)path
+{
+  return AUTORELEASE([[GSFileInputStream alloc] initWithFileAtPath: path]);
+}
+
+- (BOOL) getBuffer: (uint8_t **)buffer length: (unsigned int *)len
+{
+  [self subclassResponsibility: _cmd];
+  return NO;
+}
+
+- (BOOL) hasBytesAvailable
+{
+  [self subclassResponsibility: _cmd];
+  return NO;
+}
+
+- (id) initWithData: (NSData *)data
+{
+  RELEASE(self);
+  return [[GSDataInputStream alloc] initWithData: data];
+}
+
+- (id) initWithFileAtPath: (NSString *)path
+{
+  RELEASE(self);
+  return [[GSFileInputStream alloc] initWithFileAtPath: path];
+}
+
+- (int) read: (uint8_t *)buffer maxLength: (unsigned int)len
+{
+  [self subclassResponsibility: _cmd];
+  return -1;
+}
+
address@hidden
+
address@hidden NSOutputStream
+
++ (id) outputStreamToBuffer: (uint8_t *)buffer capacity: (unsigned int)capacity
+{
+  return AUTORELEASE([[GSBufferOutputStream alloc] 
+    initToBuffer: buffer capacity: capacity]);  
+}
+
++ (id) outputStreamToFileAtPath: (NSString *)path append: (BOOL)shouldAppend
+{
+  return AUTORELEASE([[GSFileOutputStream alloc]
+    initToFileAtPath: path append: shouldAppend]);
+}
+
++ (id) outputStreamToMemory
+{
+  return AUTORELEASE([[GSDataOutputStream alloc] init]);  
+}
+
+- (BOOL) hasSpaceAvailable
+{
+  [self subclassResponsibility: _cmd];
+  return NO;
+}
+
+- (id) initToBuffer: (uint8_t *)buffer capacity: (unsigned int)capacity
+{
+  RELEASE(self);
+  return [[GSBufferOutputStream alloc] initToBuffer: buffer capacity: 
capacity];
+}
+
+- (id) initToFileAtPath: (NSString *)path append: (BOOL)shouldAppend
+{
+  RELEASE(self);
+  return [[GSFileOutputStream alloc] initToFileAtPath: path
+                                              append: shouldAppend];  
+}
+
+- (id) initToMemory
+{
+  RELEASE(self);
+  return [[GSDataOutputStream alloc] init];
+}
+
+- (int) write: (const uint8_t *)buffer maxLength: (unsigned int)len
+{
+  [self subclassResponsibility: _cmd];
+  return -1;  
+}
+
address@hidden
+
address@hidden GSServerStream
+
++ (id) serverStreamToAddr: (NSString*)addr port: (int)port
+{
+  GSServerStream *s;
+
+  // try inet first, then inet6
+  s = [[GSInetServerStream alloc] initToAddr: addr port: port];
+  if (!s)
+    s = [[GSInet6ServerStream alloc] initToAddr: addr port: port];
+  return AUTORELEASE(s);
+}
+
++ (id) serverStreamToAddr: (NSString*)addr
+{
+  return AUTORELEASE([[GSLocalServerStream alloc] initToAddr: addr]);
+}
+
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  RELEASE(self);
+  // try inet first, then inet6
+  self = [[GSInetServerStream alloc] initToAddr: addr port: port];
+  if (!self)
+    self = [[GSInet6ServerStream alloc] initToAddr: addr port: port];
+  return self;
+}
+
+- (id) initToAddr: (NSString*)addr
+{
+  RELEASE(self);
+  return [[GSLocalServerStream alloc] initToAddr: addr];
+}
+
+- (void) acceptWithInputStream: (NSInputStream **)inputStream 
+                  outputStream: (NSOutputStream **)outputStream
+{
+  [self subclassResponsibility: _cmd];
+}
+
address@hidden
+
address@hidden GSSocketServerStream
+
+- (Class) _inputStreamClass
+{
+  [self subclassResponsibility: _cmd];
+  return Nil;
+}
+
+- (Class) _outputStreamClass
+{
+  [self subclassResponsibility: _cmd];
+  return Nil;
+}
+
+- (void) dealloc
+{
+  if ([self _isOpened])
+    {
+      [self close];
+    }
+  [super dealloc];
+}
+
+- (socklen_t) sockLen
+{
+  [self subclassResponsibility: _cmd];
+  return 0;
+}
+
+- (struct sockaddr*) serverAddr
+{
+  [self subclassResponsibility: _cmd];
+  return 0;
+}
+
+#define SOCKET_BACKLOG 256
+
+- (void) open
+{
+  int bindReturn;
+  int listenReturn;
+
+#ifndef        BROKEN_SO_REUSEADDR
+  /*
+   * Under decent systems, SO_REUSEADDR means that the port can be reused
+   * immediately that this process exits.  Under some it means
+   * that multiple processes can serve the same port simultaneously.
+   * We don't want that broken behavior!
+   */
+  int  status = 1;
+
+  setsockopt((int)(intptr_t)_loopID, SOL_SOCKET, SO_REUSEADDR,
+    (char *)&status, sizeof(status));
+#endif
+
+  bindReturn = bind((int)(intptr_t)_loopID, [self serverAddr], [self sockLen]);
+  listenReturn = listen((intptr_t)_loopID, SOCKET_BACKLOG);
+  if (bindReturn < 0 || listenReturn < 0)
+    {
+      [self _recordError];
+      [self _sendEvent: NSStreamEventErrorOccurred];
+      return;
+    }
+  setNonblocking((intptr_t)_loopID);
+  // put itself to the runloop
+  [super open];
+}
+
+- (void) close
+{
+  // close a server socket is safe
+  close((intptr_t)_loopID);
+  [super close];
+}
+
+- (void) acceptWithInputStream: (NSInputStream **)inputStream 
+                  outputStream: (NSOutputStream **)outputStream
+{
+  GSSocketInputStream *ins = AUTORELEASE([[self _inputStreamClass] new]);
+  GSSocketOutputStream *outs = AUTORELEASE([[self _outputStreamClass] new]);
+  socklen_t len = [ins sockLen];
+  int acceptReturn = accept((intptr_t)_loopID, [ins peerAddr], &len);
+
+  _events &= ~NSStreamEventHasBytesAvailable;
+  if (acceptReturn < 0)
+    { // test for real error
+      if (errno != EWOULDBLOCK
+#if    defined(EAGAIN)
+       && errno != EAGAIN
+#endif
+#if    defined(ECONNABORTED)
+       && errno != ECONNABORTED
+#endif
+#if    defined(EPROTO)
+       && errno != EPROTO
+#endif
+       && errno != EINTR)
+       {
+          [self _recordError];
+       }
+      ins = nil;
+      outs = nil;
+    }
+  else
+    {
+      // no need to connect again
+      [ins setPassive: YES];
+      [outs setPassive: YES];
+      // copy the addr to outs
+      memcpy([outs peerAddr], [ins peerAddr], len);
+      [ins _setLoopID: (void*)(intptr_t)acceptReturn];
+      [outs _setLoopID: (void*)(intptr_t)acceptReturn];
+    }
+  if (inputStream)
+    {
+      [ins setSibling: outs];
+      *inputStream = ins;
+    }
+  if (outputStream)
+    {
+      [outs setSibling: ins];
+      *outputStream = outs;
+    }
+}
+
+- (void) _dispatch
+{
+  NSStreamEvent myEvent;
+
+  [self _setStatus: NSStreamStatusOpen];
+  myEvent = NSStreamEventHasBytesAvailable;
+  [self _sendEvent: myEvent];
+}
+
address@hidden
+
address@hidden GSInetServerStream
+
+- (Class) _inputStreamClass
+{
+  return [GSInetInputStream class];
+}
+
+- (Class) _outputStreamClass
+{
+  return [GSInetOutputStream class];
+}
+
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_in);
+}
+
+- (struct sockaddr*) serverAddr
+{
+  return (struct sockaddr*)&_serverAddr;
+}
+
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  int ptonReturn;
+  const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
+
+  [super init];
+  _serverAddr.sin_family = AF_INET;
+  _serverAddr.sin_port = htons(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
+    {
+      RELEASE(self);
+      return nil;
+    }
+  NSAssert(_loopID >= 0, @"cannot open socket");
+  return self;
+}
+
address@hidden
+
address@hidden GSInet6ServerStream
+#if    defined(AF_INET6)
+- (Class) _inputStreamClass
+{
+  return [GSInet6InputStream class];
+}
+
+- (Class) _outputStreamClass
+{
+  return [GSInet6OutputStream class];
+}
+
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_in6);
+}
+
+- (struct sockaddr*) serverAddr
+{
+  return (struct sockaddr*)&_serverAddr;
+}
+
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  int ptonReturn;
+  const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
+
+  [super init];
+  _serverAddr.sin6_family = AF_INET6;
+  _serverAddr.sin6_port = htons(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
+    {
+      RELEASE(self);
+      return nil;
+    }
+  NSAssert(_loopID >= 0, @"cannot open socket");
+  return self;
+}
+#else
+- (id) initToAddr: (NSString*)addr port: (int)port
+{
+  RELEASE(self);
+  return nil;
+}
+#endif
address@hidden
+
address@hidden GSLocalServerStream 
+
+- (Class) _inputStreamClass
+{
+  return [GSLocalInputStream class];
+}
+
+- (Class) _outputStreamClass
+{
+  return [GSLocalOutputStream class];
+}
+
+- (socklen_t) sockLen
+{
+  return sizeof(struct sockaddr_un);
+}
+
+- (struct sockaddr*) serverAddr
+{
+  return (struct sockaddr*)&_serverAddr;
+}
+
+- (id) initToAddr: (NSString*)addr
+{
+  const char* real_addr = [addr fileSystemRepresentation];
+  [super init];
+  _serverAddr.sun_family = AF_LOCAL;
+  _loopID = (void *)(intptr_t)socket(AF_LOCAL, SOCK_STREAM, 0);
+  if (strlen(real_addr) > sizeof(_serverAddr.sun_path)-1 || _loopID < 0)
+    {
+      RELEASE(self);
+      return nil;
+    }
+  strncpy(_serverAddr.sun_path, real_addr, sizeof(_serverAddr.sun_path)-1);
+  return self;
+}
+
address@hidden
+
-- 
1.5.2.rc0.14.g520d-dirty





reply via email to

[Prev in Thread] Current Thread [Next in Thread]