From: Laurent Sansonetti Date: 2003-05-14T23:08:28+09:00 Subject: [PATCH] Re: return value for PTY.spawn Laurent Sansonetti wrote: > Hi rubyists ;-) > > Is there a way to retrieve the return value of a process which was > started by PTY.spawn? > Finally, after some tests, I looked the code. Here is a patch for pty.c, which will include the exit value of the spawned process in the ChildExited exception: <<------------------------------------------------------------------ --- pty.c.old Wed May 14 16:41:29 2003 +++ pty.c Wed May 14 16:47:21 2003 @@ -138,12 +138,13 @@ struct pty_info *info; { extern VALUE rb_last_status; - int cpid, status; + int cpid, status, retval; char buf[1024]; VALUE exc, st; char *state = "changed"; cpid = rb_waitpid(info->child_pid, &status, WUNTRACED); + retval = WEXITSTATUS(status); st = rb_last_status; if (cpid == 0 || cpid == -1) @@ -166,7 +167,7 @@ state = "exit"; } - snprintf(buf, sizeof(buf), "pty - %s: %d", state, cpid); + snprintf(buf, sizeof(buf), "pty - %s: %d (%d)", state, cpid, retval); exc = rb_exc_new2(eChildExited, buf); rb_iv_set(exc, "status", st); rb_funcall(info->thread, rb_intern("raise"), 1, exc); ------------------------------------------------------------------>> And an IRB session working with the patched pty.so: <<------------------------------------------------------------------ pinux@natalie /[...]/ruby-1.8.0/ext/pty> irb18 --simple-prompt >> require 'pty' => true >> PTY.spawn("uname") { |r, w, pid| puts r.readlines } FreeBSD PTY::ChildExited: pty - exit: 26219 (0) from (irb):3:in `spawn' from (irb):3 >> PTY.spawn("ls /does_not_exist") { |r, w, pid| puts r.readlines } ls: /does_not_exist: No such file or directory PTY::ChildExited: pty - exit: 26239 (1) from (irb):4:in `spawn' from (irb):4 >> PTY.spawn("ls") { |r, w, pid| puts r.readlines } MANIFEST README.expect depend lib pty.c.old script.rb Makefile README.expect.ja expect_sample.rb mkmf.log pty.o shl.rb README README.ja extconf.rb pty.c pty.so PTY::ChildExited: pty - exit: 26240 (0) from (irb):5:in `spawn' from (irb):5 >> ------------------------------------------------------------------>> I know this is not very 'clean' to add information in the exception. Maybe we should include these information in the class itself, and create some accessor methods, so we can write: begin PTY.spawn(...) { ... } rescue => e raise unless e.is_a?(PTY::ChildExited) pid = e.pid val = e.exit_val end BTW, please excuse me for my bad English ;-) -- Laurent