1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Revert r36213 "popen: shell commands with envvar"

* io.c (rb_io_s_popen): revert r36213 "popen: shell commands with
  envvar" because it disabled to let single command bypass shell.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36218 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-06-26 01:01:59 +00:00
parent f4af54f212
commit 876d4c4cc8
3 changed files with 43 additions and 63 deletions

View file

@ -1,3 +1,8 @@
Tue Jun 26 10:01:56 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* io.c (rb_io_s_popen): revert r36213 "popen: shell commands with
envvar" because it disabled to let single command bypass shell.
Mon Jun 25 17:49:28 2012 Nobuyoshi Nakada <nobu@ruby-lang.org> Mon Jun 25 17:49:28 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* class.c (rb_mix_module): revert Module#mix. * class.c (rb_mix_module): revert Module#mix.
@ -7,14 +12,6 @@ Mon Jun 25 16:57:38 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* proc.c (rb_mod_define_method): allow method transplanting from a * proc.c (rb_mod_define_method): allow method transplanting from a
module to either class or module. [ruby-core:34267][Feature #4254] module to either class or module. [ruby-core:34267][Feature #4254]
Mon Jun 25 15:42:00 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* io.c (is_popen_fork): check if fork and raise NotImplementedError if
unavailable.
* io.c (rb_io_s_popen): allow shell commands with modified environment
variables.
Mon Jun 25 11:34:45 2012 NAKAMURA Usaku <usa@ruby-lang.org> Mon Jun 25 11:34:45 2012 NAKAMURA Usaku <usa@ruby-lang.org>
* internal.h: use rb_pid_t instead of pid_t because of there is no * internal.h: use rb_pid_t instead of pid_t because of there is no

44
io.c
View file

@ -5692,30 +5692,35 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
return port; return port;
} }
static int static VALUE
is_popen_fork(VALUE prog) pipe_open_v(int argc, VALUE *argv, const char *modestr, int fmode, convconfig_t *convconfig)
{ {
if (RSTRING_LEN(prog) == 1 && RSTRING_PTR(prog)[0] == '-') { VALUE execarg_obj, ret;
#if !defined(HAVE_FORK) execarg_obj = rb_execarg_new(argc, argv, FALSE);
rb_raise(rb_eNotImpError, ret = pipe_open(execarg_obj, modestr, fmode, convconfig);
"fork() function is unimplemented on this machine"); return ret;
#else
return TRUE;
#endif
}
return FALSE;
} }
static VALUE static VALUE
pipe_open_s(VALUE prog, const char *modestr, int fmode, convconfig_t *convconfig) pipe_open_s(VALUE prog, const char *modestr, int fmode, convconfig_t *convconfig)
{ {
const char *cmd = RSTRING_PTR(prog);
int argc = 1; int argc = 1;
VALUE *argv = &prog; VALUE *argv = &prog;
VALUE execarg_obj = Qnil; VALUE execarg_obj, ret;
if (!is_popen_fork(prog)) if (RSTRING_LEN(prog) == 1 && cmd[0] == '-') {
execarg_obj = rb_execarg_new(argc, argv, TRUE); #if !defined(HAVE_FORK)
return pipe_open(execarg_obj, modestr, fmode, convconfig); rb_raise(rb_eNotImpError,
"fork() function is unimplemented on this machine");
#else
return pipe_open(Qnil, modestr, fmode, convconfig);
#endif
}
execarg_obj = rb_execarg_new(argc, argv, TRUE);
ret = pipe_open(execarg_obj, modestr, fmode, convconfig);
return ret;
} }
/* /*
@ -5805,7 +5810,7 @@ static VALUE
rb_io_s_popen(int argc, VALUE *argv, VALUE klass) rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
{ {
const char *modestr; const char *modestr;
VALUE pname, pmode, port, tmp, opt, execarg_obj; VALUE pname, pmode, port, tmp, opt;
int oflags, fmode; int oflags, fmode;
convconfig_t convconfig; convconfig_t convconfig;
@ -5824,16 +5829,13 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
#endif #endif
tmp = rb_ary_dup(tmp); tmp = rb_ary_dup(tmp);
RBASIC(tmp)->klass = 0; RBASIC(tmp)->klass = 0;
execarg_obj = rb_execarg_new((int)len, RARRAY_PTR(tmp), TRUE); port = pipe_open_v((int)len, RARRAY_PTR(tmp), modestr, fmode, &convconfig);
rb_ary_clear(tmp); rb_ary_clear(tmp);
} }
else { else {
SafeStringValue(pname); SafeStringValue(pname);
execarg_obj = Qnil; port = pipe_open_s(pname, modestr, fmode, &convconfig);
if (!is_popen_fork(pname))
execarg_obj = rb_execarg_new(1, &pname, TRUE);
} }
port = pipe_open(execarg_obj, modestr, fmode, &convconfig);
if (NIL_P(port)) { if (NIL_P(port)) {
/* child */ /* child */
if (rb_block_given_p()) { if (rb_block_given_p()) {

View file

@ -275,53 +275,34 @@ class TestProcess < Test::Unit::TestCase
assert_equal("PATH\n", io.read) assert_equal("PATH\n", io.read)
} }
IO.popen([{"FOO"=>"BAR"}, *ENVCOMMAND]) {|io|
assert_match(/^FOO=BAR$/, io.read)
}
with_tmpchdir {|d| with_tmpchdir {|d|
system({"fofo"=>"haha"}, *ENVCOMMAND, STDOUT=>"out") system({"fofo"=>"haha"}, *ENVCOMMAND, STDOUT=>"out")
assert_match(/^fofo=haha$/, File.read("out").chomp, message) assert_match(/^fofo=haha$/, File.read("out").chomp)
}
end
def _test_execopts_env_popen(cmd)
message = cmd.inspect
IO.popen([{"FOO"=>"BAR"}, *cmd]) {|io|
assert_match(/^FOO=BAR$/, io.read, message)
} }
old = ENV["hmm"] old = ENV["hmm"]
begin begin
ENV["hmm"] = "fufu" ENV["hmm"] = "fufu"
IO.popen(cmd) {|io| assert_match(/^hmm=fufu$/, io.read, message)} IO.popen(ENVCOMMAND) {|io| assert_match(/^hmm=fufu$/, io.read) }
IO.popen([{"hmm"=>""}, *cmd]) {|io| assert_match(/^hmm=$/, io.read, message)} IO.popen([{"hmm"=>""}, *ENVCOMMAND]) {|io| assert_match(/^hmm=$/, io.read) }
IO.popen([{"hmm"=>nil}, *cmd]) {|io| assert_not_match(/^hmm=/, io.read, message)} IO.popen([{"hmm"=>nil}, *ENVCOMMAND]) {|io| assert_not_match(/^hmm=/, io.read) }
ENV["hmm"] = "" ENV["hmm"] = ""
IO.popen(cmd) {|io| assert_match(/^hmm=$/, io.read, message)} IO.popen(ENVCOMMAND) {|io| assert_match(/^hmm=$/, io.read) }
IO.popen([{"hmm"=>""}, *cmd]) {|io| assert_match(/^hmm=$/, io.read, message)} IO.popen([{"hmm"=>""}, *ENVCOMMAND]) {|io| assert_match(/^hmm=$/, io.read) }
IO.popen([{"hmm"=>nil}, *cmd]) {|io| assert_not_match(/^hmm=/, io.read, message)} IO.popen([{"hmm"=>nil}, *ENVCOMMAND]) {|io| assert_not_match(/^hmm=/, io.read) }
ENV["hmm"] = nil ENV["hmm"] = nil
IO.popen(cmd) {|io| assert_not_match(/^hmm=/, io.read, message)} IO.popen(ENVCOMMAND) {|io| assert_not_match(/^hmm=/, io.read) }
IO.popen([{"hmm"=>""}, *cmd]) {|io| assert_match(/^hmm=$/, io.read, message)} IO.popen([{"hmm"=>""}, *ENVCOMMAND]) {|io| assert_match(/^hmm=$/, io.read) }
IO.popen([{"hmm"=>nil}, *cmd]) {|io| assert_not_match(/^hmm=/, io.read, message)} IO.popen([{"hmm"=>nil}, *ENVCOMMAND]) {|io| assert_not_match(/^hmm=/, io.read) }
ensure ensure
ENV["hmm"] = old ENV["hmm"] = old
end end
end end
def test_execopts_env_popen_vector
_test_execopts_env_popen(ENVCOMMAND)
end
def test_execopts_env_popen_string
with_tmpchdir do |d|
open('test-script', 'w') do |f|
ENVCOMMAND.each_with_index do |cmd, i|
next if i.zero? or cmd == "-e"
f.puts cmd
end
end
_test_execopts_env_popen("#{RUBY} test-script")
end
end
def test_execopts_preserve_env_on_exec_failure def test_execopts_preserve_env_on_exec_failure
with_tmpchdir {|d| with_tmpchdir {|d|
write_file 's', <<-"End" write_file 's', <<-"End"
@ -622,7 +603,7 @@ class TestProcess < Test::Unit::TestCase
def test_execopts_popen def test_execopts_popen
with_tmpchdir {|d| with_tmpchdir {|d|
IO.popen("#{RUBY} -e 'puts :foo'") {|io| assert_equal("foo\n", io.read) } IO.popen("#{RUBY} -e 'puts :foo'") {|io| assert_equal("foo\n", io.read) }
IO.popen(["echo bar"]) {|io| assert_equal("bar\n", io.read) } assert_raise(Errno::ENOENT) { IO.popen(["echo bar"]) {} } # assuming "echo bar" command not exist.
IO.popen(ECHO["baz"]) {|io| assert_equal("baz\n", io.read) } IO.popen(ECHO["baz"]) {|io| assert_equal("baz\n", io.read) }
assert_raise(ArgumentError) { assert_raise(ArgumentError) {
IO.popen([*ECHO["qux"], STDOUT=>STDOUT]) {|io| } IO.popen([*ECHO["qux"], STDOUT=>STDOUT]) {|io| }