nonblocking stdin?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

nonblocking stdin?

Pavel Krivanek-3
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

Reply | Threaded
Open this post in threaded view
|

Re: nonblocking stdin?

Camillo Bruni-3
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 <[hidden email]> 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
>


Reply | Threaded
Open this post in threaded view
|

Re: nonblocking stdin?

Sven Van Caekenberghe-2
In reply to this post by Pavel Krivanek-3
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 <[hidden email]> 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
>


Reply | Threaded
Open this post in threaded view
|

Re: nonblocking stdin?

Pavel Krivanek-3
In reply to this post by Camillo Bruni-3
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 <[hidden email]> 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 <[hidden email]> 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
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: nonblocking stdin?

David T. Lewis
In reply to this post by Camillo Bruni-3
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 <[hidden email]> 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
> >
>

Reply | Threaded
Open this post in threaded view
|

Re: nonblocking stdin?

Tudor Girba-2
In reply to this post by Pavel Krivanek-3
I would be very interested in something like this.

Cheers,
Doru



On 13 Nov 2012, at 10:01, Pavel Krivanek <[hidden email]> 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."


Reply | Threaded
Open this post in threaded view
|

Re: nonblocking stdin?

Pavel Krivanek-3
In reply to this post by Sven Van Caekenberghe-2
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 <[hidden email]> 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 <[hidden email]> 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
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: nonblocking stdin?

Sean P. DeNigris
Administrator
In reply to this post by Pavel Krivanek-3
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 ].! !
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: nonblocking stdin?

Camillo Bruni-3
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" <[hidden email]> 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.
>