I am trying make a text UI program. At the moment linux is target os.
Using C, I have enabled reading from the stdin without the need to press ENTER key.
Reading the stdin is in one thread (IN) while updating the state is in another thread (DO).
I can press q in IN thread and I can pass isRunning=false to DO thread and the program exits. So, all works perfectly, except when the DO thread reaches exit condition and sets isRunning=false… the IN thread still waits for user input, because this seems to be blocking:
std.io.getStdIn().reader().readByte()
Now, what I am trying to achieve is either
stopping/killing the IN thread (which seems to have removed from zig) or
time out the std.io.getStdIn().reader().readByte() so that the thread can see the changed isRunning value.
Any thoughts?
After thoughts:
would there be a way to “fork” the stdin pipe so that I could write ‘q’ into it?
The following example does not set the input to raw mode, you have to press a character and then enter. Press ^D to exit. Wait for 3 seconds for timeout.
The signature can be a little strange. You’ll want something like this.
var poller = std.io.poll(allocator, enum { stdin }, .{ .stdin = stdin })
mainloop: while (true) {
const ready = try poller.pollTimeout( 100 * std.time.ns_per_us); // Or however long you want the timeout to be
if(ready) {
const n = poller.fifo(.stdin).read(&inbuff);
// Process inbuff ...
}
if (!isRunning) {
break :mainloop
}
}
With poll you can define a number of files to be watched for write events. the pollTimeout will block for a timeout.
The key is that you define the set of files to watch using an enum and file descriptors. That lets you select what fifo you want to read from nicely.
EDIT:
I do want to note what is noted in the linked thread: std.io.poll is broken on MacOS if you are polling a tty.