/* * call-seq: * ios.sysread(integer ) => string * * Reads <i>integer</i> bytes from <em>ios</em> using a low-level * read and returns them as a string. Do not mix with other methods * that read from <em>ios</em> or you may get unpredictable results. * Raises <code>SystemCallError</code> on error and * <code>EOFError</code> at end of file. * * f = File.new("testfile") * f.sysread(16) #=> "This is line one" */ static VALUE rb_io_sysread(argc, argv, io) int argc; VALUE *argv; VALUE io; { VALUE len, str; OpenFile *fptr; long n, ilen; rb_scan_args(argc, argv, "11", &len, &str); ilen = NUM2LONG(len); if (NIL_P(str)) { str = rb_str_new(0, ilen); } else { StringValue(str); rb_str_modify(str); rb_str_resize(str, ilen); } if (ilen == 0) return str; GetOpenFile(io, fptr); rb_io_check_readable(fptr); if (READ_DATA_BUFFERED(fptr->f)) { rb_raise(rb_eIOError, "sysread for buffered IO"); } rb_str_locktmp(str); n = fileno(fptr->f); rb_thread_wait_fd(fileno(fptr->f)); rb_io_check_closed(fptr); if (RSTRING(str)->len != ilen) { rb_raise(rb_eRuntimeError, "buffer string modified"); } TRAP_BEG; n = read(fileno(fptr->f), RSTRING(str)->ptr, ilen); TRAP_END; rb_str_unlocktmp(str); if (n == -1) { rb_sys_fail(fptr->path); } rb_str_resize(str, n); if (n == 0 && ilen > 0) { rb_eof_error(); } RSTRING(str)->len = n; RSTRING(str)->ptr[n] = '\0'; OBJ_TAINT(str); return str; }