From: Simon Strandgaard <0bz63fz3m1qt3001@...> Date: 2003-05-11T09:29:43+09:00 Subject: Re: RCR for child execution On Sun, 11 May 2003 05:39:31 +0900, Brian Candler wrote: > On Sun, May 11, 2003 at 01:27:31AM +0900, Simon Strandgaard wrote: >> Ruby-child-processes inherit stdout/stderr, not rb_stdout, rb_stderr. >> From C/C++ I cannot use stdout/stderr. > > What do you mean, "from C/C++ I cannot use stdout/stderr"?? Everything is OK when your application starts up, stdout/stderr works fine. Then you initialize ruby and redirects its output elsewhere. Now stdout/stderr doesn't work any longer. I tried restoring stdout/stderr to the console again, but this affects the "system" call in ruby, see "process.c" that stdout/stderr is being used. After redirecting rubys output, you cannot use stdout/stderr. > cat main.cpp #include // pipe, select #include // FIONREAD #include #include #include #include // rb_xxx extern "C" { VALUE rb_defout; VALUE rb_stdout; VALUE rb_stderr; } int main(int argc, char *argv[]) { using namespace std; int pipes[2]; if(pipe(pipes)) exit(-1); int bak_stdout = dup(fileno(stdout)); int bak_stderr = dup(fileno(stderr)); cout << "backups: stdout=" << bak_stdout << " stderr=" << bak_stderr << endl; FILE *fd_out = fdopen(bak_stdout, "a"); FILE *fd_err = fdopen(bak_stderr, "a"); ruby_init(); ruby_init_loadpath(); VALUE params[2]; params[0] = INT2FIX(pipes[1]); params[1] = rb_str_new2("w"); VALUE w = rb_class_new_instance(2, params, rb_path2class("IO")); rb_gv_set("$defout", w); rb_gv_set("$stdout", w); rb_gv_set("$stderr", w); int new_stdout = dup2(bak_stdout, 1); int new_stderr = dup2(bak_stdout, 2); fprintf(fd_out, "new: stdout=%d stderr=%d\n", new_stdout, new_stderr); stdout = fdopen(new_stdout, "a"); // BOOM! stderr = fdopen(new_stderr, "a"); // BOOM! fprintf(fd_out, "bak_stdout\n"); cout << "cout is working again" << endl; rb_eval_string("sleep 1; $stdout.puts 'aa';" " puts 'hello'; system('ls a.c xx'); sleep 1"); close(pipes[0]); close(pipes[1]); return 0; } > cat Makefile RUBY=$(HOME)/install/language/ruby-1.8.0 LIBS=$(RUBY)/libruby-static.a -lcrypt all: g++ main.cpp -lc_r -I$(RUBY) $(LIBS) -Wall > Well, there is no thread to flush the pipe.. but this is not important here! What is important is that system('ls a.c xx')'s output goes to stdout/stderr, is mixed up with C's output. If I remove those 2 lines containing "BOOM!" then system's output will go to the pipe. After redirection I cannot use stdout/stderr! Making this possible would require changes to ruby.. this is what my RCR proposal is about. -- Simon Strandgaard