Thread overview
pipeProcess, interactions with stderr ... I am missing something here
Aug 30, 2021
james.p.leblanc
Aug 30, 2021
Ali Çehreli
Aug 30, 2021
james.p.leblanc
August 30, 2021

D-ers,

I am attempting to use pipeProcess for interacting with an external process.
My simplified routine can work somewhat. But, trying to print any messages
that process writes to stderr yields the message:

(master) gnuplot > gnuplot_example
core.exception.InvalidMemoryOperationError@src/core/exception.d(647): Invalid memory operation


Simplified code:

    import std.stdio;
    import std.process;

    class Gnuplot {
       ProcessPipes pipe;

       void cmd(string txt){
          pipe.stdin.writeln(txt);
          pipe.stdin.flush();
       }

       this(){
          this.pipe = pipeProcess("/usr/local/bin/gnuplot", Redirect.stdin |
          Redirect.stdout | Redirect.stderr);
       }

       ~this(){
          pipe.stdin.close();
          pipe.stdout.flush();
          pipe.stderr.flush();

          foreach( line ; pipe.stdout.byLine ) writeln("stdout: ", line);
          foreach( line ; pipe.stderr.byLine ) writeln("stderr: ", line);
       }
    }

    void main(){

       auto gp = new Gnuplot();
       gp.cmd("plot sin(x)");
       gp.cmd("pause 2");
       gp.cmd("plot line contains error ... should create output to stderr");
       gp.cmd("quit");
    }

Also, I have found a few examples on similar programs (for example in Adam Ruppe's
D-Cookbook - page 107), which provide some very good information and examples.
But, I do not understand what I am seeing in my program example.

Any pointers are gratefully received. ... especially tutorials or example code

Best Regards,
James

PS You may note that I do not have the line "scope (exit) wait pipe.pid".
Two reasons for this are: I do not understand what this is supposed to do,
and attempts to add this froze my program.

PPS I have seen some of Steven Schveighoffers helpful descriptions about
piped processes and child process hanging with excessive outputs ... this
should not be the case here ... only a handful of bytes might possibly be written.

August 30, 2021
On 8/30/21 9:35 AM, james.p.leblanc wrote:
> D-ers,
>
> I am attempting to use pipeProcess for interacting with an external
> process.
> My simplified routine can work somewhat.  But, trying to print any messages
> that process writes to stderr yields the message:
>
> (master) gnuplot > gnuplot_example
> **core.exception.InvalidMemoryOperationError@src/core/exception.d(647):
> Invalid memory operation**

That error almost always means you are allocating memory in a destructor, which sometimes is presumably due to using parts of your object that have already been finalized by the GC. (Or, the GC has already been terminated? I am not sure.)

In this case, converting your ~this to a named function solves the issue:

  // Was: ~this()
  void close() {
    // ...
  }

// ...

  auto gp = new Gnuplot();
  scope (exit) {
    gp.close();
  }

Ali

August 30, 2021
On Monday, 30 August 2021 at 16:51:12 UTC, Ali Çehreli wrote:

> In this case, converting your ~this to a named function solves the issue:
>
>   // Was: ~this()
>   void close() {
>     // ...
>   }
>
> // ...
>
>   auto gp = new Gnuplot();
>   scope (exit) {
>     gp.close();
>   }
>
> Ali

> Ali

Ali,

Yet again, you have helped me.  Thanks for the keen eye and clear
description of what was happening.

I am enjoying this language **very** much, and the community has been incredibly
helpful to my progress.

Best Regards,
James