mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* gc.c (obj_free), io.c (rb_io_fptr_finalize), rubyio.h (OpenFile):
sharing OpenFile. * io.c (rb_io_initialize): accept IO instance. [ruby-dev:22195] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5831 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
61deeb3741
commit
b0e0f45571
4 changed files with 65 additions and 12 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Wed Feb 25 21:17:33 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* gc.c (obj_free), io.c (rb_io_fptr_finalize), rubyio.h (OpenFile):
|
||||||
|
sharing OpenFile.
|
||||||
|
|
||||||
|
* io.c (rb_io_initialize): accept IO instance. [ruby-dev:22195]
|
||||||
|
|
||||||
Wed Feb 25 21:16:10 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Wed Feb 25 21:16:10 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* instruby.rb (with_destdir): should return the given argument if no
|
* instruby.rb (with_destdir): should return the given argument if no
|
||||||
|
|
1
gc.c
1
gc.c
|
@ -1178,7 +1178,6 @@ obj_free(obj)
|
||||||
case T_FILE:
|
case T_FILE:
|
||||||
if (RANY(obj)->as.file.fptr) {
|
if (RANY(obj)->as.file.fptr) {
|
||||||
rb_io_fptr_finalize(RANY(obj)->as.file.fptr);
|
rb_io_fptr_finalize(RANY(obj)->as.file.fptr);
|
||||||
RUBY_CRITICAL(free(RANY(obj)->as.file.fptr));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
|
|
67
io.c
67
io.c
|
@ -1780,6 +1780,7 @@ rb_io_fptr_finalize(fptr)
|
||||||
OpenFile *fptr;
|
OpenFile *fptr;
|
||||||
{
|
{
|
||||||
if (!fptr) return;
|
if (!fptr) return;
|
||||||
|
if (fptr->refcnt <= 0 || --fptr->refcnt) return;
|
||||||
if (fptr->path) {
|
if (fptr->path) {
|
||||||
free(fptr->path);
|
free(fptr->path);
|
||||||
}
|
}
|
||||||
|
@ -1787,6 +1788,7 @@ rb_io_fptr_finalize(fptr)
|
||||||
if (fileno(fptr->f) < 3) return;
|
if (fileno(fptr->f) < 3) return;
|
||||||
|
|
||||||
rb_io_fptr_cleanup(fptr, Qtrue);
|
rb_io_fptr_cleanup(fptr, Qtrue);
|
||||||
|
free(fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -3059,6 +3061,13 @@ rb_io_get_io(io)
|
||||||
return rb_convert_type(io, T_FILE, "IO", "to_io");
|
return rb_convert_type(io, T_FILE, "IO", "to_io");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_io_check_io(io)
|
||||||
|
VALUE io;
|
||||||
|
{
|
||||||
|
return rb_check_convert_type(io, T_FILE, "IO", "to_io");
|
||||||
|
}
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
rb_io_mode_string(fptr)
|
rb_io_mode_string(fptr)
|
||||||
OpenFile *fptr;
|
OpenFile *fptr;
|
||||||
|
@ -3751,9 +3760,12 @@ prep_path(io, path)
|
||||||
* IO.new(fd, mode) => io
|
* IO.new(fd, mode) => io
|
||||||
*
|
*
|
||||||
* Returns a new <code>IO</code> object (a stream) for the given
|
* Returns a new <code>IO</code> object (a stream) for the given
|
||||||
* integer file descriptor and mode string. See also
|
* <code>IO</code> object or integer file descriptor and mode
|
||||||
* <code>IO#fileno</code> and <code>IO::for_fd</code>.
|
* string. See also <code>IO#fileno</code> and
|
||||||
*
|
* <code>IO::for_fd</code>.
|
||||||
|
*
|
||||||
|
* puts IO.new($stdout).fileno # => 1
|
||||||
|
*
|
||||||
* a = IO.new(2,"w") # '2' is standard error
|
* a = IO.new(2,"w") # '2' is standard error
|
||||||
* $stderr.puts "Hello"
|
* $stderr.puts "Hello"
|
||||||
* a.puts "World"
|
* a.puts "World"
|
||||||
|
@ -3770,14 +3782,24 @@ rb_io_initialize(argc, argv, io)
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE io;
|
VALUE io;
|
||||||
{
|
{
|
||||||
VALUE fnum, mode;
|
VALUE fnum, mode, orig;
|
||||||
OpenFile *fp;
|
OpenFile *fp, *ofp = NULL;
|
||||||
int fd, flags;
|
int fd, flags, fmode;
|
||||||
char mbuf[4];
|
char mbuf[4];
|
||||||
|
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
rb_scan_args(argc, argv, "11", &fnum, &mode);
|
rb_scan_args(argc, argv, "11", &fnum, &mode);
|
||||||
fd = NUM2INT(fnum);
|
orig = rb_io_check_io(fnum);
|
||||||
|
if (NIL_P(orig)) {
|
||||||
|
fd = NUM2INT(fnum);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GetOpenFile(orig, ofp);
|
||||||
|
if (ofp->refcnt == LONG_MAX) {
|
||||||
|
VALUE s = rb_inspect(orig);
|
||||||
|
rb_raise(rb_eIOError, "too many shared IO for %s", StringValuePtr(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
if (FIXNUM_P(mode)) {
|
if (FIXNUM_P(mode)) {
|
||||||
flags = FIX2LONG(mode);
|
flags = FIX2LONG(mode);
|
||||||
|
@ -3786,17 +3808,40 @@ rb_io_initialize(argc, argv, io)
|
||||||
SafeStringValue(mode);
|
SafeStringValue(mode);
|
||||||
flags = rb_io_mode_modenum(RSTRING(mode)->ptr);
|
flags = rb_io_mode_modenum(RSTRING(mode)->ptr);
|
||||||
}
|
}
|
||||||
|
fmode = rb_io_modenum_flags(flags);
|
||||||
}
|
}
|
||||||
else {
|
else if (!ofp) {
|
||||||
#if defined(HAVE_FCNTL) && defined(F_GETFL)
|
#if defined(HAVE_FCNTL) && defined(F_GETFL)
|
||||||
flags = fcntl(fd, F_GETFL);
|
flags = fcntl(fd, F_GETFL);
|
||||||
#else
|
#else
|
||||||
flags = O_RDONLY;
|
flags = O_RDONLY;
|
||||||
#endif
|
#endif
|
||||||
|
fmode = rb_io_modenum_flags(flags);
|
||||||
|
}
|
||||||
|
if (!ofp) {
|
||||||
|
MakeOpenFile(io, fp);
|
||||||
|
fp->mode = fmode;
|
||||||
|
fp->f = rb_fdopen(fd, rb_io_modenum_mode(flags, mbuf));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (argc == 2) {
|
||||||
|
if ((ofp->mode ^ fmode) & (FMODE_READWRITE|FMODE_BINMODE)) {
|
||||||
|
if (FIXNUM_P(mode)) {
|
||||||
|
rb_raise(rb_eArgError, "incompatible mode 0%o", flags);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_raise(rb_eArgError, "incompatible mode %s", RSTRING(mode)->ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (RFILE(io)->fptr) {
|
||||||
|
rb_io_close(io);
|
||||||
|
free(RFILE(io)->fptr);
|
||||||
|
RFILE(io)->fptr = 0;
|
||||||
|
}
|
||||||
|
ofp->refcnt++;
|
||||||
|
RFILE(io)->fptr = ofp;
|
||||||
}
|
}
|
||||||
MakeOpenFile(io, fp);
|
|
||||||
fp->mode = rb_io_modenum_flags(flags);
|
|
||||||
fp->f = rb_fdopen(fd, rb_io_modenum_mode(flags, mbuf));
|
|
||||||
|
|
||||||
return io;
|
return io;
|
||||||
}
|
}
|
||||||
|
|
2
rubyio.h
2
rubyio.h
|
@ -24,6 +24,7 @@ typedef struct OpenFile {
|
||||||
int lineno; /* number of lines read */
|
int lineno; /* number of lines read */
|
||||||
char *path; /* pathname for file */
|
char *path; /* pathname for file */
|
||||||
void (*finalize) _((struct OpenFile*,int)); /* finalize proc */
|
void (*finalize) _((struct OpenFile*,int)); /* finalize proc */
|
||||||
|
long refcnt;
|
||||||
} OpenFile;
|
} OpenFile;
|
||||||
|
|
||||||
#define FMODE_READABLE 1
|
#define FMODE_READABLE 1
|
||||||
|
@ -50,6 +51,7 @@ typedef struct OpenFile {
|
||||||
fp->lineno = 0;\
|
fp->lineno = 0;\
|
||||||
fp->path = NULL;\
|
fp->path = NULL;\
|
||||||
fp->finalize = 0;\
|
fp->finalize = 0;\
|
||||||
|
fp->refcnt = 1;\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define GetReadFile(fptr) ((fptr)->f)
|
#define GetReadFile(fptr) ((fptr)->f)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue