summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--array.c2
-rw-r--r--intern.h2
-rw-r--r--io.c89
-rw-r--r--process.c15
-rw-r--r--string.c20
6 files changed, 73 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index c69d897717..84d7c2ba6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Mon Nov 1 01:14:52 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * io.c (rb_f_open): create copy of popen specifier. [ruby-dev:24656]
+
+ * string.c (rb_str_locktmp): lock string temporarily.
+
+ * string.c (str_independent): add tmplock check.
+
+ * io.c (io_write): lock output string temporarily.
+ [ruby-dev:24649]
+
+ * io.c (io_write): use rb_str_locktmp().
+
+ * io.c (read_all): ditto.
+
Sun Oct 31 23:37:00 2004 NARUSE, Yui <naruse@ruby-lang.org>
* process.c: on NetBSD don't use setruid() and setrgid().
diff --git a/array.c b/array.c
index 8d173d8a06..dc5f65e435 100644
--- a/array.c
+++ b/array.c
@@ -52,7 +52,7 @@ rb_ary_modify_check(ary)
{
if (OBJ_FROZEN(ary)) rb_error_frozen("array");
if (FL_TEST(ary, ARY_TMPLOCK))
- rb_raise(rb_eTypeError, "can't modify array during iteration");
+ rb_raise(rb_eRuntimeError, "can't modify array during iteration");
if (!OBJ_TAINTED(ary) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify array");
}
diff --git a/intern.h b/intern.h
index 7f12ebc5d2..b7340cf83a 100644
--- a/intern.h
+++ b/intern.h
@@ -418,6 +418,8 @@ VALUE rb_str_buf_cat2 _((VALUE, const char*));
VALUE rb_obj_as_string _((VALUE));
VALUE rb_check_string_type _((VALUE));
VALUE rb_str_dup _((VALUE));
+VALUE rb_str_locktmp _((VALUE));
+VALUE rb_str_unlocktmp _((VALUE));
VALUE rb_str_dup_frozen _((VALUE));
VALUE rb_str_plus _((VALUE, VALUE));
VALUE rb_str_times _((VALUE, VALUE));
diff --git a/io.c b/io.c
index 3fa254a2fa..4c3bcd45dd 100644
--- a/io.c
+++ b/io.c
@@ -473,7 +473,9 @@ io_write(io, str)
rb_io_check_writable(fptr);
f = GetWriteFile(fptr);
+ rb_str_locktmp(str);
n = rb_io_fwrite(RSTRING(str)->ptr, RSTRING(str)->len, f);
+ rb_str_unlocktmp(str);
if (n == -1L) rb_sys_fail(fptr->path);
if (fptr->mode & FMODE_SYNC) {
io_fflush(f, fptr);
@@ -1031,10 +1033,10 @@ read_all(fptr, siz, str)
rb_str_resize(str, siz);
}
for (;;) {
- FL_SET(str, FL_FREEZE);
+ rb_str_locktmp(str);
READ_CHECK(fptr->f);
n = rb_io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr->f);
- FL_UNSET(str, FL_FREEZE);
+ rb_str_unlocktmp(str);
if (n == 0 && bytes == 0) {
rb_str_resize(str,0);
if (!fptr->f) break;
@@ -1212,10 +1214,10 @@ io_read(argc, argv, io)
}
if (len == 0) return str;
- FL_SET(str, FL_FREEZE);
+ rb_str_locktmp(str);
READ_CHECK(fptr->f);
n = rb_io_fread(RSTRING(str)->ptr, len, fptr->f);
- FL_UNSET(str, FL_FREEZE);
+ rb_str_unlocktmp(str);
if (n == 0) {
rb_str_resize(str,0);
if (!fptr->f) return Qnil;
@@ -2511,15 +2513,12 @@ rb_fopen(fname, mode)
const char *mode;
{
FILE *file;
- char mbuf[MODENUM_MAX];
- strncpy(mbuf, mode, sizeof(mbuf) - 1);
- mbuf[sizeof(mbuf) - 1] = 0;
- file = fopen(fname, mbuf);
+ file = fopen(fname, mode);
if (!file) {
if (errno == EMFILE || errno == ENFILE) {
rb_gc();
- file = fopen(fname, mbuf);
+ file = fopen(fname, mode);
}
if (!file) {
rb_sys_fail(fname);
@@ -2776,7 +2775,7 @@ pipe_open(argc, argv, pname, mode)
int modef = rb_io_mode_flags(mode);
int pid = 0;
OpenFile *fptr;
- VALUE port, arg0;
+ VALUE port, prog;
#if defined(HAVE_FORK)
int status;
struct popen_arg arg;
@@ -2786,17 +2785,20 @@ pipe_open(argc, argv, pname, mode)
int openmode = rb_io_mode_modenum(mode);
char *prog = NULL;
#endif
- char *cmd = pname;
+ char *cmd;
if (!pname) {
- arg0 = rb_check_argv(argc, argv);
- if (arg0) pname = StringValuePtr(arg0);
- cmd = pname;
- if (!pname) pname = RSTRING(argv[0])->ptr;
+ prog = rb_check_argv(argc, argv);
+ if (!prog && argc == 1) {
+ argc = 0;
+ prog = argv[0];
+ }
+ pname = StringValuePtr(prog);
}
+ cmd = pname;
#if defined(HAVE_FORK)
- doexec = (argc > 0) || (strcmp("-", pname) != 0);
+ doexec = (strcmp("-", pname) != 0);
if (!doexec) {
fflush(stdin); /* is it really needed? */
fflush(stdout);
@@ -2871,8 +2873,8 @@ pipe_open(argc, argv, pname, mode)
#define PIPE_FDOPEN(i) (i?fpw:fpr)
#else
if (argc > 0) {
- arg0 = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
- cmd = StringValuePtr(arg0);
+ prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
+ cmd = StringValuePtr(prog);
}
fpr = popen(cmd, mode);
@@ -2900,44 +2902,6 @@ pipe_open(argc, argv, pname, mode)
return port;
}
-static VALUE
-rb_io_popen(str, argc, argv, klass)
- char *str;
- int argc;
- VALUE *argv;
- VALUE klass;
-{
- char *mode;
- VALUE pname, pmode, port;
-
- if (rb_scan_args(argc, argv, "11", &pname, &pmode) == 1) {
- mode = "r";
- }
- else if (FIXNUM_P(pmode)) {
- mode = rb_io_modenum_mode(FIX2INT(pmode));
- }
- else {
- mode = rb_io_flags_mode(rb_io_mode_flags(StringValuePtr(pmode)));
- }
- SafeStringValue(pname);
- port = pipe_open(0, 0, str, mode);
- if (NIL_P(port)) {
- /* child */
- if (rb_block_given_p()) {
- rb_yield(Qnil);
- fflush(stdout);
- fflush(stderr);
- _exit(0);
- }
- return Qnil;
- }
- RBASIC(port)->klass = klass;
- if (rb_block_given_p()) {
- return rb_ensure(rb_yield, port, io_close, port);
- }
- return port;
-}
-
/*
* call-seq:
* IO.popen(cmd, mode="r") => io
@@ -2995,7 +2959,6 @@ rb_io_s_popen(argc, argv, klass)
{
char *mode;
VALUE pname, pmode, port, tmp;
- char mbuf[MODENUM_MAX];
if (rb_scan_args(argc, argv, "11", &pname, &pmode) == 1) {
mode = "r";
@@ -3004,9 +2967,7 @@ rb_io_s_popen(argc, argv, klass)
mode = rb_io_modenum_mode(FIX2INT(pmode));
}
else {
- strncpy(mbuf, StringValuePtr(pmode), sizeof(mbuf) - 1);
- mbuf[sizeof(mbuf) - 1] = 0;
- mode = mbuf;
+ mode = rb_io_flags_mode(rb_io_mode_flags(StringValuePtr(pmode)));
}
tmp = rb_check_array_type(pname);
if (!NIL_P(tmp)) {
@@ -3018,7 +2979,7 @@ rb_io_s_popen(argc, argv, klass)
}
else {
SafeStringValue(pname);
- port = pipe_open(0, 0, RSTRING(pname)->ptr, mode);
+ port = pipe_open(1, &pname, 0, mode);
if (NIL_P(port)) {
/* child */
if (rb_block_given_p()) {
@@ -3237,7 +3198,9 @@ rb_f_open(argc, argv)
if (!NIL_P(tmp)) {
char *str = StringValuePtr(tmp);
if (str && str[0] == '|') {
- return rb_io_popen(str+1, argc, argv, rb_cIO);
+ argv[0] = rb_str_new(str+1, RSTRING(tmp)->len-1);
+ OBJ_INFECT(argv[0], tmp);
+ return rb_io_s_popen(argc, argv, rb_cIO);
}
}
}
@@ -4478,7 +4441,7 @@ rb_f_backquote(obj, str)
OpenFile *fptr;
SafeStringValue(str);
- port = pipe_open(0, 0, RSTRING(str)->ptr, "r");
+ port = pipe_open(1, &str, 0, "r");
if (NIL_P(port)) return rb_str_new(0,0);
GetOpenFile(port, fptr);
diff --git a/process.c b/process.c
index b7058b04c3..bdf651f37b 100644
--- a/process.c
+++ b/process.c
@@ -1260,14 +1260,17 @@ rb_f_exec(argc, argv)
prog = rb_check_argv(argc, argv);
if (!prog && argc == 1) {
- --argc;
- prog = *argv++;
+ e.argc = 0;
+ e.argv = 0;
+ e.prog = RSTRING(argv[0])->ptr;
+ }
+ else {
+ e.argc = argc;
+ e.argv = argv;
+ e.prog = RSTRING(prog)->ptr;
}
- e.argc = argc;
- e.argv = argv;
- e.prog = prog ? RSTRING(prog)->ptr : 0;
rb_exec(&e);
- rb_sys_fail(prog ? e.prog : RSTRING(argv[0])->ptr);
+ rb_sys_fail(e.prog);
return Qnil; /* dummy */
}
diff --git a/string.c b/string.c
index cc31d1f606..43c8f7908a 100644
--- a/string.c
+++ b/string.c
@@ -27,6 +27,7 @@
VALUE rb_cString;
+#define STR_TMPLOCK FL_USER1
#define STR_ASSOC FL_USER3
#define STR_NOCAPA (ELTS_SHARED|STR_ASSOC)
@@ -462,6 +463,9 @@ static int
str_independent(str)
VALUE str;
{
+ if (FL_TEST(str, STR_TMPLOCK)) {
+ rb_raise(rb_eRuntimeError, "can't modify string; temporarily locked");
+ }
if (OBJ_FROZEN(str)) rb_error_frozen("string");
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
@@ -633,6 +637,22 @@ rb_str_dup_frozen(str)
}
VALUE
+rb_str_locktmp(str)
+ VALUE str;
+{
+ FL_SET(str, STR_TMPLOCK);
+ return str;
+}
+
+VALUE
+rb_str_unlocktmp(str)
+ VALUE str;
+{
+ FL_UNSET(str, STR_TMPLOCK);
+ return str;
+}
+
+VALUE
rb_str_resize(str, len)
VALUE str;
long len;