On 11 April 2018 at 15:11, Sven Van Caekenberghe <s...@stfx.eu> wrote: > > >> On 11 Apr 2018, at 11:12, Sven Van Caekenberghe <s...@stfx.eu> wrote: >> >> How does one modify #atEnd to block ? I suppose you are talking about >> StdioStream>>#atEnd ? >> >> ^ self peek isNil >> >> ? > > Still the same question, how do you implement a blocking #atEnd for stdin ? > > I have seen your stdio.cs which is indeed needed as the current > StdioStream>>#atEnd is bogus for sure. > > But that is still a non-blocking one, right ? > > Since there is a peekBuffer in StdioStream, why can't that be used ?
I think you've created a chicken-and-egg problem with this question, but ignoring that for now: StdioStream>>peek "Answer what would be returned if the message next were sent to the receiver. If the receiver is at the end, answer nil. " self atEnd ifTrue: [^ nil ]. peekBuffer ifNotNil: [ ^ peekBuffer ]. ^ peekBuffer := self next. So when we first start the program, i.e. the user hasn't entered any input yet, and #peek is called: 1. #atEnd returns false because Ctrl-D (or similar) hasn't been entered (assuming it is non-blocking). 2. peekBuffer is nil because we haven't previously called #peek. 3. The system now blocks on "self next". Just a reminder: for terminal input the end-of-file isn't reached until the user explicitly enters the end of file key (Ctrl-D). So, if there is no buffered input (either none has been entered yet, or all input has been consumed) #atEnd (after the patch) calls #primAtEnd:. At the moment, #primAtEnd: ends up calling the libc function feof(), which is non-blocking and answers the end-of-file flag for the FILE*. Since the user hasn't entered Ctrl-D, that's false. If we want to control iteration over the stream and ensure that we don't need to do a "stream next == nil" check, then #primAtEnd: is going to have to peek for the next character, and that means waiting for the user to enter that character. In c that is typically done using: atEnd = ungetc(fgetc(fp), fp); and fgetc() will block until the user enters something. > I have run your example testAtEnd.st now, and it works/fails as advertised. :-) Cheers, Alistair