From cf06d8b20becccb7b5b8bcdbbad25ae239d83a40 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 27 Mar 2002 05:28:00 +0000 Subject: * io.c (rb_io_sysseek): new method based on a patch from Aristarkh A Zagorodnikov . [new] * io.c (READ_DATA_PENDING): use !feof(fp) for default behavior. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2294 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- io.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'io.c') diff --git a/io.c b/io.c index 1b5221d1ee..b500a018a3 100644 --- a/io.c +++ b/io.c @@ -95,6 +95,10 @@ extern void Init_File _((void)); #include "util.h" +#if SIZEOF_OFF_T > SIZEOF_LONG && !defined(HAVE_LONG_LONG) +# error off_t is bigger than long, but you have no long long... +#endif + VALUE rb_cIO; VALUE rb_eEOFError; VALUE rb_eIOError; @@ -148,7 +152,7 @@ static VALUE lineno; #else /* requires systems own version of the ReadDataPending() */ extern int ReadDataPending(); -# define READ_DATA_PENDING(fp) ReadDataPending(fp) +# define READ_DATA_PENDING(fp) (!feof(fp)) #endif #ifndef READ_DATA_PENDING_PTR # ifdef FILE_READPTR @@ -350,15 +354,7 @@ rb_io_tell(io) GetOpenFile(io, fptr); pos = ftello(fptr->f); if (ferror(fptr->f)) rb_sys_fail(fptr->path); - -#if SIZEOF_OFF_T > SIZEOF_LONG -# if !HAVE_LONG_LONG -# error off_t is bigger than long, but you have no long long... -# endif - return rb_ll2inum(pos); -#else - return rb_int2inum(pos); -#endif + return OFFT2NUM(pos); } #ifndef SEEK_CUR @@ -1324,6 +1320,35 @@ rb_io_close_write(io) return Qnil; } +static VALUE +rb_io_sysseek(argc, argv, io) + int argc; + VALUE *argv; + VALUE io; +{ + VALUE offset, ptrname; + int whence; + OpenFile *fptr; + off_t pos; + + rb_scan_args(argc, argv, "11", &offset, &ptrname); + if (argc == 1) whence = SEEK_SET; + else whence = NUM2INT(ptrname); + + GetOpenFile(io, fptr); + if ((fptr->mode & FMODE_READABLE) && READ_DATA_PENDING(fptr->f)) { + rb_raise(rb_eIOError, "syseek for buffered IO"); + } + if ((fptr->mode & FMODE_WRITABLE) && (fptr->mode & FMODE_WBUF)) { + rb_warn("sysseek for buffered IO"); + } + pos = lseek(fileno(fptr->f), NUM2OFFT(offset), whence); + if (pos == -1) rb_sys_fail(fptr->path); + clearerr(fptr->f); + + return OFFT2NUM(pos); +} + static VALUE rb_io_syswrite(io, str) VALUE io, str; @@ -3761,6 +3786,7 @@ Init_IO() 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, "sysseek", rb_io_sysseek, -1); rb_define_method(rb_cIO, "ioctl", rb_io_ioctl, -1); rb_define_method(rb_cIO, "fcntl", rb_io_fcntl, -1); -- cgit v1.2.3