* io.c (io_reopen, rb_io_reopen): prohibit to change access mode for

special IO ports.  [ruby-dev:25225]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7649 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2004-12-23 17:53:58 +00:00
Родитель 4bdc2a662d
Коммит a892f803ef
2 изменённых файлов: 39 добавлений и 28 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Fri Dec 24 02:52:52 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* io.c (io_reopen, rb_io_reopen): prohibit to change access mode for
special IO ports. [ruby-dev:25225]
Fri Dec 24 02:22:53 2004 Nobuyoshi Nakada <nobu@ruby-lang.org> Fri Dec 24 02:22:53 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/syck/rubyext.c (syck_loader_transfer): check type conversion. * ext/syck/rubyext.c (syck_loader_transfer): check type conversion.

62
io.c
Просмотреть файл

@ -1920,6 +1920,10 @@ rb_io_isatty(io)
return Qtrue; return Qtrue;
} }
#define FMODE_PREP (1<<16)
#define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
#define PREP_STDIO_NAME(f) ((f)->path)
static void static void
fptr_finalize(fptr, noraise) fptr_finalize(fptr, noraise)
OpenFile *fptr; OpenFile *fptr;
@ -1928,9 +1932,7 @@ fptr_finalize(fptr, noraise)
if (fptr->wbuf_len) { if (fptr->wbuf_len) {
io_fflush(fptr); io_fflush(fptr);
} }
if (fptr->stdio_file == stdin || if (IS_PREP_STDIO(fptr) ||
fptr->stdio_file == stdout ||
fptr->stdio_file == stderr ||
fptr->fd <= 2) { fptr->fd <= 2) {
return; return;
} }
@ -3280,6 +3282,16 @@ io_reopen(io, nfile)
GetOpenFile(nfile, orig); GetOpenFile(nfile, orig);
if (fptr == orig) return io; if (fptr == orig) return io;
#if !defined __CYGWIN__
if (IS_PREP_STDIO(fptr)) {
if ((fptr->mode & FMODE_READWRITE) != (orig->mode & FMODE_READWRITE)) {
rb_raise(rb_eArgError,
"%s cannot change access mode from \"%s\" to \"%s\"",
PREP_STDIO_NAME(fptr), rb_io_flags_mode(fptr->mode),
rb_io_flags_mode(orig->mode));
}
}
#endif
if (orig->mode & FMODE_READABLE) { if (orig->mode & FMODE_READABLE) {
pos = io_tell(orig); pos = io_tell(orig);
} }
@ -3303,9 +3315,7 @@ io_reopen(io, nfile)
fd2 = orig->fd; fd2 = orig->fd;
if (fd != fd2) { if (fd != fd2) {
#if !defined __CYGWIN__ #if !defined __CYGWIN__
if (fptr->stdio_file == stdin || if (IS_PREP_STDIO(fptr)) {
fptr->stdio_file == stdout ||
fptr->stdio_file == stderr) {
/* need to keep stdio objects */ /* need to keep stdio objects */
if (dup2(fd2, fd) < 0) if (dup2(fd2, fd) < 0)
rb_sys_fail(orig->path); rb_sys_fail(orig->path);
@ -3386,7 +3396,15 @@ rb_io_reopen(argc, argv, file)
} }
if (!NIL_P(nmode)) { if (!NIL_P(nmode)) {
fptr->mode = rb_io_mode_flags(StringValuePtr(nmode)); int flags = rb_io_mode_flags(StringValuePtr(nmode));
if (IS_PREP_STDIO(fptr) &&
(fptr->mode & FMODE_READWRITE) != (flags & FMODE_READWRITE)) {
rb_raise(rb_eArgError,
"%s cannot change access mode from \"%s\" to \"%s\"",
PREP_STDIO_NAME(fptr), rb_io_flags_mode(fptr->mode),
rb_io_flags_mode(flags));
}
fptr->mode = flags;
} }
if (fptr->path) { if (fptr->path) {
@ -3866,10 +3884,11 @@ deferr_setter(val, id, variable)
} }
static VALUE static VALUE
prep_stdio(f, mode, klass) prep_stdio(f, mode, klass, path)
FILE *f; FILE *f;
int mode; int mode;
VALUE klass; VALUE klass;
const char *path;
{ {
OpenFile *fp; OpenFile *fp;
VALUE io = io_alloc(klass); VALUE io = io_alloc(klass);
@ -3883,29 +3902,18 @@ prep_stdio(f, mode, klass)
} }
#endif #endif
fp->stdio_file = f; fp->stdio_file = f;
fp->mode = mode; fp->mode = mode | FMODE_PREP;
if (fp->mode & FMODE_WRITABLE) { if (fp->mode & FMODE_WRITABLE) {
if (fp->fd == 2) { /* stderr must be unbuffered */ if (fp->fd == 2) { /* stderr must be unbuffered */
fp->mode |= FMODE_SYNC; fp->mode |= FMODE_SYNC;
} }
io_check_tty(fp); io_check_tty(fp);
} }
fp->path = strdup(path);
return io; return io;
} }
static void
prep_path(io, path)
VALUE io;
char *path;
{
OpenFile *fptr;
GetOpenFile(io, fptr);
if (fptr->path) rb_bug("illegal prep_path() call");
fptr->path = strdup(path);
}
FILE *rb_io_stdio_file(OpenFile *fptr) FILE *rb_io_stdio_file(OpenFile *fptr)
{ {
if (!fptr->stdio_file) { if (!fptr->stdio_file) {
@ -4219,12 +4227,10 @@ next_argv()
fchown(fileno(fw), st.st_uid, st.st_gid); fchown(fileno(fw), st.st_uid, st.st_gid);
} }
#endif #endif
rb_stdout = prep_stdio(fw, FMODE_WRITABLE, rb_cFile); rb_stdout = prep_stdio(fw, FMODE_WRITABLE, rb_cFile, fn);
prep_path(rb_stdout, fn);
if (stdout_binmode) rb_io_binmode(rb_stdout); if (stdout_binmode) rb_io_binmode(rb_stdout);
} }
current_file = prep_stdio(fr, FMODE_READABLE, rb_cFile); current_file = prep_stdio(fr, FMODE_READABLE, rb_cFile, fn);
prep_path(current_file, fn);
} }
if (binmode) rb_io_binmode(current_file); if (binmode) rb_io_binmode(current_file);
} }
@ -5558,11 +5564,11 @@ Init_IO()
rb_define_method(rb_cIO, "pid", rb_io_pid, 0); rb_define_method(rb_cIO, "pid", rb_io_pid, 0);
rb_define_method(rb_cIO, "inspect", rb_io_inspect, 0); rb_define_method(rb_cIO, "inspect", rb_io_inspect, 0);
rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO); rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO, "<STDIN>");
rb_define_variable("$stdin", &rb_stdin); rb_define_variable("$stdin", &rb_stdin);
rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO); rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO, "<STDOUT>");
rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter); rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter);
rb_stderr = prep_stdio(stderr, FMODE_WRITABLE, rb_cIO); rb_stderr = prep_stdio(stderr, FMODE_WRITABLE, rb_cIO, "<STDERR>");
rb_define_hooked_variable("$stderr", &rb_stderr, 0, stdout_setter); rb_define_hooked_variable("$stderr", &rb_stderr, 0, stdout_setter);
rb_define_hooked_variable("$>", &rb_stdout, 0, stdout_setter); rb_define_hooked_variable("$>", &rb_stdout, 0, stdout_setter);
orig_stdout = rb_stdout; orig_stdout = rb_stdout;