[macruby-changes] [1604] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Tue May 26 17:26:24 PDT 2009
Revision: 1604
http://trac.macosforge.org/projects/ruby/changeset/1604
Author: pthomson at apple.com
Date: 2009-05-26 17:26:24 -0700 (Tue, 26 May 2009)
Log Message:
-----------
Finally fixed popen().
Modified Paths:
--------------
MacRuby/branches/experimental/include/ruby/io.h
MacRuby/branches/experimental/io.c
Modified: MacRuby/branches/experimental/include/ruby/io.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/io.h 2009-05-26 23:14:23 UTC (rev 1603)
+++ MacRuby/branches/experimental/include/ruby/io.h 2009-05-27 00:26:24 UTC (rev 1604)
@@ -29,9 +29,7 @@
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
- // The Unixy low-level file handles.
int fd; // You can expect this to be what the above CFStreams point to.
- int pipe;
// Additional information.
CFStringRef path;
Modified: MacRuby/branches/experimental/io.c
===================================================================
--- MacRuby/branches/experimental/io.c 2009-05-26 23:14:23 UTC (rev 1603)
+++ MacRuby/branches/experimental/io.c 2009-05-27 00:26:24 UTC (rev 1604)
@@ -25,15 +25,12 @@
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/syscall.h>
+#include <sys/socket.h>
#include <spawn.h>
#include <crt_externs.h>
extern void Init_File(void);
-#if SIZEOF_OFF_T > SIZEOF_LONG && !defined(HAVE_LONG_LONG)
-# error off_t is bigger than long, but you have no long long...
-#endif
-
VALUE rb_cIO;
VALUE rb_eEOFError;
VALUE rb_eIOError;
@@ -51,8 +48,6 @@
static ID id_write, id_read, id_getc, id_flush, id_encode, id_readpartial;
-struct timeval rb_time_interval(VALUE);
-
struct argf {
VALUE filename, current_file;
int gets_lineno;
@@ -67,15 +62,6 @@
#define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
#define ARGF argf_of(argf)
-// static int
-// is_socket(int fd, const char *path)
-// {
-// struct stat sbuf;
-// if (fstat(fd, &sbuf) < 0)
-// rb_sys_fail(path);
-// return S_ISSOCK(sbuf.st_mode);
-// }
-
static int
convert_mode_string_to_fmode(VALUE rstr)
{
@@ -325,12 +311,9 @@
// TODO: Eventually make the ungetc_buf a ByteString
io_struct->fd = fd;
- io_struct->pipe = -1;
io_struct->ungetc_buf = NULL;
io_struct->ungetc_buf_len = 0;
io_struct->ungetc_buf_pos = 0;
-
-
io_struct->sync = mode & FMODE_SYNC;
}
@@ -344,10 +327,6 @@
if (close_write && io_struct->writeStream != NULL) {
CFWriteStreamClose(io_struct->writeStream);
}
- if(io_struct->pipe != -1) {
- write(io_struct->pipe, "\0", 1);
- close(io_struct->pipe);
- }
rb_last_status_set(0, io_struct->pid);
io_struct->pid = -1;
}
@@ -680,8 +659,7 @@
{
rb_io_t *io_struct = ExtractIOStruct(io);
rb_io_assert_readable(io_struct);
- return CONDITION_TO_BOOLEAN(
- CFReadStreamGetStatus(io_struct->readStream) == kCFStreamStatusAtEnd);
+ return CONDITION_TO_BOOLEAN(CFReadStreamGetStatus(io_struct->readStream) == kCFStreamStatusAtEnd);
}
/*
@@ -889,13 +867,6 @@
return data_read;
}
}
-
- if (io_struct->pipe != -1) {
- int status;
- waitpid(io_struct->pid, &status, 0);
- close(io_struct->pipe);
- io_struct->pipe = -1;
- }
// Read from the stream.
data_read += rb_io_stream_read_internal(io_struct->readStream,
@@ -1781,6 +1752,7 @@
static VALUE
rb_io_close_read(VALUE io, SEL sel)
{
+ rb_io_assert_readable(ExtractIOStruct(io));
io_close(io, true, false);
return Qnil;
}
@@ -1926,94 +1898,76 @@
* <foo>bar;zot;
*/
-// just set errno, you bastards
-#define rb_sys_fail_unless(action, msg) do { \
- errno = action;\
- if (errno != 0) { \
- rb_sys_fail(msg);\
- }\
-} while(0)
-
-
VALUE
io_from_spawning_new_process(VALUE prog, VALUE mode)
{
+ // Allocate space for a new IO struct.
VALUE io = io_alloc(rb_cIO, 0);
rb_io_t *io_struct = ExtractIOStruct(io);
- CFReadStreamRef r = NULL;
- CFWriteStreamRef w = NULL;
- pid_t pid;
- int fd[2];
- // TODO: Split the process_name up into char* components?
- char *spawnedArgs[] = {(char*)_PATH_BSHELL, "-c", (char*)RSTRING_PTR(prog), NULL};
+ io_struct->readStream = NULL;
+ io_struct->writeStream = NULL;
posix_spawn_file_actions_t actions;
+
+ // Streams for reading and writing.
+ CFReadStreamRef r;
+ CFWriteStreamRef w;
+
+ // Required variables for pipe() and posix_spawn().
+ pid_t pid;
+ int comms[2] = {};
- int fmode = convert_mode_string_to_fmode(mode);
- int readable = ((fmode & FMODE_READABLE) || (fmode & FMODE_READWRITE));
- int writable = ((fmode & FMODE_WRITABLE) || (fmode & FMODE_READWRITE));
- assert(readable || writable);
+ socketpair(PF_LOCAL, SOCK_STREAM, 0, comms);
- if (pipe(fd) < 0) {
- posix_spawn_file_actions_destroy(&actions);
- rb_sys_fail("pipe() failed.");
- }
- if (readable) {
- r = _CFReadStreamCreateFromFileDescriptor(NULL, fd[0]);
+ posix_spawn_file_actions_init(&actions);
+ posix_spawn_file_actions_adddup2(&actions, comms[1], STDOUT_FILENO);
+ posix_spawn_file_actions_adddup2(&actions, STDOUT_FILENO, STDERR_FILENO);
+ posix_spawn_file_actions_addclose(&actions, comms[0]);
+ posix_spawn_file_actions_addclose(&actions, comms[1]);
+
+ char *spawnedArgs[] = {(char*)_PATH_BSHELL, "-c", (char*)RSTRING_PTR(prog), NULL};
+ int error = posix_spawn(&pid, spawnedArgs[0], &actions, NULL, spawnedArgs, *(_NSGetEnviron()));
+
+ if (error != 0) {
+ close(comms[0]);
+ close(comms[1]);
+ rb_bug("posix_spawn failed.");
+ }
+ else {
+ r = _CFReadStreamCreateFromFileDescriptor(NULL, comms[0]);
if (r != NULL) {
- CFReadStreamOpen(r);
- GC_WB(&io_struct->readStream, r);
+ CFReadStreamOpen(r);
CFMakeCollectable(r);
- } else {
- io_struct->readStream = NULL;
+ GC_WB(&io_struct->readStream, r);
}
- }
- if (writable) {
- w = _CFWriteStreamCreateFromFileDescriptor(NULL, fd[0]);
+
+ w = _CFWriteStreamCreateFromFileDescriptor(NULL, comms[1]);
if (w != NULL) {
CFWriteStreamOpen(w);
- GC_WB(&io_struct->writeStream, w);
CFMakeCollectable(w);
- } else {
- io_struct->writeStream = NULL;
- }
+ GC_WB(&io_struct->writeStream, w);
+ }
+ io_struct->fd = comms[0];
+ io_struct->pid = pid;
+ io_struct->ungetc_buf = NULL;
+ io_struct->ungetc_buf_len = 0;
+ io_struct->ungetc_buf_pos = 0;
+ posix_spawn_file_actions_destroy(&actions);
}
-
- 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], STDOUT_FILENO), "could not add dup2() to stdout");
- rb_sys_fail_unless(posix_spawn_file_actions_addclose(&actions, fd[1]), "could not add a close() to stdout");
-
- errno = posix_spawn(&pid, spawnedArgs[0], &actions, NULL, spawnedArgs, *(_NSGetEnviron()));
- if(errno != 0) {
- int err = errno;
- close(fd[0]);
- close(fd[1]);
- errno = err;
- rb_sys_fail("posix_spawn failed.");
- }
- posix_spawn_file_actions_destroy(&actions);
-
- // TODO: Eventually make the ungetc_buf a ByteString
- io_struct->fd = fd[0];
- io_struct->pipe = fd[1];
- io_struct->ungetc_buf = NULL;
- io_struct->ungetc_buf_len = 0;
- io_struct->ungetc_buf_pos = 0;
- io_struct->pid = pid;
- io_struct->sync = mode & FMODE_SYNC;
-
- rb_objc_keep_for_exit_finalize((VALUE)io);
- return io;
+
+ return io;
}
-
static VALUE
rb_io_s_popen(VALUE klass, SEL sel, int argc, VALUE *argv)
{
VALUE process_name, mode;
+
rb_scan_args(argc, argv, "11", &process_name, &mode);
if (NIL_P(mode)) mode = (VALUE)CFSTR("r");
+
StringValue(process_name);
VALUE io = io_from_spawning_new_process(process_name, mode);
+
if (rb_block_given_p()) {
VALUE ret = rb_vm_yield(1, &io);
rb_io_close_m(io, 0);
@@ -2051,23 +2005,6 @@
/*
* call-seq:
- * IO.sysopen(path, [mode, [perm]]) => fixnum
- *
- * Opens the given path, returning the underlying file descriptor as a
- * <code>Fixnum</code>.
- *
- * IO.sysopen("testfile") #=> 3
- *
- */
-
-static VALUE
-rb_io_s_sysopen(VALUE klass, SEL sel, int argc, VALUE *argv)
-{
-rb_notimplement();
-}
-
-/*
- * call-seq:
* open(path [, mode_enc [, perm]] ) => io or nil
* open(path [, mode_enc [, perm]] ) {|io| block } => obj
*
@@ -2208,8 +2145,29 @@
return io;
}
+
/*
* call-seq:
+ * IO.sysopen(path, [mode, [perm]]) => fixnum
+ *
+ * Opens the given path, returning the underlying file descriptor as a
+ * <code>Fixnum</code>.
+ *
+ * IO.sysopen("testfile") #=> 3
+ *
+ */
+
+static VALUE
+rb_io_s_sysopen(VALUE klass, SEL sel, int argc, VALUE *argv)
+{
+ VALUE io = rb_class_new_instance(argc, argv, rb_cFile);
+ io = rb_file_open(io, argc, argv);
+ return INT2FIX(ExtractIOStruct(io)->fd);
+}
+
+
+/*
+ * call-seq:
* ios.reopen(other_IO) => ios
* ios.reopen(path, mode_str) => ios
*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090526/257cc6ad/attachment.html>
More information about the macruby-changes
mailing list