[macruby-changes] [3939] MacRuby/trunk/io.c
source_changes at macosforge.org
source_changes at macosforge.org
Fri Apr 16 19:09:57 PDT 2010
Revision: 3939
http://trac.macosforge.org/projects/ruby/changeset/3939
Author: martinlagardette at apple.com
Date: 2010-04-16 19:09:53 -0700 (Fri, 16 Apr 2010)
Log Message:
-----------
Adds support for `Array` arguments in `IO.popen`
Also adds support for the "|" argument in `IO.read` and `IO.open`
Modified Paths:
--------------
MacRuby/trunk/io.c
Modified: MacRuby/trunk/io.c
===================================================================
--- MacRuby/trunk/io.c 2010-04-17 00:55:39 UTC (rev 3938)
+++ MacRuby/trunk/io.c 2010-04-17 02:09:53 UTC (rev 3939)
@@ -2111,11 +2111,31 @@
"could not add a close() to stdout");
pid_t pid;
- // TODO: Split the process_name up into char* components?
- char *spawnedArgs[] = {(char*)_PATH_BSHELL, "-c",
- (char*)RSTRING_PTR(prog), NULL};
- errno = posix_spawn(&pid, spawnedArgs[0], &actions, NULL, spawnedArgs,
- *(_NSGetEnviron()));
+
+ VALUE argArray = rb_check_array_type(prog);
+ if (!NIL_P(argArray)) {
+ const long len = RARRAY_LEN(argArray);
+ char **spawnedArgs =
+ malloc((len + 1) * sizeof(char *));
+ for (long i = 0; i < len; i++) {
+ VALUE str = RARRAY_AT(argArray, i);
+ spawnedArgs[i] = StringValuePtr(str);
+ }
+ spawnedArgs[len] = 0;
+ // using posix_spawnP (look up binary in PATH)
+ errno = posix_spawnp(&pid, spawnedArgs[0], &actions, NULL, spawnedArgs,
+ *(_NSGetEnviron()));
+ const int err = errno;
+ free(spawnedArgs);
+ errno = err;
+ }
+ else {
+ // TODO: Split the process_name up into char* components?
+ char *spawnedArgs[] = {(char*)_PATH_BSHELL, "-c",
+ StringValuePtr(prog), NULL};
+ errno = posix_spawn(&pid, spawnedArgs[0], &actions, NULL, spawnedArgs,
+ *(_NSGetEnviron()));
+ }
if (errno != 0) {
const int err = errno;
close(fd[0]);
@@ -2153,7 +2173,6 @@
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);
@@ -2190,6 +2209,19 @@
return io;
}
+static VALUE
+check_pipe_command(VALUE fname)
+{
+ const char *cname = StringValuePtr(fname);
+ const size_t len = strlen(cname);
+
+ if (cname[0] == '|') {
+ VALUE cmd = rb_str_new(cname + 1, len - 1);
+ return cmd;
+ }
+ return Qnil;
+}
+
/*
* call-seq:
* open(path [, mode_enc [, perm]] ) => io or nil
@@ -2300,12 +2332,23 @@
static VALUE
rb_file_open(VALUE io, int argc, VALUE *argv)
{
+ if (argc > 0) {
+ // First argument must always be a path, we are checking it here to
+ // conform to RubySpecs which states that the conversion must only
+ // happen once.
+ FilePathValue(argv[0]);
+ }
+ if (argc >= 1) {
+ VALUE cmd = check_pipe_command(argv[0]);
+ if (cmd != Qnil) {
+ return rb_io_s_popen(rb_cIO, 0, 1, &cmd);
+ }
+ }
VALUE path, modes, permissions;
rb_scan_args(argc, argv, "12", &path, &modes, &permissions);
if (NIL_P(modes)) {
modes = (VALUE)CFSTR("r");
}
- FilePathValue(path);
const char *filepath = RSTRING_PTR(path);
const int flags = convert_mode_string_to_oflags(modes);
const mode_t perm = NIL_P(permissions) ? 0666 : NUM2UINT(permissions);
@@ -2349,6 +2392,12 @@
VALUE
rb_f_open(VALUE klass, SEL sel, int argc, VALUE *argv)
{
+ if (argc >= 1) {
+ VALUE cmd = check_pipe_command(argv[0]);
+ if (cmd != Qnil) {
+ return rb_io_s_popen(rb_cIO, 0, 1, &cmd);
+ }
+ }
VALUE io = rb_class_new_instance(argc, argv, rb_cFile);
if (rb_block_given_p()) {
return rb_ensure(f_open_body, io, f_open_ensure, io);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100416/d8100153/attachment-0001.html>
More information about the macruby-changes
mailing list