[Pharo-project] nonblocking stdin?
Hi, is there a way how to use nonblocking input from stdin? I have a simple REPL but the stdin is blocking the VM. | stdin input lineEnd | stdin := FileStream stdin ifNil: [ ^ self ]. stdin atEnd ifTrue: [ ^ self ]. [ lineEnd := false. FileStream stdout nextPutAll: '> '. input := String streamContents: [:s| [ stdin atEnd or: [lineEnd] ] whileFalse: [ stdin next ifNotNilDo: [:char| char = Character lf ifTrue: [lineEnd := true]. s nextPut: char ]]]. [ FileStream stdout print: (Compiler evaluate: input); lf ] ifError: [:error | FileStream stdout nextPutAll: 'ERROR: ', error asString; lf]. Processor yield. ] repeat Cheers, -- Pavel
hmm we solved that by changing the behavior of stdin before launching the vm. so you get character by character input, otherwise stdin is only flushed on lf... see the starter script from coral. On 2012-11-13, at 10:01, Pavel Krivanek <pavel.krivanek@gmail.com> wrote:
Hi,
is there a way how to use nonblocking input from stdin? I have a simple REPL but the stdin is blocking the VM.
| stdin input lineEnd |
stdin := FileStream stdin ifNil: [ ^ self ]. stdin atEnd ifTrue: [ ^ self ].
[ lineEnd := false. FileStream stdout nextPutAll: '> '. input := String streamContents: [:s| [ stdin atEnd or: [lineEnd] ] whileFalse: [ stdin next ifNotNilDo: [:char| char = Character lf ifTrue: [lineEnd := true]. s nextPut: char ]]].
[ FileStream stdout print: (Compiler evaluate: input); lf ] ifError: [:error | FileStream stdout nextPutAll: 'ERROR: ', error asString; lf].
Processor yield. ] repeat
Cheers, -- Pavel
The way used in Coral (stty -icanon -echo) doesn't work. The stdin next is still blocking the image. It seems that it must be solved on the VM level somehow :-/ -- Pavel On Tue, Nov 13, 2012 at 10:56 AM, Camillo Bruni <camillobruni@gmail.com> wrote:
hmm we solved that by changing the behavior of stdin before launching the vm. so you get character by character input, otherwise stdin is only flushed on lf...
see the starter script from coral.
On 2012-11-13, at 10:01, Pavel Krivanek <pavel.krivanek@gmail.com> wrote:
Hi,
is there a way how to use nonblocking input from stdin? I have a simple REPL but the stdin is blocking the VM.
| stdin input lineEnd |
stdin := FileStream stdin ifNil: [ ^ self ]. stdin atEnd ifTrue: [ ^ self ].
[ lineEnd := false. FileStream stdout nextPutAll: '> '. input := String streamContents: [:s| [ stdin atEnd or: [lineEnd] ] whileFalse: [ stdin next ifNotNilDo: [:char| char = Character lf ifTrue: [lineEnd := true]. s nextPut: char ]]].
[ FileStream stdout print: (Compiler evaluate: input); lf ] ifError: [:error | FileStream stdout nextPutAll: 'ERROR: ', error asString; lf].
Processor yield. ] repeat
Cheers, -- Pavel
Or you can use #primitiveSQFileSetNonBlocking, as in "OSProcess thisOSProcess stdIn setNonBlocking". Also make sure that you don't run your VM in background (with '&') otherwise your stdin will be detached and the VM can still be blocked. Dave On Tue, Nov 13, 2012 at 10:56:02AM +0100, Camillo Bruni wrote:
hmm we solved that by changing the behavior of stdin before launching the vm. so you get character by character input, otherwise stdin is only flushed on lf...
see the starter script from coral.
On 2012-11-13, at 10:01, Pavel Krivanek <pavel.krivanek@gmail.com> wrote:
Hi,
is there a way how to use nonblocking input from stdin? I have a simple REPL but the stdin is blocking the VM.
| stdin input lineEnd |
stdin := FileStream stdin ifNil: [ ^ self ]. stdin atEnd ifTrue: [ ^ self ].
[ lineEnd := false. FileStream stdout nextPutAll: '> '. input := String streamContents: [:s| [ stdin atEnd or: [lineEnd] ] whileFalse: [ stdin next ifNotNilDo: [:char| char = Character lf ifTrue: [lineEnd := true]. s nextPut: char ]]].
[ FileStream stdout print: (Compiler evaluate: input); lf ] ifError: [:error | FileStream stdout nextPutAll: 'ERROR: ', error asString; lf].
Processor yield. ] repeat
Cheers, -- Pavel
Hi Pavel, Last week I was playing with a REPL exported over a local socket, I am reading input until an empty line, like this: NeoREPLServer new start. $ telnet localhost 13731 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Welcome to Pharo2.0a of '18 April 2012' update 20372 Type a multi-line Smalltalk expression and an empty line to evaluate it Type !quit to exit, !help for information about other special commands 42 factorial 1405006117752879898543142606244511569936384000000000 'Pavel' reverse 'levaP' 3 timesRepeat: [ Smalltalk garbageCollect ] 3 ZTimestampFormat verbose german; format: ZTimestamp now 'Dienstag, 13-November-2012 10:06:13 AM (+00:00)' !quit Bye! Connection closed by foreign host. If you want I can share the code, it is very small (but incomplete). Sven -- Sven Van Caekenberghe http://stfx.eu Smalltalk is the Red Pill On 13 Nov 2012, at 10:01, Pavel Krivanek <pavel.krivanek@gmail.com> wrote:
Hi,
is there a way how to use nonblocking input from stdin? I have a simple REPL but the stdin is blocking the VM.
| stdin input lineEnd |
stdin := FileStream stdin ifNil: [ ^ self ]. stdin atEnd ifTrue: [ ^ self ].
[ lineEnd := false. FileStream stdout nextPutAll: '> '. input := String streamContents: [:s| [ stdin atEnd or: [lineEnd] ] whileFalse: [ stdin next ifNotNilDo: [:char| char = Character lf ifTrue: [lineEnd := true]. s nextPut: char ]]].
[ FileStream stdout print: (Compiler evaluate: input); lf ] ifError: [:error | FileStream stdout nextPutAll: 'ERROR: ', error asString; lf].
Processor yield. ] repeat
Cheers, -- Pavel
Hi Sven, I primarily wanted it to communicate to Pharo Kernel without network support. But the telnet REPL will be very useful in many cases. It would be cool to publish it somewhere (even in the incomplete state). Cheers, -- Pavel On Tue, Nov 13, 2012 at 11:07 AM, Sven Van Caekenberghe <sven@stfx.eu> wrote:
Hi Pavel,
Last week I was playing with a REPL exported over a local socket, I am reading input until an empty line, like this:
NeoREPLServer new start.
$ telnet localhost 13731
Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Welcome to Pharo2.0a of '18 April 2012' update 20372 Type a multi-line Smalltalk expression and an empty line to evaluate it Type !quit to exit, !help for information about other special commands
42 factorial
1405006117752879898543142606244511569936384000000000
'Pavel' reverse
'levaP'
3 timesRepeat: [ Smalltalk garbageCollect ]
3
ZTimestampFormat verbose german; format: ZTimestamp now
'Dienstag, 13-November-2012 10:06:13 AM (+00:00)'
!quit
Bye! Connection closed by foreign host.
If you want I can share the code, it is very small (but incomplete).
Sven
-- Sven Van Caekenberghe http://stfx.eu Smalltalk is the Red Pill
On 13 Nov 2012, at 10:01, Pavel Krivanek <pavel.krivanek@gmail.com> wrote:
Hi,
is there a way how to use nonblocking input from stdin? I have a simple REPL but the stdin is blocking the VM.
| stdin input lineEnd |
stdin := FileStream stdin ifNil: [ ^ self ]. stdin atEnd ifTrue: [ ^ self ].
[ lineEnd := false. FileStream stdout nextPutAll: '> '. input := String streamContents: [:s| [ stdin atEnd or: [lineEnd] ] whileFalse: [ stdin next ifNotNilDo: [:char| char = Character lf ifTrue: [lineEnd := true]. s nextPut: char ]]].
[ FileStream stdout print: (Compiler evaluate: input); lf ] ifError: [:error | FileStream stdout nextPutAll: 'ERROR: ', error asString; lf].
Processor yield. ] repeat
Cheers, -- Pavel
I would be very interested in something like this. Cheers, Doru On 13 Nov 2012, at 10:01, Pavel Krivanek <pavel.krivanek@gmail.com> wrote:
Hi,
is there a way how to use nonblocking input from stdin? I have a simple REPL but the stdin is blocking the VM.
| stdin input lineEnd |
stdin := FileStream stdin ifNil: [ ^ self ]. stdin atEnd ifTrue: [ ^ self ].
[ lineEnd := false. FileStream stdout nextPutAll: '> '. input := String streamContents: [:s| [ stdin atEnd or: [lineEnd] ] whileFalse: [ stdin next ifNotNilDo: [:char| char = Character lf ifTrue: [lineEnd := true]. s nextPut: char ]]].
[ FileStream stdout print: (Compiler evaluate: input); lf ] ifError: [:error | FileStream stdout nextPutAll: 'ERROR: ', error asString; lf].
Processor yield. ] repeat
Cheers, -- Pavel
-- www.tudorgirba.com "It's not how it is, it is how we see it."
Pavel Krivanek-3 wrote
Is there a way how to use nonblocking input from stdin?
Not sure if this helps, but this works out of the box on 2.0 (see https://gist.github.com/2604215):
| command | [ command := FileStream stdin nextLine. command ~= 'exit' ] whileTrue: [ | result | result := Compiler evaluate: command. FileStream stdout nextPutAll: result asString; lf ].
Smalltalk snapshot: false andQuit: true.
On 1.3 or 1.4, file in https://gist.github.com/2602113 first:
'From Pharo2.0a of ''18 April 2012'' [Latest update: #20041] on 3 May 2012 at 10:45:48 pm'!
!FileStream class methodsFor: 'stdio' stamp: 'SeanDeNigris 5/3/2012 22:37'! stdin
^Stdin ifNil: [ Stdin := self standardIOStreamNamed: #stdin forWrite: false. Stdin disableReadBuffering; yourself ].! !
-- View this message in context: http://forum.world.st/nonblocking-stdin-tp4654956p4655653.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
your example still blocks any background process! the goal would be to have an stdin that only blocks the current thread (or maybe returns nil if it's empty/not ready) so you can still can do some background work. On 2012-11-16, at 20:45, "Sean P. DeNigris" <sean@clipperadams.com> wrote:
Pavel Krivanek-3 wrote
Is there a way how to use nonblocking input from stdin?
Not sure if this helps, but this works out of the box on 2.0 (see https://gist.github.com/2604215):
| command | [ command := FileStream stdin nextLine. command ~= 'exit' ] whileTrue: [ | result | result := Compiler evaluate: command. FileStream stdout nextPutAll: result asString; lf ].
Smalltalk snapshot: false andQuit: true.
On 1.3 or 1.4, file in https://gist.github.com/2602113 first:
'From Pharo2.0a of ''18 April 2012'' [Latest update: #20041] on 3 May 2012 at 10:45:48 pm'!
!FileStream class methodsFor: 'stdio' stamp: 'SeanDeNigris 5/3/2012 22:37'! stdin
^Stdin ifNil: [ Stdin := self standardIOStreamNamed: #stdin forWrite: false. Stdin disableReadBuffering; yourself ].! !
-- View this message in context: http://forum.world.st/nonblocking-stdin-tp4654956p4655653.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
participants (6)
-
Camillo Bruni -
David T. Lewis -
Pavel Krivanek -
Sean P. DeNigris -
Sven Van Caekenberghe -
Tudor Girba