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