Is there any way for non-blocking IO with phobos?
Rémy Mouëza
remy.moueza at gmail.com
Tue Nov 13 20:49:29 UTC 2018
On Tuesday, 13 November 2018 at 13:52:57 UTC, Sobaya wrote:
> I want to connect to a server and communicate with ssh.
>
> So I tried to spawn the process of ssh using pipeProcess
> function, and read/write with its pipe's stdin and stdout.
>
> But I don't know how many lines are sent from the server for an
> input, so readln function blocks.
>
> I think this can be solved with non-blocking IO, but I cannot
> find how do I use non-blocking IO with phobos.
>
> Please give me any ideas.
>
> Thanks.
I had some success with the "hasdata" package available on
code.dlang.org:
https://code.dlang.org/packages/hasdata
Below is a sample program that I have tested on Linux:
--------------------------------------------------
/+ dub.sdl:
name "non-blocking-io"
description "A non blocking IO example using hasdata."
authors "Rémy J. A. Mouëza"
license "MIT"
dependency "hasdata" version="~>1.1.0"
-- sourcePaths "."
configuration "application" {
targetType "executable"
}
+/
// Written in the D programming language: http://dlang.org
import std.process;
import std.string;
import std.range;
import std.stdio;
import core.thread;
import hasdata;
struct NonBlockingPs {
/// The underlying vlc process.
ProcessPipes ps;
alias ps this;
immutable bufsize = 8;
this (string [] args...) {
this.ps = pipeProcess (args,
Redirect.stdin |
Redirect.stdout |
Redirect.stderrToStdout);
}
~this () {
if (! ps.pid.tryWait.terminated) {
ps.pid.kill ();
}
}
string [] readlines () {
string lines;
string line;
char [bufsize] buffer;
try {
int loop = 16;
while (loop -- > 0 && ps.stdout.hasData) {
line = cast (string) ps.stdout.rawRead (buffer);
if (! line.empty) {
lines ~= line;
}
}
}
catch (Exception e) {
"Exception: %s".writeln (e);
}
return lines.splitLines ();
}
}
void main () {
NonBlockingPs ps = NonBlockingPs ("bash", "-c", `
for i in {1..10}; do
printf "hello %02d" $i
sleep 1
done
`);
while (! ps.pid.tryWait.terminated) {
string [] text = ps.readlines ();
if (text.empty) {
"Nothing to read for now".writeln;
}
else {
"=> %s".writefln (text.join ("\n => "));
}
Thread.getThis ().sleep (500.dur!"msecs");
}
}
--------------------------------------------------
And here is the output of its execution (launched with `dub
nbio.d` -- as I named the file `nbio.d`):
Nothing to read for now
=> hello 01
Nothing to read for now
=> hello 02
Nothing to read for now
=> hello 03
Nothing to read for now
=> hello 04
Nothing to read for now
=> hello 05
Nothing to read for now
=> hello 06
Nothing to read for now
=> hello 07
Nothing to read for now
=> hello 08
Nothing to read for now
=> hello 09
Nothing to read for now
=> hello 10
Nothing to read for now
More information about the Digitalmars-d-learn
mailing list