From: Simon Strandgaard <0bz63fz3m1qt3001@...> Date: 2003-05-12T21:01:19+09:00 Subject: Re: RCR for child execution On Mon, 12 May 2003 17:31:44 +0900, Brian Candler wrote: > On Mon, May 12, 2003 at 07:16:51AM +0900, Simon Strandgaard wrote: >> Separation of ruby stdout/stderr from C/C++ stdout/stderr is what I want. > .. >> Using system or backquote, then it goes BOOM. The problem as I see it is >> localized in Rubys code - not mine! Ruby spawns a child which inherits >> stdout/stderr. This child should instead inherit rb_stdout/rb_stderr >> instead!!! Can this issue be fixed on Ruby ??? > > It can't be fixed easily; if rb_stdout were pointing at a StringIO object, > then this cannot be represented as a Unix fd. Agree this will be a major patch and it will make heavy use of pipes. > I mean, I'm guessing you want something like '$deferr' like '$defout', > right? So that rb_warn sends to $deferr, and you can map this variable to > point to some other object? I see no reason to introduce a '$deferr'... But this could be possible sideeffect of this. rb_warn outputs to stderr, perhaps it should output to rb_stderr ? > OK, but what do you want to happen here? > > $deferr = StringIO.new(x) > system("ls /nonexistent") I don't feel comfortable with '$deferr'.. so I cannot tell. > What do you want instead? That Ruby should create two new pipes, pass these > to the child as stdout/stderr; then read any data generated on those pipes, > and pass them to $defout.write and $deferr.write respectively? yes... this is very much what I want. > The problems I can see with this are: > > - It adds overhead even for the 99% of cases where this is not needed I understand your concern, maybe this will add overhead. But normal Ruby users don't have to suffer from it. During build of Ruby there can be generated a ruby-embedding library which you can link with if you are embedding ruby into C/C++. > - It doesn't follow the Unix API model, therefore violates POLS: > "system" should not create pipes to the child. "popen" should. Disagree! What is POLS ? where can I read more about the standard Unix API model ? > But there are more fundamental problems. Firstly, your Ruby function can > call C at any time: it's as easy to embed C in Ruby as Ruby in C. What > happens when the C function does a write to stdout or stderr? You can't > possibily intercept it without modifying the C. What if the C in turn calls > system() to run a child process, and the child process writes to stderr? > Hard luck, it gets written to your main program's stderr. Then the output of cause should go to stdout. OK.. there is 2 sides of this issue. A) a C extension for ruby.. in your C code you are outputting to stdour/stderr. This output should be redirected to Rubys rb_stdout/rb_stderr. If you from C call system, then the output likewise should be redirected to rb_stdout/rb_stderr. B) the C program into which you embeds Ruby. If your C code is outputting to stdout/stderr. Then it should go to stdout/stderr. If you from C call system, then the output likewise should go to stdout/stderr. No problems here. Admitted (A) & (B) can easily be confused. No scepticism == no democrazy :-) -- Simon Strandgaard