--- a/UnixOperatingSystem.st Tue Dec 18 21:49:04 2001 +0100
+++ b/UnixOperatingSystem.st Wed Dec 19 13:01:26 2001 +0100
@@ -3555,11 +3555,11 @@
__HANDLE_INTERRUPTS__;
goto again;
} else {
- error = __MKSMALLINT(errno);
+ error = __mkSmallInteger(errno);
goto err;
}
}
- fileDescriptor = __MKSMALLINT(fd);
+ fileDescriptor = __mkSmallInteger(fd);
err:;
%}.
^ fileDescriptor notNil ifTrue:[
@@ -9284,7 +9284,7 @@
!UnixOperatingSystem::FileDescriptorHandle methodsFor:'misc functions'!
-readCheck
+canReadWithoutBlocking
"return true, if data is available on a filedescriptor
(i.e. read is possible without blocking).
This depends on a working select or FIONREAD to be provided by the OS."
@@ -9349,12 +9349,78 @@
^ true
].
- (OperatingSystem selectOnAnyReadable:(Array with:fd)
- writable:nil
- exception:nil
- withTimeOut:0) == fd
- ifTrue:[^ true].
- ^ false
+ ^ (OperatingSystem selectOnAnyReadable:(Array with:fd)
+ writable:nil
+ exception:nil
+ withTimeOut:0) == fd
+!
+
+seekTo:newPosition from:whence
+ "seek to newPosition
+ whence is one of: #begin #current #end.
+ Return the new position.
+
+ TODO: 64 bit handling"
+
+ |error|
+
+%{
+ INT fd, pos, ret;
+ INT __whence;
+ __uint64__ pos64;
+
+ if (! __isSmallInteger(__INST(fd))) {
+ error = @symbol(errorNotOpen);
+ goto bad;
+ }
+ if (__isSmallInteger(newPosition)) {
+ pos = __smallIntegerVal(newPosition);
+ } else if (__signedLong64IntVal(newPosition, &pos64) == 0) {
+ error = @symbol(badArgument1);
+ goto bad;
+ }
+ fd = __smallIntegerVal(__INST(fd));
+ if (fd < 0) {
+ error = @symbol(internalError);
+ goto bad;
+ }
+ if (whence == @symbol(begin)) {
+ __whence = SEEK_SET;
+ } else if (whence == @symbol(current)) {
+ __whence = SEEK_CUR;
+ } else if (whence == @symbol(end)) {
+ __whence = SEEK_END;
+ } else {
+ error = @symbol(badArgument2);
+ goto bad;
+ }
+
+again:
+ ret = lseek(fd, pos, __whence);
+ if (ret < 0) {
+ if (errno == EINTR) {
+ __HANDLE_INTERRUPTS__;
+ goto again;
+ }
+ error = __mkSmallInteger(errno);
+ goto bad;
+ }
+ /* RETURN (__mkInteger(ret)); */
+ RETURN (__mkSmallInteger(ret));
+
+bad: ;
+%}.
+ ^ self error:error.
+
+ "
+ |h buff n|
+
+ h := OperatingSystem openFileForRead:'/etc/hosts'.
+ h seekTo:10 from:#begin.
+ buff := ByteArray new:1000. buff inspect.
+ n := h readBytes:1000 into:buff startingAt:1.
+ Transcript show:n; space; showCR:buff asString.
+ "
!
selectWithTimeOut:millis
@@ -9421,28 +9487,6 @@
^ self primitiveFailed
-!
-
-writeCheck
- "return true, if filedescriptor can be written without blocking"
-
- OperatingSystem supportsSelect ifFalse:[
- "/ mhmh - what should we do then ?
- "/ For now, return true as if data was present,
- "/ and let the thread fall into the write.
- "/ It will then (hopefully) be desceduled there and
- "/ effectively polling for output.
- ^ true
- ].
-
- (OperatingSystem selectOnAnyReadable:nil
- writable:(Array with:fd)
- exception:nil
- withTimeOut:0) == fd
- ifTrue:[^ true].
- ^ false
-
- "Created: 1.10.1997 / 08:49:24 / stefan"
! !
!UnixOperatingSystem::FileDescriptorHandle methodsFor:'private accessing'!
@@ -9460,6 +9504,24 @@
!UnixOperatingSystem::FileDescriptorHandle methodsFor:'queries'!
+canWriteWithoutBlocking
+ "return true, if filedescriptor can be written without blocking"
+
+ OperatingSystem supportsSelect ifFalse:[
+ "/ mhmh - what should we do then ?
+ "/ For now, return true as if data was present,
+ "/ and let the thread fall into the write.
+ "/ It will then (hopefully) be desceduled there and
+ "/ effectively polling for output.
+ ^ true
+ ].
+
+ ^ (OperatingSystem selectOnAnyReadable:nil
+ writable:(Array with:fd)
+ exception:nil
+ withTimeOut:0) == fd
+!
+
isValid
"answer true, if the handle is valid, i.e. connected to
a file or some other OS object"
@@ -9506,10 +9568,78 @@
"Modified: 30.9.1997 / 12:42:16 / stefan"
! !
+!UnixOperatingSystem::FileDescriptorHandle methodsFor:'waiting'!
+
+readWaitWithTimeoutMs:timeout
+ "suspend the current process, until the receiver
+ becomes ready for reading or a timeout (in milliseconds) expired.
+ If data is already available, return immediate.
+ Return true if a timeout occured (i.e. false, if data is available).
+ The other threads are not affected by the wait."
+
+ |inputSema hasData wasBlocked|
+
+ fd isNil ifTrue:[^ self error:#errorNotOpen].
+
+ wasBlocked := OperatingSystem blockInterrupts.
+ hasData := self canReadWithoutBlocking.
+ hasData ifFalse:[
+ inputSema := Semaphore new name:'readWait'.
+ [
+ timeout notNil ifTrue:[
+ Processor signal:inputSema afterMilliseconds:timeout
+ ].
+ Processor signal:inputSema onInput:fd.
+ Processor activeProcess state:#ioWait.
+ inputSema wait.
+ Processor disableSemaphore:inputSema.
+ hasData := self canReadWithoutBlocking.
+ ] ifCurtailed:[
+ Processor disableSemaphore:inputSema.
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ]
+ ].
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ^ hasData not
+!
+
+writeWaitWithTimeoutMs:timeout
+ "suspend the current process, until the receiver
+ becomes ready for writing or a timeout (in seconds) expired.
+ Return true if a timeout occured (i.e. false, if data is available).
+ Return immediate if the receiver is already ready.
+ The other threads are not affected by the wait."
+
+ |fd outputSema canWrite wasBlocked|
+
+ fd isNil ifTrue:[^ self error:#errorNotOpen].
+
+ wasBlocked := OperatingSystem blockInterrupts.
+ canWrite := self canWriteWithoutBlocking.
+ canWrite ifFalse:[
+ outputSema := Semaphore new name:'writeWait'.
+ [
+ timeout notNil ifTrue:[
+ Processor signal:outputSema afterMilliseconds:timeout
+ ].
+ Processor signal:outputSema onOutput:fd.
+ Processor activeProcess state:#ioWait.
+ outputSema wait.
+ Processor disableSemaphore:outputSema.
+ canWrite := self canWriteWithoutBlocking.
+ ] ifCurtailed:[
+ Processor disableSemaphore:outputSema.
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ]
+ ].
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ^ canWrite not
+! !
+
!UnixOperatingSystem::FilePointerHandle class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.105 2001-12-18 13:12:38 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.106 2001-12-19 12:01:26 stefan Exp $'
! !
!UnixOperatingSystem::FilePointerHandle methodsFor:'release'!
@@ -9821,6 +9951,6 @@
!UnixOperatingSystem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.105 2001-12-18 13:12:38 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.106 2001-12-19 12:01:26 stefan Exp $'
! !
UnixOperatingSystem initialize!