/* * call-seq: * ios.reopen(other_IO) => ios * ios.reopen(path, mode_str) => ios * * Reassociates <em>ios</em> with the I/O stream given in * <i>other_IO</i> or to a new stream opened on <i>path</i>. This may * dynamically change the actual class of this stream. * * f1 = File.new("testfile") * f2 = File.new("testfile") * f2.readlines[0] #=> "This is line one\n" * f2.reopen(f1) #=> #<File:testfile> * f2.readlines[0] #=> "This is line one\n" */ static VALUE rb_io_reopen(argc, argv, file) int argc; VALUE *argv; VALUE file; { VALUE fname, nmode; char *mode; OpenFile *fptr; rb_secure(4); if (rb_scan_args(argc, argv, "11", &fname, &nmode) == 1) { VALUE tmp = rb_io_check_io(fname); if (!NIL_P(tmp)) { return io_reopen(file, tmp); } } SafeStringValue(fname); rb_io_taint_check(file); fptr = RFILE(file)->fptr; if (!fptr) { fptr = RFILE(file)->fptr = ALLOC(OpenFile); MEMZERO(fptr, OpenFile, 1); } if (!NIL_P(nmode)) { fptr->mode = rb_io_mode_flags(StringValueCStr(nmode)); } if (fptr->path) { free(fptr->path); fptr->path = 0; } fptr->path = strdup(StringValueCStr(fname)); mode = rb_io_flags_mode(fptr->mode); if (!fptr->f) { fptr->f = rb_fopen(fptr->path, mode); if (fptr->f2) { fclose(fptr->f2); fptr->f2 = 0; } return file; } if (freopen(fptr->path, mode, fptr->f) == 0) { rb_sys_fail(fptr->path); } #ifdef USE_SETVBUF if (setvbuf(fptr->f, NULL, _IOFBF, 0) != 0) rb_warn("setvbuf() can't be honoured for %s", fptr->path); #endif if (fptr->f2) { if (freopen(fptr->path, "w", fptr->f2) == 0) { rb_sys_fail(fptr->path); } } return file; }