GSFileHandle stuff for windoze

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@13998 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-06-30 09:19:30 +00:00
parent 14b2a2e3e2
commit 6fec988fe1
9 changed files with 2608 additions and 69 deletions

View file

@ -1,3 +1,11 @@
2002-06-30 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/gnustep/base/GSFileHandle.h: New version of UnixFileHandle
for combined unix/windoze use.
* Source/GSFileHandle.m: New combined unix/windows implementation.
* Source/NSFileHandle.m: Use GSFileHandle under windoze.
* Source/GNUMakefile: Build GSFileHandle under windoze.
2002-06-29 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSObject.m: ([-respondsToSelector:]) handle nul selectors.

View file

@ -0,0 +1,104 @@
/* Interface for GSFileHandle for GNUStep
Copyright (C) 1997-2002 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: 1997
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __GSFileHandle_h_GNUSTEP_BASE_INCLUDE
#define __GSFileHandle_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSFileHandle.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSRunLoop.h>
#include <GSConfig.h>
#if USE_ZLIB
#include <zlib.h>
#endif
@interface GSFileHandle : NSFileHandle <RunLoopEvents, GCFinalization>
{
int descriptor;
BOOL closeOnDealloc;
BOOL isStandardFile;
BOOL isNullDevice;
BOOL isNonBlocking;
BOOL wasNonBlocking;
BOOL acceptOK;
BOOL connectOK;
BOOL readOK;
BOOL writeOK;
NSMutableDictionary *readInfo;
int readMax;
NSMutableArray *writeInfo;
int writePos;
NSString *address;
NSString *service;
NSString *protocol;
#if USE_ZLIB
gzFile gzDescriptor;
#endif
}
- (id) initAsClientAtAddress: (NSString*)address
service: (NSString*)service
protocol: (NSString*)protocol;
- (id) initAsClientInBackgroundAtAddress: (NSString*)address
service: (NSString*)service
protocol: (NSString*)protocol
forModes: (NSArray*)modes;
- (id) initAsServerAtAddress: (NSString*)address
service: (NSString*)service
protocol: (NSString*)protocol;
- (id) initForReadingAtPath: (NSString*)path;
- (id) initForWritingAtPath: (NSString*)path;
- (id) initForUpdatingAtPath: (NSString*)path;
- (id) initWithStandardError;
- (id) initWithStandardInput;
- (id) initWithStandardOutput;
- (id) initWithNullDevice;
- (void) checkAccept;
- (void) checkConnect;
- (void) checkRead;
- (void) checkWrite;
- (void) ignoreReadDescriptor;
- (void) ignoreWriteDescriptor;
- (void) setNonBlocking: (BOOL)flag;
- (void) postReadNotification;
- (void) postWriteNotification;
- (void) receivedEvent: (void*)data
type: (RunLoopEventType)type
extra: (void*)extra
forMode: (NSString*)mode;
- (void) setAddr: (struct sockaddr_in *)sin;
- (NSDate*) timedOutEvent: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode;
- (BOOL) useCompression;
- (void) watchReadDescriptorForModes: (NSArray*)modes;
- (void) watchWriteDescriptor;
@end
#endif /* __GSFileHandle_h_GNUSTEP_BASE_INCLUDE */

View file

@ -103,7 +103,7 @@ endif
endif
ifeq ($(GNUSTEP_TARGET_OS), mingw32)
GNU_MFILES += WindowsFileHandle.m libgnustep-base-entry.m
GNU_MFILES += GSFileHandle.m libgnustep-base-entry.m
else
GNU_MFILES += UnixFileHandle.m
endif

2268
Source/GSFileHandle.m Normal file

File diff suppressed because it is too large Load diff

View file

