www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - pipeProcess, interactions with stderr ... I am missing something here

reply james.p.leblanc <james.p.leblanc gmail.com> writes:
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.
Aug 30 2021
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Aug 30 2021
parent james.p.leblanc <james.p.leblanc gmail.com> writes:
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
Aug 30 2021