mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-06 06:30:46 +00:00
tidied pipe streams in mingw32
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22711 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
8325ce26d1
commit
eaedea3169
2 changed files with 132 additions and 97 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2006-03-25 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/win32/NSStreamWin32.m: Variout tidyups for pipe streams.
|
||||||
|
|
||||||
2006-03-24 Richard Frith-Macdonald <rfm@gnu.org>
|
2006-03-24 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/GSRunLoopCtxt.h:
|
* Source/GSRunLoopCtxt.h:
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
|
|
||||||
#include "../GSStream.h"
|
#include "../GSStream.h"
|
||||||
|
|
||||||
|
#define BUFFERSIZE (BUFSIZ*64)
|
||||||
|
|
||||||
typedef int socklen_t;
|
typedef int socklen_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,12 +65,13 @@ typedef int socklen_t;
|
||||||
{
|
{
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
OVERLAPPED ov;
|
OVERLAPPED ov;
|
||||||
uint8_t data[BUFSIZ*64];
|
uint8_t data[BUFFERSIZE];
|
||||||
unsigned offset; // Read pointer within buffer
|
unsigned offset; // Read pointer within buffer
|
||||||
unsigned length; // Amount of data in buffer
|
unsigned length; // Amount of data in buffer
|
||||||
unsigned want; // Amount of data we want to read.
|
unsigned want; // Amount of data we want to read.
|
||||||
DWORD size; // Number of bytes returned by read.
|
DWORD size; // Number of bytes returned by read.
|
||||||
}
|
}
|
||||||
|
- (NSStreamStatus) _check;
|
||||||
- (void) _queue;
|
- (void) _queue;
|
||||||
- (void) _setHandle: (HANDLE)h;
|
- (void) _setHandle: (HANDLE)h;
|
||||||
@end
|
@end
|
||||||
|
@ -141,11 +144,12 @@ typedef int socklen_t;
|
||||||
{
|
{
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
OVERLAPPED ov;
|
OVERLAPPED ov;
|
||||||
NSMutableData *data;
|
uint8_t data[BUFFERSIZE];
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
unsigned want;
|
unsigned want;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
}
|
}
|
||||||
|
- (NSStreamStatus) _check;
|
||||||
- (void) _queue;
|
- (void) _queue;
|
||||||
- (void) _setHandle: (HANDLE)h;
|
- (void) _setHandle: (HANDLE)h;
|
||||||
@end
|
@end
|
||||||
|
@ -419,6 +423,43 @@ static void setNonblocking(SOCKET fd)
|
||||||
[self _queue];
|
[self _queue];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSStreamStatus) _check
|
||||||
|
{
|
||||||
|
// Must only be called when current status is NSStreamStatusReading.
|
||||||
|
|
||||||
|
if (GetOverlappedResult(handle, &ov, &size, TRUE) == 0)
|
||||||
|
{
|
||||||
|
errno = GetLastError();
|
||||||
|
if (errno == ERROR_HANDLE_EOF
|
||||||
|
|| errno == ERROR_BROKEN_PIPE)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Got EOF, but we don't want to register it until a
|
||||||
|
* -read:maxLength: is called.
|
||||||
|
*/
|
||||||
|
offset = length = want = 0;
|
||||||
|
[self _setStatus: NSStreamStatusOpen];
|
||||||
|
}
|
||||||
|
else if (errno != ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Got an error ... record it.
|
||||||
|
*/
|
||||||
|
want = 0;
|
||||||
|
[self _recordError];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Read completed and some data was read.
|
||||||
|
*/
|
||||||
|
length = size;
|
||||||
|
[self _setStatus: NSStreamStatusOpen];
|
||||||
|
}
|
||||||
|
return [self streamStatus];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) _queue
|
- (void) _queue
|
||||||
{
|
{
|
||||||
if ([self streamStatus] == NSStreamStatusOpen)
|
if ([self streamStatus] == NSStreamStatusOpen)
|
||||||
|
@ -461,6 +502,10 @@ static void setNonblocking(SOCKET fd)
|
||||||
{
|
{
|
||||||
NSStreamStatus myStatus = [self streamStatus];
|
NSStreamStatus myStatus = [self streamStatus];
|
||||||
|
|
||||||
|
if (myStatus == NSStreamStatusReading)
|
||||||
|
{
|
||||||
|
myStatus = [self _check];
|
||||||
|
}
|
||||||
if (myStatus == NSStreamStatusAtEnd)
|
if (myStatus == NSStreamStatusAtEnd)
|
||||||
{
|
{
|
||||||
return 0; // At EOF
|
return 0; // At EOF
|
||||||
|
@ -509,54 +554,27 @@ static void setNonblocking(SOCKET fd)
|
||||||
- (void) _dispatch
|
- (void) _dispatch
|
||||||
{
|
{
|
||||||
NSStreamEvent myEvent;
|
NSStreamEvent myEvent;
|
||||||
NSStreamStatus myStatus = [self streamStatus];
|
NSStreamStatus oldStatus = [self streamStatus];
|
||||||
|
NSStreamStatus myStatus = oldStatus;
|
||||||
|
|
||||||
if (myStatus == NSStreamStatusReading)
|
if (myStatus == NSStreamStatusReading
|
||||||
|
|| myStatus == NSStreamStatusOpening)
|
||||||
{
|
{
|
||||||
if (GetOverlappedResult(handle, &ov, &size, TRUE) == 0)
|
myStatus = [self _check];
|
||||||
{
|
|
||||||
errno = GetLastError();
|
|
||||||
if (errno == ERROR_HANDLE_EOF
|
|
||||||
|| errno == ERROR_BROKEN_PIPE)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Got EOF, but we don't want to register it until a
|
|
||||||
* -read:maxLength: is called.
|
|
||||||
*/
|
|
||||||
offset = length = 0;
|
|
||||||
}
|
|
||||||
else if (errno == ERROR_IO_PENDING)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Read operation has not completed.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Got an error ... record it.
|
|
||||||
*/
|
|
||||||
[self _recordError];
|
|
||||||
}
|
|
||||||
myStatus = NSStreamStatusOpen;
|
|
||||||
want = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Read completed and some data was read.
|
|
||||||
*/
|
|
||||||
myStatus = NSStreamStatusOpen;
|
|
||||||
length = size;
|
|
||||||
}
|
|
||||||
[self _setStatus: myStatus];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myStatus == NSStreamStatusAtEnd)
|
if (myStatus == NSStreamStatusAtEnd)
|
||||||
{
|
{
|
||||||
myEvent = NSStreamEventEndEncountered;
|
myEvent = NSStreamEventEndEncountered;
|
||||||
}
|
}
|
||||||
|
else if (myStatus == NSStreamStatusError)
|
||||||
|
{
|
||||||
|
myEvent = NSStreamEventErrorOccurred;
|
||||||
|
}
|
||||||
|
else if (oldStatus == NSStreamStatusOpening)
|
||||||
|
{
|
||||||
|
myEvent = NSStreamEventOpenCompleted;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myEvent = NSStreamEventHasBytesAvailable;
|
myEvent = NSStreamEventHasBytesAvailable;
|
||||||
|
@ -569,15 +587,12 @@ static void setNonblocking(SOCKET fd)
|
||||||
{
|
{
|
||||||
NSStreamStatus myStatus = [self streamStatus];
|
NSStreamStatus myStatus = [self streamStatus];
|
||||||
|
|
||||||
|
*trigger = YES;
|
||||||
if (myStatus == NSStreamStatusReading)
|
if (myStatus == NSStreamStatusReading)
|
||||||
{
|
{
|
||||||
// Need to wait for I/O
|
return YES; // Need to wait for I/O
|
||||||
*trigger = YES;
|
|
||||||
return YES;
|
|
||||||
}
|
}
|
||||||
// Need to signal for an event
|
return NO; // Need to signal for an event
|
||||||
*trigger = YES;
|
|
||||||
return NO;
|
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -973,10 +988,6 @@ static void setNonblocking(SOCKET fd)
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
if (data != nil)
|
|
||||||
{
|
|
||||||
DESTROY(data);
|
|
||||||
}
|
|
||||||
if ([self _isOpened])
|
if ([self _isOpened])
|
||||||
[self close];
|
[self close];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
|
@ -1022,7 +1033,7 @@ static void setNonblocking(SOCKET fd)
|
||||||
ov.OffsetHigh = 0;
|
ov.OffsetHigh = 0;
|
||||||
ov.hEvent = (HANDLE)_loopID;
|
ov.hEvent = (HANDLE)_loopID;
|
||||||
size = 0;
|
size = 0;
|
||||||
rc = WriteFile(handle, [data bytes]+offset, want-offset, &size, &ov);
|
rc = WriteFile(handle, data + offset, want - offset, &size, &ov);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
{
|
{
|
||||||
offset += size;
|
offset += size;
|
||||||
|
@ -1043,23 +1054,56 @@ static void setNonblocking(SOCKET fd)
|
||||||
|
|
||||||
- (int) write: (const uint8_t *)buffer maxLength: (unsigned int)len
|
- (int) write: (const uint8_t *)buffer maxLength: (unsigned int)len
|
||||||
{
|
{
|
||||||
if (len <= 0 || [self streamStatus] != NSStreamStatusOpen)
|
NSStreamStatus myStatus = [self streamStatus];
|
||||||
|
|
||||||
|
if (len < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (data == nil)
|
if (myStatus == NSStreamStatusWriting)
|
||||||
{
|
{
|
||||||
data = [[NSMutableData alloc] initWithBytes: buffer length: len];
|
myStatus = [self _check];
|
||||||
|
}
|
||||||
|
if ((myStatus != NSStreamStatusOpen && myStatus != NSStreamStatusWriting))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (len > (sizeof(data) - offset))
|
||||||
|
{
|
||||||
|
len = sizeof(data) - offset;
|
||||||
|
}
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
memcpy(data + offset, buffer, len);
|
||||||
|
want = offset + len;
|
||||||
|
[self _queue];
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSStreamStatus) _check
|
||||||
|
{
|
||||||
|
// Must only be called when current status is NSStreamStatusWriting.
|
||||||
|
if (GetOverlappedResult(handle, &ov, &size, TRUE) == 0)
|
||||||
|
{
|
||||||
|
errno = GetLastError();
|
||||||
|
if (errno != ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
want = 0;
|
||||||
|
[self _recordError];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[data setLength: 0];
|
[self _setStatus: NSStreamStatusOpen];
|
||||||
[data appendBytes: buffer length: len];
|
offset += size;
|
||||||
|
if (offset <= want)
|
||||||
|
{
|
||||||
|
[self _queue];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
want = len;
|
return [self streamStatus];
|
||||||
offset = 0;
|
|
||||||
[self _queue];
|
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) _setHandle: (HANDLE)h
|
- (void) _setHandle: (HANDLE)h
|
||||||
|
@ -1069,44 +1113,32 @@ static void setNonblocking(SOCKET fd)
|
||||||
|
|
||||||
- (void) _dispatch
|
- (void) _dispatch
|
||||||
{
|
{
|
||||||
BOOL av;
|
|
||||||
NSStreamEvent myEvent;
|
NSStreamEvent myEvent;
|
||||||
|
NSStreamStatus oldStatus = [self streamStatus];
|
||||||
|
NSStreamStatus myStatus = oldStatus;
|
||||||
|
|
||||||
if ([self streamStatus] == NSStreamStatusWriting)
|
if (myStatus == NSStreamStatusWriting
|
||||||
|
|| myStatus == NSStreamStatusOpening)
|
||||||
{
|
{
|
||||||
if (GetOverlappedResult(handle, &ov, &size, TRUE) == 0)
|
myStatus = [self _check];
|
||||||
{
|
|
||||||
errno = GetLastError();
|
|
||||||
if (errno == ERROR_IO_PENDING)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Write operation has not completed.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
[self _recordError];
|
|
||||||
offset = 0;
|
|
||||||
want = 0;
|
|
||||||
[self _setStatus: NSStreamStatusAtEnd];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[self _setStatus: NSStreamStatusOpen];
|
|
||||||
offset += size;
|
|
||||||
if (offset <= want)
|
|
||||||
{
|
|
||||||
[self _queue];
|
|
||||||
}
|
|
||||||
if ([self streamStatus] == NSStreamStatusWriting)
|
|
||||||
{
|
|
||||||
return; // Write not complete
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
av = [self hasSpaceAvailable];
|
if (myStatus == NSStreamStatusAtEnd)
|
||||||
myEvent = av ? NSStreamEventHasSpaceAvailable :
|
{
|
||||||
NSStreamEventEndEncountered;
|
myEvent = NSStreamEventEndEncountered;
|
||||||
|
}
|
||||||
|
else if (myStatus == NSStreamStatusError)
|
||||||
|
{
|
||||||
|
myEvent = NSStreamEventErrorOccurred;
|
||||||
|
}
|
||||||
|
else if (oldStatus == NSStreamStatusOpening)
|
||||||
|
{
|
||||||
|
myEvent = NSStreamEventOpenCompleted;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myEvent = NSStreamEventHasSpaceAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
[self _sendEvent: myEvent];
|
[self _sendEvent: myEvent];
|
||||||
}
|
}
|
||||||
|
@ -1115,12 +1147,11 @@ static void setNonblocking(SOCKET fd)
|
||||||
{
|
{
|
||||||
NSStreamStatus myStatus = [self streamStatus];
|
NSStreamStatus myStatus = [self streamStatus];
|
||||||
|
|
||||||
|
*trigger = YES;
|
||||||
if (myStatus == NSStreamStatusWriting)
|
if (myStatus == NSStreamStatusWriting)
|
||||||
{
|
{
|
||||||
*trigger = YES;
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
*trigger = YES;
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in a new issue