@ -256,7 +256,7 @@ $(GNUSTEP_OBJ_DIR)/NSGeometry.o \
# by hand when new classes get added. Then mv libgnustep-base.def.new to
# libgnustep-base.def
#
libgnustep-base.def.new: $(GNUSTEP_OBJ_DIR)/*o
libgnustep-base.def.new: $(GNUSTEP_OBJ_DIR)/*o Additions/$(GNUSTEP_OBJ_DIR)/*o
rm -f $@
rm -f _tmp.def
cat win32-def.top > $@

View file

@ -33,7 +33,7 @@
#include <Foundation/NSPathUtilities.h>
#include <Foundation/NSBundle.h>
#ifdef __MINGW__
#include <Foundation/WindowsFileHandle.h>
#include <Foundation/GSFileHandle.h>
#else
#include <Foundation/UnixFileHandle.h>
#endif
@ -62,7 +62,7 @@ static Class NSFileHandle_ssl_class = nil;
{
NSFileHandle_abstract_class = self;
#ifdef __MINGW__
NSFileHandle_concrete_class = [WindowsFileHandle class];
NSFileHandle_concrete_class = [GSFileHandle class];
#else
NSFileHandle_concrete_class = [UnixFileHandle class];
#endif

View file

@ -45,6 +45,12 @@
#if defined(__MINGW__)
#include <winsock2.h>
#include <fcntl.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <stdio.h>
#else
#include <time.h>
#include <sys/time.h>
@ -53,8 +59,6 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#endif /* __MINGW__ */
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
@ -63,6 +67,8 @@
#include <sys/filio.h>
#endif
#include <netdb.h>
#endif /* __MINGW__ */
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@ -190,11 +196,13 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
{
if (self == [UnixFileHandle class])
{
#if !defined(__MINGW__)
/*
* 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);
#endif
}
}
@ -707,7 +715,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
[self setAddr: &sin]; // Store the address of the remote end.
/*
* Don't use SOCKS if we are contancting the local host.
* Don't use SOCKS if we are contacting the local host.
*/
if (shost != nil)
{
@ -743,14 +751,20 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
[self setNonBlocking: YES];
if (connect(net, (struct sockaddr*)&sin, sizeof(sin)) < 0)
if (errno != EINPROGRESS)
{
NSLog(@"unable to make connection to %s:%d - %s",
inet_ntoa(sin.sin_addr),
GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno));
RELEASE(self);
return nil;
}
{
#if defined(__MINGW__)
if (WSAGetLastError() != WSAEWOULDBLOCK)
#else
if (errno != EINPROGRESS)
#endif
{
NSLog(@"unable to make connection to %s:%d - %s",
inet_ntoa(sin.sin_addr),
GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno));
RELEASE(self);
return nil;
}
}
info = [[NSMutableDictionary alloc] initWithCapacity: 4];
[info setObject: address forKey: NSFileHandleNotificationDataItem];
@ -794,7 +808,9 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
service: (NSString*)s
protocol: (NSString*)p
{
#ifndef BROKEN_SO_REUSEADDR
int status = 1;
#endif
int net;
struct sockaddr_in sin;
int size = sizeof(sin);
@ -825,9 +841,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
NSLog(@"unable to bind to port %s:%d - %s",
inet_ntoa(sin.sin_addr),
GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno));
NSLog(@"unable to bind to port %s:%d - %s", inet_ntoa(sin.sin_addr),
GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno));
(void) close(net);
RELEASE(self);
return nil;
@ -988,12 +1003,18 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
- (id) initWithNullDevice
{
#if defined(__MINGW__)
isNullDevice = YES;
isStandardFile = YES;
descriptor = -1;
#else
self = [self initWithFileDescriptor: open("/dev/null", O_RDWR|O_BINARY)
closeOnDealloc: YES];
if (self)
{
isNullDevice = YES;
}
#endif
return self;
}
@ -1002,10 +1023,18 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
self = [super init];
if (self)
{
#if defined(__MINGW__)
struct _stat sbuf;
#else
struct stat sbuf;
int e;
#endif
#if defined(__MINGW__)
if (_fstat(desc, &sbuf) < 0)
#else
if (fstat(desc, &sbuf) < 0)
#endif
{
NSLog(@"unable to get status of descriptor - %s",
GSLastErrorStr(errno));
@ -1021,6 +1050,25 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
isStandardFile = NO;
}
#if defined(__MINGW__)
if (isStandardFile == NO)
{
unsigned long dummy = 0;
/*
* This is probably a socket ... try
* using a socket specific call and see if that fails.
*/
if (ioctlsocket(desc, FIONBIO, &dummy) < 0)
{
NSLog(@"unable to get status/type of descriptor - %s",
GSLastErrorStr(errno));
[self release];
return nil;
}
wasNonBlocking = (dummy == 0) ? NO : YES;
}
#else
if ((e = fcntl(desc, F_GETFL, 0)) >= 0)
{
if (e & NBLK_OPT)
@ -1032,6 +1080,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
wasNonBlocking = NO;
}
}
#endif
isNonBlocking = wasNonBlocking;
descriptor = desc;
@ -1050,12 +1099,22 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
- (id) initWithNativeHandle: (void*)hdl
{
#if defined(__MINGW__)
return [self initWithFileDescriptor: _open_osfhandle((int)hdl, 0)
closeOnDealloc: NO];
#else
return [self initWithFileDescriptor: (gsaddr)hdl closeOnDealloc: NO];
#endif
}
- (id) initWithNativeHandle: (void*)hdl closeOnDealloc: (BOOL)flag
{
#if defined(__MINGW__)
return [self initWithFileDescriptor: _open_osfhandle((int)hdl, 0)
closeOnDealloc: flag];
#else
return [self initWithFileDescriptor: (gsaddr)hdl closeOnDealloc: flag];
#endif
}
- (void) checkAccept
@ -1160,7 +1219,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
- (void*) nativeHandle
{
return (void*)0;
#if defined(__MINGW__)
return (void*)_get_osfhandle(descriptor);
#else
return (void*)descriptor;
#endif
}
// Synchronous I/O operations
@ -1206,7 +1269,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
else
#endif
if ((len = read(descriptor, buf, sizeof(buf))) > 0)
if ((len = recv(descriptor, buf, sizeof(buf), 0)) > 0)
{
[d appendBytes: buf length: len];
}
@ -1466,7 +1529,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
else
#endif
#if defined(__MINGW__)
result = _lseek(descriptor, 0, SEEK_CUR);
#else
result = lseek(descriptor, 0, SEEK_CUR);
#endif
}
if (result < 0)
{
@ -1490,7 +1557,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
else
#endif
#if defined(__MINGW__)
result = _lseek(descriptor, 0, SEEK_END);
#else
result = lseek(descriptor, 0, SEEK_END);
#endif
}
if (result < 0)
{
@ -1514,7 +1585,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
else
#endif
#if defined(__MINGW__)
result = _lseek(descriptor, (off_t)pos, SEEK_SET);
#else
result = lseek(descriptor, (off_t)pos, SEEK_SET);
#endif
}
if (result < 0)
{
@ -1530,9 +1605,10 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
- (void) closeFile
{
if (descriptor < 0)
[NSException raise: NSFileHandleOperationException
format: @"attempt to close closed file"];
{
[NSException raise: NSFileHandleOperationException
format: @"attempt to close closed file"];
}
[self ignoreReadDescriptor];
[self ignoreWriteDescriptor];
@ -1544,7 +1620,18 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
gzDescriptor = 0;
}
#endif
#if defined(__MINGW__)
if (isStandardFile)
{
(void)_close(descriptor);
}
else
{
(void)closesocket(descriptor);
}
#else
(void)close(descriptor);
#endif
descriptor = -1;
acceptOK = NO;
connectOK = NO;
@ -1575,16 +1662,24 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
- (void) synchronizeFile
{
#if !defined(__MINGW__)
if (isStandardFile)
{
(void)sync();
}
#endif
}
- (void) truncateFileAtOffset: (unsigned long long)pos
{
#if defined(__MINGW__)
_chsize(descriptor, pos);
#else
if (isStandardFile && descriptor >= 0)
(void)ftruncate(descriptor, pos);
{
(void)ftruncate(descriptor, pos);
}
#endif
[self seekToFileOffset: pos];
}
@ -1914,7 +2009,14 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
else
#endif
received = read(descriptor, buf, length);
if (isStandardFile)
{
received = read(descriptor, buf, length);
}
else
{
received = recv(descriptor, buf, length, 0);
}
if (received == 0)
{ // Read up to end of file.
[self postReadNotification];
@ -1992,7 +2094,16 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
}
else
#endif
written = write(descriptor, (char*)ptr+writePos, length-writePos);
if (isStandardFile)
{
written = write(descriptor, (char*)ptr+writePos,
length-writePos);
}
else
{
written = send(descriptor, (char*)ptr+writePos,
length-writePos, 0);
}
if (written <= 0)
{
if (written < 0 && errno != EAGAIN && errno != EINTR)
@ -2035,42 +2146,69 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr";
- (void) setNonBlocking: (BOOL)flag
{
int e;
if (descriptor < 0)
{
return;
}
if (isStandardFile == YES)
else if (isStandardFile == YES)
{
return;
}
if (isNonBlocking == flag)
else if (isNonBlocking == flag)
{
return;
}
if ((e = fcntl(descriptor, F_GETFL, 0)) >= 0)
{
if (flag == YES)
{
e |= NBLK_OPT;
}
else
{
e &= ~NBLK_OPT;
}
if (fcntl(descriptor, F_SETFL, e) < 0)
{
NSLog(@"unable to set non-blocking mode - %s", GSLastErrorStr(errno));
}
else
{
isNonBlocking = flag;
}
}
else
{
NSLog(@"unable to get non-blocking mode - %s", GSLastErrorStr(errno));
#if defined(__MINGW__)
unsigned long dummy;
if (flag)
{
dummy = 1;
if (ioctlsocket(descriptor, FIONBIO, &dummy) < 0)
{
NSLog(@"unable to set non-blocking mode - %s",
GSLastErrorStr(errno));
}
}
else
{
dummy = 0;
if (ioctlsocket(descriptor, FIONBIO, &dummy) < 0)
{
NSLog(@"unable to set blocking mode - %s",
GSLastErrorStr(errno));
}
}
#else
int e;
if ((e = fcntl(descriptor, F_GETFL, 0)) >= 0)
{
if (flag == YES)
{
e |= NBLK_OPT;
}
else
{
e &= ~NBLK_OPT;
}
if (fcntl(descriptor, F_SETFL, e) < 0)
{
NSLog(@"unable to set non-blocking mode - %s",
GSLastErrorStr(errno));
}
else
{
isNonBlocking = flag;
}
}
else
{
NSLog(@"unable to get non-blocking mode - %s", GSLastErrorStr(errno));
}
#endif
}
}

View file

@ -49,13 +49,10 @@ __objc_class_name_GSMutableDictionary
__objc_class_name_NSGDictionary
__objc_class_name_NSGMutableDictionary
__objc_class_name_GSFFCallInvocation
__objc_class_name_GSFTPURLHandle
__objc_class_name_GSTelnetHandle
__objc_class_name_GSFileHandle
__objc_class_name_GSHTTPURLHandle
__objc_class_name_GSMimeBase64DecoderContext
__objc_class_name_GSMimeChunkedDecoderContext
__objc_class_name_GSMimeCodingContext
__objc_class_name_GSMimeDocument
__objc_class_name_GSMimeParser
__objc_class_name_GSMimeQuotedDecoderContext
__objc_class_name_GSMutableSet
__objc_class_name_GSSet
__objc_class_name_GSSetEnumerator
@ -64,6 +61,7 @@ __objc_class_name_NSGSet
__objc_class_name_GSCInlineString
__objc_class_name_GSCString
__objc_class_name_GSCSubString
__objc_class_name_GSImmutableString
__objc_class_name_GSMutableString
__objc_class_name_GSPlaceholderString
__objc_class_name_GSString
@ -74,6 +72,7 @@ __objc_class_name_NSGCString
__objc_class_name_NSGMutableCString
__objc_class_name_NSGMutableString
__objc_class_name_NSGString
__objc_class_name_NSImmutableString
__objc_class_name_NXConstantString
__objc_class_name_GSTcpHandle
__objc_class_name_GSTcpPort
@ -84,13 +83,6 @@ __objc_class_name_GSPointerValue
__objc_class_name_GSRangeValue
__objc_class_name_GSRectValue
__objc_class_name_GSSizeValue
__objc_class_name_GSSAXHandler
__objc_class_name_GSXMLAttribute
__objc_class_name_GSXMLDocument
__objc_class_name_GSXMLDummy
__objc_class_name_GSXMLNamespace
__objc_class_name_GSXMLNode
__objc_class_name_GSXMLParser
__objc_class_name_NSArchiver
__objc_class_name_NSArray
__objc_class_name_NSArrayEnumerator
@ -167,6 +159,7 @@ __objc_class_name_NSULongNumber
__objc_class_name_NSLongLongNumber
__objc_class_name_NSNumberFormatter
__objc_class_name_NSObject
__objc_class_name_NSZombie
__objc_class_name__FastMallocBuffer
__objc_class_name_NSPipe
__objc_class_name_NSPort
@ -179,6 +172,7 @@ __objc_class_name_NSProcessInfo
__objc_class_name__NSConcreteProcessInfo
__objc_class_name_NSProtocolChecker
__objc_class_name_NSProxy
__objc_class_name_GSRunLoopCtxt
__objc_class_name_GSRunLoopPerformer
__objc_class_name_GSRunLoopWatcher
__objc_class_name_GSTimedPerformer
@ -216,4 +210,31 @@ __objc_class_name_PrivateUndoGroup
__objc_class_name_NSUserDefaults
__objc_class_name_GSPlaceholderValue
__objc_class_name_NSValue
__objc_class_name_WindowsFileHandle
__objc_class_name_GSMimeBase64DecoderContext
__objc_class_name_GSMimeChunkedDecoderContext
__objc_class_name_GSMimeCodingContext
__objc_class_name_GSMimeDocument
__objc_class_name_GSMimeHeader
__objc_class_name_GSMimeParser
__objc_class_name_GSMimeQuotedDecoderContext
__objc_class_name_GSSAXHandler
__objc_class_name_GSXMLAttribute
__objc_class_name_GSXMLDocument
__objc_class_name_GSXMLDummy
__objc_class_name_GSXMLNamespace
__objc_class_name_GSXMLNode
__objc_class_name_GSXMLParser
__objc_class_name_GSMimeBase64DecoderContext
__objc_class_name_GSMimeChunkedDecoderContext
__objc_class_name_GSMimeCodingContext
__objc_class_name_GSMimeDocument
__objc_class_name_GSMimeHeader
__objc_class_name_GSMimeParser
__objc_class_name_GSMimeQuotedDecoderContext
__objc_class_name_GSSAXHandler
__objc_class_name_GSXMLAttribute
__objc_class_name_GSXMLDocument
__objc_class_name_GSXMLDummy
__objc_class_name_GSXMLNamespace
__objc_class_name_GSXMLNode
__objc_class_name_GSXMLParser

View file

@ -11,16 +11,16 @@
#include <Foundation/Foundation.h>
@class GSTelnetHandle;
extern NSString * const GSTelnetNotification;
extern NSString * const GSTelnetErrorKey;
extern NSString * const GSTelnetTextKey;
GS_EXPORT NSString * const GSTelnetNotification;
GS_EXPORT NSString * const GSTelnetErrorKey;
GS_EXPORT NSString * const GSTelnetTextKey;
@class GSTelnetHandle;
@interface Call : NSObject
{
NSFileHandle *ichan;
NSFileHandle *ochan;
GSTelnetHandle *remote;
id remote;
NSMutableData *buf;
}
- (void) didRead: (NSNotification*)notification;