[macruby-changes] [4902] MacRuby/trunk/io.c

source_changes at macosforge.org source_changes at macosforge.org
Sat Nov 13 16:30:38 PST 2010


Revision: 4902
          http://trac.macosforge.org/projects/ruby/changeset/4902
Author:   watson1978 at gmail.com
Date:     2010-11-13 16:30:36 -0800 (Sat, 13 Nov 2010)
Log Message:
-----------
connected the pipe into stdin of child process in IO.popen.

Test Script:
{{{
require 'test/unit/assertions.rb'
include Test::Unit::Assertions

ruby = "/usr/bin/ruby"
prog =<<EOS
File.open('tmp', 'w') {|f|
  f.puts gets
}
EOS

args = [ruby, '-e', prog]
io = IO.popen(args, 'r+')
io.close_read
io.write "foo"
assert_raise(IOError) { io.read }
io.write "bar"
io.close

assert_equal("foobar\n", IO.read('tmp'))

io = IO.popen("echo 'hello'", "r+")
io.close_write
assert_equal("hello\n", io.gets)
io.close

puts :ok
}}}

Modified Paths:
--------------
    MacRuby/trunk/io.c

Modified: MacRuby/trunk/io.c
===================================================================
--- MacRuby/trunk/io.c	2010-11-13 15:08:06 UTC (rev 4901)
+++ MacRuby/trunk/io.c	2010-11-14 00:30:36 UTC (rev 4902)
@@ -2265,19 +2265,33 @@
     rb_io_t *io_struct = ExtractIOStruct(io);
     posix_spawn_file_actions_t actions;
 
-    int fd[2];
-    if (pipe(fd) < 0) {
-	posix_spawn_file_actions_destroy(&actions);
+    int fd_r[2], fd_w[2];
+    if (pipe(fd_r) < 0) {
 	rb_sys_fail("pipe() failed");
     }
+    if (pipe(fd_w) < 0) {
+	close(fd_r[0]);
+	close(fd_r[1]);
+	rb_sys_fail("pipe() failed");
+    }
 
+    // MacRuby               child process
+    //  in  : fd_r[0]  -----  fd_r[1] : stdout
+    //  out : fd_w[1]  -----  fd_w[0] : stdin
     rb_sys_fail_unless(posix_spawn_file_actions_init(&actions),
 	    "could not init file actions");
-    rb_sys_fail_unless(posix_spawn_file_actions_adddup2(&actions, fd[1],
+    rb_sys_fail_unless(posix_spawn_file_actions_adddup2(&actions, fd_w[0],
+		STDIN_FILENO), "could not add dup2() to stdin");
+    rb_sys_fail_unless(posix_spawn_file_actions_addclose(&actions, fd_w[0]),
+	    "could not add a close() to stdin");
+    rb_sys_fail_unless(posix_spawn_file_actions_addclose(&actions, fd_w[1]),
+	    "could not add a close() to stdin");
+    rb_sys_fail_unless(posix_spawn_file_actions_adddup2(&actions, fd_r[1],
 		STDOUT_FILENO), "could not add dup2() to stdout");
-    rb_sys_fail_unless(posix_spawn_file_actions_addclose(&actions, fd[1]),
+    rb_sys_fail_unless(posix_spawn_file_actions_addclose(&actions, fd_r[0]),
 	    "could not add a close() to stdout");
-
+    rb_sys_fail_unless(posix_spawn_file_actions_addclose(&actions, fd_r[1]),
+	    "could not add a close() to stdout");
     pid_t pid;
 
     VALUE argArray = rb_check_array_type(prog);
@@ -2304,32 +2318,38 @@
 	errno = posix_spawn(&pid, spawnedArgs[0], &actions, NULL, spawnedArgs,
 		*(_NSGetEnviron()));
     }
+
+    posix_spawn_file_actions_destroy(&actions);
     if (errno != 0) {
 	const int err = errno;
-	close(fd[0]);
-	close(fd[1]);
+	close(fd_r[0]);
+	close(fd_r[1]);
+	close(fd_w[0]);
+	close(fd_w[1]);
 	errno = err;
 	rb_sys_fail("posix_spawn() failed");
     }
-    posix_spawn_file_actions_destroy(&actions);
 
-    io_struct->fd = fd[0];
+    io_struct->fd = fd_r[0];
     io_struct->pid = pid;
     io_struct->mode = mode;
 
     const int fmode = convert_mode_string_to_fmode(mode);
     if (fmode & FMODE_READABLE) {
-	io_struct->read_fd = fd[0];
+	io_struct->read_fd = fd_r[0];
     }
     else {
-	close(fd[0]);
+	close(fd_r[0]);
     }
     if (fmode & FMODE_WRITABLE) {
-	io_struct->write_fd = fd[1];
+	io_struct->write_fd = fd_w[1];
     }
     else {
-	close(fd[1]);
+	close(fd_w[1]);
     }
+    close(fd_r[1]);
+    close(fd_w[0]);
+
     return io;
 }
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20101113/f1bc6762/attachment.html>


More information about the macruby-changes mailing list