* 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>
* ext/syck/rubyext.c (syck_loader_transfer): check type conversion.

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

@ -1920,6 +1920,10 @@ rb_io_isatty(io)
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
fptr_finalize(fptr, noraise)
OpenFile *fptr;
@ -1928,9 +1932,7 @@ fptr_finalize(fptr, noraise)
if (fptr->wbuf_len) {
io_fflush(fptr);
}
if (fptr->stdio_file == stdin ||
fptr->stdio_file == stdout ||
fptr->stdio_file == stderr ||
if (IS_PREP_STDIO(fptr) ||
fptr->fd <= 2) {
return;
}
@ -3280,6 +3282,16 @@ io_reopen(io, nfile)
GetOpenFile(nfile, orig);
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) {
pos = io_tell(orig);
}
@ -3303,9 +3315,7 @@ io_reopen(io, nfile)
fd2 = orig->fd;
if (fd != fd2) {
#if !defined __CYGWIN__
if (fptr->stdio_file == stdin ||
fptr->stdio_file == stdout ||
fptr->stdio_file == stderr) {
if (IS_PREP_STDIO(fptr)) {
/* need to keep stdio objects */
if (dup2(fd2, fd) < 0)
rb_sys_fail(orig->path);
@ -3386,7 +3396,15 @@ rb_io_reopen(argc, argv, file)
}
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) {
@ -3866,10 +3884,11 @@ deferr_setter(val, id, variable)
}
static VALUE
prep_stdio(f, mode, klass)
prep_stdio(f, mode, klass, path)
FILE *f;
int mode;
VALUE klass;
const char *path;
{
OpenFile *fp;
VALUE io = io_alloc(klass);
@ -3883,29 +3902,18 @@ prep_stdio(f, mode, klass)
}
#endif
fp->stdio_file = f;
fp->mode = mode;
fp->mode = mode | FMODE_PREP;
if (fp->mode & FMODE_WRITABLE) {
if (fp->fd == 2) { /* stderr must be unbuffered */
fp->mode |= FMODE_SYNC;
}
io_check_tty(fp);
}
fp->path = strdup(path);
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)
{
if (!fptr->stdio_file) {
@ -4219,12 +4227,10 @@ next_argv()
fchown(fileno(fw), st.st_uid, st.st_gid);
}
#endif
rb_stdout = prep_stdio(fw, FMODE_WRITABLE, rb_cFile);
prep_path(rb_stdout, fn);
rb_stdout = prep_stdio(fw, FMODE_WRITABLE, rb_cFile, fn);
if (stdout_binmode) rb_io_binmode(rb_stdout);
}
current_file = prep_stdio(fr, FMODE_READABLE, rb_cFile);
prep_path(current_file, fn);
current_file = prep_stdio(fr, FMODE_READABLE, rb_cFile, fn);
}
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, "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_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_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("$>", &rb_stdout, 0, stdout_setter);
orig_stdout = rb_stdout;