diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-01-20 04:59:39 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-01-20 04:59:39 +0000 |
commit | 210367ec889f5910e270d6ea2c7ddb8a8d939e61 (patch) | |
tree | feb35473da45947378fbc02defe39bcd79ef600e /io.c | |
parent | 9c5b1986a36c7a700b4c76817e35aa874ba7907c (diff) |
This commit was generated by cvs2svn to compensate for changes in r372,
which included commits to RCS files with non-trunk default branches.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 1562 |
1 files changed, 998 insertions, 564 deletions
@@ -6,12 +6,13 @@ $Date$ created at: Fri Oct 15 18:08:59 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ #include "ruby.h" -#include "io.h" +#include "rubyio.h" +#include "rubysig.h" #include <ctype.h> #include <errno.h> @@ -39,10 +40,6 @@ struct timeval { #include <sys/stat.h> -#if defined(DJGPP) || defined(__CYGWIN32__) || defined(NT) || defined(__human68k__) -#include <fcntl.h> -#endif - #ifdef HAVE_SYS_PARAM_H # include <sys/param.h> #else @@ -53,29 +50,43 @@ struct timeval { #include <unistd.h> #endif -VALUE rb_ad_string(); +#ifdef USE_CWGUSI + #include <sys/errno.h> + #include <unix.mac.h> + #include <compat.h> +#endif +extern void Init_File _((void)); + +#ifdef __BEOS__ +#include <net/socket.h> +#endif + +#include "util.h" -VALUE cIO; -extern VALUE cFile; -VALUE eEOFError; -VALUE eIOError; +VALUE rb_cIO; +VALUE rb_eEOFError; +VALUE rb_eIOError; VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout; -VALUE FS, OFS; -VALUE RS, ORS; -VALUE RS_default; +VALUE rb_fs; +VALUE rb_output_fs; +VALUE rb_rs; +VALUE rb_output_rs; +VALUE rb_default_rs; static VALUE argf; -ID id_write; +static ID id_write; -VALUE lastline_get(); -void lastline_set(); +extern char *ruby_inplace_mode; -extern char *inplace; +struct timeval rb_time_timeval _((VALUE)); -struct timeval time_timeval(); +static VALUE filename, file; +static int gets_lineno; +static int init_p = 0, next_p = 0; +static VALUE lineno; #ifdef _STDIO_USES_IOSTREAM /* GNU libc */ # ifdef _IO_fpos_t @@ -83,86 +94,89 @@ struct timeval time_timeval(); # else # define READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr) # endif +#elif defined(FILE_COUNT) +# define READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0) +#elif defined(__BEOS__) +# define ReadDataPending(fp) (fp->_state._eof == 0) +#elif defined(USE_CWGUSI) +# define ReadDataPending(fp) (fp->state.eof == 0) #else -# ifdef FILE_COUNT -# define READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0) -# else /* requires systems own version of the ReadDataPending() */ extern int ReadDataPending(); -# define READ_DATA_PENDING(fp) ReadDataPending(fp) -# endif +# define READ_DATA_PENDING(fp) ReadDataPending(fp) #endif -#ifndef THREAD +#ifndef USE_THREAD # define READ_CHECK(fp) 0 #else # define READ_CHECK(fp) do {\ - if (!READ_DATA_PENDING(fp)) thread_wait_fd(fileno(fp));\ + if (!READ_DATA_PENDING(fp)) rb_thread_wait_fd(fileno(fp));\ } while(0) #endif void -eof_error() +rb_eof_error() { - Raise(eEOFError, "End of file reached"); + rb_raise(rb_eEOFError, "End of file reached"); } void -io_writable(fptr) +rb_io_check_closed(fptr) OpenFile *fptr; { - if (!(fptr->mode & FMODE_WRITABLE)) { - Raise(eIOError, "not opened for writing"); - } + if (fptr->f == NULL && fptr->f2 == NULL) + rb_raise(rb_eIOError, "closed stream"); } void -io_readable(fptr) +rb_io_check_readable(fptr) OpenFile *fptr; { if (!(fptr->mode & FMODE_READABLE)) { - Raise(eIOError, "not opened for reading"); + rb_raise(rb_eIOError, "not opened for reading"); } } -static void -closed() +void +rb_io_check_writable(fptr) + OpenFile *fptr; { - Raise(eIOError, "closed stream"); + if (!(fptr->mode & FMODE_WRITABLE)) { + rb_raise(rb_eIOError, "not opened for writing"); + } } /* writing functions */ VALUE -io_write(io, str) +rb_io_write(io, str) VALUE io, str; { OpenFile *fptr; FILE *f; int n; + rb_secure(4); if (TYPE(str) != T_STRING) - str = obj_as_string(str); + str = rb_obj_as_string(str); if (RSTRING(str)->len == 0) return INT2FIX(0); if (BUILTIN_TYPE(io) != T_FILE) { + /* port is not IO, call write method for it. */ return rb_funcall(io, id_write, 1, str); } - rb_secure(4); GetOpenFile(io, fptr); - io_writable(fptr); - + rb_io_check_writable(fptr); f = GetWriteFile(fptr); - if (f == NULL) closed(); #ifdef __human68k__ { - register UCHAR *ptr = str->ptr; - n = (int) str->len; + register char *ptr = RSTRING(str)->ptr; + n = (int)RSTRING(str)->len; while (--n >= 0) if (fputc(*ptr++, f) == EOF) rb_sys_fail(fptr->path); - n = ptr - str->ptr; + n = ptr - RSTRING(str)->ptr; } if (ferror(f)) rb_sys_fail(fptr->path); @@ -180,24 +194,23 @@ io_write(io, str) } static VALUE -io_addstr(io, str) +rb_io_addstr(io, str) VALUE io, str; { - io_write(io, str); + rb_io_write(io, str); return io; } static VALUE -io_flush(io) +rb_io_flush(io) VALUE io; { OpenFile *fptr; FILE *f; GetOpenFile(io, fptr); - io_writable(fptr); + rb_io_check_writable(fptr); f = GetWriteFile(fptr); - if (f == NULL) closed(); if (fflush(f) == EOF) rb_sys_fail(0); @@ -205,42 +218,108 @@ io_flush(io) } static VALUE -io_eof(io) +rb_io_tell(io) + VALUE io; +{ + OpenFile *fptr; + long pos; + + GetOpenFile(io, fptr); + pos = ftell(fptr->f); + if (ferror(fptr->f) != 0) rb_sys_fail(fptr->path); + + return rb_int2inum(pos); +} + +static VALUE +rb_io_seek(io, offset, ptrname) + VALUE io, offset, ptrname; +{ + OpenFile *fptr; + long pos; + + GetOpenFile(io, fptr); + pos = fseek(fptr->f, NUM2INT(offset), NUM2INT(ptrname)); + if (pos != 0) rb_sys_fail(fptr->path); + clearerr(fptr->f); + + return INT2FIX(0); +} + +#ifndef SEEK_CUR +# define SEEK_SET 0 +# define SEEK_CUR 1 +# define SEEK_END 2 +#endif + +static VALUE +rb_io_set_pos(io, offset) + VALUE io, offset; +{ + OpenFile *fptr; + long pos; + + GetOpenFile(io, fptr); + pos = fseek(fptr->f, NUM2INT(offset), SEEK_SET); + if (pos != 0) rb_sys_fail(fptr->path); + clearerr(fptr->f); + + return INT2NUM(pos); +} + +static VALUE +rb_io_rewind(io) + VALUE io; +{ + OpenFile *fptr; + + GetOpenFile(io, fptr); + if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(fptr->path); + clearerr(fptr->f); + + return INT2FIX(0); +} + +VALUE +rb_io_eof(io) VALUE io; { OpenFile *fptr; int ch; GetOpenFile(io, fptr); - io_readable(fptr); - if (fptr->f == NULL) closed(); - - if (READ_DATA_PENDING(fptr->f)) return FALSE; - if (feof(fptr->f)) return TRUE; + rb_io_check_readable(fptr); + if (READ_DATA_PENDING(fptr->f)) return Qfalse; +#if 0 + if (feof(fptr->f)) return Qtrue; + return Qfalse; +#else + READ_CHECK(fptr->f); TRAP_BEG; ch = getc(fptr->f); TRAP_END; if (ch != EOF) { - (void)ungetc(ch, fptr->f); - return FALSE; + ungetc(ch, fptr->f); + return Qfalse; } - return TRUE; + return Qtrue; +#endif } static VALUE -io_sync(io) +rb_io_sync(io) VALUE io; { OpenFile *fptr; GetOpenFile(io, fptr); - return (fptr->mode & FMODE_SYNC) ? TRUE : FALSE; + return (fptr->mode & FMODE_SYNC) ? Qtrue : Qfalse; } static VALUE -io_set_sync(io, mode) +rb_io_set_sync(io, mode) VALUE io, mode; { OpenFile *fptr; @@ -256,7 +335,7 @@ io_set_sync(io, mode) } static VALUE -io_fileno(io) +rb_io_fileno(io) VALUE io; { OpenFile *fptr; @@ -267,6 +346,13 @@ io_fileno(io) return INT2FIX(fd); } +static VALUE +rb_io_to_io(io) + VALUE io; +{ + return io; +} + /* reading functions */ #ifndef S_ISREG @@ -281,45 +367,52 @@ read_all(port) { OpenFile *fptr; VALUE str = Qnil; - char *buf; struct stat st; - int siz = BUFSIZ; - int bytes = 0; + long siz = BUFSIZ; + long bytes = 0; int n; GetOpenFile(port, fptr); - io_readable(fptr); - if (fptr->f == NULL) closed(); + rb_io_check_readable(fptr); - if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode)) { - if (st.st_size == 0) return Qnil; + if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode) +#ifdef __BEOS__ + && (st.st_dev > 3) +#endif + ) + { + if (st.st_size == 0) return rb_str_new(0, 0); else { - int pos = ftell(fptr->f); + long pos = ftell(fptr->f); if (st.st_size > pos && pos >= 0) { siz = st.st_size - pos + 1; } } } - str = str_new(0, siz); + str = rb_str_new(0, siz); for (;;) { READ_CHECK(fptr->f); TRAP_BEG; n = fread(RSTRING(str)->ptr+bytes, 1, siz-bytes, fptr->f); TRAP_END; - if (n == 0) break; - if (n < 0) rb_sys_fail(fptr->path); + if (n <= 0) { + if (ferror(fptr->f)) rb_sys_fail(fptr->path); + return rb_str_new(0,0); + } bytes += n; - if (bytes < siz) break; + if (bytes < siz) break; siz += BUFSIZ; - str_resize(str, siz); + rb_str_resize(str, siz); } - if (bytes == 0) return Qnil; - if (bytes != siz) str_resize(str, bytes); - return str_taint(str); + if (bytes == 0) return rb_str_new(0,0); + if (bytes != siz) rb_str_resize(str, bytes); + OBJ_TAINT(str); + + return str; } static VALUE -io_read(argc, argv, io) +rb_io_read(argc, argv, io) int argc; VALUE *argv; VALUE io; @@ -328,36 +421,34 @@ io_read(argc, argv, io) int n, len; VALUE length, str; - if (rb_scan_args(argc, argv, "01", &length) == 0) { + rb_scan_args(argc, argv, "01", &length); + if (NIL_P(length)) { return read_all(io); } len = NUM2INT(length); GetOpenFile(io, fptr); - io_readable(fptr); - if (fptr->f == NULL) closed(); + rb_io_check_readable(fptr); - str = str_new(0, len); + str = rb_str_new(0, len); READ_CHECK(fptr->f); TRAP_BEG; n = fread(RSTRING(str)->ptr, 1, len, fptr->f); TRAP_END; - if (n == 0) return Qnil; - if (n < 0) { - rb_sys_fail(fptr->path); + if (n <= 0) { + if (ferror(fptr->f)) rb_sys_fail(fptr->path); + return Qnil; } - RSTRING(str)->len = n; RSTRING(str)->ptr[n] = '\0'; + OBJ_TAINT(str); - return str_taint(str); + return str; } -static VALUE lineno; - -VALUE -io_gets_method(argc, argv, io) +static VALUE +rb_io_gets_internal(argc, argv, io) int argc; VALUE *argv; VALUE io; @@ -370,33 +461,36 @@ io_gets_method(argc, argv, io) int rslen, rspara = 0; VALUE rs; - if (argc == 0) rs = RS; + if (argc == 0) { + rs = rb_rs; + } else { rb_scan_args(argc, argv, "1", &rs); if (!NIL_P(rs)) Check_Type(rs, T_STRING); } - GetOpenFile(io, fptr); - io_readable(fptr); - f = fptr->f; - if (f == NULL) closed(); - - if (!NIL_P(rs)) { + if (NIL_P(rs)) { + rsptr = 0; + rslen = 0; + } + else { rslen = RSTRING(rs)->len; if (rslen == 0) { rsptr = "\n\n"; rslen = 2; rspara = 1; } + else if (rslen == 1 && RSTRING(rs)->ptr[0] == '\n') { + return rb_io_gets(io); + } else { rsptr = RSTRING(rs)->ptr; } } - else { - rsptr = 0; - rslen = 0; - } - newline = rslen ? rsptr[rslen - 1] : 0777; + + GetOpenFile(io, fptr); + rb_io_check_readable(fptr); + f = fptr->f; if (rspara) { do { @@ -411,6 +505,7 @@ io_gets_method(argc, argv, io) } while (c != EOF); } + newline = rslen ? rsptr[rslen - 1] : 0777; { char buf[8192]; char *bp, *bpe = buf + sizeof buf - 3; @@ -426,7 +521,10 @@ io_gets_method(argc, argv, io) TRAP_BEG; c = getc(f); TRAP_END; - if (c == EOF) break; + if (c == EOF) { + if (errno == EINTR) continue; + break; + } if ((*bp++ = c) == newline) break; if (bp == bpe) break; } @@ -437,25 +535,29 @@ io_gets_method(argc, argv, io) TRAP_BEG; cnt = fread(buf, 1, sizeof(buf), f); TRAP_END; - c = cnt ? 0 : EOF; + if (cnt == 0) { + if (ferror(f)) rb_sys_fail(fptr->path); + c = EOF; + } + else { + c = 0; + } } - if (c == EOF) { - if (!append && cnt == 0) { - str = Qnil; - goto return_gets; - } + if (c == EOF && !append && cnt == 0) { + str = Qnil; + goto return_gets; } if (append) - str_cat(str, buf, cnt); + rb_str_cat(str, buf, cnt); else - str = str_new(buf, cnt); + str = rb_str_new(buf, cnt); if (c != EOF && (!rslen || RSTRING(str)->len < rslen || - memcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen, rsptr, rslen))) { + memcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen,rsptr,rslen))) { append = 1; goto again; } @@ -478,65 +580,161 @@ io_gets_method(argc, argv, io) if (!NIL_P(str)) { fptr->lineno++; lineno = INT2FIX(fptr->lineno); - str_taint(str); + OBJ_TAINT(str); } - lastline_set(str); return str; } VALUE -io_gets(io) +rb_io_gets(io) VALUE io; { - return io_gets_method(0, 0, io); + OpenFile *fptr; + FILE *f; + VALUE str = Qnil; + int c; + char buf[8192]; + char *bp, *bpe = buf + sizeof buf - 3; + int cnt; + int append = 0; + + GetOpenFile(io, fptr); + rb_io_check_readable(fptr); + f = fptr->f; + + again: + bp = buf; + for (;;) { + READ_CHECK(f); + TRAP_BEG; + c = getc(f); + TRAP_END; + if (c == EOF) { + if (errno == EINTR) continue; + break; + } + if ((*bp++ = c) == '\n') break; + if (bp == bpe) break; + } + cnt = bp - buf; + + if (c == EOF && !append && cnt == 0) { + str = Qnil; + goto return_gets; + } + + if (append) + rb_str_cat(str, buf, cnt); + else + str = rb_str_new(buf, cnt); + + if (c != EOF && RSTRING(str)->ptr[RSTRING(str)->len-1] != '\n') { + append = 1; + goto again; + } + + return_gets: + if (!NIL_P(str)) { + fptr->lineno++; + lineno = INT2FIX(fptr->lineno); + OBJ_TAINT(str); + } + + return str; } static VALUE -io_readline(argc, argv, io) +rb_io_gets_method(argc, argv, io) int argc; VALUE *argv; VALUE io; { - VALUE line = io_gets_method(argc, argv, io); + VALUE str = rb_io_gets_internal(argc, argv, io); + + if (!NIL_P(str)) { + rb_lastline_set(str); + } + return str; +} + +static VALUE +rb_io_lineno(io) + VALUE io; +{ + OpenFile *fptr; + + GetOpenFile(io, fptr); + rb_io_check_readable(fptr); + return INT2NUM(fptr->lineno); +} + +static VALUE +rb_io_set_lineno(io, lineno) + VALUE io, lineno; +{ + OpenFile *fptr; + + GetOpenFile(io, fptr); + rb_io_check_readable(fptr); + return fptr->lineno = NUM2INT(lineno); +} + +static void +lineno_setter(val, id, var) + VALUE val; + ID id; + VALUE *var; +{ + gets_lineno = NUM2INT(val); + *var = INT2FIX(gets_lineno); +} + +static VALUE +rb_io_readline(argc, argv, io) + int argc; + VALUE *argv; + VALUE io; +{ + VALUE line = rb_io_gets_method(argc, argv, io); if (NIL_P(line)) { - eof_error(); + rb_eof_error(); } return line; } static VALUE -io_readlines(argc, argv, io) +rb_io_readlines(argc, argv, io) int argc; VALUE *argv; VALUE io; { VALUE line, ary; - ary = ary_new(); - while (!NIL_P(line = io_gets_method(argc, argv, io))) { - ary_push(ary, line); + ary = rb_ary_new(); + while (!NIL_P(line = rb_io_gets_internal(argc, argv, io))) { + rb_ary_push(ary, line); } return ary; } static VALUE -io_each_line(argc, argv, io) +rb_io_each_line(argc, argv, io) int argc; VALUE *argv; VALUE io; { VALUE str; - while (!NIL_P(str = io_gets_method(argc, argv, io))) { + while (!NIL_P(str = rb_io_gets_internal(argc, argv, io))) { rb_yield(str); } return Qnil; } static VALUE -io_each_byte(io) +rb_io_each_byte(io) VALUE io; { OpenFile *fptr; @@ -544,9 +742,8 @@ io_each_byte(io) int c; GetOpenFile(io, fptr); - io_readable(fptr); + rb_io_check_readable(fptr); f = fptr->f; - if (f == NULL) closed(); for (;;) { READ_CHECK(f); @@ -561,7 +758,7 @@ io_each_byte(io) } VALUE -io_getc(io) +rb_io_getc(io) VALUE io; { OpenFile *fptr; @@ -569,9 +766,8 @@ io_getc(io) int c; GetOpenFile(io, fptr); - io_readable(fptr); + rb_io_check_readable(fptr); f = fptr->f; - if (f == NULL) closed(); READ_CHECK(f); TRAP_BEG; @@ -586,27 +782,26 @@ io_getc(io) } static VALUE -io_readchar(io) +rb_io_readchar(io) VALUE io; { - VALUE c = io_getc(io); + VALUE c = rb_io_getc(io); if (NIL_P(c)) { - eof_error(); + rb_eof_error(); } return c; } VALUE -io_ungetc(io, c) +rb_io_ungetc(io, c) VALUE io, c; { OpenFile *fptr; Check_Type(c, T_FIXNUM); GetOpenFile(io, fptr); - io_readable(fptr); - if (fptr->f == NULL) closed(); + rb_io_check_readable(fptr); if (ungetc(FIX2INT(c), fptr->f) == EOF) rb_sys_fail(fptr->path); @@ -614,16 +809,15 @@ io_ungetc(io, c) } static VALUE -io_isatty(io) +rb_io_isatty(io) VALUE io; { OpenFile *fptr; GetOpenFile(io, fptr); - if (fptr->f == NULL) closed(); if (isatty(fileno(fptr->f)) == 0) - return FALSE; - return TRUE; + return Qfalse; + return Qtrue; } static void @@ -636,23 +830,20 @@ fptr_finalize(fptr) if (fptr->f2 != NULL) { fclose(fptr->f2); } - if (fptr->path) { - free(fptr->path); - fptr->path = NULL; - } if (fptr->pid) { rb_syswait(fptr->pid); fptr->pid = 0; } } -void -io_fptr_finalize(fptr) +static void +rb_io_fptr_close(fptr) OpenFile *fptr; { + if (fptr->f == NULL && fptr->f2 == NULL) return; + if (fptr->finalize) { (*fptr->finalize)(fptr); - fptr->finalize = 0; } else { fptr_finalize(fptr); @@ -660,30 +851,93 @@ io_fptr_finalize(fptr) fptr->f = fptr->f2 = NULL; } +void +rb_io_fptr_finalize(fptr) + OpenFile *fptr; +{ + rb_io_fptr_close(fptr); + if (fptr->path) { + free(fptr->path); + fptr->path = NULL; + } +} + +VALUE +rb_io_close(io) + VALUE io; +{ + OpenFile *fptr; + + GetOpenFile(io, fptr); + rb_io_fptr_close(fptr); + + return Qnil; +} + +static VALUE +rb_io_close_method(io) + VALUE io; +{ + rb_secure(4); + rb_io_close(io); + return Qnil; +} + +static VALUE +rb_io_closed(io) + VALUE io; +{ + OpenFile *fptr; + + fptr = RFILE(io)->fptr; + return (fptr->f || fptr->f2)?Qfalse:Qtrue; +} + VALUE -io_close(io) +rb_io_close_read(io) VALUE io; { OpenFile *fptr; + rb_secure(4); GetOpenFile(io, fptr); - io_fptr_finalize(fptr); + if (fptr->f2 == 0 && (fptr->mode & FMODE_WRITABLE)) { + rb_raise(rb_eIOError, "closing non-duplex IO for reading"); + } + if (fptr->f2 == 0) { + return rb_io_close(io); + } + fclose(fptr->f); + fptr->mode &= ~FMODE_READABLE; + fptr->f = fptr->f2; + fptr->f2 = 0; return Qnil; } static VALUE -io_closed(io) +rb_io_close_write(io) VALUE io; { OpenFile *fptr; + rb_secure(4); GetOpenFile(io, fptr); - return fptr->f?FALSE:TRUE; + if (fptr->f2 == 0 && (fptr->mode & FMODE_READABLE)) { + rb_raise(rb_eIOError, "closing non-duplex IO for writing"); + } + if (fptr->f2 == 0) { + return rb_io_close(io); + } + fclose(fptr->f2); + fptr->f2 = 0; + fptr->mode &= ~FMODE_WRITABLE; + + return Qnil; } static VALUE -io_syswrite(io, str) +rb_io_syswrite(io, str) VALUE io, str; { OpenFile *fptr; @@ -692,15 +946,14 @@ io_syswrite(io, str) rb_secure(4); if (TYPE(str) != T_STRING) - str = obj_as_string(str); + str = rb_obj_as_string(str); GetOpenFile(io, fptr); - io_writable(fptr); + rb_io_check_writable(fptr); f = GetWriteFile(fptr); - if (f == NULL) closed(); -#ifdef THREAD - thread_fd_writable(fileno(f)); +#ifdef USE_THREAD + rb_thread_fd_writable(fileno(f)); #endif n = write(fileno(f), RSTRING(str)->ptr, RSTRING(str)->len); @@ -710,7 +963,7 @@ io_syswrite(io, str) } static VALUE -io_sysread(io, len) +rb_io_sysread(io, len) VALUE io, len; { OpenFile *fptr; @@ -719,44 +972,52 @@ io_sysread(io, len) ilen = NUM2INT(len); GetOpenFile(io, fptr); - io_readable(fptr); - if (fptr->f == NULL) closed(); + rb_io_check_readable(fptr); - str = str_new(0, ilen); + str = rb_str_new(0, ilen); -#ifdef THREAD - thread_wait_fd(fileno(fptr->f)); +#ifdef USE_THREAD + rb_thread_wait_fd(fileno(fptr->f)); #endif TRAP_BEG; n = read(fileno(fptr->f), RSTRING(str)->ptr, RSTRING(str)->len); TRAP_END; if (n == -1) rb_sys_fail(fptr->path); - if (n == 0) eof_error(); + if (n == 0) rb_eof_error(); RSTRING(str)->len = n; RSTRING(str)->ptr[n] = '\0'; - return str_taint(str); + OBJ_TAINT(str); + + return str; } VALUE -io_binmode(io) +rb_io_binmode(io) VALUE io; { -#if defined(NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__) +#if defined(NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__) || defined(USE_CWGUSI) OpenFile *fptr; GetOpenFile(io, fptr); #ifdef __human68k__ if (fptr->f) fmode(fptr->f, _IOBIN); - if (fptr->f2); + if (fptr->f2) fmode(fptr->f2, _IOBIN); #else +# ifndef USE_CWGUSI if (fptr->f && setmode(fileno(fptr->f), O_BINARY) == -1) rb_sys_fail(fptr->path); if (fptr->f2 && setmode(fileno(fptr->f2), O_BINARY) == -1) rb_sys_fail(fptr->path); +# else /* USE_CWGUSI */ + if (fptr->f) + fptr->f->mode.binrb_ary_io = 1; + if (fptr->f2) + fptr->f2->mode.binrb_ary_io = 1; +# endif /* USE_CWGUSI */ #endif fptr->mode |= FMODE_BINMODE; @@ -765,7 +1026,7 @@ io_binmode(io) } int -io_mode_flags(mode) +rb_io_mode_flags(mode) char *mode; { int flags = 0; @@ -781,7 +1042,7 @@ io_mode_flags(mode) flags |= FMODE_WRITABLE; break; default: - ArgError("illegal access mode"); + rb_raise(rb_eArgError, "illegal access mode"); } if (mode[1] == 'b') { @@ -806,7 +1067,7 @@ rb_fopen(fname, mode) f = fopen(fname, mode); if (f == NULL) { if (errno == EMFILE || errno == ENFILE) { - gc_gc(); + rb_gc(); f = fopen(fname, mode); } if (f == NULL) { @@ -862,6 +1123,7 @@ pipe_del_fptr(fptr) if (list->fptr == fptr) { pipe_list = list->next; + free(list); return; } @@ -880,18 +1142,20 @@ static void pipe_atexit() { struct pipe_list *list = pipe_list; + struct pipe_list *tmp; while (list) { - io_fptr_finalize(list->fptr); - list = list->next; + tmp = list->next; + rb_io_fptr_finalize(list->fptr); + list = tmp; } } -#if !defined (__CYGWIN32__) static void pipe_finalize(fptr) OpenFile *fptr; { +#if !defined (__CYGWIN32__) if (fptr->f != NULL) { pclose(fptr->f); } @@ -899,16 +1163,18 @@ pipe_finalize(fptr) pclose(fptr->f2); } fptr->f = fptr->f2 = NULL; +#else + fptr_finalize(fptr); +#endif pipe_del_fptr(fptr); } #endif -#endif void -io_unbuffered(fptr) +rb_io_unbuffered(fptr) OpenFile *fptr; { - if (fptr->f2 == 0) TypeError("non-writable fptr"); + if (fptr->f2 == 0) rb_raise(rb_eTypeError, "non-writable fptr"); if (fptr->f != 0) setbuf(fptr->f, NULL); setbuf(fptr->f2, NULL); fptr->mode |= FMODE_SYNC; @@ -918,7 +1184,8 @@ static VALUE pipe_open(pname, mode) char *pname, *mode; { - int modef = io_mode_flags(mode); +#ifndef USE_CWGUSI + int modef = rb_io_mode_flags(mode); OpenFile *fptr; #if defined(NT) || defined(DJGPP) || defined(__human68k__) @@ -927,7 +1194,7 @@ pipe_open(pname, mode) if (f == NULL) rb_sys_fail(pname); else { NEWOBJ(port, struct RFile); - OBJSETUP(port, cIO, T_FILE); + OBJSETUP(port, rb_cIO, T_FILE); MakeOpenFile(port, fptr); fptr->finalize = pipe_finalize; fptr->mode = modef; @@ -936,8 +1203,9 @@ pipe_open(pname, mode) if (modef & FMODE_READABLE) fptr->f = f; if (modef & FMODE_WRITABLE) { fptr->f2 = f; - io_unbuffered(fptr); + rb_io_unbuffered(fptr); } + rb_obj_call_init((VALUE)port); return (VALUE)port; } #else @@ -974,23 +1242,23 @@ pipe_open(pname, mode) } if (doexec) { - extern char *sourcefile; - extern int sourceline; + extern char *ruby_sourcefile; + extern int ruby_sourceline; int fd; for (fd = 3; fd < NOFILE; fd++) close(fd); rb_proc_exec(pname); fprintf(stderr, "%s:%d: command not found: %s\n", - sourcefile, sourceline, pname); + ruby_sourcefile, ruby_sourceline, pname); _exit(127); } return Qnil; case -1: /* fork failed */ if (errno == EAGAIN) { -#ifdef THREAD - thread_sleep(1); +#ifdef USE_THREAD + rb_thread_sleep(1); #else sleep(1); #endif @@ -1001,9 +1269,10 @@ pipe_open(pname, mode) break; default: /* parent */ - { + if (pid < 0) rb_sys_fail(pname); + else { NEWOBJ(port, struct RFile); - OBJSETUP(port, cIO, T_FILE); + OBJSETUP(port, rb_cIO, T_FILE); MakeOpenFile(port, fptr); fptr->mode = modef; fptr->mode |= FMODE_SYNC; @@ -1021,16 +1290,22 @@ pipe_open(pname, mode) else fptr->f = f; } #if defined (__CYGWIN32__) + fptr->finalize = pipe_finalize; pipe_add_fptr(fptr); #endif + rb_obj_call_init((VALUE)port); return (VALUE)port; } } #endif +#else /* USE_CWGUSI */ + rb_notimplement(); + return Qnil; /* not reached */ +#endif } static VALUE -io_s_popen(argc, argv, self) +rb_io_s_popen(argc, argv, self) int argc; VALUE *argv; VALUE self; @@ -1038,34 +1313,35 @@ io_s_popen(argc, argv, self) char *mode; VALUE pname, pmode; - rb_scan_args(argc, argv, "11", &pname, &pmode); - Check_SafeStr(pname); - if (NIL_P(pmode)) { + if (rb_scan_args(argc, argv, "11", &pname, &pmode) == 1) { mode = "r"; } else { - Check_Type(pmode, T_STRING); - if (RSTRING(pmode)->len == 0 || RSTRING(pmode)->len > 3) - ArgError("illegal access mode"); - mode = RSTRING(pmode)->ptr; - } + int len; + + mode = STR2CSTR(pmode); + len = strlen(mode); + if (len == 0 || len > 3) + rb_raise(rb_eArgError, "illegal access mode"); + } + Check_SafeStr(pname); return pipe_open(RSTRING(pname)->ptr, mode); } static VALUE -io_open(fname, mode) +rb_io_open(fname, mode) char *fname, *mode; { if (fname[0] == '|') { return pipe_open(fname+1, mode); } else { - return file_open(fname, mode); + return rb_file_open(fname, mode); } } static VALUE -f_open(argc, argv) +rb_f_open(argc, argv) int argc; VALUE *argv; { @@ -1079,26 +1355,31 @@ f_open(argc, argv) mode = "r"; } else { - Check_Type(pmode, T_STRING); - if (RSTRING(pmode)->len == 0 || RSTRING(pmode)->len > 3) - ArgError("illegal access mode"); - mode = RSTRING(pmode)->ptr; + int len; + + mode = STR2CSTR(pmode); + len = strlen(mode); + if (len == 0 || len > 3) + rb_raise(rb_eArgError, "illegal access mode"); } - port = io_open(RSTRING(pname)->ptr, mode); - if (iterator_p()) { - rb_ensure(rb_yield, port, io_close, port); + port = rb_io_open(RSTRING(pname)->ptr, mode); + if (rb_iterator_p()) { + return rb_ensure(rb_yield, port, rb_io_close, port); } return port; } -#ifndef NT -extern char *strdup(); -#endif +static VALUE +rb_io_get_io(io) + VALUE io; +{ + return rb_convert_type(io, T_FILE, "IO", "to_io"); +} static char* -io_mode_string(fptr) +rb_io_mode_string(fptr) OpenFile *fptr; { switch (fptr->mode & FMODE_READWRITE) { @@ -1110,19 +1391,19 @@ io_mode_string(fptr) case FMODE_READWRITE: return "r+"; } - return "r"; } VALUE -io_reopen(io, nfile) +rb_io_reopen(io, nfile) VALUE io, nfile; { OpenFile *fptr, *orig; char *mode; int fd; + rb_secure(4); GetOpenFile(io, fptr); - Check_Type(nfile, T_FILE); + nfile = rb_io_get_io(nfile); GetOpenFile(nfile, orig); if (orig->f2) { @@ -1141,20 +1422,27 @@ io_reopen(io, nfile) else fptr->path = 0; fptr->finalize = orig->finalize; - mode = io_mode_string(fptr); + mode = rb_io_mode_string(fptr); fd = fileno(fptr->f); - if (fileno(fptr->f) < 3) /* need to keep stdio */ + if (fd < 3) { + /* need to keep stdio */ + if (dup2(fileno(orig->f), fd) < 0) + rb_sys_fail(orig->path); + } + else { fclose(fptr->f); - dup2(fileno(orig->f), fd); - fptr->f = rb_fdopen(fd, mode); + if (dup2(fileno(orig->f), fd) < 0) + rb_sys_fail(orig->path); + fptr->f = rb_fdopen(fd, mode); + } if (fptr->f2) { fd = fileno(fptr->f2); - if (fileno(fptr->f2) < 3) - fclose(fptr->f2); + fclose(fptr->f2); if (orig->f2) { - dup2(fileno(orig->f2), fd); - fptr->f = rb_fdopen(fd, "w"); + if (dup2(fileno(orig->f2), fd) < 0) + rb_sys_fail(orig->path); + fptr->f2 = rb_fdopen(fd, "w"); } else { fptr->f2 = 0; @@ -1162,15 +1450,15 @@ io_reopen(io, nfile) } if (fptr->mode & FMODE_BINMODE) { - io_binmode(io); + rb_io_binmode(io); } - RBASIC(io)->class = RBASIC(nfile)->class; + RBASIC(io)->klass = RBASIC(nfile)->klass; return io; } static VALUE -io_clone(io) +rb_io_clone(io) VALUE io; { OpenFile *fptr, *orig; @@ -1215,25 +1503,25 @@ io_clone(io) fptr->f = rb_fdopen(fd, "w"); } if (fptr->mode & FMODE_BINMODE) { - io_binmode((VALUE)obj); + rb_io_binmode((VALUE)obj); } return (VALUE)obj; } static VALUE -io_printf(argc, argv, out) +rb_io_printf(argc, argv, out) int argc; VALUE argv[]; VALUE out; { - rb_funcall(out, id_write, 1, f_sprintf(argc, argv)); + rb_funcall(out, id_write, 1, rb_f_sprintf(argc, argv)); return Qnil; } static VALUE -f_printf(argc, argv) +rb_rb_f_printf(argc, argv) int argc; VALUE argv[]; { @@ -1249,97 +1537,134 @@ f_printf(argc, argv) argc--; } else { - NameError("output must responds to `write'"); + rb_raise(rb_eNameError, "output must responds to `write'"); } - rb_funcall(out, id_write, 1, f_sprintf(argc, argv)); + rb_funcall(out, id_write, 1, rb_f_sprintf(argc, argv)); return Qnil; } static VALUE -io_print(argc, argv, out) +rb_io_print(argc, argv, out) int argc; VALUE *argv; VALUE out; { - int i, j; + int i; VALUE line; /* if no argument given, print `$_' */ if (argc == 0) { argc = 1; - line = lastline_get(); + line = rb_lastline_get(); argv = &line; } for (i=0; i<argc; i++) { - if (!NIL_P(OFS) && i>0) { - io_write(out, OFS); + if (!NIL_P(rb_output_fs) && i>0) { + rb_io_write(out, rb_output_fs); } switch (TYPE(argv[i])) { case T_NIL: - io_write(out, str_new2("nil")); - break; - case T_ARRAY: - for (j=0; j<RARRAY(argv[i])->len; j++) { - if (!NIL_P(OFS) && j>0) { - io_write(out, OFS); - } - io_write(out, RARRAY(argv[i])->ptr[j]); - } + rb_io_write(out, rb_str_new2("nil")); break; default: - io_write(out, argv[i]); + rb_io_write(out, argv[i]); break; } } - if (!NIL_P(ORS)) { - io_write(out, ORS); + if (!NIL_P(rb_output_rs)) { + rb_io_write(out, rb_output_rs); } return Qnil; } static VALUE -f_print(argc, argv) +rb_f_print(argc, argv) int argc; VALUE *argv; { - io_print(argc, argv, rb_defout); + rb_io_print(argc, argv, rb_defout); + return Qnil; +} + +static VALUE +rb_io_putc(io, ch) + VALUE io, ch; +{ + OpenFile *fptr; + FILE *f; + int c = NUM2CHR(ch); + + rb_secure(4); + GetOpenFile(io, fptr); + rb_io_check_writable(fptr); + f = GetWriteFile(fptr); + + if (fputc(c, f) == EOF || ferror(f)) + rb_sys_fail(fptr->path); + if (fptr->mode & FMODE_SYNC) + fflush(f); + + return ch; +} + +static VALUE +rb_f_putc(recv, ch) + VALUE recv, ch; +{ + return rb_io_putc(rb_defout, ch); +} + +static VALUE rb_io_puts _((int, VALUE*, VALUE)); + +static VALUE +io_puts_ary(ary, out) + VALUE ary, out; +{ + VALUE tmp; + int i; + + for (i=0; i<RARRAY(ary)->len; i++) { + tmp = RARRAY(ary)->ptr[i]; + if (rb_inspecting_p(tmp)) { + tmp = rb_str_new2("[...]"); + } + rb_io_puts(1, &tmp, out); + } return Qnil; } static VALUE -io_puts(argc, argv, out) +rb_io_puts(argc, argv, out) int argc; VALUE *argv; VALUE out; { - int i, j; + int i; VALUE line; /* if no argument given, print newline. */ if (argc == 0) { - io_write(out, str_new2("\n")); + rb_io_write(out, rb_default_rs); return Qnil; } for (i=0; i<argc; i++) { switch (TYPE(argv[i])) { case T_NIL: - line = str_new2("nil"); + line = rb_str_new2("nil"); break; case T_ARRAY: - for (j=0; j<RARRAY(argv[i])->len; j++) { - io_puts(1, &RARRAY(argv[i])->ptr[j], out); - } + rb_protect_inspect(io_puts_ary, argv[i], out); continue; default: line = argv[i]; break; } - line = obj_as_string(line); - io_write(out, line); + line = rb_obj_as_string(line); + rb_io_write(out, line); if (RSTRING(line)->ptr[RSTRING(line)->len-1] != '\n') { - io_write(out, str_new2("\n")); + rb_io_write(out, rb_default_rs); } } @@ -1347,122 +1672,127 @@ io_puts(argc, argv, out) } static VALUE -f_puts(argc, argv) +rb_f_puts(argc, argv) int argc; VALUE *argv; { - io_puts(argc, argv, rb_defout); + rb_io_puts(argc, argv, rb_defout); return Qnil; } +void +rb_p(obj) /* for debug print within C code */ + VALUE obj; +{ + obj = rb_obj_as_string(rb_inspect(obj)); + fwrite(RSTRING(obj)->ptr, 1, RSTRING(obj)->len, stdout); + obj = rb_default_rs; + fwrite(RSTRING(obj)->ptr, 1, RSTRING(obj)->len, stdout); +} + static VALUE -f_p(obj, val) - VALUE obj, val; +rb_f_p(argc, argv) + int argc; + VALUE *argv; { - VALUE str = rb_inspect(val); + int i; - Check_Type(str, T_STRING); - io_write(rb_defout, str); - io_write(rb_defout, str_new2("\n")); + for (i=0; i<argc; i++) { + rb_p(argv[i]); + } return Qnil; } -void -rb_p(obj) /* for debug print within C code */ - VALUE obj; +static VALUE +rb_obj_display(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; { - f_p(Qnil, obj); + VALUE out; + + if (rb_scan_args(argc, argv, "01", &out) == 0) { + out = rb_defout; + } + + rb_io_write(out, self); + + return Qnil; } static void -io_defset(val, id) +rb_io_defset(val, id) VALUE val; ID id; { if (TYPE(val) == T_STRING) { - val = io_open(RSTRING(val)->ptr, "w"); + val = rb_io_open(RSTRING(val)->ptr, "w"); } if (!rb_respond_to(val, id_write)) { - TypeError("$< must have write method, %s given", - rb_class2name(CLASS_OF(val))); + rb_raise(rb_eTypeError, "$< must have write method, %s given", + rb_class2name(CLASS_OF(val))); } rb_defout = val; } static void -io_errset(val, id) +rb_io_stdio_set(val, id, var) VALUE val; ID id; + VALUE *var; { OpenFile *fptr; int fd; if (TYPE(val) != T_FILE) { - TypeError("$stderr must be IO Object"); + rb_raise(rb_eTypeError, "%s must be IO object", rb_id2name(id)); } + GetOpenFile(*var, fptr); + fd = fileno(fptr->f); GetOpenFile(val, fptr); - io_writable(fptr); - rb_stderr = val; - - fd = fileno(fptr->f2?fptr->f2:fptr->f); - if (fd != 2) { - FILE *f; - - fflush(stderr); - dup2(fd, 2); - f = rb_fdopen(2, io_mode_string(fptr)); - if (fptr->f2) { - if (fileno(fptr->f2) < 3) /* need to keep stdio */ - fclose(fptr->f2); - fptr->f2 = f; - } - else { - if (fileno(fptr->f) < 3) - fclose(fptr->f); - fptr->f = f; - } + if (fd == 0) { + rb_io_check_readable(fptr); } + else { + rb_io_check_writable(fptr); + } + rb_io_reopen(*var, val); } static VALUE -prep_stdio(f, mode) +prep_stdio(f, mode, klass) FILE *f; int mode; + VALUE klass; { OpenFile *fp; - NEWOBJ(obj, struct RFile); - OBJSETUP(obj, cIO, T_FILE); + NEWOBJ(io, struct RFile); + OBJSETUP(io, klass, T_FILE); - MakeOpenFile(obj, fp); + MakeOpenFile(io, fp); fp->f = f; fp->mode = mode; + rb_obj_call_init((VALUE)io); - return (VALUE)obj; + return (VALUE)io; } static VALUE -io_s_new(argc, argv) +rb_io_s_new(argc, argv, klass) int argc; VALUE *argv; + VALUE klass; { VALUE fnum, mode; - FILE *f; char *m = "r"; - rb_scan_args(argc, argv, "11", &fnum, &mode); - - if (!NIL_P(mode)) { + if (rb_scan_args(argc, argv, "11", &fnum, &mode) == 2) { Check_SafeStr(mode); m = RSTRING(mode)->ptr; } - f = rb_fdopen(NUM2INT(fnum), m); - return prep_stdio(f, io_mode_flags(m)); + return prep_stdio(rb_fdopen(NUM2INT(fnum), m), rb_io_mode_flags(m), klass); } -static VALUE filename, file; -static int gets_lineno; -static int init_p = 0, next_p = 0; - static int next_argv() { @@ -1485,32 +1815,33 @@ next_argv() if (next_p == 1) { next_p = 0; if (RARRAY(rb_argv)->len > 0) { - filename = ary_shift(rb_argv); + filename = rb_ary_shift(rb_argv); fn = RSTRING(filename)->ptr; if (RSTRING(filename)->len == 1 && fn[0] == '-') { file = rb_stdin; - if (inplace) { + if (ruby_inplace_mode) { rb_defout = rb_stdout; } } else { FILE *fr = rb_fopen(fn, "r"); - if (inplace) { + if (ruby_inplace_mode) { struct stat st, st2; VALUE str; FILE *fw; if (TYPE(rb_defout) == T_FILE && rb_defout != rb_stdout) { - io_close(rb_defout); + rb_io_close(rb_defout); } fstat(fileno(fr), &st); - if (*inplace) { - str = str_new2(fn); + if (*ruby_inplace_mode) { + str = rb_str_new2(fn); #if defined(MSDOS) || defined(__CYGWIN32__) || defined(NT) - add_suffix(str, inplace); + ruby_add_suffix(str, ruby_inplace_mode); #else - str_cat(str, inplace, strlen(inplace)); + rb_str_cat(str, ruby_inplace_mode, + strlen(ruby_inplace_mode)); #endif #if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN32__) || defined(NT) || defined(__human68k__) (void)fclose(fr); @@ -1519,7 +1850,7 @@ next_argv() fr = rb_fopen(RSTRING(str)->ptr, "r"); #else if (rename(fn, RSTRING(str)->ptr) < 0) { - Warning("Can't rename %s to %s: %s, skipping file", + rb_warn("Can't rename %s to %s: %s, skipping file", fn, RSTRING(str)->ptr, strerror(errno)); fclose(fr); goto retry; @@ -1529,38 +1860,39 @@ next_argv() else { #if !defined(MSDOS) && !defined(__BOW__) && !defined(__CYGWIN32__) && !defined(NT) && !defined(__human68k__) if (unlink(fn) < 0) { - Warning("Can't remove %s: %s, skipping file", - fn, strerror(errno)); + rb_warn("Can't remove %s: %s, skipping file", + fn, strerror(errno)); fclose(fr); goto retry; } #else - Fatal("Can't do inplace edit without backup"); + rb_fatal("Can't do inplace edit without backup"); #endif } fw = rb_fopen(fn, "w"); -#if !defined(MSDOS) && !defined(__CYGWIN32__) && !(NT) && !defined(__human68k__) +#if !defined(MSDOS) && !defined(__CYGWIN32__) && !(NT) && !defined(__human68k__)\ + && !defined(USE_CWGUSI) && !defined(__BEOS__) fstat(fileno(fw), &st2); fchmod(fileno(fw), st.st_mode); if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) { fchown(fileno(fw), st.st_uid, st.st_gid); } #endif - rb_defout = prep_stdio(fw, FMODE_WRITABLE); + rb_defout = prep_stdio(fw, FMODE_WRITABLE, rb_cFile); } - file = prep_stdio(fr, FMODE_READABLE); + file = prep_stdio(fr, FMODE_READABLE, rb_cFile); } } else { init_p = 0; - return FALSE; + return Qfalse; } } - return TRUE; + return Qtrue; } static VALUE -f_gets_method(argc, argv) +rb_f_gets_internal(argc, argv) int argc; VALUE *argv; { @@ -1568,9 +1900,9 @@ f_gets_method(argc, argv) retry: if (!next_argv()) return Qnil; - line = io_gets_method(argc, argv, file); + line = rb_io_gets_internal(argc, argv, file); if (NIL_P(line) && next_p != -1) { - io_close(file); + rb_io_close(file); next_p = 1; goto retry; } @@ -1580,76 +1912,133 @@ f_gets_method(argc, argv) return line; } +static VALUE +rb_f_gets(argc, argv) + int argc; + VALUE *argv; +{ + VALUE line = rb_f_gets_internal(argc, argv); + + if (!NIL_P(line)) rb_lastline_set(line); + return line; +} + VALUE -f_gets() +rb_gets() { - return f_gets_method(0,0); + VALUE line; + + retry: + if (!next_argv()) return Qnil; + line = rb_io_gets(file); + if (NIL_P(line) && next_p != -1) { + rb_io_close(file); + next_p = 1; + goto retry; + } + if (!NIL_P(line)) { + rb_lastline_set(line); + gets_lineno++; + lineno = INT2FIX(gets_lineno); + } + + return line; } static VALUE -f_readline(argc, argv) +rb_f_readline(argc, argv) int argc; - VALUE argv; + VALUE *argv; { - VALUE line = f_gets_method(argc, argv); + VALUE line = rb_f_gets(argc, argv); if (NIL_P(line)) { - eof_error(); + rb_eof_error(); } return line; } static VALUE -f_eof() +rb_f_tell() +{ + return rb_io_tell(file); +} + +static VALUE +rb_f_seek(self, offset, ptrname) + VALUE self, offset, ptrname; +{ + if (!next_argv()) { + rb_raise(rb_eArgError, "no stream to seek"); + } + + return rb_io_seek(file, offset, ptrname); +} + +static VALUE +rb_f_set_pos(self, offset) + VALUE self, offset; +{ + if (!next_argv()) { + rb_raise(rb_eArgError, "no stream to pos"); + } + + return rb_io_set_pos(file, offset); +} + +static VALUE +rb_f_rewind() +{ + return rb_io_rewind(file); +} + +static VALUE +rb_f_eof() { if (init_p == 0 && !next_argv()) - return TRUE; - if (io_eof(file)) { + return Qtrue; + if (rb_io_eof(file)) { next_p = 1; - return TRUE; + return Qtrue; } - return FALSE; + return Qfalse; } static VALUE -f_getc() +rb_f_getc() { - return io_getc(rb_stdin); + return rb_io_getc(rb_stdin); } static VALUE -f_ungetc(obj, c) - VALUE obj, c; +rb_f_ungetc(self, c) + VALUE self, c; { - if (!next_argv()) { - ArgError("no stream to ungetc"); - } - - return io_ungetc(file, c); + return rb_io_ungetc(rb_stdin, c); } static VALUE -f_readchar() +rb_f_readchar() { - VALUE c = f_getc(); + VALUE c = rb_f_getc(); if (NIL_P(c)) { - eof_error(); + rb_eof_error(); } return c; } static VALUE -f_readlines(argc, argv) +rb_f_readlines(argc, argv) int argc; - VALUE argv; + VALUE *argv; { VALUE line, ary; - ary = ary_new(); - while (!NIL_P(line = f_gets_method(argc, argv))) { - ary_push(ary, line); + ary = rb_ary_new(); + while (!NIL_P(line = rb_f_gets_internal(argc, argv))) { + rb_ary_push(ary, line); } return ary; @@ -1662,13 +2051,13 @@ rb_str_setter(val, id, var) VALUE *var; { if (!NIL_P(val) && TYPE(val) != T_STRING) { - TypeError("value of %s must be String", rb_id2name(id)); + rb_raise(rb_eTypeError, "value of %s must be String", rb_id2name(id)); } *var = val; } static VALUE -f_backquote(obj, str) +rb_f_backquote(obj, str) VALUE obj, str; { VALUE port, result; @@ -1677,9 +2066,9 @@ f_backquote(obj, str) port = pipe_open(RSTRING(str)->ptr, "r"); result = read_all(port); - io_close(port); + rb_io_close(port); - if (NIL_P(result)) return str_new(0,0); + if (NIL_P(result)) return rb_str_new(0,0); return result; } @@ -1691,7 +2080,7 @@ f_backquote(obj, str) #endif static VALUE -f_select(argc, argv, obj) +rb_f_select(argc, argv, obj) int argc; VALUE *argv; VALUE obj; @@ -1702,7 +2091,7 @@ f_select(argc, argv, obj) struct timeval *tp, timerec; OpenFile *fptr; int i, max = 0, n; - int interrupt = 0; + int interrupt_flag = 0; int pending = 0; rb_scan_args(argc, argv, "13", &read, &write, &except, &timeout); @@ -1710,20 +2099,19 @@ f_select(argc, argv, obj) tp = NULL; } else { - timerec = time_timeval(timeout); + timerec = rb_time_timeval(timeout); tp = &timerec; } FD_ZERO(&pset); if (!NIL_P(read)) { - Check_Type(read, T_ARRAY); rp = &rset; FD_ZERO(rp); for (i=0; i<RARRAY(read)->len; i++) { - Check_Type(RARRAY(read)->ptr[i], T_FILE); - GetOpenFile(RARRAY(read)->ptr[i], fptr); - if (fptr->f == NULL) closed(); + VALUE io = rb_io_get_io(RARRAY(read)->ptr[i]); + + GetOpenFile(io, fptr); FD_SET(fileno(fptr->f), rp); if (READ_DATA_PENDING(fptr->f)) { /* check for buffered data */ pending++; @@ -1744,14 +2132,14 @@ f_select(argc, argv, obj) wp = &wset; FD_ZERO(wp); for (i=0; i<RARRAY(write)->len; i++) { - Check_Type(RARRAY(write)->ptr[i], T_FILE); - GetOpenFile(RARRAY(write)->ptr[i], fptr); - if (fptr->f == NULL) closed(); + VALUE io = rb_io_get_io(RARRAY(write)->ptr[i]); + + GetOpenFile(io, fptr); FD_SET(fileno(fptr->f), wp); - if (max > fileno(fptr->f)) max = fileno(fptr->f); + if (max < fileno(fptr->f)) max = fileno(fptr->f); if (fptr->f2) { FD_SET(fileno(fptr->f2), wp); - if (max < (int)fileno(fptr->f2)) max = fileno(fptr->f2); + if (max < fileno(fptr->f2)) max = fileno(fptr->f2); } } } @@ -1763,14 +2151,14 @@ f_select(argc, argv, obj) ep = &eset; FD_ZERO(ep); for (i=0; i<RARRAY(except)->len; i++) { - Check_Type(RARRAY(except)->ptr[i], T_FILE); - GetOpenFile(RARRAY(except)->ptr[i], fptr); - if (fptr->f == NULL) closed(); + VALUE io = rb_io_get_io(RARRAY(except)->ptr[i]); + + GetOpenFile(io, fptr); FD_SET(fileno(fptr->f), ep); if (max < fileno(fptr->f)) max = fileno(fptr->f); if (fptr->f2) { FD_SET(fileno(fptr->f2), ep); - if (max > (int)fileno(fptr->f2)) max = fileno(fptr->f2); + if (max < fileno(fptr->f2)) max = fileno(fptr->f2); } } } @@ -1779,8 +2167,8 @@ f_select(argc, argv, obj) max++; -#ifdef THREAD - n = thread_select(max, rp, wp, ep, tp); +#ifdef USE_THREAD + n = rb_thread_select(max, rp, wp, ep, tp); if (n < 0) { rb_sys_fail(0); } @@ -1794,24 +2182,24 @@ f_select(argc, argv, obj) rb_sys_fail(0); } if (tp == NULL) goto retry; - interrupt = 1; + interrupt_flag = 1; } #endif if (!pending && n == 0) return Qnil; /* returns nil on timeout */ - res = ary_new2(3); - ary_push(res, rp?ary_new():ary_new2(0)); - ary_push(res, wp?ary_new():ary_new2(0)); - ary_push(res, ep?ary_new():ary_new2(0)); + res = rb_ary_new2(3); + rb_ary_push(res, rp?rb_ary_new():rb_ary_new2(0)); + rb_ary_push(res, wp?rb_ary_new():rb_ary_new2(0)); + rb_ary_push(res, ep?rb_ary_new():rb_ary_new2(0)); - if (interrupt == 0) { + if (interrupt_flag == 0) { if (rp) { list = RARRAY(res)->ptr[0]; for (i=0; i< RARRAY(read)->len; i++) { GetOpenFile(RARRAY(read)->ptr[i], fptr); if (FD_ISSET(fileno(fptr->f), rp) || FD_ISSET(fileno(fptr->f), &pset)) { - ary_push(list, RARRAY(read)->ptr[i]); + rb_ary_push(list, RARRAY(read)->ptr[i]); } } } @@ -1821,10 +2209,10 @@ f_select(argc, argv, obj) for (i=0; i< RARRAY(write)->len; i++) { GetOpenFile(RARRAY(write)->ptr[i], fptr); if (FD_ISSET(fileno(fptr->f), wp)) { - ary_push(list, RARRAY(write)->ptr[i]); + rb_ary_push(list, RARRAY(write)->ptr[i]); } else if (fptr->f2 && FD_ISSET(fileno(fptr->f2), wp)) { - ary_push(list, RARRAY(write)->ptr[i]); + rb_ary_push(list, RARRAY(write)->ptr[i]); } } } @@ -1834,10 +2222,10 @@ f_select(argc, argv, obj) for (i=0; i< RARRAY(except)->len; i++) { GetOpenFile(RARRAY(except)->ptr[i], fptr); if (FD_ISSET(fileno(fptr->f), ep)) { - ary_push(list, RARRAY(except)->ptr[i]); + rb_ary_push(list, RARRAY(except)->ptr[i]); } else if (fptr->f2 && FD_ISSET(fileno(fptr->f2), ep)) { - ary_push(list, RARRAY(except)->ptr[i]); + rb_ary_push(list, RARRAY(except)->ptr[i]); } } } @@ -1847,27 +2235,28 @@ f_select(argc, argv, obj) } static VALUE -io_ctl(io, req, arg, io_p) +rb_io_ctl(io, req, arg, io_p) VALUE io, req, arg; int io_p; { #if !defined(MSDOS) && !defined(__human68k__) int cmd = NUM2INT(req); OpenFile *fptr; - int len, fd; + int len = 0; + int fd; long narg = 0; int retval; rb_secure(2); GetOpenFile(io, fptr); - if (NIL_P(arg) || (VALUE)arg == FALSE) { + if (NIL_P(arg) || arg == Qfalse) { narg = 0; } else if (FIXNUM_P(arg)) { narg = FIX2INT(arg); } - else if ((VALUE)arg == TRUE) { + else if (arg == Qtrue) { narg = 1; } else { @@ -1883,38 +2272,47 @@ io_ctl(io, req, arg, io_p) #else len = 256; /* otherwise guess at what's safe */ #endif - str_modify(arg); + rb_str_modify(arg); if (len <= RSTRING(arg)->len) { len = RSTRING(arg)->len; } if (RSTRING(arg)->len < len) { - str_resize(arg, len+1); + rb_str_resize(arg, len+1); } RSTRING(arg)->ptr[len] = 17; /* a little sanity check here */ narg = (long)RSTRING(arg)->ptr; } fd = fileno(fptr->f); #ifdef HAVE_FCNTL + TRAP_BEG; +# ifdef USE_CWGUSI + retval = io_p?ioctl(fd, cmd, (void*) narg):fcntl(fd, cmd, narg); +# else retval = io_p?ioctl(fd, cmd, narg):fcntl(fd, cmd, narg); +# endif + TRAP_END; #else if (!io_p) { rb_notimplement(); } + TRAP_BEG; retval = ioctl(fd, cmd, narg); + TRAP_END; #endif if (retval < 0) rb_sys_fail(fptr->path); if (TYPE(arg) == T_STRING && RSTRING(arg)->ptr[len] != 17) { - ArgError("return value overflowed string"); + rb_raise(rb_eArgError, "return value overflowed string"); } return INT2NUM(retval); #else rb_notimplement(); + return Qnil; /* not reached */ #endif } static VALUE -io_ioctl(argc, argv, io) +rb_io_ioctl(argc, argv, io) int argc; VALUE *argv; VALUE io; @@ -1922,11 +2320,11 @@ io_ioctl(argc, argv, io) VALUE req, arg; rb_scan_args(argc, argv, "11", &req, &arg); - return io_ctl(io, req, arg, 1); + return rb_io_ctl(io, req, arg, 1); } static VALUE -io_fcntl(argc, argv, io) +rb_io_fcntl(argc, argv, io) int argc; VALUE *argv; VALUE io; @@ -1935,14 +2333,15 @@ io_fcntl(argc, argv, io) VALUE req, arg; rb_scan_args(argc, argv, "11", &req, &arg); - return io_ctl(io, req, arg, 0); + return rb_io_ctl(io, req, arg, 0); #else rb_notimplement(); + return Qnil; /* not reached */ #endif } static VALUE -f_syscall(argc, argv) +rb_f_syscall(argc, argv) int argc; VALUE *argv; { @@ -1962,6 +2361,8 @@ f_syscall(argc, argv) */ rb_secure(2); + if (argc == 0) + rb_raise(rb_eArgError, "too few arguments for syscall"); arg[0] = NUM2INT(argv[0]); argv++; while (items--) { if (FIXNUM_P(*argv)) { @@ -1969,14 +2370,13 @@ f_syscall(argc, argv) } else { Check_Type(*argv, T_STRING); - str_modify(*argv); + rb_str_modify(*argv); arg[i] = (unsigned long)RSTRING(*argv)->ptr; argv++; } i++; } + TRAP_BEG; switch (argc) { - case 0: - ArgError("Too few args to syscall"); case 1: retval = syscall(arg[0]); break; @@ -2029,15 +2429,17 @@ f_syscall(argc, argv) break; #endif /* atarist */ } + TRAP_END; if (retval == -1) rb_sys_fail(0); return INT2FIX(0); #else rb_notimplement(); + return Qnil; /* not reached */ #endif } static VALUE -io_s_pipe() +rb_io_s_pipe() { #ifndef __human68k__ int pipes[2]; @@ -2050,16 +2452,17 @@ io_s_pipe() #endif rb_sys_fail(0); - r = prep_stdio(fdopen(pipes[0], "r"), FMODE_READABLE); - w = prep_stdio(fdopen(pipes[1], "w"), FMODE_WRITABLE); + r = prep_stdio(fdopen(pipes[0], "r"), FMODE_READABLE, rb_cIO); + w = prep_stdio(fdopen(pipes[1], "w"), FMODE_WRITABLE, rb_cIO); - ary = ary_new2(2); - ary_push(ary, r); - ary_push(ary, w); + ary = rb_ary_new2(2); + rb_ary_push(ary, r); + rb_ary_push(ary, w); return ary; #else rb_notimplement(); + return Qnil; /* not reached */ #endif } @@ -2070,19 +2473,19 @@ struct foreach_arg { }; static VALUE -io_foreach_line(arg) +rb_io_foreach_line(arg) struct foreach_arg *arg; { VALUE str; - while (!NIL_P(str = io_gets_method(arg->argc, &arg->sep, arg->io))) { + while (!NIL_P(str = rb_io_gets_internal(arg->argc, &arg->sep, arg->io))) { rb_yield(str); } return Qnil; } static VALUE -io_s_foreach(argc, argv, io) +rb_io_s_foreach(argc, argv, io) int argc; VALUE *argv; VALUE io; @@ -2094,26 +2497,26 @@ io_s_foreach(argc, argv, io) Check_SafeStr(fname); arg.argc = argc - 1; - arg.io = io_open(RSTRING(fname)->ptr, "r"); - return rb_ensure(io_foreach_line, &arg, io_close, arg.io); + arg.io = rb_io_open(RSTRING(fname)->ptr, "r"); + return rb_ensure(rb_io_foreach_line, (VALUE)&arg, rb_io_close, arg.io); } static VALUE -io_readline_line(arg) +rb_io_readline_line(arg) struct foreach_arg *arg; { VALUE line, ary; - ary = ary_new(); - while (!NIL_P(line = io_gets_method(arg->argc, &arg->sep, arg->io))) { - ary_push(ary, line); + ary = rb_ary_new(); + while (!NIL_P(line = rb_io_gets_internal(arg->argc, &arg->sep, arg->io))) { + rb_ary_push(ary, line); } return ary; } static VALUE -io_s_readlines(argc, argv, io) +rb_io_s_readlines(argc, argv, io) int argc; VALUE *argv; VALUE io; @@ -2125,14 +2528,20 @@ io_s_readlines(argc, argv, io) Check_SafeStr(fname); arg.argc = argc - 1; - arg.io = io_open(RSTRING(fname)->ptr, "r"); - return rb_ensure(io_readline_line, &arg, io_close, arg.io); + arg.io = rb_io_open(RSTRING(fname)->ptr, "r"); + return rb_ensure(rb_io_readline_line, (VALUE)&arg, rb_io_close, arg.io); } static VALUE arg_fileno() { - return io_fileno(file); + return rb_io_fileno(file); +} + +static VALUE +arg_to_io() +{ + return file; } static VALUE @@ -2141,22 +2550,22 @@ arg_read(argc, argv) VALUE *argv; { VALUE tmp, str; - int len; + size_t len; if (argc == 1) len = NUM2INT(argv[0]); str = Qnil; retry: if (!next_argv()) return str; - tmp = io_read(argc, argv, file); + tmp = rb_io_read(argc, argv, file); if (NIL_P(tmp) && next_p != -1) { - io_close(file); + rb_io_close(file); next_p = 1; goto retry; } - if (NIL_P(tmp)) return str; + if (NIL_P(tmp) || RSTRING(tmp)->len == 0) return str; else if (NIL_P(str)) str = tmp; - else str_cat(str, RSTRING(tmp)->ptr, RSTRING(tmp)->len); + else rb_str_cat(str, RSTRING(tmp)->ptr, RSTRING(tmp)->len); if (argc == 0) { goto retry; } @@ -2176,9 +2585,9 @@ arg_getc() retry: if (!next_argv()) return Qnil; - byte = io_getc(file); + byte = rb_io_getc(file); if (NIL_P(byte) && next_p != -1) { - io_close(file); + rb_io_close(file); next_p = 1; goto retry; } @@ -2189,10 +2598,10 @@ arg_getc() static VALUE arg_readchar() { - VALUE c = io_getc(file); + VALUE c = rb_io_getc(file); if (NIL_P(c)) { - eof_error(); + rb_eof_error(); } return c; } @@ -2200,11 +2609,11 @@ arg_readchar() static VALUE arg_each_line(argc, argv) int argc; - VALUE argv; + VALUE *argv; { VALUE str; - while (RTEST(str = f_gets_method(argc, argv))) { + while (RTEST(str = rb_f_gets_internal(argc, argv))) { rb_yield(str); } return Qnil; @@ -2237,7 +2646,7 @@ static VALUE arg_skip() { if (next_p != -1) { - io_close(file); + rb_io_close(file); next_p = 1; } return argf; @@ -2246,7 +2655,7 @@ arg_skip() static VALUE arg_close() { - io_close(file); + rb_io_close(file); if (next_p != -1) { next_p = 1; } @@ -2257,162 +2666,186 @@ arg_close() static VALUE arg_closed() { - return io_closed(file); + return rb_io_closed(file); } static VALUE opt_i_get() { - if (!inplace) return Qnil; - return str_new2(inplace); + if (!ruby_inplace_mode) return Qnil; + return rb_str_new2(ruby_inplace_mode); } static void opt_i_set(val) VALUE val; { - if (NIL_P(val)) { - inplace = 0; + if (!RTEST(val)) { + ruby_inplace_mode = 0; return; } - Check_Type(val, T_STRING); - inplace = RSTRING(val)->ptr; + ruby_inplace_mode = STR2CSTR(val); } void Init_IO() { - extern VALUE mEnumerable; - extern VALUE eException; - - eEOFError = rb_define_class("EOFError", eException); + rb_eIOError = rb_define_class("IOError", rb_eStandardError); + rb_eEOFError = rb_define_class("EOFError", rb_eIOError); id_write = rb_intern("write"); - rb_define_global_function("syscall", f_syscall, -1); - - rb_define_global_function("open", f_open, -1); - rb_define_global_function("printf", f_printf, -1); - rb_define_global_function("print", f_print, -1); - rb_define_global_function("puts", f_puts, -1); - rb_define_global_function("gets", f_gets_method, -1); - rb_define_global_function("readline", f_readline, -1); - rb_define_global_function("eof", f_eof, 0); - rb_define_global_function("eof?", f_eof, 0); - rb_define_global_function("getc", f_getc, 0); - rb_define_global_function("readchar", f_readchar, 0); - rb_define_global_function("select", f_select, -1); - rb_define_global_function("ungetc", f_ungetc, 1); - - rb_define_global_function("readlines", f_readlines, -1); - - rb_define_global_function("`", f_backquote, 1); - rb_define_global_function("pipe", io_s_pipe, 0); - - rb_define_global_function("p", f_p, 1); - - cIO = rb_define_class("IO", cObject); - rb_include_module(cIO, mEnumerable); - - rb_define_singleton_method(cIO, "new", io_s_new, -1); - rb_define_singleton_method(cIO, "popen", io_s_popen, -1); - rb_define_singleton_method(cIO, "foreach", io_s_foreach, -1); - rb_define_singleton_method(cIO, "readlines", io_s_readlines, -1); - rb_define_singleton_method(cIO, "select", f_select, -1); - - FS = OFS = Qnil; - rb_define_hooked_variable("$;", &FS, 0, rb_str_setter); - rb_define_hooked_variable("$-F", &FS, 0, rb_str_setter); - rb_define_hooked_variable("$,", &OFS, 0, rb_str_setter); - - RS = RS_default = str_new2("\n"); ORS = Qnil; - rb_global_variable(&RS_default); - rb_define_hooked_variable("$/", &RS, 0, rb_str_setter); - rb_define_hooked_variable("$-0", &RS, 0, rb_str_setter); - rb_define_hooked_variable("$\\", &ORS, 0, rb_str_setter); - - rb_define_variable("$.", &lineno); - rb_define_virtual_variable("$_", lastline_get, lastline_set); - - rb_define_method(cIO, "clone", io_clone, 0); - rb_define_method(cIO, "reopen", io_reopen, 1); - - rb_define_method(cIO, "print", io_print, -1); - rb_define_method(cIO, "puts", io_puts, -1); - rb_define_method(cIO, "printf", io_printf, -1); - - rb_define_method(cIO, "each", io_each_line, -1); - rb_define_method(cIO, "each_line", io_each_line, -1); - rb_define_method(cIO, "each_byte", io_each_byte, 0); - - rb_define_method(cIO, "syswrite", io_syswrite, 1); - rb_define_method(cIO, "sysread", io_sysread, 1); - - rb_define_method(cIO, "fileno", io_fileno, 0); - rb_define_alias(cIO, "to_i", "fileno"); - - rb_define_method(cIO, "sync", io_sync, 0); - rb_define_method(cIO, "sync=", io_set_sync, 1); - - rb_define_method(cIO, "readlines", io_readlines, -1); - - rb_define_method(cIO, "read", io_read, -1); - rb_define_method(cIO, "write", io_write, 1); - rb_define_method(cIO, "gets", io_gets_method, -1); - rb_define_method(cIO, "readline", io_readline, -1); - rb_define_method(cIO, "getc", io_getc, 0); - rb_define_method(cIO, "readchar", io_readchar, 0); - rb_define_method(cIO, "ungetc",io_ungetc, 1); - rb_define_method(cIO, "<<", io_addstr, 1); - rb_define_method(cIO, "flush", io_flush, 0); - rb_define_method(cIO, "eof", io_eof, 0); - rb_define_method(cIO, "eof?", io_eof, 0); - - rb_define_method(cIO, "close", io_close, 0); - rb_define_method(cIO, "closed?", io_closed, 0); - - rb_define_method(cIO, "isatty", io_isatty, 0); - rb_define_method(cIO, "tty?", io_isatty, 0); - rb_define_method(cIO, "binmode", io_binmode, 0); - - rb_define_method(cIO, "ioctl", io_ioctl, -1); - rb_define_method(cIO, "fcntl", io_fcntl, -1); - - rb_stdin = prep_stdio(stdin, FMODE_READABLE); - rb_define_readonly_variable("$stdin", &rb_stdin); - rb_stdout = prep_stdio(stdout, FMODE_WRITABLE); - rb_define_readonly_variable("$stdout", &rb_stdout); - rb_stderr = prep_stdio(stderr, FMODE_WRITABLE); - rb_define_hooked_variable("$stderr", &rb_stderr, 0, io_errset); + rb_define_global_function("syscall", rb_f_syscall, -1); + + rb_define_global_function("open", rb_f_open, -1); + rb_define_global_function("printf", rb_rb_f_printf, -1); + rb_define_global_function("print", rb_f_print, -1); + rb_define_global_function("putc", rb_f_putc, 1); + rb_define_global_function("puts", rb_f_puts, -1); + rb_define_global_function("gets", rb_f_gets, -1); + rb_define_global_function("readline", rb_f_readline, -1); + rb_define_global_function("tell", rb_f_tell, 0); + rb_define_global_function("seek", rb_f_seek, 2); + rb_define_global_function("rewind", rb_f_rewind, 0); + rb_define_global_function("eof", rb_f_eof, 0); + rb_define_global_function("eof?", rb_f_eof, 0); + rb_define_global_function("getc", rb_f_getc, 0); + rb_define_global_function("readchar", rb_f_readchar, 0); + rb_define_global_function("select", rb_f_select, -1); + rb_define_global_function("ungetc", rb_f_ungetc, 1); + + rb_define_global_function("readlines", rb_f_readlines, -1); + + rb_define_global_function("`", rb_f_backquote, 1); + rb_define_global_function("pipe", rb_io_s_pipe, 0); + + rb_define_global_function("p", rb_f_p, -1); + rb_define_method(rb_mKernel, "display", rb_obj_display, -1); + + rb_cIO = rb_define_class("IO", rb_cObject); + rb_include_module(rb_cIO, rb_mEnumerable); + + rb_define_singleton_method(rb_cIO, "new", rb_io_s_new, -1); + rb_define_singleton_method(rb_cIO, "popen", rb_io_s_popen, -1); + rb_define_singleton_method(rb_cIO, "foreach", rb_io_s_foreach, -1); + rb_define_singleton_method(rb_cIO, "readlines", rb_io_s_readlines, -1); + rb_define_singleton_method(rb_cIO, "select", rb_f_select, -1); + + rb_fs = rb_output_fs = Qnil; + rb_define_hooked_variable("$;", &rb_fs, 0, rb_str_setter); + rb_define_hooked_variable("$-F", &rb_fs, 0, rb_str_setter); + rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter); + + rb_rs = rb_default_rs = rb_str_new2("\n"); rb_output_rs = Qnil; + rb_global_variable(&rb_default_rs); + rb_str_freeze(rb_default_rs); /* avoid modifying RS_default */ + rb_define_hooked_variable("$/", &rb_rs, 0, rb_str_setter); + rb_define_hooked_variable("$-0", &rb_rs, 0, rb_str_setter); + rb_define_hooked_variable("$\\", &rb_output_rs, 0, rb_str_setter); + + rb_define_hooked_variable("$.", &lineno, 0, lineno_setter); + rb_define_virtual_variable("$_", rb_lastline_get, rb_lastline_set); + + rb_define_method(rb_cIO, "clone", rb_io_clone, 0); + rb_define_method(rb_cIO, "reopen", rb_io_reopen, 1); + + rb_define_method(rb_cIO, "print", rb_io_print, -1); + rb_define_method(rb_cIO, "putc", rb_io_putc, 1); + rb_define_method(rb_cIO, "puts", rb_io_puts, -1); + rb_define_method(rb_cIO, "printf", rb_io_printf, -1); + + rb_define_method(rb_cIO, "each", rb_io_each_line, -1); + rb_define_method(rb_cIO, "each_line", rb_io_each_line, -1); + rb_define_method(rb_cIO, "each_byte", rb_io_each_byte, 0); + + rb_define_method(rb_cIO, "syswrite", rb_io_syswrite, 1); + rb_define_method(rb_cIO, "sysread", rb_io_sysread, 1); + + rb_define_method(rb_cIO, "fileno", rb_io_fileno, 0); + rb_define_alias(rb_cIO, "to_i", "fileno"); + rb_define_method(rb_cIO, "to_io", rb_io_to_io, 0); + + rb_define_method(rb_cIO, "sync", rb_io_sync, 0); + rb_define_method(rb_cIO, "sync=", rb_io_set_sync, 1); + + rb_define_method(rb_cIO, "lineno", rb_io_lineno, 0); + rb_define_method(rb_cIO, "lineno=", rb_io_set_lineno, 1); + + rb_define_method(rb_cIO, "readlines", rb_io_readlines, -1); + + rb_define_method(rb_cIO, "read", rb_io_read, -1); + rb_define_method(rb_cIO, "write", rb_io_write, 1); + rb_define_method(rb_cIO, "gets", rb_io_gets_method, -1); + rb_define_method(rb_cIO, "readline", rb_io_readline, -1); + rb_define_method(rb_cIO, "getc", rb_io_getc, 0); + rb_define_method(rb_cIO, "readchar", rb_io_readchar, 0); + rb_define_method(rb_cIO, "ungetc",rb_io_ungetc, 1); + rb_define_method(rb_cIO, "<<", rb_io_addstr, 1); + rb_define_method(rb_cIO, "flush", rb_io_flush, 0); + rb_define_method(rb_cIO, "tell", rb_io_tell, 0); + rb_define_method(rb_cIO, "seek", rb_io_seek, 2); + rb_define_const(rb_cIO, "SEEK_SET", SEEK_SET); + rb_define_const(rb_cIO, "SEEK_CUR", SEEK_CUR); + rb_define_const(rb_cIO, "SEEK_END", SEEK_END); + rb_define_method(rb_cIO, "rewind", rb_io_rewind, 0); + rb_define_method(rb_cIO, "pos", rb_io_tell, 0); + rb_define_method(rb_cIO, "pos=", rb_io_set_pos, 1); + rb_define_method(rb_cIO, "eof", rb_io_eof, 0); + rb_define_method(rb_cIO, "eof?", rb_io_eof, 0); + + rb_define_method(rb_cIO, "close", rb_io_close_method, 0); + rb_define_method(rb_cIO, "closed?", rb_io_closed, 0); + rb_define_method(rb_cIO, "close_read", rb_io_close_read, 0); + rb_define_method(rb_cIO, "close_write", rb_io_close_write, 0); + + rb_define_method(rb_cIO, "isatty", rb_io_isatty, 0); + rb_define_method(rb_cIO, "tty?", rb_io_isatty, 0); + rb_define_method(rb_cIO, "binmode", rb_io_binmode, 0); + + rb_define_method(rb_cIO, "ioctl", rb_io_ioctl, -1); + rb_define_method(rb_cIO, "fcntl", rb_io_fcntl, -1); + + rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO); + rb_define_hooked_variable("$stdin", &rb_stdin, 0, rb_io_stdio_set); + rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO); + rb_define_hooked_variable("$stdout", &rb_stdout, 0, rb_io_stdio_set); + rb_stderr = prep_stdio(stderr, FMODE_WRITABLE, rb_cIO); + rb_define_hooked_variable("$stderr", &rb_stderr, 0, rb_io_stdio_set); rb_defout = rb_stdout; - rb_define_hooked_variable("$>", &rb_defout, 0, io_defset); + rb_define_hooked_variable("$>", &rb_defout, 0, rb_io_defset); rb_define_global_const("STDIN", rb_stdin); rb_define_global_const("STDOUT", rb_stdout); rb_define_global_const("STDERR", rb_stderr); - argf = obj_alloc(cObject); - rb_extend_object(argf, mEnumerable); + argf = rb_obj_alloc(rb_cObject); + rb_extend_object(argf, rb_mEnumerable); rb_define_readonly_variable("$<", &argf); rb_define_global_const("ARGF", argf); rb_define_singleton_method(argf, "fileno", arg_fileno, 0); rb_define_singleton_method(argf, "to_i", arg_fileno, 0); + rb_define_singleton_method(argf, "to_io", arg_to_io, 0); rb_define_singleton_method(argf, "each", arg_each_line, -1); rb_define_singleton_method(argf, "each_line", arg_each_line, -1); rb_define_singleton_method(argf, "each_byte", arg_each_byte, 0); rb_define_singleton_method(argf, "read", arg_read, -1); - rb_define_singleton_method(argf, "readlines", f_readlines, -1); - rb_define_singleton_method(argf, "to_a", f_readlines, -1); - rb_define_singleton_method(argf, "gets", f_gets_method, -1); - rb_define_singleton_method(argf, "readline", f_readline, -1); + rb_define_singleton_method(argf, "readlines", rb_f_readlines, -1); + rb_define_singleton_method(argf, "to_a", rb_f_readlines, -1); + rb_define_singleton_method(argf, "gets", rb_f_gets, -1); + rb_define_singleton_method(argf, "readline", rb_f_readline, -1); rb_define_singleton_method(argf, "getc", arg_getc, 0); rb_define_singleton_method(argf, "readchar", arg_readchar, 0); - rb_define_singleton_method(argf, "eof", f_eof, 0); - rb_define_singleton_method(argf, "eof?", f_eof, 0); - rb_define_singleton_method(argf, "ungetc", f_ungetc, 1); + rb_define_singleton_method(argf, "tell", rb_f_tell, 0); + rb_define_singleton_method(argf, "seek", rb_f_seek, 2); + rb_define_singleton_method(argf, "rewind", rb_f_rewind, 0); + rb_define_singleton_method(argf, "pos", rb_f_tell, 0); + rb_define_singleton_method(argf, "pos=", rb_f_set_pos, 1); + rb_define_singleton_method(argf, "eof", rb_f_eof, 0); + rb_define_singleton_method(argf, "eof?", rb_f_eof, 0); + rb_define_singleton_method(argf, "ungetc", rb_f_ungetc, 1); rb_define_singleton_method(argf, "to_s", arg_filename, 0); rb_define_singleton_method(argf, "filename", arg_filename, 0); @@ -2421,15 +2854,16 @@ Init_IO() rb_define_singleton_method(argf, "close", arg_close, 0); rb_define_singleton_method(argf, "closed?", arg_closed, 0); - filename = str_new2("-"); + filename = rb_str_new2("-"); rb_define_readonly_variable("$FILENAME", &filename); file = rb_stdin; rb_global_variable(&file); rb_define_virtual_variable("$-i", opt_i_get, opt_i_set); - Init_File(); #if defined (NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__) atexit(pipe_atexit); #endif + + Init_File(); } |