Index: src/OFStream.h ================================================================== --- src/OFStream.h +++ src/OFStream.h @@ -59,12 +59,11 @@ { char *cache; char *writeBuffer; size_t cacheLength, writeBufferLength; BOOL writeBufferEnabled; - BOOL blocking; - BOOL waitingForDelimiter; + BOOL blocking, waitingForDelimiter; } #ifdef OF_HAVE_PROPERTIES @property (getter=isWriteBufferEnabled) BOOL writeBufferEnabled; @property (getter=isBlocking) BOOL blocking; Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -37,10 +37,11 @@ #import "OFSystemInfo.h" #import "OFRunLoop.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" +#import "OFNotImplementedException.h" #import "OFSetOptionFailedException.h" #import "macros.h" #import "of_asprintf.h" @@ -99,20 +100,20 @@ return [self retain]; } - (BOOL)isAtEndOfStream { - if (cache != NULL) + if (cacheLength > 0) return NO; return [self lowlevelIsAtEndOfStream]; } - (size_t)readIntoBuffer: (void*)buffer length: (size_t)length { - if (cache == NULL) + if (cacheLength == 0) return [self lowlevelReadIntoBuffer: buffer length: length]; if (length >= cacheLength) { size_t ret = cacheLength; @@ -1464,33 +1465,66 @@ } - (void)setBlocking: (BOOL)enable { #ifndef _WIN32 - int readFlags, writeFlags; - - readFlags = fcntl([self fileDescriptorForReading], F_GETFL); - writeFlags = fcntl([self fileDescriptorForWriting], F_GETFL); - - if (readFlags == -1 || writeFlags == -1) - @throw [OFSetOptionFailedException - exceptionWithClass: [self class] - stream: self]; - - if (enable) { - readFlags &= ~O_NONBLOCK; - writeFlags &= ~O_NONBLOCK; - } else { - readFlags |= O_NONBLOCK; - writeFlags |= O_NONBLOCK; - } - - if (fcntl([self fileDescriptorForReading], F_SETFL, readFlags) == -1 || - fcntl([self fileDescriptorForWriting], F_SETFL, writeFlags) == -1) - @throw [OFSetOptionFailedException - exceptionWithClass: [self class] - stream: self]; + BOOL readImplemented = NO, writeImplemented = NO; + + @try { + int readFlags; + + readFlags = fcntl([self fileDescriptorForReading], F_GETFL); + + readImplemented = YES; + + if (readFlags == -1) + @throw [OFSetOptionFailedException + exceptionWithClass: [self class] + stream: self]; + + if (enable) + readFlags &= ~O_NONBLOCK; + else + readFlags |= O_NONBLOCK; + + if (fcntl([self fileDescriptorForReading], F_SETFL, + readFlags) == -1) + @throw [OFSetOptionFailedException + exceptionWithClass: [self class] + stream: self]; + } @catch (OFNotImplementedException *e) { + } + + @try { + int writeFlags; + + writeFlags = fcntl([self fileDescriptorForWriting], F_GETFL); + + writeImplemented = YES; + + if (writeFlags == -1) + @throw [OFSetOptionFailedException + exceptionWithClass: [self class] + stream: self]; + + if (enable) + writeFlags &= ~O_NONBLOCK; + else + writeFlags |= O_NONBLOCK; + + if (fcntl([self fileDescriptorForWriting], F_SETFL, + writeFlags) == -1) + @throw [OFSetOptionFailedException + exceptionWithClass: [self class] + stream: self]; + } @catch (OFNotImplementedException *e) { + } + + if (!readImplemented && !writeImplemented) + @throw [OFNotImplementedException + exceptionWithClass: [self class] + selector: _cmd]; #else [self doesNotRecognizeSelector: _cmd]; abort(); #endif }