diff --git a/io.c b/io.c index af0e89c356..31d4bce67e 100644 --- a/io.c +++ b/io.c @@ -407,6 +407,24 @@ rb_io_fwrite(ptr, len, f) return len - n; } +/* + * call-seq: + * ios.write(string) => integer + * + * Writes the given string to ios. The stream must be opened + * for writing. If the argument is not a string, it will be converted + * to a string using to_s. Returns the number of bytes + * written. + * + * count = $stdout.write( "This is a test\n" ) + * puts "That was #{count} bytes of data" + * + * produces: + * + * This is a test + * That was 15 bytes of data + */ + static VALUE io_write(io, str) VALUE io, str; @@ -448,6 +466,22 @@ rb_io_write(io, str) return rb_funcall(io, id_write, 1, str); } +/* + * call-seq: + * ios << obj => ios + * + * String Output---Writes obj to ios. + * obj will be converted to a string using + * to_s. + * + * $stdout << "Hello " << "world!\n" + * + * produces: + * + * Hello world! + */ + + VALUE rb_io_addstr(io, str) VALUE io, str; @@ -456,6 +490,22 @@ rb_io_addstr(io, str) return io; } +/* + * call-seq: + * ios.flush => ios + * + * Flushes any buffered data within ios to the underlying + * operating system (note that this is Ruby internal buffering only; + * the OS may buffer the data as well). + * + * $stdout.print "no newline" + * $stdout.flush + * + * produces: + * + * no newline + */ + static VALUE rb_io_flush(io) VALUE io; @@ -472,6 +522,20 @@ rb_io_flush(io) return io; } + +/* + * call-seq: + * ios.pos => integer + * ios.tell => integer + * + * Returns the current offset (in bytes) of ios. + * + * f = File.new("testfile") + * f.pos #=> 0 + * f.gets #=> "This is line one\n" + * f.pos #=> 17 + */ + static VALUE rb_io_tell(io) VALUE io; @@ -501,6 +565,27 @@ rb_io_seek(io, offset, whence) return INT2FIX(0); } +/* + * call-seq: + * ios.seek(amount, whence=SEEK_SET) -> 0 + * + * Seeks to a given offset anInteger in the stream according to + * the value of whence: + * + * IO::SEEK_CUR | Seeks to _amount_ plus current position + * --------------+---------------------------------------------------- + * IO::SEEK_END | Seeks to _amount_ plus end of stream (you probably + * | want a negative value for _amount_) + * --------------+---------------------------------------------------- + * IO::SEEK_SET | Seeks to the absolute location given by _amount_ + * + * Example: + * + * f = File.new("testfile") + * f.seek(-13, IO::SEEK_END) #=> 0 + * f.readline #=> "And so on...\n" + */ + static VALUE rb_io_seek_m(argc, argv, io) int argc; @@ -517,6 +602,17 @@ rb_io_seek_m(argc, argv, io) return rb_io_seek(io, offset, whence); } +/* + * call-seq: + * ios.pos = integer => 0 + * + * Seeks to the given position (in bytes) in ios. + * + * f = File.new("testfile") + * f.pos = 17 + * f.gets #=> "This is line two\n" + */ + static VALUE rb_io_set_pos(io, offset) VALUE io, offset; @@ -532,6 +628,20 @@ rb_io_set_pos(io, offset) return OFFT2NUM(pos); } +/* + * call-seq: + * ios.rewind => 0 + * + * Positions ios to the beginning of input, resetting + * lineno to zero. + * + * f = File.new("testfile") + * f.readline #=> "This is line one\n" + * f.rewind #=> 0 + * f.lineno #=> 0 + * f.readline #=> "This is line one\n" + */ + static VALUE rb_io_rewind(io) VALUE io; @@ -549,6 +659,19 @@ rb_io_rewind(io) return INT2FIX(0); } +/* + * call-seq: + * ios.eof => true or false + * ios.eof? => true or false + * + * Returns true if ios is at end of file. The stream must be + * opened for reading or an IOError will be raised. + * + * f = File.new("testfile") + * dummy = f.readlines + * f.eof #=> true + */ + VALUE rb_io_eof(io) VALUE io; @@ -574,6 +697,19 @@ rb_io_eof(io) return Qtrue; } +/* + * call-seq: + * ios.sync => true or false + * + * Returns the current ``sync mode'' of ios. When sync mode is + * true, all output is immediately flushed to the underlying operating + * system and is not buffered by Ruby internally. See also + * IO#fsync. + * + * f = File.new("testfile") + * f.sync #=> false + */ + static VALUE rb_io_sync(io) VALUE io; @@ -584,6 +720,21 @@ rb_io_sync(io) return (fptr->mode & FMODE_SYNC) ? Qtrue : Qfalse; } +/* + * call-seq: + * ios.sync = boolean => boolean + * + * Sets the ``sync mode'' to true or false. + * When sync mode is true, all output is immediately flushed to the + * underlying operating system and is not buffered internally. Returns + * the new state. See also IO#fsync. + * + * f = File.new("testfile") + * f.sync = true + * + * (produces no output) + */ + static VALUE rb_io_set_sync(io, mode) VALUE io, mode; @@ -600,6 +751,18 @@ rb_io_set_sync(io, mode) return mode; } +/* + * call-seq: + * ios.fsync => 0 or nil + * + * Immediately writes all buffered data in ios to disk. + * Returns nil if the underlying operating system does not + * support fsync(2). Note that fsync differs from + * using IO#sync=. The latter ensures that data is flushed + * from Ruby's buffers, but doesn't not guarantee that the underlying + * operating system actually writes it to disk. + */ + static VALUE rb_io_fsync(io) VALUE io; @@ -622,6 +785,18 @@ rb_io_fsync(io) #endif } +/* + * call-seq: + * ios.fileno => fixnum + * ios.to_i => fixnum + * + * Returns an integer representing the numeric file descriptor for + * ios. + * + * $stdin.fileno #=> 0 + * $stdout.fileno #=> 1 + */ + static VALUE rb_io_fileno(io) VALUE io; @@ -634,6 +809,27 @@ rb_io_fileno(io) return INT2FIX(fd); } + +/* + * call-seq: + * ios.pid => fixnum + * + * Returns the process ID of a child process associated with + * ios. This will be set by IO::popen. + * + * pipe = IO.popen("-") + * if pipe + * $stderr.puts "In parent, child pid is #{pipe.pid}" + * else + * $stderr.puts "In child, pid is #{$$}" + * end + * + * produces: + * + * In child, pid is 26209 + * In parent, child pid is 26209 + */ + static VALUE rb_io_pid(io) VALUE io; @@ -646,6 +842,14 @@ rb_io_pid(io) return INT2FIX(fptr->pid); } + +/* + * call-seq: + * ios.inspect => string + * + * Return a string describing this IO object. + */ + static VALUE rb_io_inspect(obj) VALUE obj; @@ -667,6 +871,13 @@ rb_io_inspect(obj) return rb_str_new2(buf); } +/* + * call-seq: + * ios.to_io -> ios + * + * Returns ios. + */ + static VALUE rb_io_to_io(io) VALUE io; @@ -809,6 +1020,20 @@ read_all(fptr, siz, str) return str; } +/* + * call-seq: + * ios.read([integer [, buffer]]) => string, buffer, or nil + * + * Reads at most integer bytes from the I/O stream, or to the + * end of file if integer is omitted or is nil. + * If the optional buffer argument is present, it must reference + * a String, which will receive the data. Returns nil + * if called at end of file. + * + * f = File.new("testfile") + * f.read(16) #=> "This is line one" + */ + static VALUE io_read(argc, argv, io) int argc; @@ -1087,6 +1312,23 @@ rb_io_gets(io) return rb_io_getline_fast(fptr, '\n'); } +/* + * call-seq: + * ios.gets(sep_string=$/) => string or nil + * + * Reads the next ``line'' from the I/O stream; lines are separated by + * sep_string. A separator of nil reads the entire + * contents, and a zero-length separator reads the input a paragraph at + * a time (two successive newlines in the input separate paragraphs). + * The stream must be opened for reading or an IOerror + * will be raised. The line read in will be returned and also assigned + * to $_. Returns nil if called at end of + * file. + * + * File.new("testfile").gets #=> "This is line one\n" + * $_ #=> "This is line one\n" + */ + static VALUE rb_io_gets_m(argc, argv, io) int argc; @@ -1111,6 +1353,25 @@ rb_io_gets_m(argc, argv, io) return str; } +/* + * call-seq: + * ios.lineno => integer + * + * Returns the current line number in ios. The stream must be + * opened for reading. lineno counts the number of times + * gets is called, rather than the number of newlines + * encountered. The two values will differ if gets is + * called with a separator other than newline. See also the + * $. variable. + * + * f = File.new("testfile") + * f.lineno #=> 0 + * f.gets #=> "This is line one\n" + * f.lineno #=> 1 + * f.gets #=> "This is line two\n" + * f.lineno #=> 2 + */ + static VALUE rb_io_lineno(io) VALUE io; @@ -1122,6 +1383,23 @@ rb_io_lineno(io) return INT2NUM(fptr->lineno); } +/* + * call-seq: + * ios.lineno = integer => integer + * + * Manually sets the current line number to the given value. + * $. is updated only on the next read. + * + * f = File.new("testfile") + * f.gets #=> "This is line one\n" + * $. #=> 1 + * f.lineno = 1000 + * f.lineno #=> 1000 + * $. # lineno of last read #=> 1 + * f.gets #=> "This is line two\n" + * $. # lineno of last read #=> 1001 + */ + static VALUE rb_io_set_lineno(io, lineno) VALUE io, lineno; @@ -1159,6 +1437,14 @@ argf_lineno() return lineno; } +/* + * call-seq: + * ios.readline(sep_string=$/) => string + * + * Reads a line as with IO#gets, but raises an + * EOFError on end of file. + */ + static VALUE rb_io_readline(argc, argv, io) int argc; @@ -1173,6 +1459,21 @@ rb_io_readline(argc, argv, io) return line; } +/* + * call-seq: + * ios.readlines(sep_string=$/) => array + * + * Reads all of the lines in ios, and returns them in + * anArray. Lines are separated by the optional + * sep_string. If set_string is nil, the + * rest of the stream is returned as a single record. + * The stream must be opened for reading or an + * IOerror will be raised. + * + * f = File.new("testfile") + * f.readlines[0] #=> "This is line one\n" + */ + static VALUE rb_io_readlines(argc, argv, io) int argc; @@ -1197,6 +1498,26 @@ rb_io_readlines(argc, argv, io) return ary; } +/* + * call-seq: + * ios.each(sep_string=$/) {|line| block } => ios + * ios.each_line(sep_string=$/) {|line| block } => ios + * + * Executes the block for every line in ios, where lines are + * separated by sep_string. ios must be opened for + * reading or an IOerror will be raised. + * + * f = File.new("testfile") + * f.each {|line| puts "#{f.lineno}: #{line}" } + * + * produces: + * + * 1: This is line one + * 2: This is line two + * 3: This is line three + * 4: And so on... + */ + static VALUE rb_io_each_line(argc, argv, io) int argc; @@ -1220,6 +1541,20 @@ rb_io_each_line(argc, argv, io) return io; } +/* + * call-seq: + * ios.each_byte {|byte| block } => nil + * + * Calls the given block once for each byte (0..255) in ios, + * passing the byte as an argument. The stream must be opened for + * reading or an IOerror will be raised. + * + * f = File.new("testfile") + * checksum = 0 + * f.each_byte {|x| checksum ^= x } #=> # + * checksum #=> 12 + */ + static VALUE rb_io_each_byte(io) VALUE io; @@ -1252,6 +1587,18 @@ rb_io_each_byte(io) return io; } +/* + * call-seq: + * ios.getc => fixnum or nil + * + * Gets the next 8-bit byte (0..255) from ios. Returns + * nil if called at end of file. + * + * f = File.new("testfile") + * f.getc #=> 84 + * f.getc #=> 104 + */ + VALUE rb_io_getc(io) VALUE io; @@ -1298,6 +1645,14 @@ rb_getc(f) return c; } +/* + * call-seq: + * ios.readchar => fixnum + * + * Reads a character as with IO#getc, but raises an + * EOFError on end of file. + */ + static VALUE rb_io_readchar(io) VALUE io; @@ -1310,6 +1665,22 @@ rb_io_readchar(io) return c; } +/* + * call-seq: + * ios.ungetc(integer) => nil + * + * Pushes back one character (passed as a parameter) onto ios, + * such that a subsequent buffered read will return it. Only one character + * may be pushed back before a subsequent read operation (that is, + * you will be able to read only the last of several characters that have been pushed + * back). Has no effect with unbuffered reads (such as IO#sysread). + * + * f = File.new("testfile") #=> # + * c = f.getc #=> 84 + * f.ungetc(c) #=> nil + * f.getc #=> 84 + */ + VALUE rb_io_ungetc(io, c) VALUE io, c; @@ -1327,6 +1698,18 @@ rb_io_ungetc(io, c) return Qnil; } +/* + * call-seq: + * ios.isatty => true or false + * ios.tty? => true or false + * + * Returns true if ios is associated with a + * terminal device (tty), false otherwise. + * + * File.new("testfile").isatty #=> false + * File.new("/dev/tty").isatty #=> true + */ + static VALUE rb_io_isatty(io) VALUE io; @@ -1432,6 +1815,17 @@ rb_io_close(io) return Qnil; } +/* + * call-seq: + * ios.close => nil + * + * Closes ios and flushes any pending writes to the operating + * system. The stream is unavailable for any further data operations; + * an IOError is raised if such an attempt is made. I/O + * streams are automatically closed when they are claimed by the + * garbage collector. + */ + static VALUE rb_io_close_m(io) VALUE io; @@ -1451,6 +1845,25 @@ io_close(io) return rb_funcall(io, rb_intern("close"), 0, 0); } +/* + * call-seq: + * ios.closed? => true or false + * + * Returns true if ios is completely closed (for + * duplex streams, both reader and writer), false + * otherwise. + * + * f = File.new("testfile") + * f.close #=> nil + * f.closed? #=> true + * f = IO.popen("/bin/sh","r+") + * f.close_write #=> nil + * f.closed? #=> false + * f.close_read #=> nil + * f.closed? #=> true + */ + + static VALUE rb_io_closed(io) VALUE io; @@ -1461,6 +1874,24 @@ rb_io_closed(io) return (fptr->f || fptr->f2)?Qfalse:Qtrue; } +/* + * call-seq: + * ios.close_read => nil + * + * Closes the read end of a duplex I/O stream (i.e., one that contains + * both a read and a write stream, such as a pipe). Will raise an + * IOError if the stream is not duplexed. + * + * f = IO.popen("/bin/sh","r+") + * f.close_read + * f.readlines + * + * produces: + * + * prog.rb:3:in `readlines': not opened for reading (IOError) + * from prog.rb:3 + */ + static VALUE rb_io_close_read(io) VALUE io; @@ -1487,6 +1918,25 @@ rb_io_close_read(io) return Qnil; } +/* + * call-seq: + * ios.close_write => nil + * + * Closes the write end of a duplex I/O stream (i.e., one that contains + * both a read and a write stream, such as a pipe). Will raise an + * IOError if the stream is not duplexed. + * + * f = IO.popen("/bin/sh","r+") + * f.close_write + * f.print "nowhere" + * + * produces: + * + * prog.rb:3:in `write': not opened for writing (IOError) + * from prog.rb:3:in `print' + * from prog.rb:3 + */ + static VALUE rb_io_close_write(io) VALUE io; @@ -1512,6 +1962,19 @@ rb_io_close_write(io) return Qnil; } +/* + * call-seq: + * ios.sysseek(offset, whence=SEEK_SET) => integer + * + * Seeks to a given offset in the stream according to the value + * of whence (see IO#seek for values of + * whence). Returns the new offset into the file. + * + * f = File.new("testfile") + * f.sysseek(-13, IO::SEEK_END) #=> 53 + * f.sysread(10) #=> "And so on." + */ + static VALUE rb_io_sysseek(argc, argv, io) int argc; @@ -1541,6 +2004,19 @@ rb_io_sysseek(argc, argv, io) return OFFT2NUM(pos); } +/* + * call-seq: + * ios.syswrite(string ) => integer + * + * Writes the given string to ios using a low-level write. + * Returns the number of bytes written. Do not mix with other methods + * that write to ios or you may get unpredictable results. + * Raises SystemCallError on error. + * + * f = File.new("out", "w") + * f.syswrite("ABCDEF") #=> 6 + */ + static VALUE rb_io_syswrite(io, str) VALUE io, str; @@ -1570,6 +2046,20 @@ rb_io_syswrite(io, str) return LONG2FIX(n); } +/* + * call-seq: + * ios.sysread(integer ) => string + * + * Reads integer bytes from ios using a low-level + * read and returns them as a string. Do not mix with other methods + * that read from ios or you may get unpredictable results. + * Raises SystemCallError on error and + * EOFError 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; @@ -1620,6 +2110,15 @@ rb_io_sysread(argc, argv, io) return str; } +/* + * call-seq: + * ios.binmode => ios + * + * Puts ios into binary mode. This is useful only in + * MS-DOS/Windows environments. Once a stream is in binary mode, it + * cannot be reset to nonbinary mode. + */ + VALUE rb_io_binmode(io) VALUE io; @@ -2229,6 +2728,47 @@ rb_io_popen(str, argc, argv, klass) return port; } +/* + * call-seq: + * IO.popen(cmd_string, mode="r" ) => io + * IO.popen(cmd_string, mode="r" ) {|io| block } => obj + * + * Runs the specified command string as a subprocess; the subprocess's + * standard input and output will be connected to the returned + * IO object. If cmd_string starts with a + * ``-'', then a new instance of Ruby is started as the + * subprocess. The default mode for the new file object is ``r'', but + * mode may be set to any of the modes listed in the description + * for class IO. + * + * If a block is given, Ruby will run the command as a child connected + * to Ruby with a pipe. Ruby's end of the pipe will be passed as a + * parameter to the block. In this case IO::popen returns + * the value of the block. + * + * If a block is given with a cmd_string of ``-'', + * the block will be run in two separate processes: once in the parent, + * and once in a child. The parent process will be passed the pipe + * object as a parameter to the block, the child version of the block + * will be passed nil, and the child's standard in and + * standard out will be connected to the parent through the pipe. Not + * available on all platforms. + * + * f = IO.popen("uname") + * p f.readlines + * puts "Parent is #{Process.pid}" + * IO.popen ("date") { |f| puts f.gets } + * IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f}"} + * + * produces: + * + * ["Linux\n"] + * Parent is 26166 + * Wed Apr 9 08:53:52 CDT 2003 + * 26169 is here, f is + * 26166 is here, f is # + */ + static VALUE rb_io_s_popen(argc, argv, klass) int argc; @@ -2276,6 +2816,19 @@ rb_open_file(argc, argv, io) return io; } +/* + * call-seq: + * IO.open(fd, mode_string="r" ) => io + * IO.open(fd, mode_string="r" ) {|io| block } => obj + * + * With no associated block, open is a synonym for + * IO::new. If the optional code block is given, it will + * be passed io as an argument, and the IO object will + * automatically be closed when the block terminates. In this instance, + * IO::open returns the value of the block. + * + */ + static VALUE rb_io_s_open(argc, argv, klass) int argc; @@ -2291,6 +2844,17 @@ rb_io_s_open(argc, argv, klass) return io; } +/* + * call-seq: + * IO.sysopen(path, [mode, [perm]]) => fixnum + * + * Opens the given path, returning the underlying file descriptor as a + * Fixnum. + * + * IO.sysopen("testfile") #=> 3 + * + */ + static VALUE rb_io_s_sysopen(argc, argv) int argc; @@ -2450,6 +3014,22 @@ io_reopen(io, nfile) return io; } +/* + * call-seq: + * ios.reopen(other_IO) => ios + * ios.reopen(path, mode_str) => ios + * + * Reassociates ios with the I/O stream given in + * other_IO or to a new stream opened on path. 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) #=> # + * f2.readlines[0] #=> "This is line one\n" + */ + static VALUE rb_io_reopen(argc, argv, file) int argc; @@ -2574,6 +3154,15 @@ rb_io_init_copy(dest, io) return dest; } +/* + * call-seq: + * ios.printf(format_string [, obj, ...] ) => nil + * + * Formats and writes to ios, converting parameters under + * control of the format string. See Kernel#sprintf + * for details. + */ + VALUE rb_io_printf(argc, argv, out) int argc; @@ -2605,6 +3194,26 @@ rb_f_printf(argc, argv) return Qnil; } +/* + * call-seq: + * ios.print() => nil + * ios.print(obj, ...) => nil + * + * Writes the given object(s) to ios. The stream must be + * opened for writing. If the output record separator ($\) + * is not nil, it will be appended to the output. If no + * arguments are given, prints $_. Objects that aren't + * strings will be converted by calling their to_s method. + * With no argument, prints the contents of the variable $_. + * Returns nil. + * + * $stdout.print("This is ", 100, " percent.\n") + * + * produces: + * + * This is 100 percent. + */ + VALUE rb_io_print(argc, argv, out) int argc; @@ -2649,6 +3258,22 @@ rb_f_print(argc, argv) return Qnil; } +/* + * call-seq: + * ios.putc(obj) => obj + * + * If obj is Numeric, write the character whose + * code is obj, otherwise write the first character of the + * string representation of obj to ios. + * + * $stdout.putc "A" + * $stdout.putc 65 + * + * produces: + * + * AA + */ + static VALUE rb_io_putc(io, ch) VALUE io, ch; @@ -2683,6 +3308,26 @@ io_puts_ary(ary, out) return Qnil; } +/* + * call-seq: + * ios.puts(obj, ...) => nil + * + * Writes the given objects to ios as with + * IO#print. Writes a record separator (typically a + * newline) after any that do not already end with a newline sequence. + * If called with an array argument, writes each element on a new line. + * If called without arguments, outputs a single record separator. + * + * $stdout.puts("this", "is", "a", "test") + * + * produces: + * + * this + * is + * a + * test + */ + VALUE rb_io_puts(argc, argv, out) int argc; @@ -2861,6 +3506,24 @@ prep_path(io, path) fptr->path = strdup(path); } +/* + * call-seq: + * IO.new(fd, mode) => io + * + * Returns a new IO object (a stream) for the given + * integer file descriptor and mode string. See also + * IO#fileno and IO::for_fd. + * + * a = IO.new(2,"w") # '2' is standard error + * $stderr.puts "Hello" + * a.puts "World" + * + * produces: + * + * Hello + * World + */ + static VALUE rb_io_initialize(argc, argv, io) int argc; @@ -2922,6 +3585,24 @@ rb_file_initialize(argc, argv, io) return io; } +/* + * call-seq: + * IO.new(fd, mode_string) => io + * + * Returns a new IO object (a stream) for the given + * integer file descriptor and mode string. See also + * IO#fileno and IO::for_fd. + * + * a = IO.new(2,"w") # '2' is standard error + * $stderr.puts "Hello" + * a.puts "World" + * + * produces: + * + * Hello + * World + */ + static VALUE rb_io_s_new(argc, argv, klass) int argc; @@ -2937,6 +3618,15 @@ rb_io_s_new(argc, argv, klass) return rb_class_new_instance(argc, argv, klass); } + +/* + * call-seq: + * IO.for_fd(fd, mode) => io + * + * Synonym for IO::new. + * + */ + static VALUE rb_io_s_for_fd(argc, argv, klass) int argc; @@ -3238,6 +3928,16 @@ rb_f_backquote(obj, str) #include #endif +/* + * call-seq: + * IO.select(read_array + * [, write_array + * [, error_array + * [, timeout]]] ) => array or nil + * + * See Kernel#select. + */ + static VALUE rb_f_select(argc, argv, obj) int argc; @@ -3475,6 +4175,19 @@ rb_io_ctl(io, req, arg, io_p) #endif } + +/* + * call-seq: + * ios.ioctl(integer_cmd, arg) => integer + * + * Provides a mechanism for issuing low-level commands to control or + * query I/O devices. Arguments and results are platform dependent. If + * arg is a number, its value is passed directly. If it is a + * string, it is interpreted as a binary sequence of bytes. On Unix + * platforms, see ioctl(2) for details. Not implemented on + * all platforms. + */ + static VALUE rb_io_ioctl(argc, argv, io) int argc; @@ -3487,6 +4200,19 @@ rb_io_ioctl(argc, argv, io) return rb_io_ctl(io, req, arg, 1); } +/* + * call-seq: + * ios.fcntl(integer_cmd, arg) => integer + * + * Provides a mechanism for issuing low-level commands to control or + * query file-oriented I/O streams. Arguments and results are platform + * dependent. If arg is a number, its value is passed + * directly. If it is a string, it is interpreted as a binary sequence + * of bytes (Array#pack might be a useful way to build this + * string). On Unix platforms, see fcntl(2) for details. + * Not implemented on all platforms. + */ + static VALUE rb_io_fcntl(argc, argv, io) int argc; @@ -3613,6 +4339,42 @@ io_new_instance(args) return rb_class_new_instance(2, (VALUE*)args+1, *(VALUE*)args); } +/* + * call-seq: + * IO.pipe -> array + * + * Creates a pair of pipe endpoints (connected to each other) and + * returns them as a two-element array of IO objects: + * [ read_file, write_file ]. Not + * available on all platforms. + * + * In the example below, the two processes close the ends of the pipe + * that they are not using. This is not just a cosmetic nicety. The + * read end of a pipe will not generate an end of file condition if + * there are any writers with the pipe still open. In the case of the + * parent process, the rd.read will never return if it + * does not first issue a wr.close. + * + * rd, wr = IO.pipe + * + * if fork + * wr.close + * puts "Parent got: <#{rd.read}>" + * rd.close + * Process.wait + * else + * rd.close + * puts "Sending message to parent" + * wr.write "Hi Dad" + * wr.close + * end + * + * produces: + * + * Sending message to parent + * Parent got: + */ + static VALUE rb_io_s_pipe(klass) VALUE klass; @@ -3673,6 +4435,23 @@ io_s_foreach(arg) return Qnil; } +/* + * call-seq: + * IO.foreach(name, sep_string=$/) {|line| block } => nil + * + * Executes the block for every line in the named I/O port, where lines + * are separated by sep_string. + * + * IO.foreach("testfile") {|x| print "GOT ", x } + * + * produces: + * + * GOT This is line one + * GOT This is line two + * GOT This is line three + * GOT And so on... + */ + static VALUE rb_io_s_foreach(argc, argv) int argc; @@ -3703,6 +4482,19 @@ io_s_readlines(arg) return rb_io_readlines(arg->argc, &arg->sep, arg->io); } +/* + * call-seq: + * IO.readlines(name, sep_string=$/) => array + * + * Reads the entire file specified by name as individual + * lines, and returns those lines in an array. Lines are separated by + * sep_string. + * + * a = IO.readlines("testfile") + * a[0] #=> "This is line one\n" + * + */ + static VALUE rb_io_s_readlines(argc, argv, io) int argc; @@ -3728,6 +4520,19 @@ io_s_read(arg) return io_read(arg->argc, &arg->sep, arg->io); } +/* + * call-seq: + * IO.read(rane, [length [, offset]] ) => string + * + * Opens the file, optionally seeks to the given offset, then returns + * length bytes (defaulting to the rest of the file). + * read ensures the file is closed before returning. + * + * IO.read("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n" + * IO.read("testfile", 20) #=> "This is line one\nThi" + * IO.read("testfile", 20, 10) #=> "ne one\nThis is line " + */ + static VALUE rb_io_s_read(argc, argv, io) int argc; @@ -4060,8 +4865,14 @@ opt_i_set(val) * platform-specific separator character. * * I/O ports may be opened in any one of several different modes, which - * are shown in this section as mode_string. This mode string - * must be one of the values listed in the following table. + * are shown in this section as mode. The mode may + * either be a Fixnum or a String. If numeric, it should be + * one of the operating system specific constants (O_RDONLY, + * O_WRONLY, O_RDWR, O_APPEND and so on). See man open(2) for + * more information. + * + * If the mode is given as a String, it must be one of the + * values listed in the following table. * * Mode | Meaning * -----+-------------------------------------------------------- @@ -4085,6 +4896,12 @@ opt_i_set(val) * "b" | (DOS/Windows only) Binary file mode (may appear with * | any of the key letters listed above). * + * + * The global constant ARGF (also accessible as $<) provides an + * IO-like stream which allows access to all files mentioned on the + * command line (or STDIN if no files are mentioned). ARGF provides + * the methods #path and #filename to access + * the name of the file currently being read. */ void