Re: Is there any way for non-blocking IO with phobos?
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
Re: Is there any way for non-blocking IO with phobos?
On 11/13/18 8:52 AM, 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. Phobos process pipes use std.stdio.File and therefore FILE * as underlying mechanism. I don't think you can do this non-blocking. You could extract the FILE *, and extract the file descriptor, and do it manually. Only way I can think of. -Steve
Is there any way for non-blocking IO with phobos?
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.
Re: Inherit from class based on bool value
On Tuesday, 13 November 2018 at 07:10:26 UTC, Jamie wrote: I would like my class to inherit from one of two classes based on a boolean value known at compile time. Something like this: void main() { Top!(OPTION.FALSE) top = new Top!(OPTION.FALSE); } enum OPTION { FALSE = 0., TRUE = 1. } class One {} class Two {} class Top(OPTION option) : option ? One : Two {} Is this possible? I can't get it to work in the way I'm showing above. Cheers You can use an alias seq : void main() { Top!(OPTION.FALSE) top = new Top!(OPTION.FALSE); } enum OPTION { FALSE = 0, TRUE = 1 } class One {} class Two {} import std.meta : AliasSeq; alias Bases = AliasSeq!(One, Two); class Top(OPTION option) : Bases[option] {}
Re: Inherit from class based on bool value
On Tuesday, 13 November 2018 at 07:29:30 UTC, Ali Çehreli wrote: On 11/12/2018 11:10 PM, Jamie wrote: > I would like my class to inherit from one of two classes ... > Is this possible? I can't get it to work in the way I'm showing above. > Cheers I got it working inside an eponymous template. D is pretty cool actually. :) enum OPTION { FALSE = 0., TRUE = 1. } class One {} class Two {} template Top(OPTION option) { static if (option == OPTION.TRUE) { alias Base = One; } else { alias Base = Two; } class Top : Base {} } void main() { auto a = new Top!(OPTION.FALSE); auto b = new Top!(OPTION.TRUE); } Ali Wow that's nifty, thanks very much! And thanks for the speedy response
Re: Inherit from class based on bool value
On Tuesday, 13 November 2018 at 07:10:26 UTC, Jamie wrote: Is this possible? I can't get it to work in the way I'm showing above. ...or abstract away Ali's solution: enum OPTION { FALSE, TRUE, } template Select(OPTION opt, IfTrue, IfFalse) { static if (opt == OPTION.TRUE) alias Select = IfTrue; else alias Select = IfFalse; } class One {} class Two {} class Top(OPTION opt) : Select!(opt, One, Two) {} void main() { import std.traits : BaseClassesTuple; auto t1 = new Top!(OPTION.TRUE); static assert(is(BaseClassesTuple!(typeof(t1))[0] == One)); auto t2 = new Top!(OPTION.FALSE); static assert(is(BaseClassesTuple!(typeof(t2))[0] == Two)); }