1 /**********************************************************************
6 created at: Fri Oct 15 18:08:59 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
12 **********************************************************************/
14 #include "ruby/ruby.h"
16 #include "ruby/signal.h"
21 #if defined(DOSISH) || defined(__CYGWIN__)
25 #include <sys/types.h>
26 #if !defined(_WIN32) && !defined(__DJGPP__)
27 # if defined(__BEOS__)
28 # include <net/socket.h>
30 # include <sys/socket.h>
34 #if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32) || defined(__human68k__) || defined(__EMX__) || defined(__BEOS__)
35 # define NO_SAFE_RENAME
38 #if defined(MSDOS) || defined(__CYGWIN__) || defined(_WIN32)
39 # define NO_LONG_FNAME
42 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(sun) || defined(_nec_ews)
50 #include <sys/types.h>
51 #if defined(HAVE_SYS_IOCTL_H) && !defined(DJGPP) && !defined(_WIN32) && !defined(__human68k__)
52 #include <sys/ioctl.h>
54 #if defined(HAVE_FCNTL_H) || defined(_WIN32)
56 #elif defined(HAVE_SYS_FCNTL_H)
57 #include <sys/fcntl.h>
60 #if !HAVE_OFF_T && !defined(off_t)
66 /* EMX has sys/param.h, but.. */
67 #if defined(HAVE_SYS_PARAM_H) && !(defined(__EMX__) || defined(__HIUX_MPP__))
68 # include <sys/param.h>
81 #elif defined HAVE_SYS_SYSCALL_H
82 #include <sys/syscall.h>
85 extern void Init_File(void);
89 # define NOFILE (OPEN_MAX)
91 #include <net/socket.h>
94 #include "ruby/util.h"
97 #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
100 #if SIZEOF_OFF_T > SIZEOF_LONG && !defined(HAVE_LONG_LONG)
101 # error off_t is bigger than long, but you have no long long...
105 # ifdef _POSIX_PIPE_BUF
106 # define PIPE_BUF _POSIX_PIPE_BUF
108 # define PIPE_BUF 512 /* is this ok? */
116 VALUE rb_stdin
, rb_stdout
, rb_stderr
;
117 VALUE rb_deferr
; /* rescue VIM plugin */
118 static VALUE orig_stdout
, orig_stderr
;
127 static ID id_write
, id_read
, id_getc
, id_flush
, id_encode
, id_readpartial
;
129 struct timeval
rb_time_interval(VALUE
);
132 VALUE filename
, current_file
;
139 rb_encoding
*enc
, *enc2
;
142 static int max_file_descriptor
= NOFILE
;
143 #define UPDATE_MAXFD(fd) \
145 if (max_file_descriptor < (fd)) max_file_descriptor = (fd); \
147 #define UPDATE_MAXFD_PIPE(filedes) \
149 UPDATE_MAXFD((filedes)[0]); \
150 UPDATE_MAXFD((filedes)[1]); \
154 #define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
155 #define ARGF argf_of(argf)
157 #ifdef _STDIO_USES_IOSTREAM /* GNU libc */
159 # define STDIO_READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end)
161 # define STDIO_READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr)
163 #elif defined(FILE_COUNT)
164 # define STDIO_READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0)
165 #elif defined(FILE_READEND)
166 # define STDIO_READ_DATA_PENDING(fp) ((fp)->FILE_READPTR < (fp)->FILE_READEND)
167 #elif defined(__BEOS__)
168 # define STDIO_READ_DATA_PENDING(fp) (fp->_state._eof == 0)
170 # define STDIO_READ_DATA_PENDING(fp) (((unsigned int)(*(fp))->_cnt) > 0)
172 # define STDIO_READ_DATA_PENDING(fp) (!feof(fp))
176 #define fopen(file_spec, mode) fopen(file_spec, mode, "rfm=stmlf")
177 #define open(file_spec, flags, mode) open(file_spec, flags, mode, "rfm=stmlf")
180 #define GetWriteIO(io) rb_io_get_write_io(io)
182 #define READ_DATA_PENDING(fptr) ((fptr)->rbuf_len)
183 #define READ_DATA_PENDING_COUNT(fptr) ((fptr)->rbuf_len)
184 #define READ_DATA_PENDING_PTR(fptr) ((fptr)->rbuf+(fptr)->rbuf_off)
185 #define READ_DATA_BUFFERED(fptr) READ_DATA_PENDING(fptr)
187 #define READ_CHECK(fptr) do {\
188 if (!READ_DATA_PENDING(fptr)) {\
189 rb_thread_wait_fd((fptr)->fd);\
190 rb_io_check_closed(fptr);\
196 # define S_ISSOCK(m) _S_ISSOCK(m)
199 # define S_ISSOCK(m) ((m & S_IFMT) == _S_IFSOCK)
202 # define S_ISSOCK(m) ((m & S_IFMT) == S_IFSOCK)
209 #define is_socket(fd, path) rb_w32_is_socket(fd)
210 #elif !defined(S_ISSOCK)
211 #define is_socket(fd, path) 0
212 #define shutdown(a,b) 0
215 is_socket(int fd
, const char *path
)
218 if (fstat(fd
, &sbuf
) < 0)
220 return S_ISSOCK(sbuf
.st_mode
);
227 rb_raise(rb_eEOFError
, "end of file reached");
231 rb_io_taint_check(VALUE io
)
233 if (!OBJ_TAINTED(io
) && rb_safe_level() >= 4)
234 rb_raise(rb_eSecurityError
, "Insecure: operation on untainted IO");
240 rb_io_check_initialized(rb_io_t
*fptr
)
243 rb_raise(rb_eIOError
, "uninitialized stream");
248 rb_io_check_closed(rb_io_t
*fptr
)
250 rb_io_check_initialized(fptr
);
252 rb_raise(rb_eIOError
, "closed stream");
256 static int io_fflush(rb_io_t
*);
259 rb_io_get_io(VALUE io
)
261 return rb_convert_type(io
, T_FILE
, "IO", "to_io");
265 rb_io_check_io(VALUE io
)
267 return rb_check_convert_type(io
, T_FILE
, "IO", "to_io");
271 rb_io_get_write_io(VALUE io
)
274 write_io
= RFILE(io
)->fptr
->tied_io_for_writing
;
283 * IO.try_convert(obj) -> io or nil
285 * Try to convert <i>obj</i> into an IO, using to_io method.
286 * Returns converted IO or nil if <i>obj</i> cannot be converted
289 * IO.try_convert(STDOUT) # => STDOUT
290 * IO.try_convert("STDOUT") # => nil
293 rb_io_s_try_convert(VALUE dummy
, VALUE io
)
295 return rb_io_check_io(io
);
299 io_unread(rb_io_t
*fptr
)
302 rb_io_check_closed(fptr
);
303 if (fptr
->rbuf_len
== 0 || fptr
->mode
& FMODE_DUPLEX
)
305 /* xxx: target position may be negative if buffer is filled by ungetc */
306 #if defined(_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__)
307 if (!(fptr
->mode
& FMODE_BINMODE
)) {
308 int len
= fptr
->rbuf_len
;
309 while (fptr
->rbuf_len
-- > 0) {
310 if (fptr
->rbuf
[fptr
->rbuf_len
] == '\n')
313 r
= lseek(fptr
->fd
, -len
, SEEK_CUR
);
317 r
= lseek(fptr
->fd
, -fptr
->rbuf_len
, SEEK_CUR
);
320 fptr
->mode
|= FMODE_DUPLEX
;
329 io_ungetc(VALUE str
, rb_io_t
*fptr
)
331 int len
= RSTRING_LEN(str
);
333 if (fptr
->rbuf
== NULL
) {
337 fptr
->rbuf_capa
= len
;
339 fptr
->rbuf_capa
= 8192;
340 fptr
->rbuf
= ALLOC_N(char, fptr
->rbuf_capa
);
342 if (fptr
->rbuf_capa
< len
+ fptr
->rbuf_len
) {
343 rb_raise(rb_eIOError
, "ungetc failed");
345 if (fptr
->rbuf_off
< len
) {
346 MEMMOVE(fptr
->rbuf
+fptr
->rbuf_capa
-fptr
->rbuf_len
,
347 fptr
->rbuf
+fptr
->rbuf_off
,
348 char, fptr
->rbuf_len
);
349 fptr
->rbuf_off
= fptr
->rbuf_capa
-fptr
->rbuf_len
;
353 MEMMOVE(fptr
->rbuf
+fptr
->rbuf_off
, RSTRING_PTR(str
), char, len
);
357 flush_before_seek(rb_io_t
*fptr
)
365 #define io_seek(fptr, ofs, whence) lseek(flush_before_seek(fptr)->fd, ofs, whence)
366 #define io_tell(fptr) lseek(flush_before_seek(fptr)->fd, 0, SEEK_CUR)
374 #define FMODE_SYNCWRITE (FMODE_SYNC|FMODE_WRITABLE)
377 rb_io_check_readable(rb_io_t
*fptr
)
379 rb_io_check_closed(fptr
);
380 if (!(fptr
->mode
& FMODE_READABLE
)) {
381 rb_raise(rb_eIOError
, "not opened for reading");
383 if (fptr
->wbuf_len
) {
386 if (fptr
->tied_io_for_writing
) {
388 GetOpenFile(fptr
->tied_io_for_writing
, wfptr
);
391 if (!fptr
->enc
&& fptr
->fd
== 0) {
392 fptr
->enc
= rb_default_external_encoding();
397 io_read_encoding(rb_io_t
*fptr
)
402 return rb_default_external_encoding();
406 io_input_encoding(rb_io_t
*fptr
)
411 return io_read_encoding(fptr
);
415 rb_io_check_writable(rb_io_t
*fptr
)
417 rb_io_check_closed(fptr
);
418 if (!(fptr
->mode
& FMODE_WRITABLE
)) {
419 rb_raise(rb_eIOError
, "not opened for writing");
421 if (fptr
->rbuf_len
) {
427 rb_read_pending(FILE *fp
)
429 return STDIO_READ_DATA_PENDING(fp
);
433 rb_io_read_pending(rb_io_t
*fptr
)
435 return READ_DATA_PENDING(fptr
);
439 rb_read_check(FILE *fp
)
441 if (!STDIO_READ_DATA_PENDING(fp
)) {
442 rb_thread_wait_fd(fileno(fp
));
447 rb_io_read_check(rb_io_t
*fptr
)
449 if (!READ_DATA_PENDING(fptr
)) {
450 rb_thread_wait_fd(fptr
->fd
);
462 if (errno
== EMFILE
|| errno
== ENFILE
|| errno
== ENOMEM
) {
474 io_alloc(VALUE klass
)
476 NEWOBJ(io
, struct RFile
);
477 OBJSETUP(io
, klass
, T_FILE
);
485 # define S_ISREG(m) ((m & S_IFMT) == S_IFREG)
489 wsplit_p(rb_io_t
*fptr
)
491 #if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(O_NONBLOCK)
495 if (!(fptr
->mode
& FMODE_WSPLIT_INITIALIZED
)) {
497 if (fstat(fptr
->fd
, &buf
) == 0 &&
498 !S_ISREG(buf
.st_mode
)
499 #if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(O_NONBLOCK)
500 && (r
= fcntl(fptr
->fd
, F_GETFL
)) != -1 &&
504 fptr
->mode
|= FMODE_WSPLIT
;
506 fptr
->mode
|= FMODE_WSPLIT_INITIALIZED
;
508 return fptr
->mode
& FMODE_WSPLIT
;
511 struct io_internal_struct
{
518 internal_read_func(void *ptr
)
520 struct io_internal_struct
*iis
= (struct io_internal_struct
*)ptr
;
521 return read(iis
->fd
, iis
->buf
, iis
->capa
);
525 internal_write_func(void *ptr
)
527 struct io_internal_struct
*iis
= (struct io_internal_struct
*)ptr
;
528 return write(iis
->fd
, iis
->buf
, iis
->capa
);
532 rb_read_internal(int fd
, void *buf
, size_t count
)
534 struct io_internal_struct iis
;
539 return rb_thread_blocking_region(internal_read_func
, &iis
, RB_UBF_DFL
, 0);
543 rb_write_internal(int fd
, void *buf
, size_t count
)
545 struct io_internal_struct iis
;
550 return rb_thread_blocking_region(internal_write_func
, &iis
, RB_UBF_DFL
, 0);
554 io_fflush(rb_io_t
*fptr
)
557 int wbuf_off
, wbuf_len
;
559 rb_io_check_closed(fptr
);
560 if (fptr
->wbuf_len
== 0)
562 if (!rb_thread_fd_writable(fptr
->fd
)) {
563 rb_io_check_closed(fptr
);
566 if (fptr
->wbuf_len
== 0)
568 wbuf_off
= fptr
->wbuf_off
;
569 wbuf_len
= fptr
->wbuf_len
;
572 !rb_thread_critical
&&
573 !rb_thread_alone() &&
577 r
= rb_write_internal(fptr
->fd
, fptr
->wbuf
+wbuf_off
, l
);
578 /* xxx: Other threads may modify wbuf.
579 * A lock is required, definitely. */
580 rb_io_check_closed(fptr
);
581 if (fptr
->wbuf_len
<= r
) {
591 if (rb_io_wait_writable(fptr
->fd
)) {
592 rb_io_check_closed(fptr
);
598 #ifdef HAVE_RB_FD_INIT
600 wait_readable(VALUE p
)
602 rb_fdset_t
*rfds
= (rb_fdset_t
*)p
;
604 return rb_thread_select(rb_fd_max(rfds
), rb_fd_ptr(rfds
), NULL
, NULL
, NULL
);
609 rb_io_wait_readable(int f
)
615 #if defined(ERESTART)
618 rb_thread_wait_fd(f
);
622 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
627 #ifdef HAVE_RB_FD_INIT
628 rb_ensure(wait_readable
, (VALUE
)&rfds
,
629 (VALUE (*)(VALUE
))rb_fd_term
, (VALUE
)&rfds
);
631 rb_thread_select(f
+ 1, &rfds
, NULL
, NULL
, NULL
);
640 #ifdef HAVE_RB_FD_INIT
642 wait_writable(VALUE p
)
644 rb_fdset_t
*wfds
= (rb_fdset_t
*)p
;
646 return rb_thread_select(rb_fd_max(wfds
), NULL
, rb_fd_ptr(wfds
), NULL
, NULL
);
651 rb_io_wait_writable(int f
)
657 #if defined(ERESTART)
660 rb_thread_fd_writable(f
);
664 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
669 #ifdef HAVE_RB_FD_INIT
670 rb_ensure(wait_writable
, (VALUE
)&wfds
,
671 (VALUE (*)(VALUE
))rb_fd_term
, (VALUE
)&wfds
);
673 rb_thread_select(f
+ 1, NULL
, &wfds
, NULL
, NULL
);
682 /* writing functions */
684 io_fwrite(VALUE str
, rb_io_t
*fptr
)
686 long len
, n
, r
, l
, offset
= 0;
689 * If an external encoding was specified and it differs from
690 * the strings encoding then we must transcode before writing.
691 * We must also transcode if two encodings were specified
694 /* transcode str before output */
695 /* the methods in transcode.c are static, so call indirectly */
696 /* Can't use encode! because puts writes a frozen newline */
698 str
= rb_funcall(str
, id_encode
, 2,
699 rb_enc_from_encoding(fptr
->enc2
),
700 rb_enc_from_encoding(fptr
->enc
));
703 str
= rb_funcall(str
, id_encode
, 1,
704 rb_enc_from_encoding(fptr
->enc
));
708 len
= RSTRING_LEN(str
);
709 if ((n
= len
) <= 0) return n
;
710 if (fptr
->wbuf
== NULL
&& !(fptr
->mode
& FMODE_SYNC
)) {
713 fptr
->wbuf_capa
= 8192;
714 fptr
->wbuf
= ALLOC_N(char, fptr
->wbuf_capa
);
716 if ((fptr
->mode
& (FMODE_SYNC
|FMODE_TTY
)) ||
717 (fptr
->wbuf
&& fptr
->wbuf_capa
<= fptr
->wbuf_len
+ len
)) {
718 /* xxx: use writev to avoid double write if available */
719 if (fptr
->wbuf_len
&& fptr
->wbuf_len
+len
<= fptr
->wbuf_capa
) {
720 if (fptr
->wbuf_capa
< fptr
->wbuf_off
+fptr
->wbuf_len
+len
) {
721 MEMMOVE(fptr
->wbuf
, fptr
->wbuf
+fptr
->wbuf_off
, char, fptr
->wbuf_len
);
724 MEMMOVE(fptr
->wbuf
+fptr
->wbuf_off
+fptr
->wbuf_len
, RSTRING_PTR(str
)+offset
, char, len
);
725 fptr
->wbuf_len
+= len
;
728 if (io_fflush(fptr
) < 0)
732 /* avoid context switch between "a" and "\n" in STDERR.puts "a".
734 if (fptr
->stdio_file
!= stderr
&& !rb_thread_fd_writable(fptr
->fd
)) {
735 rb_io_check_closed(fptr
);
740 !rb_thread_critical
&&
741 !rb_thread_alone() &&
745 r
= rb_write_internal(fptr
->fd
, RSTRING_PTR(str
)+offset
, l
);
746 /* xxx: other threads may modify given string. */
747 if (r
== n
) return len
;
753 if (rb_io_wait_writable(fptr
->fd
)) {
754 rb_io_check_closed(fptr
);
755 if (offset
< RSTRING_LEN(str
))
761 if (fptr
->wbuf_off
) {
763 MEMMOVE(fptr
->wbuf
, fptr
->wbuf
+fptr
->wbuf_off
, char, fptr
->wbuf_len
);
766 MEMMOVE(fptr
->wbuf
+fptr
->wbuf_off
+fptr
->wbuf_len
, RSTRING_PTR(str
)+offset
, char, len
);
767 fptr
->wbuf_len
+= len
;
772 rb_io_fwrite(const char *ptr
, long len
, FILE *f
)
778 of
.mode
= FMODE_WRITABLE
;
780 return io_fwrite(rb_str_new(ptr
, len
), &of
);
785 * ios.write(string) => integer
787 * Writes the given string to <em>ios</em>. The stream must be opened
788 * for writing. If the argument is not a string, it will be converted
789 * to a string using <code>to_s</code>. Returns the number of bytes
792 * count = $stdout.write( "This is a test\n" )
793 * puts "That was #{count} bytes of data"
798 * That was 15 bytes of data
802 io_write(VALUE io
, VALUE str
)
810 str
= rb_obj_as_string(str
);
811 tmp
= rb_io_check_io(io
);
813 /* port is not IO, call write method for it. */
814 return rb_funcall(io
, id_write
, 1, str
);
817 if (RSTRING_LEN(str
) == 0) return INT2FIX(0);
819 GetOpenFile(io
, fptr
);
820 rb_io_check_writable(fptr
);
822 n
= io_fwrite(str
, fptr
);
823 if (n
== -1L) rb_sys_fail(fptr
->path
);
829 rb_io_write(VALUE io
, VALUE str
)
831 return rb_funcall(io
, id_write
, 1, str
);
838 * String Output---Writes <i>obj</i> to <em>ios</em>.
839 * <i>obj</i> will be converted to a string using
842 * $stdout << "Hello " << "world!\n"
851 rb_io_addstr(VALUE io
, VALUE str
)
853 rb_io_write(io
, str
);
861 * Flushes any buffered data within <em>ios</em> to the underlying
862 * operating system (note that this is Ruby internal buffering only;
863 * the OS may buffer the data as well).
865 * $stdout.print "no newline"
874 rb_io_flush(VALUE io
)
878 if (TYPE(io
) != T_FILE
) {
879 return rb_funcall(io
, id_flush
, 0);
883 GetOpenFile(io
, fptr
);
885 if (fptr
->mode
& FMODE_WRITABLE
) {
888 if (fptr
->mode
& FMODE_READABLE
) {
898 * ios.tell => integer
900 * Returns the current offset (in bytes) of <em>ios</em>.
902 * f = File.new("testfile")
904 * f.gets #=> "This is line one\n"
914 GetOpenFile(io
, fptr
);
916 if (pos
< 0 && errno
) rb_sys_fail(fptr
->path
);
917 return OFFT2NUM(pos
);
921 rb_io_seek(VALUE io
, VALUE offset
, int whence
)
926 pos
= NUM2OFFT(offset
);
927 GetOpenFile(io
, fptr
);
928 pos
= io_seek(fptr
, pos
, whence
);
929 if (pos
< 0 && errno
) rb_sys_fail(fptr
->path
);
936 * ios.seek(amount, whence=SEEK_SET) -> 0
938 * Seeks to a given offset <i>anInteger</i> in the stream according to
939 * the value of <i>whence</i>:
941 * IO::SEEK_CUR | Seeks to _amount_ plus current position
942 * --------------+----------------------------------------------------
943 * IO::SEEK_END | Seeks to _amount_ plus end of stream (you probably
944 * | want a negative value for _amount_)
945 * --------------+----------------------------------------------------
946 * IO::SEEK_SET | Seeks to the absolute location given by _amount_
950 * f = File.new("testfile")
951 * f.seek(-13, IO::SEEK_END) #=> 0
952 * f.readline #=> "And so on...\n"
956 rb_io_seek_m(int argc
, VALUE
*argv
, VALUE io
)
958 VALUE offset
, ptrname
;
959 int whence
= SEEK_SET
;
961 if (rb_scan_args(argc
, argv
, "11", &offset
, &ptrname
) == 2) {
962 whence
= NUM2INT(ptrname
);
965 return rb_io_seek(io
, offset
, whence
);
970 * ios.pos = integer => integer
972 * Seeks to the given position (in bytes) in <em>ios</em>.
974 * f = File.new("testfile")
976 * f.gets #=> "This is line two\n"
980 rb_io_set_pos(VALUE io
, VALUE offset
)
985 pos
= NUM2OFFT(offset
);
986 GetOpenFile(io
, fptr
);
987 pos
= io_seek(fptr
, pos
, SEEK_SET
);
988 if (pos
< 0) rb_sys_fail(fptr
->path
);
990 return OFFT2NUM(pos
);
997 * Positions <em>ios</em> to the beginning of input, resetting
998 * <code>lineno</code> to zero.
1000 * f = File.new("testfile")
1001 * f.readline #=> "This is line one\n"
1004 * f.readline #=> "This is line one\n"
1008 rb_io_rewind(VALUE io
)
1012 GetOpenFile(io
, fptr
);
1013 if (io_seek(fptr
, 0L, 0) < 0) rb_sys_fail(fptr
->path
);
1014 if (io
== ARGF
.current_file
) {
1015 ARGF
.gets_lineno
-= fptr
->lineno
;
1023 io_fillbuf(rb_io_t
*fptr
)
1027 if (fptr
->rbuf
== NULL
) {
1030 fptr
->rbuf_capa
= 8192;
1031 fptr
->rbuf
= ALLOC_N(char, fptr
->rbuf_capa
);
1033 if (fptr
->rbuf_len
== 0) {
1036 r
= rb_read_internal(fptr
->fd
, fptr
->rbuf
, fptr
->rbuf_capa
);
1039 if (rb_io_wait_readable(fptr
->fd
))
1041 rb_sys_fail(fptr
->path
);
1046 return -1; /* EOF */
1053 * ios.eof => true or false
1054 * ios.eof? => true or false
1056 * Returns true if <em>ios</em> is at end of file that means
1057 * there are no more data to read.
1058 * The stream must be opened for reading or an <code>IOError</code> will be
1061 * f = File.new("testfile")
1062 * dummy = f.readlines
1065 * If <em>ios</em> is a stream such as pipe or socket, <code>IO#eof?</code>
1066 * blocks until the other end sends some data or closes it.
1069 * Thread.new { sleep 1; w.close }
1070 * r.eof? #=> true after 1 second blocking
1073 * Thread.new { sleep 1; w.puts "a" }
1074 * r.eof? #=> false after 1 second blocking
1077 * r.eof? # blocks forever
1079 * Note that <code>IO#eof?</code> reads data to a input buffer.
1080 * So <code>IO#sysread</code> doesn't work with <code>IO#eof?</code>.
1088 GetOpenFile(io
, fptr
);
1089 rb_io_check_readable(fptr
);
1091 if (READ_DATA_PENDING(fptr
)) return Qfalse
;
1093 if (io_fillbuf(fptr
) < 0) {
1101 * ios.sync => true or false
1103 * Returns the current ``sync mode'' of <em>ios</em>. When sync mode is
1104 * true, all output is immediately flushed to the underlying operating
1105 * system and is not buffered by Ruby internally. See also
1106 * <code>IO#fsync</code>.
1108 * f = File.new("testfile")
1113 rb_io_sync(VALUE io
)
1117 io
= GetWriteIO(io
);
1118 GetOpenFile(io
, fptr
);
1119 return (fptr
->mode
& FMODE_SYNC
) ? Qtrue
: Qfalse
;
1124 * ios.sync = boolean => boolean
1126 * Sets the ``sync mode'' to <code>true</code> or <code>false</code>.
1127 * When sync mode is true, all output is immediately flushed to the
1128 * underlying operating system and is not buffered internally. Returns
1129 * the new state. See also <code>IO#fsync</code>.
1131 * f = File.new("testfile")
1134 * <em>(produces no output)</em>
1138 rb_io_set_sync(VALUE io
, VALUE mode
)
1142 io
= GetWriteIO(io
);
1143 GetOpenFile(io
, fptr
);
1145 fptr
->mode
|= FMODE_SYNC
;
1148 fptr
->mode
&= ~FMODE_SYNC
;
1155 * ios.fsync => 0 or nil
1157 * Immediately writes all buffered data in <em>ios</em> to disk.
1158 * Returns <code>nil</code> if the underlying operating system does not
1159 * support <em>fsync(2)</em>. Note that <code>fsync</code> differs from
1160 * using <code>IO#sync=</code>. The latter ensures that data is flushed
1161 * from Ruby's buffers, but doesn't not guarantee that the underlying
1162 * operating system actually writes it to disk.
1166 rb_io_fsync(VALUE io
)
1171 io
= GetWriteIO(io
);
1172 GetOpenFile(io
, fptr
);
1175 if (fsync(fptr
->fd
) < 0)
1176 rb_sys_fail(fptr
->path
);
1180 return Qnil
; /* not reached */
1186 * ios.fileno => fixnum
1187 * ios.to_i => fixnum
1189 * Returns an integer representing the numeric file descriptor for
1192 * $stdin.fileno #=> 0
1193 * $stdout.fileno #=> 1
1197 rb_io_fileno(VALUE io
)
1202 GetOpenFile(io
, fptr
);
1212 * Returns the process ID of a child process associated with
1213 * <em>ios</em>. This will be set by <code>IO::popen</code>.
1215 * pipe = IO.popen("-")
1217 * $stderr.puts "In parent, child pid is #{pipe.pid}"
1219 * $stderr.puts "In child, pid is #{$$}"
1222 * <em>produces:</em>
1224 * In child, pid is 26209
1225 * In parent, child pid is 26209
1233 GetOpenFile(io
, fptr
);
1236 return INT2FIX(fptr
->pid
);
1242 * ios.inspect => string
1244 * Return a string describing this IO object.
1248 rb_io_inspect(VALUE obj
)
1252 const char *st
= "";
1254 fptr
= RFILE(rb_io_taint_check(obj
))->fptr
;
1255 if (!fptr
|| !fptr
->path
) return rb_any_to_s(obj
);
1256 cname
= rb_obj_classname(obj
);
1260 return rb_sprintf("#<%s:%s%s>", cname
, fptr
->path
, st
);
1267 * Returns <em>ios</em>.
1271 rb_io_to_io(VALUE io
)
1276 /* reading functions */
1278 read_buffered_data(char *ptr
, long len
, rb_io_t
*fptr
)
1282 n
= READ_DATA_PENDING_COUNT(fptr
);
1283 if (n
<= 0) return 0;
1284 if (n
> len
) n
= len
;
1285 MEMMOVE(ptr
, fptr
->rbuf
+fptr
->rbuf_off
, char, n
);
1286 fptr
->rbuf_off
+= n
;
1287 fptr
->rbuf_len
-= n
;
1292 io_fread(VALUE str
, long offset
, rb_io_t
*fptr
)
1294 long len
= RSTRING_LEN(str
) - offset
;
1299 c
= read_buffered_data(RSTRING_PTR(str
)+offset
, n
, fptr
);
1302 if ((n
-= c
) <= 0) break;
1304 rb_thread_wait_fd(fptr
->fd
);
1305 rb_io_check_closed(fptr
);
1306 if (io_fillbuf(fptr
) < 0) {
1314 rb_io_fread(char *ptr
, long len
, FILE *f
)
1322 of
.mode
= FMODE_READABLE
;
1323 str
= rb_str_new(ptr
, len
);
1324 n
= io_fread(str
, 0, &of
);
1325 MEMCPY(ptr
, RSTRING_PTR(str
), char, n
);
1329 #define SMALLBUF 100
1332 remain_size(rb_io_t
*fptr
)
1335 off_t siz
= READ_DATA_PENDING_COUNT(fptr
);
1338 if (fstat(fptr
->fd
, &st
) == 0 && S_ISREG(st
.st_mode
)
1345 pos
= lseek(fptr
->fd
, 0, SEEK_CUR
);
1346 if (st
.st_size
>= pos
&& pos
>= 0) {
1347 siz
+= st
.st_size
- pos
+ 1;
1348 if (siz
> LONG_MAX
) {
1349 rb_raise(rb_eIOError
, "file too big for single read");
1360 io_enc_str(VALUE str
, rb_io_t
*fptr
)
1364 /* two encodings, so transcode from enc2 to enc */
1365 /* the methods in transcode.c are static, so call indirectly */
1366 str
= rb_funcall(str
, id_encode
, 2,
1367 rb_enc_from_encoding(fptr
->enc
),
1368 rb_enc_from_encoding(fptr
->enc2
));
1371 /* just one encoding, so associate it with the string */
1372 rb_enc_associate(str
, io_read_encoding(fptr
));
1378 read_all(rb_io_t
*fptr
, long siz
, VALUE str
)
1383 rb_encoding
*enc
= io_input_encoding(fptr
);
1384 int cr
= fptr
->enc2
? ENC_CODERANGE_BROKEN
: 0;
1386 if (siz
== 0) siz
= BUFSIZ
;
1388 str
= rb_str_new(0, siz
);
1391 rb_str_resize(str
, siz
);
1395 n
= io_fread(str
, bytes
, fptr
);
1396 if (n
== 0 && bytes
== 0) {
1400 if (cr
!= ENC_CODERANGE_BROKEN
)
1401 pos
= rb_str_coderange_scan_restartable(RSTRING_PTR(str
) + pos
, RSTRING_PTR(str
) + bytes
, enc
, &cr
);
1402 if (bytes
< siz
) break;
1404 rb_str_resize(str
, siz
);
1406 if (bytes
!= siz
) rb_str_resize(str
, bytes
);
1407 str
= io_enc_str(str
, fptr
);
1409 ENC_CODERANGE_SET(str
, cr
);
1415 rb_io_set_nonblock(rb_io_t
*fptr
)
1419 flags
= fcntl(fptr
->fd
, F_GETFL
);
1421 rb_sys_fail(fptr
->path
);
1426 if ((flags
& O_NONBLOCK
) == 0) {
1427 flags
|= O_NONBLOCK
;
1428 if (fcntl(fptr
->fd
, F_SETFL
, flags
) == -1) {
1429 rb_sys_fail(fptr
->path
);
1435 io_getpartial(int argc
, VALUE
*argv
, VALUE io
, int nonblock
)
1441 rb_scan_args(argc
, argv
, "11", &length
, &str
);
1443 if ((len
= NUM2LONG(length
)) < 0) {
1444 rb_raise(rb_eArgError
, "negative length %ld given", len
);
1448 str
= rb_str_new(0, len
);
1453 rb_str_resize(str
, len
);
1457 GetOpenFile(io
, fptr
);
1458 rb_io_check_readable(fptr
);
1465 if (RSTRING_LEN(str
) != len
) {
1467 rb_raise(rb_eRuntimeError
, "buffer string modified");
1469 n
= read_buffered_data(RSTRING_PTR(str
), len
, fptr
);
1472 if (RSTRING_LEN(str
) != len
) goto modified
;
1474 rb_io_set_nonblock(fptr
);
1475 n
= rb_read_internal(fptr
->fd
, RSTRING_PTR(str
), len
);
1478 n
= rb_read_internal(fptr
->fd
, RSTRING_PTR(str
), len
);
1481 if (!nonblock
&& rb_io_wait_readable(fptr
->fd
))
1483 rb_sys_fail(fptr
->path
);
1486 rb_str_resize(str
, n
);
1496 * ios.readpartial(maxlen) => string
1497 * ios.readpartial(maxlen, outbuf) => outbuf
1499 * Reads at most <i>maxlen</i> bytes from the I/O stream.
1500 * It blocks only if <em>ios</em> has no data immediately available.
1501 * It doesn't block if some data available.
1502 * If the optional <i>outbuf</i> argument is present,
1503 * it must reference a String, which will receive the data.
1504 * It raises <code>EOFError</code> on end of file.
1506 * readpartial is designed for streams such as pipe, socket, tty, etc.
1507 * It blocks only when no data immediately available.
1508 * This means that it blocks only when following all conditions hold.
1509 * * the buffer in the IO object is empty.
1510 * * the content of the stream is empty.
1511 * * the stream is not reached to EOF.
1513 * When readpartial blocks, it waits data or EOF on the stream.
1514 * If some data is reached, readpartial returns with the data.
1515 * If EOF is reached, readpartial raises EOFError.
1517 * When readpartial doesn't blocks, it returns or raises immediately.
1518 * If the buffer is not empty, it returns the data in the buffer.
1519 * Otherwise if the stream has some content,
1520 * it returns the data in the stream.
1521 * Otherwise if the stream is reached to EOF, it raises EOFError.
1523 * r, w = IO.pipe # buffer pipe content
1524 * w << "abc" # "" "abc".
1525 * r.readpartial(4096) #=> "abc" "" ""
1526 * r.readpartial(4096) # blocks because buffer and pipe is empty.
1528 * r, w = IO.pipe # buffer pipe content
1529 * w << "abc" # "" "abc"
1530 * w.close # "" "abc" EOF
1531 * r.readpartial(4096) #=> "abc" "" EOF
1532 * r.readpartial(4096) # raises EOFError
1534 * r, w = IO.pipe # buffer pipe content
1535 * w << "abc\ndef\n" # "" "abc\ndef\n"
1536 * r.gets #=> "abc\n" "def\n" ""
1537 * w << "ghi\n" # "def\n" "ghi\n"
1538 * r.readpartial(4096) #=> "def\n" "" "ghi\n"
1539 * r.readpartial(4096) #=> "ghi\n" "" ""
1541 * Note that readpartial behaves similar to sysread.
1542 * The differences are:
1543 * * If the buffer is not empty, read from the buffer instead of "sysread for buffered IO (IOError)".
1544 * * It doesn't cause Errno::EAGAIN and Errno::EINTR. When readpartial meets EAGAIN and EINTR by read system call, readpartial retry the system call.
1546 * The later means that readpartial is nonblocking-flag insensitive.
1547 * It blocks on the situation IO#sysread causes Errno::EAGAIN as if the fd is blocking mode.
1552 io_readpartial(int argc
, VALUE
*argv
, VALUE io
)
1556 ret
= io_getpartial(argc
, argv
, io
, 0);
1565 * ios.read_nonblock(maxlen) => string
1566 * ios.read_nonblock(maxlen, outbuf) => outbuf
1568 * Reads at most <i>maxlen</i> bytes from <em>ios</em> using
1569 * read(2) system call after O_NONBLOCK is set for
1570 * the underlying file descriptor.
1572 * If the optional <i>outbuf</i> argument is present,
1573 * it must reference a String, which will receive the data.
1575 * read_nonblock just calls read(2).
1576 * It causes all errors read(2) causes: EAGAIN, EINTR, etc.
1577 * The caller should care such errors.
1579 * read_nonblock causes EOFError on EOF.
1581 * If the read buffer is not empty,
1582 * read_nonblock reads from the buffer like readpartial.
1583 * In this case, read(2) is not called.
1588 io_read_nonblock(int argc
, VALUE
*argv
, VALUE io
)
1592 ret
= io_getpartial(argc
, argv
, io
, 1);
1601 * ios.write_nonblock(string) => integer
1603 * Writes the given string to <em>ios</em> using
1604 * write(2) system call after O_NONBLOCK is set for
1605 * the underlying file descriptor.
1607 * write_nonblock just calls write(2).
1608 * It causes all errors write(2) causes: EAGAIN, EINTR, etc.
1609 * The result may also be smaller than string.length (partial write).
1610 * The caller should care such errors and partial write.
1612 * If the write buffer is not empty, it is flushed at first.
1617 rb_io_write_nonblock(VALUE io
, VALUE str
)
1623 if (TYPE(str
) != T_STRING
)
1624 str
= rb_obj_as_string(str
);
1626 io
= GetWriteIO(io
);
1627 GetOpenFile(io
, fptr
);
1628 rb_io_check_writable(fptr
);
1632 rb_io_set_nonblock(fptr
);
1633 n
= write(fptr
->fd
, RSTRING_PTR(str
), RSTRING_LEN(str
));
1635 if (n
== -1) rb_sys_fail(fptr
->path
);
1642 * ios.read([length [, buffer]]) => string, buffer, or nil
1644 * Reads at most <i>length</i> bytes from the I/O stream, or to the
1645 * end of file if <i>length</i> is omitted or is <code>nil</code>.
1646 * <i>length</i> must be a non-negative integer or nil.
1647 * If the optional <i>buffer</i> argument is present, it must reference
1648 * a String, which will receive the data.
1650 * At end of file, it returns <code>nil</code> or <code>""</code>
1651 * depend on <i>length</i>.
1652 * <code><i>ios</i>.read()</code> and
1653 * <code><i>ios</i>.read(nil)</code> returns <code>""</code>.
1654 * <code><i>ios</i>.read(<i>positive-integer</i>)</code> returns nil.
1656 * <code><i>ios</i>.read(0)</code> returns <code>""</code>.
1658 * f = File.new("testfile")
1659 * f.read(16) #=> "This is line one"
1663 io_read(int argc
, VALUE
*argv
, VALUE io
)
1669 rb_scan_args(argc
, argv
, "02", &length
, &str
);
1671 if (NIL_P(length
)) {
1672 if (!NIL_P(str
)) StringValue(str
);
1673 GetOpenFile(io
, fptr
);
1674 rb_io_check_readable(fptr
);
1675 return read_all(fptr
, remain_size(fptr
), str
);
1677 len
= NUM2LONG(length
);
1679 rb_raise(rb_eArgError
, "negative length %ld given", len
);
1683 str
= rb_str_new(0, len
);
1688 rb_str_resize(str
,len
);
1691 GetOpenFile(io
, fptr
);
1692 rb_io_check_readable(fptr
);
1693 if (len
== 0) return str
;
1696 if (RSTRING_LEN(str
) != len
) {
1697 rb_raise(rb_eRuntimeError
, "buffer string modified");
1699 n
= io_fread(str
, 0, fptr
);
1701 if (fptr
->fd
< 0) return Qnil
;
1702 rb_str_resize(str
, 0);
1705 rb_str_resize(str
, n
);
1711 rscheck(const char *rsptr
, long rslen
, VALUE rs
)
1714 if (RSTRING_PTR(rs
) != rsptr
&& RSTRING_LEN(rs
) != rslen
)
1715 rb_raise(rb_eRuntimeError
, "rs modified");
1719 appendline(rb_io_t
*fptr
, int delim
, VALUE
*strp
, long *lp
)
1726 long pending
= READ_DATA_PENDING_COUNT(fptr
);
1728 const char *p
= READ_DATA_PENDING_PTR(fptr
);
1730 long last
= 0, len
= (c
!= EOF
);
1731 rb_encoding
*enc
= io_read_encoding(fptr
);
1733 if (limit
> 0 && pending
> limit
) pending
= limit
;
1734 e
= memchr(p
, delim
, pending
);
1735 if (e
) pending
= e
- p
+ 1;
1738 last
= RSTRING_LEN(str
);
1739 rb_str_resize(str
, last
+ len
);
1742 *strp
= str
= rb_str_buf_new(len
);
1743 rb_str_set_len(str
, len
);
1746 RSTRING_PTR(str
)[last
++] = c
;
1748 if (limit
> 0 && limit
== pending
) {
1749 char *p
= fptr
->rbuf
+fptr
->rbuf_off
;
1750 char *pp
= p
+ limit
;
1751 char *pl
= rb_enc_left_char_head(p
, pp
, enc
);
1757 rb_str_set_len(str
, RSTRING_LEN(str
)-diff
);
1760 read_buffered_data(RSTRING_PTR(str
) + last
, pending
, fptr
); /* must not fail */
1763 if (limit
== 0) return RSTRING_PTR(str
)[RSTRING_LEN(str
)-1];
1764 if (e
) return delim
;
1766 else if (c
!= EOF
) {
1769 rb_str_buf_cat(str
, &ch
, 1);
1772 *strp
= str
= rb_str_buf_new(1);
1773 rb_str_resize(str
, 1);
1774 RSTRING_PTR(str
)[0] = c
;
1777 rb_thread_wait_fd(fptr
->fd
);
1778 rb_io_check_closed(fptr
);
1779 if (io_fillbuf(fptr
) < 0) {
1783 } while (c
!= delim
);
1788 rb_str_cat(str
, &ch
, 1);
1791 *strp
= str
= rb_str_new(&ch
, 1);
1799 swallow(rb_io_t
*fptr
, int term
)
1803 while ((cnt
= READ_DATA_PENDING_COUNT(fptr
)) > 0) {
1805 const char *p
= READ_DATA_PENDING_PTR(fptr
);
1807 if (cnt
> sizeof buf
) cnt
= sizeof buf
;
1808 if (*p
!= term
) return Qtrue
;
1810 while (--i
&& *++p
== term
);
1811 if (!read_buffered_data(buf
, cnt
- i
, fptr
)) /* must not fail */
1812 rb_sys_fail(fptr
->path
);
1814 rb_thread_wait_fd(fptr
->fd
);
1815 rb_io_check_closed(fptr
);
1816 } while (io_fillbuf(fptr
) == 0);
1821 rb_io_getline_fast(rb_io_t
*fptr
)
1826 rb_encoding
*enc
= io_input_encoding(fptr
);
1827 int cr
= fptr
->enc2
? ENC_CODERANGE_BROKEN
: 0;
1830 long pending
= READ_DATA_PENDING_COUNT(fptr
);
1833 const char *p
= READ_DATA_PENDING_PTR(fptr
);
1836 e
= memchr(p
, '\n', pending
);
1838 pending
= e
- p
+ 1;
1841 str
= rb_str_new(p
, pending
);
1842 fptr
->rbuf_off
+= pending
;
1843 fptr
->rbuf_len
-= pending
;
1846 rb_str_resize(str
, len
+ pending
);
1847 read_buffered_data(RSTRING_PTR(str
)+len
, pending
, fptr
);
1850 if (cr
!= ENC_CODERANGE_BROKEN
)
1851 pos
= rb_str_coderange_scan_restartable(RSTRING_PTR(str
) + pos
, RSTRING_PTR(str
) + len
, enc
, &cr
);
1854 rb_thread_wait_fd(fptr
->fd
);
1855 rb_io_check_closed(fptr
);
1856 if (io_fillbuf(fptr
) < 0) {
1857 if (NIL_P(str
)) return Qnil
;
1862 str
= io_enc_str(str
, fptr
);
1863 if (!fptr
->enc2
) ENC_CODERANGE_SET(str
, cr
);
1865 ARGF
.lineno
= INT2FIX(fptr
->lineno
);
1870 prepare_getline_args(int argc
, VALUE
*argv
, VALUE
*rsp
, long *limit
, VALUE io
)
1880 rb_scan_args(argc
, argv
, "11", &rs
, &lim
);
1881 if (NIL_P(lim
) && !NIL_P(rs
) && TYPE(rs
) != T_STRING
) {
1882 VALUE tmp
= rb_check_string_type(rs
);
1894 rb_encoding
*enc_rs
, *enc_io
;
1896 GetOpenFile(io
, fptr
);
1897 enc_rs
= rb_enc_get(rs
);
1898 enc_io
= io_read_encoding(fptr
);
1899 if (enc_io
!= enc_rs
&&
1900 (rb_enc_str_coderange(rs
) != ENC_CODERANGE_7BIT
||
1901 !rb_enc_asciicompat(enc_io
))) {
1902 if (rs
== rb_default_rs
) {
1903 rs
= rb_enc_str_new(0, 0, enc_io
);
1904 rb_str_buf_cat_ascii(rs
, "\n");
1907 rb_raise(rb_eArgError
, "encoding mismatch: %s IO with %s RS",
1908 rb_enc_name(enc_io
),
1909 rb_enc_name(enc_rs
));
1914 rs2
= rb_funcall(rs
, id_encode
, 2,
1915 rb_enc_from_encoding(fptr
->enc2
),
1916 rb_enc_from_encoding(fptr
->enc
));
1917 if (!RTEST(rb_str_equal(rs
, rs2
))) {
1923 *limit
= NIL_P(lim
) ? -1L : NUM2LONG(lim
);
1927 rb_io_getline_1(VALUE rs
, long limit
, VALUE io
)
1934 GetOpenFile(io
, fptr
);
1935 rb_io_check_readable(fptr
);
1936 enc
= io_input_encoding(fptr
);
1938 str
= read_all(fptr
, 0, Qnil
);
1939 if (RSTRING_LEN(str
) == 0) return Qnil
;
1941 else if (limit
== 0) {
1942 return rb_enc_str_new(0, 0, io_read_encoding(fptr
));
1944 else if (rs
== rb_default_rs
&& limit
< 0 &&
1945 rb_enc_asciicompat(io_read_encoding(fptr
))) {
1946 return rb_io_getline_fast(fptr
);
1954 rslen
= RSTRING_LEN(rs
);
1959 swallow(fptr
, '\n');
1963 rsptr
= RSTRING_PTR(rs
);
1965 newline
= rsptr
[rslen
- 1];
1967 while ((c
= appendline(fptr
, newline
, &str
, &limit
)) != EOF
) {
1969 const char *s
, *p
, *pp
;
1971 if (RSTRING_LEN(str
) < rslen
) continue;
1972 s
= RSTRING_PTR(str
);
1973 p
= s
+ RSTRING_LEN(str
) - rslen
;
1974 pp
= rb_enc_left_char_head(s
, p
, enc
);
1975 if (pp
!= p
) continue;
1976 if (!rspara
) rscheck(rsptr
, rslen
, rs
);
1977 if (memcmp(p
, rsptr
, rslen
) == 0) break;
1987 swallow(fptr
, '\n');
1990 if (!NIL_P(str
)) str
= io_enc_str(str
, fptr
);
1996 ARGF
.lineno
= INT2FIX(fptr
->lineno
);
2004 rb_io_getline(int argc
, VALUE
*argv
, VALUE io
)
2009 prepare_getline_args(argc
, argv
, &rs
, &limit
, io
);
2010 return rb_io_getline_1(rs
, limit
, io
);
2014 rb_io_gets(VALUE io
)
2018 GetOpenFile(io
, fptr
);
2019 rb_io_check_readable(fptr
);
2020 return rb_io_getline_fast(fptr
);
2025 * ios.gets(sep=$/) => string or nil
2026 * ios.gets(limit) => string or nil
2027 * ios.gets(sep, limit) => string or nil
2029 * Reads the next ``line'' from the I/O stream; lines are separated by
2030 * <i>sep</i>. A separator of <code>nil</code> reads the entire
2031 * contents, and a zero-length separator reads the input a paragraph at
2032 * a time (two successive newlines in the input separate paragraphs).
2033 * The stream must be opened for reading or an <code>IOError</code>
2034 * will be raised. The line read in will be returned and also assigned
2035 * to <code>$_</code>. Returns <code>nil</code> if called at end of
2036 * file. If the first argument is an integer, or optional second
2037 * argument is given, the returning string would not be longer than the
2040 * File.new("testfile").gets #=> "This is line one\n"
2041 * $_ #=> "This is line one\n"
2045 rb_io_gets_m(int argc
, VALUE
*argv
, VALUE io
)
2049 str
= rb_io_getline(argc
, argv
, io
);
2050 rb_lastline_set(str
);
2057 * ios.lineno => integer
2059 * Returns the current line number in <em>ios</em>. The stream must be
2060 * opened for reading. <code>lineno</code> counts the number of times
2061 * <code>gets</code> is called, rather than the number of newlines
2062 * encountered. The two values will differ if <code>gets</code> is
2063 * called with a separator other than newline. See also the
2064 * <code>$.</code> variable.
2066 * f = File.new("testfile")
2068 * f.gets #=> "This is line one\n"
2070 * f.gets #=> "This is line two\n"
2075 rb_io_lineno(VALUE io
)
2079 GetOpenFile(io
, fptr
);
2080 rb_io_check_readable(fptr
);
2081 return INT2NUM(fptr
->lineno
);
2086 * ios.lineno = integer => integer
2088 * Manually sets the current line number to the given value.
2089 * <code>$.</code> is updated only on the next read.
2091 * f = File.new("testfile")
2092 * f.gets #=> "This is line one\n"
2096 * $. #=> 1 # lineno of last read
2097 * f.gets #=> "This is line two\n"
2098 * $. #=> 1001 # lineno of last read
2102 rb_io_set_lineno(VALUE io
, VALUE lineno
)
2106 GetOpenFile(io
, fptr
);
2107 rb_io_check_readable(fptr
);
2108 fptr
->lineno
= NUM2INT(lineno
);
2114 * ios.readline(sep=$/) => string
2115 * ios.readline(limit) => string
2116 * ios.readline(sep, limit) => string
2118 * Reads a line as with <code>IO#gets</code>, but raises an
2119 * <code>EOFError</code> on end of file.
2123 rb_io_readline(int argc
, VALUE
*argv
, VALUE io
)
2125 VALUE line
= rb_io_gets_m(argc
, argv
, io
);
2135 * ios.readlines(sep=$/) => array
2136 * ios.readlines(limit) => array
2137 * ios.readlines(sep, limit) => array
2139 * Reads all of the lines in <em>ios</em>, and returns them in
2140 * <i>anArray</i>. Lines are separated by the optional <i>sep</i>. If
2141 * <i>sep</i> is <code>nil</code>, the rest of the stream is returned
2142 * as a single record. If the first argument is an integer, or
2143 * optional second argument is given, the returning string would not be
2144 * longer than the given value. The stream must be opened for reading
2145 * or an <code>IOError</code> will be raised.
2147 * f = File.new("testfile")
2148 * f.readlines[0] #=> "This is line one\n"
2152 rb_io_readlines(int argc
, VALUE
*argv
, VALUE io
)
2154 VALUE line
, ary
, rs
;
2157 prepare_getline_args(argc
, argv
, &rs
, &limit
, io
);
2159 while (!NIL_P(line
= rb_io_getline_1(rs
, limit
, io
))) {
2160 rb_ary_push(ary
, line
);
2167 * ios.each(sep=$/) {|line| block } => ios
2168 * ios.each(limit) {|line| block } => ios
2169 * ios.each(sep,limit) {|line| block } => ios
2170 * ios.each_line(sep=$/) {|line| block } => ios
2171 * ios.each_line(limit) {|line| block } => ios
2172 * ios.each_line(sep,limit) {|line| block } => ios
2174 * Executes the block for every line in <em>ios</em>, where lines are
2175 * separated by <i>sep</i>. <em>ios</em> must be opened for
2176 * reading or an <code>IOError</code> will be raised.
2178 * f = File.new("testfile")
2179 * f.each {|line| puts "#{f.lineno}: #{line}" }
2181 * <em>produces:</em>
2183 * 1: This is line one
2184 * 2: This is line two
2185 * 3: This is line three
2190 rb_io_each_line(int argc
, VALUE
*argv
, VALUE io
)
2195 RETURN_ENUMERATOR(io
, argc
, argv
);
2196 prepare_getline_args(argc
, argv
, &rs
, &limit
, io
);
2197 while (!NIL_P(str
= rb_io_getline_1(rs
, limit
, io
))) {
2205 * ios.each_byte {|byte| block } => ios
2207 * Calls the given block once for each byte (0..255) in <em>ios</em>,
2208 * passing the byte as an argument. The stream must be opened for
2209 * reading or an <code>IOError</code> will be raised.
2211 * f = File.new("testfile")
2213 * f.each_byte {|x| checksum ^= x } #=> #<File:testfile>
2218 rb_io_each_byte(VALUE io
)
2223 RETURN_ENUMERATOR(io
, 0, 0);
2224 GetOpenFile(io
, fptr
);
2227 p
= fptr
->rbuf
+fptr
->rbuf_off
;
2228 e
= p
+ fptr
->rbuf_len
;
2232 rb_yield(INT2FIX(*p
& 0xff));
2236 rb_io_check_readable(fptr
);
2238 if (io_fillbuf(fptr
) < 0) {
2246 io_getc(rb_io_t
*fptr
, rb_encoding
*enc
)
2251 if (io_fillbuf(fptr
) < 0) {
2254 if (rb_enc_asciicompat(enc
) && ISASCII(fptr
->rbuf
[fptr
->rbuf_off
])) {
2255 str
= rb_str_new(fptr
->rbuf
+fptr
->rbuf_off
, 1);
2256 fptr
->rbuf_off
+= 1;
2257 fptr
->rbuf_len
-= 1;
2258 cr
= ENC_CODERANGE_7BIT
;
2261 r
= rb_enc_precise_mbclen(fptr
->rbuf
+fptr
->rbuf_off
, fptr
->rbuf
+fptr
->rbuf_off
+fptr
->rbuf_len
, enc
);
2262 if (MBCLEN_CHARFOUND_P(r
) &&
2263 (n
= MBCLEN_CHARFOUND_LEN(r
)) <= fptr
->rbuf_len
) {
2264 str
= rb_str_new(fptr
->rbuf
+fptr
->rbuf_off
, n
);
2265 fptr
->rbuf_off
+= n
;
2266 fptr
->rbuf_len
-= n
;
2267 cr
= ENC_CODERANGE_VALID
;
2269 else if (MBCLEN_NEEDMORE_P(r
)) {
2270 str
= rb_str_new(fptr
->rbuf
+fptr
->rbuf_off
, fptr
->rbuf_len
);
2273 if (io_fillbuf(fptr
) != -1) {
2274 rb_str_cat(str
, fptr
->rbuf
+fptr
->rbuf_off
, 1);
2277 r
= rb_enc_precise_mbclen(RSTRING_PTR(str
), RSTRING_PTR(str
)+RSTRING_LEN(str
), enc
);
2278 if (MBCLEN_NEEDMORE_P(r
)) {
2281 else if (MBCLEN_CHARFOUND_P(r
)) {
2282 cr
= ENC_CODERANGE_VALID
;
2287 str
= rb_str_new(fptr
->rbuf
+fptr
->rbuf_off
, 1);
2292 if (!cr
) cr
= ENC_CODERANGE_BROKEN
;
2293 str
= io_enc_str(str
, fptr
);
2295 ENC_CODERANGE_SET(str
, cr
);
2302 * ios.each_char {|c| block } => ios
2304 * Calls the given block once for each character in <em>ios</em>,
2305 * passing the character as an argument. The stream must be opened for
2306 * reading or an <code>IOError</code> will be raised.
2308 * f = File.new("testfile")
2309 * f.each_char {|c| print c, ' ' } #=> #<File:testfile>
2313 rb_io_each_char(VALUE io
)
2319 RETURN_ENUMERATOR(io
, 0, 0);
2320 GetOpenFile(io
, fptr
);
2321 rb_io_check_readable(fptr
);
2323 enc
= io_input_encoding(fptr
);
2325 while (!NIL_P(c
= io_getc(fptr
, enc
))) {
2335 * ios.lines(sep=$/) => anEnumerator
2336 * ios.lines(limit) => anEnumerator
2337 * ios.lines(sep, limit) => anEnumerator
2339 * Returns an enumerator that gives each line in <em>ios</em>.
2340 * The stream must be opened for reading or an <code>IOError</code>
2343 * f = File.new("testfile")
2344 * f.lines.to_a #=> ["foo\n", "bar\n"]
2346 * f.lines.sort #=> ["bar\n", "foo\n"]
2350 rb_io_lines(int argc
, VALUE
*argv
, VALUE io
)
2352 return rb_enumeratorize(io
, ID2SYM(rb_intern("each_line")), argc
, argv
);
2357 * ios.bytes => anEnumerator
2359 * Returns an enumerator that gives each byte (0..255) in <em>ios</em>.
2360 * The stream must be opened for reading or an <code>IOError</code>
2363 * f = File.new("testfile")
2364 * f.bytes.to_a #=> [104, 101, 108, 108, 111]
2366 * f.bytes.sort #=> [101, 104, 108, 108, 111]
2370 rb_io_bytes(VALUE io
)
2372 return rb_enumeratorize(io
, ID2SYM(rb_intern("each_byte")), 0, 0);
2377 * ios.chars => anEnumerator
2379 * Returns an enumerator that gives each character in <em>ios</em>.
2380 * The stream must be opened for reading or an <code>IOError</code>
2383 * f = File.new("testfile")
2384 * f.chars.to_a #=> ["h", "e", "l", "l", "o"]
2386 * f.chars.sort #=> ["e", "h", "l", "l", "o"]
2390 rb_io_chars(VALUE io
)
2392 return rb_enumeratorize(io
, ID2SYM(rb_intern("each_char")), 0, 0);
2397 * ios.getc => fixnum or nil
2399 * Reads a one-character string from <em>ios</em>. Returns
2400 * <code>nil</code> if called at end of file.
2402 * f = File.new("testfile")
2408 rb_io_getc(VALUE io
)
2413 GetOpenFile(io
, fptr
);
2414 rb_io_check_readable(fptr
);
2416 enc
= io_input_encoding(fptr
);
2418 return io_getc(fptr
, enc
);
2425 if (!STDIO_READ_DATA_PENDING(f
)) {
2426 rb_thread_wait_fd(fileno(f
));
2437 * ios.readchar => string
2439 * Reads a one-character string from <em>ios</em>. Raises an
2440 * <code>EOFError</code> on end of file.
2442 * f = File.new("testfile")
2443 * f.readchar #=> "8"
2444 * f.readchar #=> "1"
2448 rb_io_readchar(VALUE io
)
2450 VALUE c
= rb_io_getc(io
);
2460 * ios.getbyte => fixnum or nil
2462 * Gets the next 8-bit byte (0..255) from <em>ios</em>. Returns
2463 * <code>nil</code> if called at end of file.
2465 * f = File.new("testfile")
2471 rb_io_getbyte(VALUE io
)
2476 GetOpenFile(io
, fptr
);
2477 rb_io_check_readable(fptr
);
2479 if (fptr
->fd
== 0 && (fptr
->mode
& FMODE_TTY
) && TYPE(rb_stdout
) == T_FILE
) {
2481 GetOpenFile(rb_stdout
, ofp
);
2482 if (ofp
->mode
& FMODE_TTY
) {
2483 rb_io_flush(rb_stdout
);
2486 if (io_fillbuf(fptr
) < 0) {
2491 c
= (unsigned char)fptr
->rbuf
[fptr
->rbuf_off
-1];
2492 return INT2FIX(c
& 0xff);
2497 * ios.readbyte => fixnum
2499 * Reads a character as with <code>IO#getc</code>, but raises an
2500 * <code>EOFError</code> on end of file.
2504 rb_io_readbyte(VALUE io
)
2506 VALUE c
= rb_io_getbyte(io
);
2516 * ios.ungetc(string) => nil
2518 * Pushes back one character (passed as a parameter) onto <em>ios</em>,
2519 * such that a subsequent buffered read will return it. Only one character
2520 * may be pushed back before a subsequent read operation (that is,
2521 * you will be able to read only the last of several characters that have been pushed
2522 * back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).
2524 * f = File.new("testfile") #=> #<File:testfile>
2525 * c = f.getc #=> "8"
2526 * f.ungetc(c) #=> nil
2531 rb_io_ungetc(VALUE io
, VALUE c
)
2535 GetOpenFile(io
, fptr
);
2536 rb_io_check_readable(fptr
);
2537 if (NIL_P(c
)) return Qnil
;
2539 int cc
= FIX2INT(c
);
2540 rb_encoding
*enc
= io_read_encoding(fptr
);
2543 c
= rb_str_new(buf
, rb_enc_mbcput(cc
, buf
, enc
));
2554 * ios.isatty => true or false
2555 * ios.tty? => true or false
2557 * Returns <code>true</code> if <em>ios</em> is associated with a
2558 * terminal device (tty), <code>false</code> otherwise.
2560 * File.new("testfile").isatty #=> false
2561 * File.new("/dev/tty").isatty #=> true
2565 rb_io_isatty(VALUE io
)
2569 GetOpenFile(io
, fptr
);
2570 if (isatty(fptr
->fd
) == 0)
2577 * ios.close_on_exec? => true or false
2579 * Returns <code>true</code> if <em>ios</em> will be closed on exec.
2581 * f = open("/dev/null")
2582 * f.close_on_exec? #=> false
2583 * f.close_on_exec = true
2584 * f.close_on_exec? #=> true
2585 * f.close_on_exec = false
2586 * f.close_on_exec? #=> false
2590 rb_io_close_on_exec_p(VALUE io
)
2592 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
2597 write_io
= GetWriteIO(io
);
2598 if (io
!= write_io
) {
2599 GetOpenFile(write_io
, fptr
);
2600 if (fptr
&& 0 <= (fd
= fptr
->fd
)) {
2601 if ((ret
= fcntl(fd
, F_GETFD
)) == -1) rb_sys_fail(fptr
->path
);
2602 if (!(ret
& FD_CLOEXEC
)) return Qfalse
;
2606 GetOpenFile(io
, fptr
);
2607 if (fptr
&& 0 <= (fd
= fptr
->fd
)) {
2608 if ((ret
= fcntl(fd
, F_GETFD
)) == -1) rb_sys_fail(fptr
->path
);
2609 if (!(ret
& FD_CLOEXEC
)) return Qfalse
;
2614 return Qnil
; /* not reached */
2620 * ios.close_on_exec = bool => true or false
2622 * Sets a close-on-exec flag.
2624 * f = open("/dev/null")
2625 * f.close_on_exec = true
2626 * system("cat", "/proc/self/fd/#{f.fileno}") # cat: /proc/self/fd/3: No such file or directory
2627 * f.closed? #=> false
2631 rb_io_set_close_on_exec(VALUE io
, VALUE arg
)
2633 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
2634 int flag
= RTEST(arg
) ? FD_CLOEXEC
: 0;
2639 write_io
= GetWriteIO(io
);
2640 if (io
!= write_io
) {
2641 GetOpenFile(write_io
, fptr
);
2642 if (fptr
&& 0 <= (fd
= fptr
->fd
)) {
2643 if ((ret
= fcntl(fptr
->fd
, F_GETFD
)) == -1) rb_sys_fail(fptr
->path
);
2644 if ((ret
& FD_CLOEXEC
) != flag
) {
2645 ret
= (ret
& ~FD_CLOEXEC
) | flag
;
2646 ret
= fcntl(fd
, F_SETFD
, ret
);
2647 if (ret
== -1) rb_sys_fail(fptr
->path
);
2653 GetOpenFile(io
, fptr
);
2654 if (fptr
&& 0 <= (fd
= fptr
->fd
)) {
2655 if ((ret
= fcntl(fd
, F_GETFD
)) == -1) rb_sys_fail(fptr
->path
);
2656 if ((ret
& FD_CLOEXEC
) != flag
) {
2657 ret
= (ret
& ~FD_CLOEXEC
) | flag
;
2658 ret
= fcntl(fd
, F_SETFD
, ret
);
2659 if (ret
== -1) rb_sys_fail(fptr
->path
);
2668 #define FMODE_PREP (1<<16)
2669 #define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
2670 #define PREP_STDIO_NAME(f) ((f)->path)
2673 fptr_finalize(rb_io_t
*fptr
, int noraise
)
2675 if (fptr
->wbuf_len
) {
2678 if (IS_PREP_STDIO(fptr
) ||
2682 if (fptr
->stdio_file
) {
2683 if (fclose(fptr
->stdio_file
) < 0 && !noraise
) {
2684 /* fptr->stdio_file is deallocated anyway */
2685 fptr
->stdio_file
= 0;
2687 rb_sys_fail(fptr
->path
);
2690 else if (0 <= fptr
->fd
) {
2691 if (close(fptr
->fd
) < 0 && !noraise
) {
2692 /* fptr->fd is still not closed */
2693 rb_sys_fail(fptr
->path
);
2697 fptr
->stdio_file
= 0;
2698 fptr
->mode
&= ~(FMODE_READABLE
|FMODE_WRITABLE
);
2702 rb_io_fptr_cleanup(rb_io_t
*fptr
, int noraise
)
2704 if (fptr
->finalize
) {
2705 (*fptr
->finalize
)(fptr
, noraise
);
2708 fptr_finalize(fptr
, noraise
);
2713 rb_io_fptr_finalize(rb_io_t
*fptr
)
2715 if (!fptr
) return 0;
2716 if (fptr
->refcnt
<= 0 || --fptr
->refcnt
) return 0;
2722 rb_io_fptr_cleanup(fptr
, Qtrue
);
2736 rb_io_close(VALUE io
)
2741 rb_io_t
*write_fptr
;
2743 write_io
= GetWriteIO(io
);
2744 if (io
!= write_io
) {
2745 write_fptr
= RFILE(write_io
)->fptr
;
2746 if (write_fptr
&& 0 <= write_fptr
->fd
) {
2747 rb_io_fptr_cleanup(write_fptr
, Qtrue
);
2751 fptr
= RFILE(io
)->fptr
;
2752 if (!fptr
) return Qnil
;
2753 if (fptr
->fd
< 0) return Qnil
;
2756 rb_io_fptr_cleanup(fptr
, Qfalse
);
2757 rb_thread_fd_close(fd
);
2760 rb_syswait(fptr
->pid
);
2771 * Closes <em>ios</em> and flushes any pending writes to the operating
2772 * system. The stream is unavailable for any further data operations;
2773 * an <code>IOError</code> is raised if such an attempt is made. I/O
2774 * streams are automatically closed when they are claimed by the
2775 * garbage collector.
2777 * If <em>ios</em> is opened by <code>IO.popen</code>,
2778 * <code>close</code> sets <code>$?</code>.
2782 rb_io_close_m(VALUE io
)
2784 if (rb_safe_level() >= 4 && !OBJ_TAINTED(io
)) {
2785 rb_raise(rb_eSecurityError
, "Insecure: can't close");
2787 rb_io_check_closed(RFILE(io
)->fptr
);
2793 io_call_close(VALUE io
)
2795 return rb_funcall(io
, rb_intern("close"), 0, 0);
2801 return rb_rescue(io_call_close
, io
, 0, 0);
2806 * ios.closed? => true or false
2808 * Returns <code>true</code> if <em>ios</em> is completely closed (for
2809 * duplex streams, both reader and writer), <code>false</code>
2812 * f = File.new("testfile")
2814 * f.closed? #=> true
2815 * f = IO.popen("/bin/sh","r+")
2816 * f.close_write #=> nil
2817 * f.closed? #=> false
2818 * f.close_read #=> nil
2819 * f.closed? #=> true
2824 rb_io_closed(VALUE io
)
2828 rb_io_t
*write_fptr
;
2830 write_io
= GetWriteIO(io
);
2831 if (io
!= write_io
) {
2832 write_fptr
= RFILE(write_io
)->fptr
;
2833 if (write_fptr
&& 0 <= write_fptr
->fd
) {
2838 fptr
= RFILE(io
)->fptr
;
2839 rb_io_check_initialized(fptr
);
2840 return 0 <= fptr
->fd
? Qfalse
: Qtrue
;
2845 * ios.close_read => nil
2847 * Closes the read end of a duplex I/O stream (i.e., one that contains
2848 * both a read and a write stream, such as a pipe). Will raise an
2849 * <code>IOError</code> if the stream is not duplexed.
2851 * f = IO.popen("/bin/sh","r+")
2855 * <em>produces:</em>
2857 * prog.rb:3:in `readlines': not opened for reading (IOError)
2862 rb_io_close_read(VALUE io
)
2867 if (rb_safe_level() >= 4 && !OBJ_TAINTED(io
)) {
2868 rb_raise(rb_eSecurityError
, "Insecure: can't close");
2870 GetOpenFile(io
, fptr
);
2871 if (is_socket(fptr
->fd
, fptr
->path
)) {
2875 if (shutdown(fptr
->fd
, SHUT_RD
) < 0)
2876 rb_sys_fail(fptr
->path
);
2877 fptr
->mode
&= ~FMODE_READABLE
;
2878 if (!(fptr
->mode
& FMODE_WRITABLE
))
2879 return rb_io_close(io
);
2883 write_io
= GetWriteIO(io
);
2884 if (io
!= write_io
) {
2886 fptr_finalize(fptr
, Qfalse
);
2887 GetOpenFile(write_io
, wfptr
);
2888 if (fptr
->refcnt
< LONG_MAX
) {
2890 RFILE(io
)->fptr
= wfptr
;
2891 rb_io_fptr_finalize(fptr
);
2896 if (fptr
->mode
& FMODE_WRITABLE
) {
2897 rb_raise(rb_eIOError
, "closing non-duplex IO for reading");
2899 return rb_io_close(io
);
2904 * ios.close_write => nil
2906 * Closes the write end of a duplex I/O stream (i.e., one that contains
2907 * both a read and a write stream, such as a pipe). Will raise an
2908 * <code>IOError</code> if the stream is not duplexed.
2910 * f = IO.popen("/bin/sh","r+")
2914 * <em>produces:</em>
2916 * prog.rb:3:in `write': not opened for writing (IOError)
2917 * from prog.rb:3:in `print'
2922 rb_io_close_write(VALUE io
)
2927 if (rb_safe_level() >= 4 && !OBJ_TAINTED(io
)) {
2928 rb_raise(rb_eSecurityError
, "Insecure: can't close");
2930 write_io
= GetWriteIO(io
);
2931 GetOpenFile(write_io
, fptr
);
2932 if (is_socket(fptr
->fd
, fptr
->path
)) {
2936 if (shutdown(fptr
->fd
, SHUT_WR
) < 0)
2937 rb_sys_fail(fptr
->path
);
2938 fptr
->mode
&= ~FMODE_WRITABLE
;
2939 if (!(fptr
->mode
& FMODE_READABLE
))
2940 return rb_io_close(write_io
);
2944 if (fptr
->mode
& FMODE_READABLE
) {
2945 rb_raise(rb_eIOError
, "closing non-duplex IO for writing");
2948 rb_io_close(write_io
);
2949 if (io
!= write_io
) {
2950 GetOpenFile(io
, fptr
);
2951 fptr
->tied_io_for_writing
= 0;
2952 fptr
->mode
&= ~FMODE_DUPLEX
;
2959 * ios.sysseek(offset, whence=SEEK_SET) => integer
2961 * Seeks to a given <i>offset</i> in the stream according to the value
2962 * of <i>whence</i> (see <code>IO#seek</code> for values of
2963 * <i>whence</i>). Returns the new offset into the file.
2965 * f = File.new("testfile")
2966 * f.sysseek(-13, IO::SEEK_END) #=> 53
2967 * f.sysread(10) #=> "And so on."
2971 rb_io_sysseek(int argc
, VALUE
*argv
, VALUE io
)
2973 VALUE offset
, ptrname
;
2974 int whence
= SEEK_SET
;
2978 if (rb_scan_args(argc
, argv
, "11", &offset
, &ptrname
) == 2) {
2979 whence
= NUM2INT(ptrname
);
2981 pos
= NUM2OFFT(offset
);
2982 GetOpenFile(io
, fptr
);
2983 if ((fptr
->mode
& FMODE_READABLE
) && READ_DATA_BUFFERED(fptr
)) {
2984 rb_raise(rb_eIOError
, "sysseek for buffered IO");
2986 if ((fptr
->mode
& FMODE_WRITABLE
) && fptr
->wbuf_len
) {
2987 rb_warn("sysseek for buffered IO");
2989 pos
= lseek(fptr
->fd
, pos
, whence
);
2990 if (pos
== -1) rb_sys_fail(fptr
->path
);
2992 return OFFT2NUM(pos
);
2997 * ios.syswrite(string) => integer
2999 * Writes the given string to <em>ios</em> using a low-level write.
3000 * Returns the number of bytes written. Do not mix with other methods
3001 * that write to <em>ios</em> or you may get unpredictable results.
3002 * Raises <code>SystemCallError</code> on error.
3004 * f = File.new("out", "w")
3005 * f.syswrite("ABCDEF") #=> 6
3009 rb_io_syswrite(VALUE io
, VALUE str
)
3015 if (TYPE(str
) != T_STRING
)
3016 str
= rb_obj_as_string(str
);
3018 io
= GetWriteIO(io
);
3019 GetOpenFile(io
, fptr
);
3020 rb_io_check_writable(fptr
);
3022 if (fptr
->wbuf_len
) {
3023 rb_warn("syswrite for buffered IO");
3025 if (!rb_thread_fd_writable(fptr
->fd
)) {
3026 rb_io_check_closed(fptr
);
3029 n
= write(fptr
->fd
, RSTRING_PTR(str
), RSTRING_LEN(str
));
3032 if (n
== -1) rb_sys_fail(fptr
->path
);
3039 * ios.sysread(integer[, outbuf]) => string
3041 * Reads <i>integer</i> bytes from <em>ios</em> using a low-level
3042 * read and returns them as a string. Do not mix with other methods
3043 * that read from <em>ios</em> or you may get unpredictable results.
3044 * If the optional <i>outbuf</i> argument is present, it must reference
3045 * a String, which will receive the data.
3046 * Raises <code>SystemCallError</code> on error and
3047 * <code>EOFError</code> at end of file.
3049 * f = File.new("testfile")
3050 * f.sysread(16) #=> "This is line one"
3054 rb_io_sysread(int argc
, VALUE
*argv
, VALUE io
)
3060 rb_scan_args(argc
, argv
, "11", &len
, &str
);
3061 ilen
= NUM2LONG(len
);
3064 str
= rb_str_new(0, ilen
);
3069 rb_str_resize(str
, ilen
);
3071 if (ilen
== 0) return str
;
3073 GetOpenFile(io
, fptr
);
3074 rb_io_check_readable(fptr
);
3076 if (READ_DATA_BUFFERED(fptr
)) {
3077 rb_raise(rb_eIOError
, "sysread for buffered IO");
3081 rb_thread_wait_fd(fptr
->fd
);
3082 rb_io_check_closed(fptr
);
3083 if (RSTRING_LEN(str
) != ilen
) {
3084 rb_raise(rb_eRuntimeError
, "buffer string modified");
3087 n
= rb_read_internal(fptr
->fd
, RSTRING_PTR(str
), ilen
);
3090 rb_sys_fail(fptr
->path
);
3092 rb_str_set_len(str
, n
);
3093 if (n
== 0 && ilen
> 0) {
3096 rb_str_resize(str
, n
);
3103 rb_io_binmode(VALUE io
)
3107 GetOpenFile(io
, fptr
);
3108 #if defined(_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__)
3109 if (!(fptr
->mode
& FMODE_BINMODE
) && READ_DATA_BUFFERED(fptr
)) {
3110 rb_raise(rb_eIOError
, "buffer already filled with text-mode content");
3112 if (0 <= fptr
->fd
&& setmode(fptr
->fd
, O_BINARY
) == -1)
3113 rb_sys_fail(fptr
->path
);
3115 fptr
->mode
|= FMODE_BINMODE
;
3121 * ios.binmode => ios
3123 * Puts <em>ios</em> into binary mode. This is useful only in
3124 * MS-DOS/Windows environments. Once a stream is in binary mode, it
3125 * cannot be reset to nonbinary mode.
3129 rb_io_binmode_m(VALUE io
)
3131 #if defined(_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__)
3137 #if defined(_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__)
3138 write_io
= GetWriteIO(io
);
3140 rb_io_binmode(write_io
);
3146 rb_io_flags_mode(int flags
)
3149 # define MODE_BINMODE(a,b) ((flags & FMODE_BINMODE) ? (b) : (a))
3151 # define MODE_BINMODE(a,b) (a)
3153 if (flags
& FMODE_APPEND
) {
3154 if ((flags
& FMODE_READWRITE
) == FMODE_READWRITE
) {
3155 return MODE_BINMODE("a+", "ab+");
3157 return MODE_BINMODE("a", "ab");
3159 switch (flags
& FMODE_READWRITE
) {
3160 case FMODE_READABLE
:
3161 return MODE_BINMODE("r", "rb");
3162 case FMODE_WRITABLE
:
3163 return MODE_BINMODE("w", "wb");
3164 case FMODE_READWRITE
:
3165 if (flags
& FMODE_CREATE
) {
3166 return MODE_BINMODE("w+", "wb+");
3168 return MODE_BINMODE("r+", "rb+");
3170 rb_raise(rb_eArgError
, "invalid access modenum %o", flags
);
3171 return NULL
; /* not reached */
3175 rb_io_mode_flags(const char *mode
)
3178 const char *m
= mode
;
3182 flags
|= FMODE_READABLE
;
3185 flags
|= FMODE_WRITABLE
| FMODE_CREATE
;
3188 flags
|= FMODE_WRITABLE
| FMODE_APPEND
| FMODE_CREATE
;
3192 rb_raise(rb_eArgError
, "invalid access mode %s", mode
);
3198 flags
|= FMODE_BINMODE
;
3201 flags
|= FMODE_READWRITE
;
3214 rb_io_modenum_flags(int mode
)
3218 switch (mode
& (O_RDONLY
|O_WRONLY
|O_RDWR
)) {
3220 flags
= FMODE_READABLE
;
3223 flags
= FMODE_WRITABLE
;
3226 flags
= FMODE_READWRITE
;
3230 if (mode
& O_APPEND
) {
3231 flags
|= FMODE_APPEND
;
3233 if (mode
& O_CREAT
) {
3234 flags
|= FMODE_CREATE
;
3237 if (mode
& O_BINARY
) {
3238 flags
|= FMODE_BINMODE
;
3246 rb_io_mode_modenum(const char *mode
)
3249 const char *m
= mode
;
3256 flags
|= O_WRONLY
| O_CREAT
| O_TRUNC
;
3259 flags
|= O_WRONLY
| O_CREAT
| O_APPEND
;
3263 rb_raise(rb_eArgError
, "invalid access mode %s", mode
);
3274 flags
= (flags
& ~O_ACCMODE
) | O_RDWR
;
3286 #define MODENUM_MAX 4
3289 rb_io_modenum_mode(int flags
)
3292 # define MODE_BINARY(a,b) ((flags & O_BINARY) ? (b) : (a))
3294 # define MODE_BINARY(a,b) (a)
3296 if (flags
& O_APPEND
) {
3297 if ((flags
& O_RDWR
) == O_RDWR
) {
3298 return MODE_BINARY("a+", "ab+");
3300 return MODE_BINARY("a", "ab");
3302 switch (flags
& (O_RDONLY
|O_WRONLY
|O_RDWR
)) {
3304 return MODE_BINARY("r", "rb");
3306 return MODE_BINARY("w", "wb");
3308 return MODE_BINARY("r+", "rb+");
3310 rb_raise(rb_eArgError
, "invalid access modenum %o", flags
);
3311 return NULL
; /* not reached */
3315 mode_enc(rb_io_t
*fptr
, const char *estr
)
3317 const char *p0
, *p1
;
3321 p0
= strrchr(estr
, ':');
3324 idx
= rb_enc_find_index(p1
);
3326 fptr
->enc
= rb_enc_from_index(idx
);
3329 rb_warn("Unsupported encoding %s ignored", p1
);
3334 if (n
> ENCODING_MAXNAMELEN
) {
3338 enc2name
= ALLOCA_N(char, n
+1);
3339 memcpy(enc2name
, estr
, n
);
3342 idx2
= rb_enc_find_index(enc2name
);
3345 rb_warn("Unsupported encoding %.*s ignored", n
, estr
);
3347 else if (idx2
== idx
) {
3348 rb_warn("Ignoring internal encoding %.*s: it is identical to external encoding %s",
3352 fptr
->enc2
= rb_enc_from_index(idx2
);
3358 rb_io_mode_enc(rb_io_t
*fptr
, const char *mode
)
3360 const char *p
= strchr(mode
, ':');
3362 mode_enc(fptr
, p
+1);
3366 struct sysopen_struct
{
3373 sysopen_func(void *ptr
)
3375 struct sysopen_struct
*data
= ptr
;
3376 return (VALUE
)open(data
->fname
, data
->flag
, data
->mode
);
3380 rb_sysopen_internal(char *fname
, int flags
, unsigned int mode
)
3382 struct sysopen_struct data
;
3386 return (int)rb_thread_blocking_region(sysopen_func
, &data
, RB_UBF_DFL
, 0);
3390 rb_sysopen(char *fname
, int flags
, unsigned int mode
)
3394 fd
= rb_sysopen_internal(fname
, flags
, mode
);
3396 if (errno
== EMFILE
|| errno
== ENFILE
) {
3398 fd
= rb_sysopen_internal(fname
, flags
, mode
);
3409 rb_fopen(const char *fname
, const char *mode
)
3413 file
= fopen(fname
, mode
);
3415 if (errno
== EMFILE
|| errno
== ENFILE
) {
3417 file
= fopen(fname
, mode
);
3424 if (setvbuf(file
, NULL
, _IOFBF
, 0) != 0)
3425 rb_warn("setvbuf() can't be honoured for %s", fname
);
3428 setmode(fileno(file
), O_TEXT
);
3434 rb_fdopen(int fd
, const char *mode
)
3441 file
= fdopen(fd
, mode
);
3447 errno
== EMFILE
|| errno
== ENFILE
) {
3452 file
= fdopen(fd
, mode
);
3456 if (errno
== 0) errno
= EINVAL
;
3458 if (errno
== 0) errno
= EMFILE
;
3464 /* xxx: should be _IONBF? A buffer in FILE may have trouble. */
3466 if (setvbuf(file
, NULL
, _IOFBF
, 0) != 0)
3467 rb_warn("setvbuf() can't be honoured (fd=%d)", fd
);
3473 io_check_tty(rb_io_t
*fptr
)
3475 if (isatty(fptr
->fd
))
3476 fptr
->mode
|= FMODE_TTY
|FMODE_DUPLEX
;
3480 rb_file_open_internal(VALUE io
, const char *fname
, const char *mode
)
3484 MakeOpenFile(io
, fptr
);
3485 fptr
->mode
= rb_io_mode_flags(mode
);
3486 rb_io_mode_enc(fptr
, mode
);
3487 fptr
->path
= strdup(fname
);
3488 fptr
->fd
= rb_sysopen(fptr
->path
, rb_io_mode_modenum(rb_io_flags_mode(fptr
->mode
)), 0666);
3495 rb_file_open(const char *fname
, const char *mode
)
3497 return rb_file_open_internal(io_alloc(rb_cFile
), fname
, mode
);
3501 rb_file_sysopen_internal(VALUE io
, const char *fname
, int flags
, int mode
)
3505 MakeOpenFile(io
, fptr
);
3507 fptr
->path
= strdup(fname
);
3508 fptr
->mode
= rb_io_modenum_flags(flags
);
3509 fptr
->fd
= rb_sysopen(fptr
->path
, flags
, mode
);
3516 rb_file_sysopen(const char *fname
, int flags
, int mode
)
3518 return rb_file_sysopen_internal(io_alloc(rb_cFile
), fname
, flags
, mode
);
3521 #if defined(__CYGWIN__) || !defined(HAVE_FORK)
3522 static struct pipe_list
{
3524 struct pipe_list
*next
;
3528 pipe_add_fptr(rb_io_t
*fptr
)
3530 struct pipe_list
*list
;
3532 list
= ALLOC(struct pipe_list
);
3534 list
->next
= pipe_list
;
3539 pipe_del_fptr(rb_io_t
*fptr
)
3541 struct pipe_list
*list
= pipe_list
;
3542 struct pipe_list
*tmp
;
3544 if (list
->fptr
== fptr
) {
3545 pipe_list
= list
->next
;
3550 while (list
->next
) {
3551 if (list
->next
->fptr
== fptr
) {
3553 list
->next
= list
->next
->next
;
3564 struct pipe_list
*list
= pipe_list
;
3565 struct pipe_list
*tmp
;
3569 rb_io_fptr_finalize(list
->fptr
);
3575 pipe_finalize(rb_io_t
*fptr
, int noraise
)
3577 #if !defined(HAVE_FORK) && !defined(_WIN32)
3579 if (fptr
->stdio_file
) {
3580 status
= pclose(fptr
->stdio_file
);
3583 fptr
->stdio_file
= 0;
3587 rb_last_status_set(status
, fptr
->pid
);
3589 fptr_finalize(fptr
, noraise
);
3591 pipe_del_fptr(fptr
);
3596 rb_io_synchronized(rb_io_t
*fptr
)
3598 rb_io_check_initialized(fptr
);
3599 fptr
->mode
|= FMODE_SYNC
;
3603 rb_io_unbuffered(rb_io_t
*fptr
)
3605 rb_io_synchronized(fptr
);
3610 struct rb_exec_arg
*execp
;
3617 popen_redirect(struct popen_arg
*p
)
3619 if ((p
->modef
& FMODE_READABLE
) && (p
->modef
& FMODE_WRITABLE
)) {
3620 close(p
->write_pair
[1]);
3621 if (p
->write_pair
[0] != 0) {
3622 dup2(p
->write_pair
[0], 0);
3623 close(p
->write_pair
[0]);
3626 if (p
->pair
[1] != 1) {
3627 dup2(p
->pair
[1], 1);
3631 else if (p
->modef
& FMODE_READABLE
) {
3633 if (p
->pair
[1] != 1) {
3634 dup2(p
->pair
[1], 1);
3640 if (p
->pair
[0] != 0) {
3641 dup2(p
->pair
[0], 0);
3648 rb_close_before_exec(int lowfd
, int maxhint
, VALUE noclose_fds
)
3651 int max
= max_file_descriptor
;
3654 for (fd
= lowfd
; fd
<= max
; fd
++) {
3655 if (!NIL_P(noclose_fds
) &&
3656 RTEST(rb_hash_lookup(noclose_fds
, INT2FIX(fd
))))
3659 ret
= fcntl(fd
, F_GETFD
);
3660 if (ret
!= -1 && !(ret
& FD_CLOEXEC
)) {
3661 fcntl(fd
, F_SETFD
, ret
|FD_CLOEXEC
);
3670 popen_exec(void *pp
)
3672 struct popen_arg
*p
= (struct popen_arg
*)pp
;
3675 return rb_exec(p
->execp
);
3680 pipe_open(struct rb_exec_arg
*eargp
, VALUE prog
, const char *mode
)
3682 int modef
= rb_io_mode_flags(mode
);
3686 rb_io_t
*write_fptr
;
3688 #if defined(HAVE_FORK)
3690 struct popen_arg arg
;
3691 #elif defined(_WIN32)
3692 int openmode
= rb_io_mode_modenum(mode
);
3693 const char *exename
= NULL
;
3694 volatile VALUE cmdbuf
;
3699 const char *cmd
= 0;
3704 cmd
= StringValueCStr(prog
);
3707 /* fork : IO.popen("-") */
3711 else if (eargp
->argc
) {
3712 /* no shell : IO.popen([prog, arg0], arg1, ...) */
3717 /* with shell : IO.popen(prog) */
3722 #if defined(HAVE_FORK)
3725 arg
.pair
[0] = arg
.pair
[1] = -1;
3726 arg
.write_pair
[0] = arg
.write_pair
[1] = -1;
3727 switch (modef
& (FMODE_READABLE
|FMODE_WRITABLE
)) {
3728 case FMODE_READABLE
|FMODE_WRITABLE
:
3729 if (pipe(arg
.write_pair
) < 0)
3731 UPDATE_MAXFD_PIPE(arg
.write_pair
);
3732 if (pipe(arg
.pair
) < 0) {
3734 close(arg
.write_pair
[0]);
3735 close(arg
.write_pair
[1]);
3739 UPDATE_MAXFD_PIPE(arg
.pair
);
3741 rb_exec_arg_addopt(eargp
, INT2FIX(0), INT2FIX(arg
.write_pair
[0]));
3742 rb_exec_arg_addopt(eargp
, INT2FIX(1), INT2FIX(arg
.pair
[1]));
3745 case FMODE_READABLE
:
3746 if (pipe(arg
.pair
) < 0)
3748 UPDATE_MAXFD_PIPE(arg
.pair
);
3750 rb_exec_arg_addopt(eargp
, INT2FIX(1), INT2FIX(arg
.pair
[1]));
3752 case FMODE_WRITABLE
:
3753 if (pipe(arg
.pair
) < 0)
3755 UPDATE_MAXFD_PIPE(arg
.pair
);
3757 rb_exec_arg_addopt(eargp
, INT2FIX(0), INT2FIX(arg
.pair
[0]));
3763 rb_exec_arg_fixup(arg
.execp
);
3764 pid
= rb_fork(&status
, popen_exec
, &arg
, arg
.execp
->redirect_fds
);
3767 fflush(stdin
); /* is it really needed? */
3768 rb_io_flush(rb_stdout
);
3769 rb_io_flush(rb_stderr
);
3770 pid
= rb_fork(&status
, 0, 0, Qnil
);
3771 if (pid
== 0) { /* child */
3772 popen_redirect(&arg
);
3773 rb_io_synchronized(RFILE(orig_stdout
)->fptr
);
3774 rb_io_synchronized(RFILE(orig_stderr
)->fptr
);
3784 if ((modef
& (FMODE_READABLE
|FMODE_WRITABLE
)) == (FMODE_READABLE
|FMODE_WRITABLE
)) {
3785 close(arg
.write_pair
[0]);
3786 close(arg
.write_pair
[1]);
3791 if ((modef
& FMODE_READABLE
) && (modef
& FMODE_WRITABLE
)) {
3794 close(arg
.write_pair
[0]);
3795 write_fd
= arg
.write_pair
[1];
3797 else if (modef
& FMODE_READABLE
) {
3805 #elif defined(_WIN32)
3807 volatile VALUE argbuf
;
3811 if (argc
>= FIXNUM_MAX
/ sizeof(char *)) {
3812 rb_raise(rb_eArgError
, "too many arguments");
3814 argbuf
= rb_str_tmp_new((argc
+1) * sizeof(char *));
3815 args
= (void *)RSTRING_PTR(argbuf
);
3816 for (i
= 0; i
< argc
; ++i
) {
3817 args
[i
] = StringValueCStr(argv
[i
]);
3821 cmdbuf
= rb_str_tmp_new(rb_w32_argv_size(args
));
3822 cmd
= rb_w32_join_argv(RSTRING_PTR(cmdbuf
), args
);
3823 rb_str_resize(argbuf
, 0);
3825 while ((pid
= rb_w32_pipe_exec(cmd
, exename
, openmode
, &fd
, &write_fd
)) == -1) {
3829 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
3841 prog
= rb_ary_join(rb_ary_new4(argc
, argv
), rb_str_new2(" "));
3842 cmd
= StringValueCStr(prog
);
3844 fp
= popen(cmd
, mode
);
3845 if (!fp
) rb_sys_fail(RSTRING_PTR(prog
));
3849 port
= io_alloc(rb_cIO
);
3850 MakeOpenFile(port
, fptr
);
3852 fptr
->stdio_file
= fp
;
3853 fptr
->mode
= modef
| FMODE_SYNC
|FMODE_DUPLEX
;
3854 rb_io_mode_enc(fptr
, mode
);
3857 if (0 <= write_fd
) {
3858 write_port
= io_alloc(rb_cIO
);
3859 MakeOpenFile(write_port
, write_fptr
);
3860 write_fptr
->fd
= write_fd
;
3861 write_fptr
->mode
= (modef
& ~FMODE_READABLE
)| FMODE_SYNC
|FMODE_DUPLEX
;
3862 fptr
->mode
&= ~FMODE_WRITABLE
;
3863 fptr
->tied_io_for_writing
= write_port
;
3864 rb_ivar_set(port
, rb_intern("@tied_io_for_writing"), write_port
);
3867 #if defined (__CYGWIN__) || !defined(HAVE_FORK)
3868 fptr
->finalize
= pipe_finalize
;
3869 pipe_add_fptr(fptr
);
3875 pipe_open_v(int argc
, VALUE
*argv
, const char *mode
)
3878 struct rb_exec_arg earg
;
3879 prog
= rb_exec_arg_init(argc
, argv
, Qfalse
, &earg
);
3880 return pipe_open(&earg
, prog
, mode
);
3884 pipe_open_s(VALUE prog
, const char *mode
)
3886 const char *cmd
= RSTRING_PTR(prog
);
3888 VALUE
*argv
= &prog
;
3889 struct rb_exec_arg earg
;
3891 if (RSTRING_LEN(prog
) == 1 && cmd
[0] == '-') {
3892 #if !defined(HAVE_FORK)
3893 rb_raise(rb_eNotImpError
,
3894 "fork() function is unimplemented on this machine");
3896 return pipe_open(0, 0, mode
);
3899 rb_exec_arg_init(argc
, argv
, Qtrue
, &earg
);
3900 return pipe_open(&earg
, prog
, mode
);
3905 * IO.popen(cmd, mode="r") => io
3906 * IO.popen(cmd, mode="r") {|io| block } => obj
3908 * Runs the specified command as a subprocess; the subprocess's
3909 * standard input and output will be connected to the returned
3910 * <code>IO</code> object. If _cmd_ is a +String+
3911 * ``<code>-</code>'', then a new instance of Ruby is started as the
3912 * subprocess. If <i>cmd</i> is an +Array+ of +String+, then it will
3913 * be used as the subprocess's +argv+ bypassing a shell.
3914 * The array can contains a hash at first for environments and
3915 * a hash at last for options similar to <code>spawn</code>. The default
3916 * mode for the new file object is ``r'', but <i>mode</i> may be set
3917 * to any of the modes listed in the description for class IO.
3919 * Raises exceptions which <code>IO::pipe</code> and
3920 * <code>Kernel::system</code> raise.
3922 * If a block is given, Ruby will run the command as a child connected
3923 * to Ruby with a pipe. Ruby's end of the pipe will be passed as a
3924 * parameter to the block.
3925 * At the end of block, Ruby close the pipe and sets <code>$?</code>.
3926 * In this case <code>IO::popen</code> returns
3927 * the value of the block.
3929 * If a block is given with a _cmd_ of ``<code>-</code>'',
3930 * the block will be run in two separate processes: once in the parent,
3931 * and once in a child. The parent process will be passed the pipe
3932 * object as a parameter to the block, the child version of the block
3933 * will be passed <code>nil</code>, and the child's standard in and
3934 * standard out will be connected to the parent through the pipe. Not
3935 * available on all platforms.
3937 * f = IO.popen("uname")
3939 * puts "Parent is #{Process.pid}"
3940 * IO.popen("date") { |f| puts f.gets }
3941 * IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f}"}
3943 * IO.popen(%w"sed -e s|^|<foo>| -e s&$&;zot;&", "r+") {|f|
3944 * f.puts "bar"; f.close_write; puts f.gets
3947 * <em>produces:</em>
3951 * Wed Apr 9 08:53:52 CDT 2003
3952 * 26169 is here, f is
3953 * 26166 is here, f is #<IO:0x401b3d44>
3954 * #<Process::Status: pid=26166,exited(0)>
3959 rb_io_s_popen(int argc
, VALUE
*argv
, VALUE klass
)
3962 VALUE pname
, pmode
, port
, tmp
;
3964 if (rb_scan_args(argc
, argv
, "11", &pname
, &pmode
) == 1) {
3967 else if (FIXNUM_P(pmode
)) {
3968 mode
= rb_io_modenum_mode(FIX2INT(pmode
));
3971 mode
= StringValueCStr(pmode
);
3973 tmp
= rb_check_array_type(pname
);
3975 tmp
= rb_ary_dup(tmp
);
3976 RBASIC(tmp
)->klass
= 0;
3977 port
= pipe_open_v(RARRAY_LEN(tmp
), RARRAY_PTR(tmp
), mode
);
3981 SafeStringValue(pname
);
3982 port
= pipe_open_s(pname
, mode
);
3986 if (rb_block_given_p()) {
3988 rb_io_flush(rb_stdout
);
3989 rb_io_flush(rb_stderr
);
3994 RBASIC(port
)->klass
= klass
;
3995 if (rb_block_given_p()) {
3996 return rb_ensure(rb_yield
, port
, io_close
, port
);
4002 rb_open_file(int argc
, VALUE
*argv
, VALUE io
)
4004 VALUE fname
, vmode
, perm
;
4008 rb_scan_args(argc
, argv
, "12", &fname
, &vmode
, &perm
);
4009 FilePathValue(fname
);
4011 if (FIXNUM_P(vmode
) || !NIL_P(perm
)) {
4012 if (FIXNUM_P(vmode
)) {
4013 flags
= FIX2INT(vmode
);
4016 SafeStringValue(vmode
);
4017 flags
= rb_io_mode_modenum(StringValueCStr(vmode
));
4019 fmode
= NIL_P(perm
) ? 0666 : NUM2INT(perm
);
4021 rb_file_sysopen_internal(io
, RSTRING_PTR(fname
), flags
, fmode
);
4025 mode
= NIL_P(vmode
) ? "r" : StringValueCStr(vmode
);
4026 rb_file_open_internal(io
, RSTRING_PTR(fname
), mode
);
4033 * IO.open(fd, mode_string="r" ) => io
4034 * IO.open(fd, mode_string="r" ) {|io| block } => obj
4036 * With no associated block, <code>open</code> is a synonym for
4037 * <code>IO::new</code>. If the optional code block is given, it will
4038 * be passed <i>io</i> as an argument, and the IO object will
4039 * automatically be closed when the block terminates. In this instance,
4040 * <code>IO::open</code> returns the value of the block.
4045 rb_io_s_open(int argc
, VALUE
*argv
, VALUE klass
)
4047 VALUE io
= rb_class_new_instance(argc
, argv
, klass
);
4049 if (rb_block_given_p()) {
4050 return rb_ensure(rb_yield
, io
, io_close
, io
);
4058 * IO.sysopen(path, [mode, [perm]]) => fixnum
4060 * Opens the given path, returning the underlying file descriptor as a
4061 * <code>Fixnum</code>.
4063 * IO.sysopen("testfile") #=> 3
4068 rb_io_s_sysopen(int argc
, VALUE
*argv
)
4070 VALUE fname
, vmode
, perm
;
4071 int flags
, fmode
, fd
;
4074 rb_scan_args(argc
, argv
, "12", &fname
, &vmode
, &perm
);
4075 FilePathValue(fname
);
4077 if (NIL_P(vmode
)) flags
= O_RDONLY
;
4078 else if (FIXNUM_P(vmode
)) flags
= FIX2INT(vmode
);
4080 SafeStringValue(vmode
);
4081 flags
= rb_io_mode_modenum(StringValueCStr(vmode
));
4083 if (NIL_P(perm
)) fmode
= 0666;
4084 else fmode
= NUM2INT(perm
);
4086 RB_GC_GUARD(fname
) = rb_str_new4(fname
);
4087 path
= RSTRING_PTR(fname
);
4088 fd
= rb_sysopen(path
, flags
, fmode
);
4094 * open(path [, mode_enc [, perm]] ) => io or nil
4095 * open(path [, mode_enc [, perm]] ) {|io| block } => obj
4097 * Creates an <code>IO</code> object connected to the given stream,
4098 * file, or subprocess.
4100 * If <i>path</i> does not start with a pipe character
4101 * (``<code>|</code>''), treat it as the name of a file to open using
4102 * the specified mode (defaulting to ``<code>r</code>'').
4105 * either a string or an integer. If it is an integer, it must be
4106 * bitwise-or of open(2) flags, such as File::RDWR or File::EXCL.
4107 * If it is a string, it is either "mode", "mode:ext_enc", or
4108 * "mode:ext_enc:int_enc".
4109 * The mode is one of the following:
4115 * The mode can be followed by "b" (means binary-mode), or "+"
4116 * (means both reading and writing allowed) or both.
4117 * If ext_enc (external encoding) is specified,
4118 * read string will be tagged by the encoding in reading,
4119 * and output string will be converted
4120 * to the specified encoding in writing.
4121 * If two encoding names,
4122 * ext_enc and int_enc (external encoding and internal encoding),
4123 * are specified, the read string is converted from ext_enc
4124 * to int_enc then tagged with the int_enc in read mode,
4125 * and in write mode, the output string will be
4126 * converted from int_enc to ext_enc before writing.
4128 * If a file is being created, its initial permissions may be
4129 * set using the integer third parameter.
4131 * If a block is specified, it will be invoked with the
4132 * <code>File</code> object as a parameter, and the file will be
4133 * automatically closed when the block terminates. The call
4134 * returns the value of the block.
4136 * If <i>path</i> starts with a pipe character, a subprocess is
4137 * created, connected to the caller by a pair of pipes. The returned
4138 * <code>IO</code> object may be used to write to the standard input
4139 * and read from the standard output of this subprocess. If the command
4140 * following the ``<code>|</code>'' is a single minus sign, Ruby forks,
4141 * and this subprocess is connected to the parent. In the subprocess,
4142 * the <code>open</code> call returns <code>nil</code>. If the command
4143 * is not ``<code>-</code>'', the subprocess runs the command. If a
4144 * block is associated with an <code>open("|-")</code> call, that block
4145 * will be run twice---once in the parent and once in the child. The
4146 * block parameter will be an <code>IO</code> object in the parent and
4147 * <code>nil</code> in the child. The parent's <code>IO</code> object
4148 * will be connected to the child's <code>$stdin</code> and
4149 * <code>$stdout</code>. The subprocess will be terminated at the end
4152 * open("testfile") do |f|
4156 * <em>produces:</em>
4160 * Open a subprocess and read its output:
4162 * cmd = open("|date")
4166 * <em>produces:</em>
4168 * Wed Apr 9 08:56:31 CDT 2003
4170 * Open a subprocess running the same Ruby program:
4172 * f = open("|-", "w+")
4177 * puts "Got: #{f.gets}"
4180 * <em>produces:</em>
4184 * Open a subprocess using a block to receive the I/O object:
4190 * puts "Got: #{f.gets}"
4194 * <em>produces:</em>
4200 rb_f_open(int argc
, VALUE
*argv
)
4203 int redirect
= Qfalse
;
4206 to_open
= rb_intern("to_open");
4207 if (rb_respond_to(argv
[0], to_open
)) {
4211 VALUE tmp
= argv
[0];
4217 char *str
= StringValuePtr(tmp
);
4218 if (str
&& str
[0] == '|') {
4219 argv
[0] = rb_str_new(str
+1, RSTRING_LEN(tmp
)-1);
4220 OBJ_INFECT(argv
[0], tmp
);
4221 return rb_io_s_popen(argc
, argv
, rb_cIO
);
4227 VALUE io
= rb_funcall2(argv
[0], to_open
, argc
-1, argv
+1);
4229 if (rb_block_given_p()) {
4230 return rb_ensure(rb_yield
, io
, io_close
, io
);
4234 return rb_io_s_open(argc
, argv
, rb_cFile
);
4238 rb_io_open(const char *fname
, const char *mode
)
4240 if (fname
[0] == '|') {
4241 VALUE cmd
= rb_str_new2(fname
+1);
4242 return pipe_open_s(cmd
, mode
);
4245 return rb_file_open(fname
, mode
);
4250 rb_io_open_with_args(int argc
, VALUE
*argv
)
4255 if (rb_scan_args(argc
, argv
, "11", &pname
, &pmode
) == 1) {
4258 else if (FIXNUM_P(pmode
)) {
4259 mode
= rb_io_modenum_mode(FIX2INT(pmode
));
4262 mode
= StringValueCStr(pmode
);
4264 return rb_io_open(StringValueCStr(pname
), mode
);
4268 io_reopen(VALUE io
, VALUE nfile
)
4270 rb_io_t
*fptr
, *orig
;
4274 nfile
= rb_io_get_io(nfile
);
4275 if (rb_safe_level() >= 4 && (!OBJ_TAINTED(io
) || !OBJ_TAINTED(nfile
))) {
4276 rb_raise(rb_eSecurityError
, "Insecure: can't reopen");
4278 GetOpenFile(io
, fptr
);
4279 GetOpenFile(nfile
, orig
);
4281 if (fptr
== orig
) return io
;
4282 #if !defined __CYGWIN__
4283 if (IS_PREP_STDIO(fptr
)) {
4284 if ((fptr
->stdio_file
== stdin
&& !(orig
->mode
& FMODE_READABLE
)) ||
4285 (fptr
->stdio_file
== stdout
&& !(orig
->mode
& FMODE_WRITABLE
)) ||
4286 (fptr
->stdio_file
== stderr
&& !(orig
->mode
& FMODE_WRITABLE
))) {
4287 rb_raise(rb_eArgError
,
4288 "%s can't change access mode from \"%s\" to \"%s\"",
4289 PREP_STDIO_NAME(fptr
), rb_io_flags_mode(fptr
->mode
),
4290 rb_io_flags_mode(orig
->mode
));
4294 if (orig
->mode
& FMODE_READABLE
) {
4295 pos
= io_tell(orig
);
4297 if (orig
->mode
& FMODE_WRITABLE
) {
4300 if (fptr
->mode
& FMODE_WRITABLE
) {
4304 /* copy rb_io_t structure */
4305 fptr
->mode
= orig
->mode
| (fptr
->mode
& FMODE_PREP
);
4306 fptr
->pid
= orig
->pid
;
4307 fptr
->lineno
= orig
->lineno
;
4308 if (fptr
->path
) free(fptr
->path
);
4309 if (orig
->path
) fptr
->path
= strdup(orig
->path
);
4310 else fptr
->path
= 0;
4311 fptr
->finalize
= orig
->finalize
;
4316 #if !defined __CYGWIN__
4317 if (IS_PREP_STDIO(fptr
)) {
4318 /* need to keep stdio objects */
4319 if (dup2(fd2
, fd
) < 0)
4320 rb_sys_fail(orig
->path
);
4324 if (fptr
->stdio_file
)
4325 fclose(fptr
->stdio_file
);
4328 fptr
->stdio_file
= 0;
4330 if (dup2(fd2
, fd
) < 0)
4331 rb_sys_fail(orig
->path
);
4333 #if !defined __CYGWIN__
4336 rb_thread_fd_close(fd
);
4337 if ((orig
->mode
& FMODE_READABLE
) && pos
>= 0) {
4338 if (io_seek(fptr
, pos
, SEEK_SET
) < 0) {
4339 rb_sys_fail(fptr
->path
);
4341 if (io_seek(orig
, pos
, SEEK_SET
) < 0) {
4342 rb_sys_fail(orig
->path
);
4347 if (fptr
->mode
& FMODE_BINMODE
) {
4351 RBASIC(io
)->klass
= RBASIC(nfile
)->klass
;
4357 * ios.reopen(other_IO) => ios
4358 * ios.reopen(path, mode_str) => ios
4360 * Reassociates <em>ios</em> with the I/O stream given in
4361 * <i>other_IO</i> or to a new stream opened on <i>path</i>. This may
4362 * dynamically change the actual class of this stream.
4364 * f1 = File.new("testfile")
4365 * f2 = File.new("testfile")
4366 * f2.readlines[0] #=> "This is line one\n"
4367 * f2.reopen(f1) #=> #<File:testfile>
4368 * f2.readlines[0] #=> "This is line one\n"
4372 rb_io_reopen(int argc
, VALUE
*argv
, VALUE file
)
4379 if (rb_scan_args(argc
, argv
, "11", &fname
, &nmode
) == 1) {
4380 VALUE tmp
= rb_io_check_io(fname
);
4382 return io_reopen(file
, tmp
);
4386 FilePathValue(fname
);
4387 rb_io_taint_check(file
);
4388 fptr
= RFILE(file
)->fptr
;
4390 fptr
= RFILE(file
)->fptr
= ALLOC(rb_io_t
);
4391 MEMZERO(fptr
, rb_io_t
, 1);
4394 if (!NIL_P(nmode
)) {
4395 int flags
= rb_io_mode_flags(StringValueCStr(nmode
));
4396 if (IS_PREP_STDIO(fptr
) &&
4397 ((fptr
->mode
& FMODE_READWRITE
) & (flags
& FMODE_READWRITE
)) !=
4398 (fptr
->mode
& FMODE_READWRITE
)) {
4399 rb_raise(rb_eArgError
,
4400 "%s can't change access mode from \"%s\" to \"%s\"",
4401 PREP_STDIO_NAME(fptr
), rb_io_flags_mode(fptr
->mode
),
4402 rb_io_flags_mode(flags
));
4405 rb_io_mode_enc(fptr
, StringValueCStr(nmode
));
4413 fptr
->path
= strdup(StringValueCStr(fname
));
4414 mode
= rb_io_flags_mode(fptr
->mode
);
4416 fptr
->fd
= rb_sysopen(fptr
->path
, rb_io_mode_modenum(mode
), 0666);
4417 fptr
->stdio_file
= 0;
4421 if (fptr
->mode
& FMODE_WRITABLE
) {
4425 if (fptr
->stdio_file
) {
4426 if (freopen(fptr
->path
, mode
, fptr
->stdio_file
) == 0) {
4427 rb_sys_fail(fptr
->path
);
4429 fptr
->fd
= fileno(fptr
->stdio_file
);
4431 if (setvbuf(fptr
->stdio_file
, NULL
, _IOFBF
, 0) != 0)
4432 rb_warn("setvbuf() can't be honoured for %s", fptr
->path
);
4436 if (close(fptr
->fd
) < 0)
4437 rb_sys_fail(fptr
->path
);
4439 fptr
->fd
= rb_sysopen(fptr
->path
, rb_io_mode_modenum(mode
), 0666);
4447 rb_io_init_copy(VALUE dest
, VALUE io
)
4449 rb_io_t
*fptr
, *orig
;
4453 io
= rb_io_get_io(io
);
4454 if (dest
== io
) return dest
;
4455 GetOpenFile(io
, orig
);
4456 MakeOpenFile(dest
, fptr
);
4460 /* copy rb_io_t structure */
4461 fptr
->mode
= orig
->mode
& ~FMODE_PREP
;
4462 fptr
->pid
= orig
->pid
;
4463 fptr
->lineno
= orig
->lineno
;
4464 if (orig
->path
) fptr
->path
= strdup(orig
->path
);
4465 fptr
->finalize
= orig
->finalize
;
4467 fd
= ruby_dup(orig
->fd
);
4469 io_seek(fptr
, io_tell(orig
), SEEK_SET
);
4470 if (fptr
->mode
& FMODE_BINMODE
) {
4471 rb_io_binmode(dest
);
4474 write_io
= GetWriteIO(io
);
4475 if (io
!= write_io
) {
4476 write_io
= rb_obj_dup(write_io
);
4477 fptr
->tied_io_for_writing
= write_io
;
4478 rb_ivar_set(dest
, rb_intern("@tied_io_for_writing"), write_io
);
4486 * ios.printf(format_string [, obj, ...] ) => nil
4488 * Formats and writes to <em>ios</em>, converting parameters under
4489 * control of the format string. See <code>Kernel#sprintf</code>
4494 rb_io_printf(int argc
, VALUE
*argv
, VALUE out
)
4496 rb_io_write(out
, rb_f_sprintf(argc
, argv
));
4502 * printf(io, string [, obj ... ] ) => nil
4503 * printf(string [, obj ... ] ) => nil
4506 * io.write(sprintf(string, obj, ...)
4508 * $stdout.write(sprintf(string, obj, ...)
4512 rb_f_printf(int argc
, VALUE
*argv
)
4516 if (argc
== 0) return Qnil
;
4517 if (TYPE(argv
[0]) == T_STRING
) {
4525 rb_io_write(out
, rb_f_sprintf(argc
, argv
));
4532 * ios.print() => nil
4533 * ios.print(obj, ...) => nil
4535 * Writes the given object(s) to <em>ios</em>. The stream must be
4536 * opened for writing. If the output record separator (<code>$\\</code>)
4537 * is not <code>nil</code>, it will be appended to the output. If no
4538 * arguments are given, prints <code>$_</code>. Objects that aren't
4539 * strings will be converted by calling their <code>to_s</code> method.
4540 * With no argument, prints the contents of the variable <code>$_</code>.
4541 * Returns <code>nil</code>.
4543 * $stdout.print("This is ", 100, " percent.\n")
4545 * <em>produces:</em>
4547 * This is 100 percent.
4551 rb_io_print(int argc
, VALUE
*argv
, VALUE out
)
4556 /* if no argument given, print `$_' */
4559 line
= rb_lastline_get();
4562 for (i
=0; i
<argc
; i
++) {
4563 rb_io_write(out
, argv
[i
]);
4564 if (!NIL_P(rb_output_fs
)) {
4565 rb_io_write(out
, rb_output_fs
);
4568 if (argc
> 0 && !NIL_P(rb_output_rs
)) {
4569 rb_io_write(out
, rb_output_rs
);
4577 * print(obj, ...) => nil
4579 * Prints each object in turn to <code>$stdout</code>. If the output
4580 * field separator (<code>$,</code>) is not +nil+, its
4581 * contents will appear between each field. If the output record
4582 * separator (<code>$\\</code>) is not +nil+, it will be
4583 * appended to the output. If no arguments are given, prints
4584 * <code>$_</code>. Objects that aren't strings will be converted by
4585 * calling their <code>to_s</code> method.
4587 * print "cat", [1,2,3], 99, "\n"
4590 * print "cat", [1,2,3], 99
4592 * <em>produces:</em>
4599 rb_f_print(int argc
, VALUE
*argv
)
4601 rb_io_print(argc
, argv
, rb_stdout
);
4607 * ios.putc(obj) => obj
4609 * If <i>obj</i> is <code>Numeric</code>, write the character whose
4610 * code is <i>obj</i>, otherwise write the first character of the
4611 * string representation of <i>obj</i> to <em>ios</em>.
4616 * <em>produces:</em>
4622 rb_io_putc(VALUE io
, VALUE ch
)
4624 char c
= NUM2CHR(ch
);
4626 rb_io_write(io
, rb_str_new(&c
, 1));
4640 rb_f_putc(VALUE recv
, VALUE ch
)
4642 if (recv
== rb_stdout
) {
4643 return rb_io_putc(recv
, ch
);
4645 return rb_funcall2(rb_stdout
, rb_intern("putc"), 1, &ch
);
4649 io_puts_ary(VALUE ary
, VALUE out
, int recur
)
4654 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
4655 tmp
= RARRAY_PTR(ary
)[i
];
4657 tmp
= rb_str_new2("[...]");
4659 rb_io_puts(1, &tmp
, out
);
4666 * ios.puts(obj, ...) => nil
4668 * Writes the given objects to <em>ios</em> as with
4669 * <code>IO#print</code>. Writes a record separator (typically a
4670 * newline) after any that do not already end with a newline sequence.
4671 * If called with an array argument, writes each element on a new line.
4672 * If called without arguments, outputs a single record separator.
4674 * $stdout.puts("this", "is", "a", "test")
4676 * <em>produces:</em>
4685 rb_io_puts(int argc
, VALUE
*argv
, VALUE out
)
4690 /* if no argument given, print newline. */
4692 rb_io_write(out
, rb_default_rs
);
4695 for (i
=0; i
<argc
; i
++) {
4696 line
= rb_check_array_type(argv
[i
]);
4698 rb_exec_recursive(io_puts_ary
, line
, out
);
4701 line
= rb_obj_as_string(argv
[i
]);
4702 rb_io_write(out
, line
);
4703 if (RSTRING_LEN(line
) == 0 ||
4704 RSTRING_PTR(line
)[RSTRING_LEN(line
)-1] != '\n') {
4705 rb_io_write(out
, rb_default_rs
);
4714 * puts(obj, ...) => nil
4718 * $stdout.puts(obj, ...)
4722 rb_f_puts(int argc
, VALUE
*argv
, VALUE recv
)
4724 if (recv
== rb_stdout
) {
4725 return rb_io_puts(argc
, argv
, recv
);
4727 return rb_funcall2(rb_stdout
, rb_intern("puts"), argc
, argv
);
4731 rb_p(VALUE obj
) /* for debug print within C code */
4733 rb_io_write(rb_stdout
, rb_obj_as_string(rb_inspect(obj
)));
4734 rb_io_write(rb_stdout
, rb_default_rs
);
4740 * p(obj1, obj2, ...) => [obj, ...]
4743 * For each object, directly writes
4744 * _obj_.+inspect+ followed by the current output
4745 * record separator to the program's standard output.
4747 * S = Struct.new(:name, :state)
4748 * s = S['dave', 'TX']
4751 * <em>produces:</em>
4753 * #<S name="dave", state="TX">
4757 rb_f_p(int argc
, VALUE
*argv
, VALUE self
)
4762 for (i
=0; i
<argc
; i
++) {
4768 else if (argc
> 1) {
4769 ret
= rb_ary_new4(argc
, argv
);
4771 if (TYPE(rb_stdout
) == T_FILE
) {
4772 rb_io_flush(rb_stdout
);
4779 * obj.display(port=$>) => nil
4781 * Prints <i>obj</i> on the given port (default <code>$></code>).
4784 * def display(port=$>)
4792 * [ 4, 5, 6 ].display
4795 * <em>produces:</em>
4801 rb_obj_display(int argc
, VALUE
*argv
, VALUE self
)
4809 rb_scan_args(argc
, argv
, "01", &out
);
4811 rb_io_write(out
, self
);
4817 rb_write_error2(const char *mesg
, long len
)
4819 if (rb_stderr
== orig_stderr
|| RFILE(orig_stderr
)->fptr
->fd
< 0) {
4820 fwrite(mesg
, sizeof(char), len
, stderr
);
4823 rb_io_write(rb_stderr
, rb_str_new(mesg
, len
));
4828 rb_write_error(const char *mesg
)
4830 rb_write_error2(mesg
, strlen(mesg
));
4834 must_respond_to(ID mid
, VALUE val
, ID id
)
4836 if (!rb_respond_to(val
, mid
)) {
4837 rb_raise(rb_eTypeError
, "%s must have %s method, %s given",
4838 rb_id2name(id
), rb_id2name(mid
),
4839 rb_obj_classname(val
));
4844 stdout_setter(VALUE val
, ID id
, VALUE
*variable
)
4846 must_respond_to(id_write
, val
, id
);
4851 prep_io(int fd
, int mode
, VALUE klass
, const char *path
)
4854 VALUE io
= io_alloc(klass
);
4856 MakeOpenFile(io
, fp
);
4861 setmode(fd
, O_BINARY
);
4866 if (path
) fp
->path
= strdup(path
);
4872 rb_io_fdopen(int fd
, int mode
, const char *path
)
4874 VALUE klass
= rb_cIO
;
4876 if (path
&& strcmp(path
, "-")) klass
= rb_cFile
;
4877 return prep_io(fd
, rb_io_modenum_flags(mode
), klass
, path
);
4881 prep_stdio(FILE *f
, int mode
, VALUE klass
, const char *path
)
4884 VALUE io
= prep_io(fileno(f
), mode
|FMODE_PREP
, klass
, path
);
4886 GetOpenFile(io
, fptr
);
4887 fptr
->stdio_file
= f
;
4893 rb_io_stdio_file(rb_io_t
*fptr
)
4895 if (!fptr
->stdio_file
) {
4896 fptr
->stdio_file
= rb_fdopen(fptr
->fd
, rb_io_flags_mode(fptr
->mode
));
4898 return fptr
->stdio_file
;
4903 * IO.new(fd, mode) => io
4905 * Returns a new <code>IO</code> object (a stream) for the given
4906 * <code>IO</code> object or integer file descriptor and mode
4907 * string. See also <code>IO#fileno</code> and
4908 * <code>IO::for_fd</code>.
4910 * puts IO.new($stdout).fileno # => 1
4912 * a = IO.new(2,"w") # '2' is standard error
4913 * $stderr.puts "Hello"
4916 * <em>produces:</em>
4923 rb_io_initialize(int argc
, VALUE
*argv
, VALUE io
)
4925 VALUE fnum
, mode
, orig
;
4926 rb_io_t
*fp
, *ofp
= NULL
;
4927 int fd
, fmode
, flags
= O_RDONLY
;
4930 rb_scan_args(argc
, argv
, "11", &fnum
, &mode
);
4932 if (FIXNUM_P(mode
)) {
4933 flags
= FIX2LONG(mode
);
4936 SafeStringValue(mode
);
4937 flags
= rb_io_mode_modenum(StringValueCStr(mode
));
4940 orig
= rb_io_check_io(fnum
);
4945 #if defined(HAVE_FCNTL) && defined(F_GETFL)
4946 flags
= fcntl(fd
, F_GETFL
);
4947 if (flags
== -1) rb_sys_fail(0);
4950 MakeOpenFile(io
, fp
);
4952 fp
->mode
= rb_io_modenum_flags(flags
);
4955 else if (RFILE(io
)->fptr
) {
4956 rb_raise(rb_eRuntimeError
, "reinitializing IO");
4959 GetOpenFile(orig
, ofp
);
4960 if (ofp
->refcnt
== LONG_MAX
) {
4961 VALUE s
= rb_inspect(orig
);
4962 rb_raise(rb_eIOError
, "too many shared IO for %s", StringValueCStr(s
));
4965 fmode
= rb_io_modenum_flags(flags
);
4966 if ((ofp
->mode
^ fmode
) & (FMODE_READWRITE
|FMODE_BINMODE
)) {
4967 if (FIXNUM_P(mode
)) {
4968 rb_raise(rb_eArgError
, "incompatible mode 0%o", flags
);
4971 rb_raise(rb_eArgError
, "incompatible mode \"%s\"", RSTRING_PTR(mode
));
4976 RFILE(io
)->fptr
= ofp
;
4985 * File.new(filename, mode="r") => file
4986 * File.new(filename [, mode [, perm]]) => file
4989 * Opens the file named by _filename_ according to
4990 * _mode_ (default is ``r'') and returns a new
4991 * <code>File</code> object. See the description of class +IO+ for
4992 * a description of _mode_. The file mode may optionally be
4993 * specified as a +Fixnum+ by _or_-ing together the
4994 * flags (O_RDONLY etc, again described under +IO+). Optional
4995 * permission bits may be given in _perm_. These mode and permission
4996 * bits are platform dependent; on Unix systems, see
4997 * <code>open(2)</code> for details.
4999 * f = File.new("testfile", "r")
5000 * f = File.new("newfile", "w+")
5001 * f = File.new("newfile", File::CREAT|File::TRUNC|File::RDWR, 0644)
5005 rb_file_initialize(int argc
, VALUE
*argv
, VALUE io
)
5007 if (RFILE(io
)->fptr
) {
5008 rb_raise(rb_eRuntimeError
, "reinitializing File");
5010 if (0 < argc
&& argc
< 3) {
5011 VALUE fd
= rb_check_convert_type(argv
[0], T_FIXNUM
, "Fixnum", "to_int");
5015 return rb_io_initialize(argc
, argv
, io
);
5018 rb_open_file(argc
, argv
, io
);
5025 * IO.new(fd, mode_string) => io
5027 * Returns a new <code>IO</code> object (a stream) for the given
5028 * integer file descriptor and mode string. See also
5029 * <code>IO#fileno</code> and <code>IO::for_fd</code>.
5031 * a = IO.new(2,"w") # '2' is standard error
5032 * $stderr.puts "Hello"
5035 * <em>produces:</em>
5042 rb_io_s_new(int argc
, VALUE
*argv
, VALUE klass
)
5044 if (rb_block_given_p()) {
5045 char *cname
= rb_class2name(klass
);
5047 rb_warn("%s::new() does not take block; use %s::open() instead",
5050 return rb_class_new_instance(argc
, argv
, klass
);
5056 * IO.for_fd(fd, mode) => io
5058 * Synonym for <code>IO::new</code>.
5063 rb_io_s_for_fd(int argc
, VALUE
*argv
, VALUE klass
)
5065 VALUE io
= rb_obj_alloc(klass
);
5066 rb_io_initialize(argc
, argv
, io
);
5071 argf_mark(void *ptr
)
5073 struct argf
*p
= ptr
;
5074 rb_gc_mark(p
->filename
);
5075 rb_gc_mark(p
->current_file
);
5076 rb_gc_mark(p
->lineno
);
5077 rb_gc_mark(p
->argv
);
5081 argf_free(void *ptr
)
5083 struct argf
*p
= ptr
;
5088 argf_init(struct argf
*p
, VALUE v
)
5091 p
->current_file
= Qnil
;
5097 argf_alloc(VALUE klass
)
5100 VALUE argf
= Data_Make_Struct(klass
, struct argf
, argf_mark
, argf_free
, p
);
5107 #define filename ARGF.filename
5108 #define current_file ARGF.current_file
5109 #define gets_lineno ARGF.gets_lineno
5110 #define init_p ARGF.init_p
5111 #define next_p ARGF.next_p
5112 #define lineno ARGF.lineno
5113 #define ruby_inplace_mode ARGF.inplace
5114 #define argf_binmode ARGF.binmode
5115 #define argf_enc ARGF.enc
5116 #define argf_enc2 ARGF.enc2
5117 #define rb_argv ARGF.argv
5120 argf_initialize(VALUE argf
, VALUE argv
)
5122 memset(&ARGF
, 0, sizeof(ARGF
));
5123 argf_init(&ARGF
, argv
);
5129 argf_initialize_copy(VALUE argf
, VALUE orig
)
5131 ARGF
= argf_of(orig
);
5132 rb_argv
= rb_obj_dup(rb_argv
);
5134 const char *inplace
= ARGF
.inplace
;
5136 ARGF
.inplace
= ruby_strdup(inplace
);
5142 argf_set_lineno(VALUE argf
, VALUE val
)
5144 gets_lineno
= NUM2INT(val
);
5145 lineno
= INT2FIX(gets_lineno
);
5150 argf_lineno(VALUE argf
)
5156 argf_forward(int argc
, VALUE
*argv
, VALUE argf
)
5158 return rb_funcall3(current_file
, rb_frame_this_func(), argc
, argv
);
5161 #define next_argv() argf_next_argv(argf)
5162 #define ARGF_GENERIC_INPUT_P() \
5163 (current_file == rb_stdin && TYPE(current_file) != T_FILE)
5164 #define ARGF_FORWARD(argc, argv) do {\
5165 if (ARGF_GENERIC_INPUT_P())\
5166 return argf_forward(argc, argv, argf);\
5168 #define NEXT_ARGF_FORWARD(argc, argv) do {\
5169 if (!next_argv()) return Qnil;\
5170 ARGF_FORWARD(argc, argv);\
5174 argf_close(VALUE file
)
5176 rb_funcall3(file
, rb_intern("close"), 0, 0);
5180 argf_next_argv(VALUE argf
)
5184 int stdout_binmode
= 0;
5186 if (TYPE(rb_stdout
) == T_FILE
) {
5187 GetOpenFile(rb_stdout
, fptr
);
5188 if (fptr
->mode
& FMODE_BINMODE
)
5193 if (!NIL_P(rb_argv
) && RARRAY_LEN(rb_argv
) > 0) {
5206 if (RARRAY_LEN(rb_argv
) > 0) {
5207 filename
= rb_ary_shift(rb_argv
);
5208 fn
= StringValueCStr(filename
);
5209 if (strlen(fn
) == 1 && fn
[0] == '-') {
5210 current_file
= rb_stdin
;
5211 if (ruby_inplace_mode
) {
5212 rb_warn("Can't do inplace edit for stdio; skipping");
5217 int fr
= rb_sysopen(fn
, O_RDONLY
, 0);
5219 if (ruby_inplace_mode
) {
5221 #ifndef NO_SAFE_RENAME
5227 if (TYPE(rb_stdout
) == T_FILE
&& rb_stdout
!= orig_stdout
) {
5228 rb_io_close(rb_stdout
);
5231 if (*ruby_inplace_mode
) {
5232 str
= rb_str_new2(fn
);
5233 #ifdef NO_LONG_FNAME
5234 ruby_add_suffix(str
, ruby_inplace_mode
);
5236 rb_str_cat2(str
, ruby_inplace_mode
);
5238 #ifdef NO_SAFE_RENAME
5240 (void)unlink(RSTRING_PTR(str
));
5241 (void)rename(fn
, RSTRING_PTR(str
));
5242 fr
= rb_sysopen(RSTRING_PTR(str
), O_RDONLY
, 0);
5244 if (rename(fn
, RSTRING_PTR(str
)) < 0) {
5245 rb_warn("Can't rename %s to %s: %s, skipping file",
5246 fn
, RSTRING_PTR(str
), strerror(errno
));
5253 #ifdef NO_SAFE_RENAME
5254 rb_fatal("Can't do inplace edit without backup");
5256 if (unlink(fn
) < 0) {
5257 rb_warn("Can't remove %s: %s, skipping file",
5258 fn
, strerror(errno
));
5264 fw
= rb_sysopen(fn
, O_WRONLY
|O_CREAT
|O_TRUNC
, 0666);
5265 #ifndef NO_SAFE_RENAME
5268 fchmod(fw
, st
.st_mode
);
5270 chmod(fn
, st
.st_mode
);
5272 if (st
.st_uid
!=st2
.st_uid
|| st
.st_gid
!=st2
.st_gid
) {
5273 fchown(fw
, st
.st_uid
, st
.st_gid
);
5276 rb_stdout
= prep_io(fw
, FMODE_WRITABLE
, rb_cFile
, fn
);
5277 if (stdout_binmode
) rb_io_binmode(rb_stdout
);
5279 current_file
= prep_io(fr
, FMODE_READABLE
, rb_cFile
, fn
);
5281 if (argf_binmode
) rb_io_binmode(current_file
);
5285 GetOpenFile(current_file
, fptr
);
5286 fptr
->enc
= argf_enc
;
5287 fptr
->enc2
= argf_enc2
;
5295 else if (next_p
== -1) {
5296 current_file
= rb_stdin
;
5297 filename
= rb_str_new2("-");
5298 if (ruby_inplace_mode
) {
5299 rb_warn("Can't do inplace edit for stdio");
5300 rb_stdout
= orig_stdout
;
5307 argf_getline(int argc
, VALUE
*argv
, VALUE argf
)
5312 if (!next_argv()) return Qnil
;
5313 if (ARGF_GENERIC_INPUT_P()) {
5314 line
= rb_funcall3(current_file
, rb_intern("gets"), argc
, argv
);
5317 if (argc
== 0 && rb_rs
== rb_default_rs
) {
5318 line
= rb_io_gets(current_file
);
5321 line
= rb_io_getline(argc
, argv
, current_file
);
5323 if (NIL_P(line
) && next_p
!= -1) {
5324 argf_close(current_file
);
5331 lineno
= INT2FIX(gets_lineno
);
5337 argf_lineno_getter(ID id
, VALUE
*var
)
5344 argf_lineno_setter(VALUE val
, ID id
, VALUE
*var
)
5347 int n
= NUM2INT(val
);
5349 lineno
= INT2FIX(n
);
5354 * gets(sep=$/) => string or nil
5355 * gets(limit) => string or nil
5356 * gets(sep,limit) => string or nil
5358 * Returns (and assigns to <code>$_</code>) the next line from the list
5359 * of files in +ARGV+ (or <code>$*</code>), or from standard input if
5360 * no files are present on the command line. Returns +nil+ at end of
5361 * file. The optional argument specifies the record separator. The
5362 * separator is included with the contents of each record. A separator
5363 * of +nil+ reads the entire contents, and a zero-length separator
5364 * reads the input one paragraph at a time, where paragraphs are
5365 * divided by two consecutive newlines. If the first argument is an
5366 * integer, or optional second argument is given, the returning string
5367 * would not be longer than the given value. If multiple filenames are
5368 * present in +ARGV+, +gets(nil)+ will read the contents one file at a
5371 * ARGV << "testfile"
5374 * <em>produces:</em>
5378 * This is line three
5381 * The style of programming using <code>$_</code> as an implicit
5382 * parameter is gradually losing favor in the Ruby community.
5385 static VALUE
argf_gets(int, VALUE
*, VALUE
);
5387 rb_f_gets(int argc
, VALUE
*argv
, VALUE recv
)
5390 return argf_gets(argc
, argv
, argf
);
5392 return rb_funcall2(argf
, rb_intern("gets"), argc
, argv
);
5396 argf_gets(int argc
, VALUE
*argv
, VALUE argf
)
5400 line
= argf_getline(argc
, argv
, argf
);
5401 rb_lastline_set(line
);
5410 if (rb_rs
!= rb_default_rs
) {
5411 return rb_f_gets(0, 0, argf
);
5415 if (!next_argv()) return Qnil
;
5416 line
= rb_io_gets(current_file
);
5417 if (NIL_P(line
) && next_p
!= -1) {
5418 rb_io_close(current_file
);
5422 rb_lastline_set(line
);
5425 lineno
= INT2FIX(gets_lineno
);
5433 * readline(sep=$/) => string
5434 * readline(limit) => string
5435 * readline(sep, limit) => string
5437 * Equivalent to <code>Kernel::gets</code>, except
5438 * +readline+ raises +EOFError+ at end of file.
5441 static VALUE
argf_readline(int, VALUE
*, VALUE
);
5443 rb_f_readline(int argc
, VALUE
*argv
, VALUE recv
)
5446 return argf_readline(argc
, argv
, argf
);
5448 return rb_funcall2(argf
, rb_intern("readline"), argc
, argv
);
5452 argf_readline(int argc
, VALUE
*argv
, VALUE argf
)
5456 if (!next_argv()) rb_eof_error();
5457 ARGF_FORWARD(argc
, argv
);
5458 line
= argf_gets(argc
, argv
, argf
);
5468 * readlines(sep=$/) => array
5469 * readlines(limit) => array
5470 * readlines(sep,limit) => array
5472 * Returns an array containing the lines returned by calling
5473 * <code>Kernel.gets(<i>sep</i>)</code> until the end of file.
5476 static VALUE
argf_readlines(int, VALUE
*, VALUE
);
5478 rb_f_readlines(int argc
, VALUE
*argv
, VALUE recv
)
5481 return argf_readlines(argc
, argv
, argf
);
5483 return rb_funcall2(argf
, rb_intern("readlines"), argc
, argv
);
5487 argf_readlines(int argc
, VALUE
*argv
, VALUE argf
)
5492 while (!NIL_P(line
= argf_getline(argc
, argv
, argf
))) {
5493 rb_ary_push(ary
, line
);
5503 * Returns the standard output of running _cmd_ in a subshell.
5504 * The built-in syntax <code>%x{...}</code> uses
5505 * this method. Sets <code>$?</code> to the process status.
5507 * `date` #=> "Wed Apr 9 08:56:30 CDT 2003\n"
5508 * `ls testdir`.split[1] #=> "main.rb"
5509 * `echo oops && exit 99` #=> "oops\n"
5510 * $?.exitstatus #=> 99
5514 rb_f_backquote(VALUE obj
, VALUE str
)
5516 volatile VALUE port
;
5520 SafeStringValue(str
);
5521 port
= pipe_open_s(str
, "r");
5522 if (NIL_P(port
)) return rb_str_new(0,0);
5524 GetOpenFile(port
, fptr
);
5525 result
= read_all(fptr
, remain_size(fptr
), Qnil
);
5531 #ifdef HAVE_SYS_SELECT_H
5532 #include <sys/select.h>
5536 select_internal(VALUE read
, VALUE write
, VALUE except
, struct timeval
*tp
, rb_fdset_t
*fds
)
5539 fd_set
*rp
, *wp
, *ep
;
5543 int interrupt_flag
= 0;
5545 struct timeval timerec
;
5548 Check_Type(read
, T_ARRAY
);
5549 for (i
=0; i
<RARRAY_LEN(read
); i
++) {
5550 GetOpenFile(rb_io_get_io(RARRAY_PTR(read
)[i
]), fptr
);
5551 rb_fd_set(fptr
->fd
, &fds
[0]);
5552 if (READ_DATA_PENDING(fptr
)) { /* check for buffered data */
5554 rb_fd_set(fptr
->fd
, &fds
[3]);
5556 if (max
< fptr
->fd
) max
= fptr
->fd
;
5558 if (pending
) { /* no blocking if there's buffered data */
5559 timerec
.tv_sec
= timerec
.tv_usec
= 0;
5562 rp
= rb_fd_ptr(&fds
[0]);
5567 if (!NIL_P(write
)) {
5568 Check_Type(write
, T_ARRAY
);
5569 for (i
=0; i
<RARRAY_LEN(write
); i
++) {
5570 VALUE write_io
= GetWriteIO(rb_io_get_io(RARRAY_PTR(write
)[i
]));
5571 GetOpenFile(write_io
, fptr
);
5572 rb_fd_set(fptr
->fd
, &fds
[1]);
5573 if (max
< fptr
->fd
) max
= fptr
->fd
;
5575 wp
= rb_fd_ptr(&fds
[1]);
5580 if (!NIL_P(except
)) {
5581 Check_Type(except
, T_ARRAY
);
5582 for (i
=0; i
<RARRAY_LEN(except
); i
++) {
5583 VALUE io
= rb_io_get_io(RARRAY_PTR(except
)[i
]);
5584 VALUE write_io
= GetWriteIO(io
);
5585 GetOpenFile(io
, fptr
);
5586 rb_fd_set(fptr
->fd
, &fds
[2]);
5587 if (max
< fptr
->fd
) max
= fptr
->fd
;
5588 if (io
!= write_io
) {
5589 GetOpenFile(write_io
, fptr
);
5590 rb_fd_set(fptr
->fd
, &fds
[2]);
5591 if (max
< fptr
->fd
) max
= fptr
->fd
;
5594 ep
= rb_fd_ptr(&fds
[2]);
5602 n
= rb_thread_select(max
, rp
, wp
, ep
, tp
);
5606 if (!pending
&& n
== 0) return Qnil
; /* returns nil on timeout */
5608 res
= rb_ary_new2(3);
5609 rb_ary_push(res
, rp
?rb_ary_new():rb_ary_new2(0));
5610 rb_ary_push(res
, wp
?rb_ary_new():rb_ary_new2(0));
5611 rb_ary_push(res
, ep
?rb_ary_new():rb_ary_new2(0));
5613 if (interrupt_flag
== 0) {
5615 list
= RARRAY_PTR(res
)[0];
5616 for (i
=0; i
< RARRAY_LEN(read
); i
++) {
5617 VALUE obj
= rb_ary_entry(read
, i
);
5618 VALUE io
= rb_io_get_io(obj
);
5619 GetOpenFile(io
, fptr
);
5620 if (rb_fd_isset(fptr
->fd
, &fds
[0]) ||
5621 rb_fd_isset(fptr
->fd
, &fds
[3])) {
5622 rb_ary_push(list
, obj
);
5628 list
= RARRAY_PTR(res
)[1];
5629 for (i
=0; i
< RARRAY_LEN(write
); i
++) {
5630 VALUE obj
= rb_ary_entry(write
, i
);
5631 VALUE io
= rb_io_get_io(obj
);
5632 VALUE write_io
= GetWriteIO(io
);
5633 GetOpenFile(write_io
, fptr
);
5634 if (rb_fd_isset(fptr
->fd
, &fds
[1])) {
5635 rb_ary_push(list
, obj
);
5641 list
= RARRAY_PTR(res
)[2];
5642 for (i
=0; i
< RARRAY_LEN(except
); i
++) {
5643 VALUE obj
= rb_ary_entry(except
, i
);
5644 VALUE io
= rb_io_get_io(obj
);
5645 VALUE write_io
= GetWriteIO(io
);
5646 GetOpenFile(io
, fptr
);
5647 if (rb_fd_isset(fptr
->fd
, &fds
[2])) {
5648 rb_ary_push(list
, obj
);
5650 else if (io
!= write_io
) {
5651 GetOpenFile(write_io
, fptr
);
5652 if (rb_fd_isset(fptr
->fd
, &fds
[2])) {
5653 rb_ary_push(list
, obj
);
5660 return res
; /* returns an empty array on interrupt */
5663 struct select_args
{
5664 VALUE read
, write
, except
;
5665 struct timeval
*timeout
;
5666 rb_fdset_t fdsets
[4];
5669 #ifdef HAVE_RB_FD_INIT
5671 select_call(VALUE arg
)
5673 struct select_args
*p
= (struct select_args
*)arg
;
5675 return select_internal(p
->read
, p
->write
, p
->except
, p
->timeout
, p
->fdsets
);
5679 select_end(VALUE arg
)
5681 struct select_args
*p
= (struct select_args
*)arg
;
5684 for (i
= 0; i
< sizeof(p
->fdsets
) / sizeof(p
->fdsets
[0]); ++i
)
5685 rb_fd_term(&p
->fdsets
[i
]);
5692 * IO.select(read_array
5695 * [, timeout]]] ) => array or nil
5697 * See <code>Kernel#select</code>.
5701 rb_f_select(int argc
, VALUE
*argv
, VALUE obj
)
5704 struct select_args args
;
5705 struct timeval timerec
;
5708 rb_scan_args(argc
, argv
, "13", &args
.read
, &args
.write
, &args
.except
, &timeout
);
5709 if (NIL_P(timeout
)) {
5713 timerec
= rb_time_interval(timeout
);
5714 args
.timeout
= &timerec
;
5717 for (i
= 0; i
< sizeof(args
.fdsets
) / sizeof(args
.fdsets
[0]); ++i
)
5718 rb_fd_init(&args
.fdsets
[i
]);
5720 #ifdef HAVE_RB_FD_INIT
5721 return rb_ensure(select_call
, (VALUE
)&args
, select_end
, (VALUE
)&args
);
5723 return select_internal(args
.read
, args
.write
, args
.except
,
5724 args
.timeout
, args
.fdsets
);
5729 #if !defined(MSDOS) && !defined(__human68k__)
5731 io_cntl(int fd
, int cmd
, long narg
, int io_p
)
5737 # if defined(__CYGWIN__)
5738 retval
= io_p
?ioctl(fd
, cmd
, (void*)narg
):fcntl(fd
, cmd
, narg
);
5740 retval
= io_p
?ioctl(fd
, cmd
, narg
):fcntl(fd
, cmd
, narg
);
5748 retval
= ioctl(fd
, cmd
, narg
);
5756 rb_io_ctl(VALUE io
, VALUE req
, VALUE arg
, int io_p
)
5758 #if !defined(MSDOS) && !defined(__human68k__)
5759 int cmd
= NUM2ULONG(req
);
5767 if (NIL_P(arg
) || arg
== Qfalse
) {
5770 else if (FIXNUM_P(arg
)) {
5771 narg
= FIX2LONG(arg
);
5773 else if (arg
== Qtrue
) {
5777 VALUE tmp
= rb_check_string_type(arg
);
5780 narg
= NUM2LONG(arg
);
5786 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
5790 len
= IOCPARM_LEN(cmd
); /* on BSDish systems we're safe */
5792 len
= 256; /* otherwise guess at what's safe */
5796 if (len
<= RSTRING_LEN(arg
)) {
5797 len
= RSTRING_LEN(arg
);
5799 if (RSTRING_LEN(arg
) < len
) {
5800 rb_str_resize(arg
, len
+1);
5802 RSTRING_PTR(arg
)[len
] = 17; /* a little sanity check here */
5803 narg
= (long)RSTRING_PTR(arg
);
5806 GetOpenFile(io
, fptr
);
5807 retval
= io_cntl(fptr
->fd
, cmd
, narg
, io_p
);
5808 if (retval
< 0) rb_sys_fail(fptr
->path
);
5809 if (TYPE(arg
) == T_STRING
&& RSTRING_PTR(arg
)[len
] != 17) {
5810 rb_raise(rb_eArgError
, "return value overflowed string");
5813 if (!io_p
&& cmd
== F_SETFL
) {
5814 if (narg
& O_NONBLOCK
) {
5815 fptr
->mode
|= FMODE_WSPLIT_INITIALIZED
;
5816 fptr
->mode
&= ~FMODE_WSPLIT
;
5819 fptr
->mode
&= ~(FMODE_WSPLIT_INITIALIZED
|FMODE_WSPLIT
);
5823 return INT2NUM(retval
);
5826 return Qnil
; /* not reached */
5833 * ios.ioctl(integer_cmd, arg) => integer
5835 * Provides a mechanism for issuing low-level commands to control or
5836 * query I/O devices. Arguments and results are platform dependent. If
5837 * <i>arg</i> is a number, its value is passed directly. If it is a
5838 * string, it is interpreted as a binary sequence of bytes. On Unix
5839 * platforms, see <code>ioctl(2)</code> for details. Not implemented on
5844 rb_io_ioctl(int argc
, VALUE
*argv
, VALUE io
)
5848 rb_scan_args(argc
, argv
, "11", &req
, &arg
);
5849 return rb_io_ctl(io
, req
, arg
, 1);
5854 * ios.fcntl(integer_cmd, arg) => integer
5856 * Provides a mechanism for issuing low-level commands to control or
5857 * query file-oriented I/O streams. Arguments and results are platform
5858 * dependent. If <i>arg</i> is a number, its value is passed
5859 * directly. If it is a string, it is interpreted as a binary sequence
5860 * of bytes (<code>Array#pack</code> might be a useful way to build this
5861 * string). On Unix platforms, see <code>fcntl(2)</code> for details.
5862 * Not implemented on all platforms.
5866 rb_io_fcntl(int argc
, VALUE
*argv
, VALUE io
)
5871 rb_scan_args(argc
, argv
, "11", &req
, &arg
);
5872 return rb_io_ctl(io
, req
, arg
, 0);
5875 return Qnil
; /* not reached */
5881 * syscall(fixnum [, args...]) => integer
5883 * Calls the operating system function identified by _fixnum_,
5884 * passing in the arguments, which must be either +String+
5885 * objects, or +Integer+ objects that ultimately fit within
5886 * a native +long+. Up to nine parameters may be passed (14
5887 * on the Atari-ST). The function identified by _fixnum_ is system
5888 * dependent. On some Unix systems, the numbers may be obtained from a
5889 * header file called <code>syscall.h</code>.
5891 * syscall 4, 1, "hello\n", 6 # '4' is write(2) on our box
5893 * <em>produces:</em>
5899 rb_f_syscall(int argc
, VALUE
*argv
)
5901 #if defined(HAVE_SYSCALL) && !defined(__CHECKER__)
5903 unsigned long arg
[14]; /* yes, we really need that many ! */
5905 unsigned long arg
[8];
5909 int items
= argc
- 1;
5911 /* This probably won't work on machines where sizeof(long) != sizeof(int)
5912 * or where sizeof(long) != sizeof(char*). But such machines will
5913 * not likely have syscall implemented either, so who cares?
5918 rb_raise(rb_eArgError
, "too few arguments for syscall");
5919 if (argc
> sizeof(arg
) / sizeof(arg
[0]))
5920 rb_raise(rb_eArgError
, "too many arguments for syscall");
5921 arg
[0] = NUM2LONG(argv
[0]); argv
++;
5923 VALUE v
= rb_check_string_type(*argv
);
5928 arg
[i
] = (unsigned long)StringValueCStr(v
);
5931 arg
[i
] = (unsigned long)NUM2LONG(*argv
);
5939 retval
= syscall(arg
[0]);
5942 retval
= syscall(arg
[0],arg
[1]);
5945 retval
= syscall(arg
[0],arg
[1],arg
[2]);
5948 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3]);
5951 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4]);
5954 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5]);
5957 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5],arg
[6]);
5960 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5],arg
[6],
5965 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5],arg
[6],
5969 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5],arg
[6],
5970 arg
[7], arg
[8], arg
[9]);
5973 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5],arg
[6],
5974 arg
[7], arg
[8], arg
[9], arg
[10]);
5977 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5],arg
[6],
5978 arg
[7], arg
[8], arg
[9], arg
[10], arg
[11]);
5981 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5],arg
[6],
5982 arg
[7], arg
[8], arg
[9], arg
[10], arg
[11], arg
[12]);
5985 retval
= syscall(arg
[0],arg
[1],arg
[2],arg
[3],arg
[4],arg
[5],arg
[6],
5986 arg
[7], arg
[8], arg
[9], arg
[10], arg
[11], arg
[12], arg
[13]);
5988 #endif /* atarist */
5991 if (retval
< 0) rb_sys_fail(0);
5992 return INT2NUM(retval
);
5995 return Qnil
; /* not reached */
6000 io_new_instance(VALUE args
)
6002 return rb_class_new_instance(2, (VALUE
*)args
+1, *(VALUE
*)args
);
6006 io_encoding_set(rb_io_t
*fptr
, int argc
, VALUE v1
, VALUE v2
)
6008 if (NIL_P(v2
)) argc
= 1;
6010 fptr
->enc2
= rb_to_encoding(v1
);
6011 fptr
->enc
= rb_to_encoding(v2
);
6013 else if (argc
== 1) {
6018 VALUE tmp
= rb_check_string_type(v1
);
6020 mode_enc(fptr
, StringValueCStr(tmp
));
6023 fptr
->enc
= rb_to_encoding(v1
);
6031 * IO.pipe -> [read_io, write_io]
6032 * IO.pipe(ext_enc) -> [read_io, write_io]
6033 * IO.pipe("ext_enc:int_enc") -> [read_io, write_io]
6034 * IO.pipe(ext_enc, int_enc) -> [read_io, write_io]
6036 * Creates a pair of pipe endpoints (connected to each other) and
6037 * returns them as a two-element array of <code>IO</code> objects:
6038 * <code>[</code> <i>read_io</i>, <i>write_io</i> <code>]</code>. Not
6039 * available on all platforms.
6041 * If an encoding (encoding name or encoding object) is specified as an optional argument,
6042 * read string from pipe is tagged with the encoding specified.
6043 * If the argument is a colon separated two encoding names "A:B",
6044 * the read string is converted from encoding A (external encoding)
6045 * to encoding B (internal encoding), then tagged with B.
6046 * If two optional arguments are specified, those must be
6047 * encoding objects or encoding names,
6048 * and the first one is the external encoding,
6049 * and the second one is the internal encoding.
6051 * In the example below, the two processes close the ends of the pipe
6052 * that they are not using. This is not just a cosmetic nicety. The
6053 * read end of a pipe will not generate an end of file condition if
6054 * there are any writers with the pipe still open. In the case of the
6055 * parent process, the <code>rd.read</code> will never return if it
6056 * does not first issue a <code>wr.close</code>.
6062 * puts "Parent got: <#{rd.read}>"
6067 * puts "Sending message to parent"
6072 * <em>produces:</em>
6074 * Sending message to parent
6075 * Parent got: <Hi Dad>
6079 rb_io_s_pipe(int argc
, VALUE
*argv
, VALUE klass
)
6083 return Qnil
; /* not reached */
6085 int pipes
[2], state
;
6086 VALUE r
, w
, args
[3], v1
, v2
;
6089 rb_scan_args(argc
, argv
, "02", &v1
, &v2
);
6090 if (pipe(pipes
) == -1)
6092 UPDATE_MAXFD_PIPE(pipes
);
6095 args
[1] = INT2NUM(pipes
[0]);
6096 args
[2] = INT2FIX(O_RDONLY
);
6097 r
= rb_protect(io_new_instance
, (VALUE
)args
, &state
);
6103 GetOpenFile(r
, fptr
);
6104 io_encoding_set(fptr
, argc
, v1
, v2
);
6105 args
[1] = INT2NUM(pipes
[1]);
6106 args
[2] = INT2FIX(O_WRONLY
);
6107 w
= rb_protect(io_new_instance
, (VALUE
)args
, &state
);
6110 if (!NIL_P(r
)) rb_io_close(r
);
6113 rb_io_synchronized(RFILE(w
)->fptr
);
6115 return rb_assoc_new(r
, w
);
6119 struct foreach_arg
{
6126 open_key_args(int argc
, VALUE
*argv
, struct foreach_arg
*arg
)
6129 static VALUE encoding
, mode
, open_args
;
6131 FilePathValue(argv
[0]);
6133 arg
->argc
= argc
> 1 ? 1 : 0;
6134 arg
->argv
= argv
+ 1;
6137 arg
->io
= rb_io_open(RSTRING_PTR(argv
[0]), "r");
6140 opt
= rb_check_convert_type(argv
[argc
-1], T_HASH
, "Hash", "to_hash");
6141 if (NIL_P(opt
)) goto no_key
;
6142 if (argc
> 2) arg
->argc
= 1;
6147 id
= rb_intern("encoding");
6148 encoding
= ID2SYM(id
);
6149 id
= rb_intern("mode");
6151 id
= rb_intern("open_args");
6152 open_args
= ID2SYM(id
);
6154 v
= rb_hash_aref(opt
, open_args
);
6158 v
= rb_convert_type(v
, T_ARRAY
, "Array", "to_ary");
6159 args
= rb_ary_new2(RARRAY_LEN(v
)+1);
6160 rb_ary_push(args
, argv
[0]);
6161 rb_ary_concat(args
, v
);
6162 MEMCPY(RARRAY_PTR(args
)+1, RARRAY_PTR(v
), VALUE
, RARRAY_LEN(v
));
6164 arg
->io
= rb_io_open_with_args(RARRAY_LEN(args
), RARRAY_PTR(args
));
6167 v
= rb_hash_aref(opt
, mode
);
6169 arg
->io
= rb_io_open(RSTRING_PTR(argv
[0]), StringValueCStr(v
));
6172 arg
->io
= rb_io_open(RSTRING_PTR(argv
[0]), "r");
6175 v
= rb_hash_aref(opt
, encoding
);
6178 GetOpenFile(arg
->io
, fptr
);
6179 mode_enc(fptr
, StringValueCStr(v
));
6184 io_s_foreach(struct foreach_arg
*arg
)
6188 while (!NIL_P(str
= rb_io_gets_m(arg
->argc
, arg
->argv
, arg
->io
))) {
6196 * IO.foreach(name, sep=$/) {|line| block } => nil
6197 * IO.foreach(name, limit) {|line| block } => nil
6198 * IO.foreach(name, sep, limit) {|line| block } => nil
6200 * Executes the block for every line in the named I/O port, where lines
6201 * are separated by <em>sep</em>.
6203 * IO.foreach("testfile") {|x| print "GOT ", x }
6205 * <em>produces:</em>
6207 * GOT This is line one
6208 * GOT This is line two
6209 * GOT This is line three
6212 * If the last argument is a hash, it's the keyword argument to open.
6213 * See <code>IO.read</code> for detail.
6218 rb_io_s_foreach(int argc
, VALUE
*argv
, VALUE self
)
6220 struct foreach_arg arg
;
6222 rb_scan_args(argc
, argv
, "13", NULL
, NULL
, NULL
, NULL
);
6223 RETURN_ENUMERATOR(self
, argc
, argv
);
6224 open_key_args(argc
, argv
, &arg
);
6225 if (NIL_P(arg
.io
)) return Qnil
;
6226 return rb_ensure(io_s_foreach
, (VALUE
)&arg
, rb_io_close
, arg
.io
);
6230 io_s_readlines(struct foreach_arg
*arg
)
6232 return rb_io_readlines(arg
->argc
, arg
->argv
, arg
->io
);
6237 * IO.readlines(name, sep=$/) => array
6238 * IO.readlines(name, limit) => array
6239 * IO.readlines(name, sep, limit) => array
6241 * Reads the entire file specified by <i>name</i> as individual
6242 * lines, and returns those lines in an array. Lines are separated by
6245 * a = IO.readlines("testfile")
6246 * a[0] #=> "This is line one\n"
6248 * If the last argument is a hash, it's the keyword argument to open.
6249 * See <code>IO.read</code> for detail.
6254 rb_io_s_readlines(int argc
, VALUE
*argv
, VALUE io
)
6256 struct foreach_arg arg
;
6258 rb_scan_args(argc
, argv
, "13", NULL
, NULL
, NULL
, NULL
);
6259 open_key_args(argc
, argv
, &arg
);
6260 if (NIL_P(arg
.io
)) return Qnil
;
6261 return rb_ensure(io_s_readlines
, (VALUE
)&arg
, rb_io_close
, arg
.io
);
6265 io_s_read(struct foreach_arg
*arg
)
6267 return io_read(arg
->argc
, arg
->argv
, arg
->io
);
6272 * IO.read(name, [length [, offset]] ) => string
6273 * IO.read(name, [length [, offset]], opt) => string
6275 * Opens the file, optionally seeks to the given offset, then returns
6276 * <i>length</i> bytes (defaulting to the rest of the file).
6277 * <code>read</code> ensures the file is closed before returning.
6279 * If the last argument is a hash, it specifies option for internal
6280 * open(). The key would be the following. open_args: is exclusive
6283 * encoding: string or encoding
6285 * specifies encoding of the read string. encoding will be ignored
6286 * if length is specified.
6290 * specifies mode argument for open(). it should start with "r"
6291 * otherwise it would cause error.
6293 * open_args: array of strings
6295 * specifies arguments for open() as an array.
6297 * IO.read("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
6298 * IO.read("testfile", 20) #=> "This is line one\nThi"
6299 * IO.read("testfile", 20, 10) #=> "ne one\nThis is line "
6303 rb_io_s_read(int argc
, VALUE
*argv
, VALUE io
)
6306 struct foreach_arg arg
;
6308 rb_scan_args(argc
, argv
, "13", NULL
, NULL
, &offset
, NULL
);
6309 open_key_args(argc
, argv
, &arg
);
6310 if (NIL_P(arg
.io
)) return Qnil
;
6311 if (!NIL_P(offset
)) {
6312 rb_io_binmode(arg
.io
);
6313 rb_io_seek(arg
.io
, offset
, SEEK_SET
);
6314 if (arg
.argc
== 2) arg
.argc
= 1;
6316 return rb_ensure(io_s_read
, (VALUE
)&arg
, rb_io_close
, arg
.io
);
6319 struct copy_stream_struct
{
6322 off_t copy_length
; /* (off_t)-1 if not specified */
6323 off_t src_offset
; /* (off_t)-1 if not specified */
6338 copy_stream_wait_read(struct copy_stream_struct
*stp
)
6341 rb_fd_zero(&stp
->fds
);
6342 rb_fd_set(stp
->src_fd
, &stp
->fds
);
6343 ret
= rb_fd_select(rb_fd_max(&stp
->fds
), &stp
->fds
, NULL
, NULL
, NULL
);
6345 stp
->syserr
= "select";
6346 stp
->error_no
= errno
;
6353 copy_stream_wait_write(struct copy_stream_struct
*stp
)
6356 rb_fd_zero(&stp
->fds
);
6357 rb_fd_set(stp
->dst_fd
, &stp
->fds
);
6358 ret
= rb_fd_select(rb_fd_max(&stp
->fds
), NULL
, &stp
->fds
, NULL
, NULL
);
6360 stp
->syserr
= "select";
6361 stp
->error_no
= errno
;
6367 #ifdef HAVE_SENDFILE
6370 #define USE_SENDFILE
6372 #ifdef HAVE_SYS_SENDFILE_H
6373 #include <sys/sendfile.h>
6377 simple_sendfile(int out_fd
, int in_fd
, off_t
*offset
, size_t count
)
6379 return sendfile(out_fd
, in_fd
, offset
, count
);
6388 copy_stream_sendfile(struct copy_stream_struct
*stp
)
6390 struct stat src_stat
, dst_stat
;
6398 ret
= fstat(stp
->src_fd
, &src_stat
);
6400 stp
->syserr
= "fstat";
6401 stp
->error_no
= errno
;
6404 if (!S_ISREG(src_stat
.st_mode
))
6407 ret
= fstat(stp
->dst_fd
, &dst_stat
);
6409 stp
->syserr
= "fstat";
6410 stp
->error_no
= errno
;
6413 if ((dst_stat
.st_mode
& S_IFMT
) != S_IFSOCK
)
6416 src_offset
= stp
->src_offset
;
6417 use_pread
= src_offset
!= (off_t
)-1;
6419 copy_length
= stp
->copy_length
;
6420 if (copy_length
== (off_t
)-1) {
6422 copy_length
= src_stat
.st_size
- src_offset
;
6424 off_t cur
= lseek(stp
->src_fd
, 0, SEEK_CUR
);
6425 if (cur
== (off_t
)-1) {
6426 stp
->syserr
= "lseek";
6427 stp
->error_no
= errno
;
6430 copy_length
= src_stat
.st_size
- cur
;
6436 ss
= simple_sendfile(stp
->dst_fd
, stp
->src_fd
, &src_offset
, copy_length
);
6439 ss
= simple_sendfile(stp
->dst_fd
, stp
->src_fd
, NULL
, copy_length
);
6444 if (0 < copy_length
) {
6450 if (errno
== EINVAL
|| errno
== ENOSYS
)
6452 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
) {
6453 if (copy_stream_wait_write(stp
) == -1)
6455 if (RUBY_VM_INTERRUPTED(stp
->th
))
6457 goto retry_sendfile
;
6459 stp
->syserr
= "sendfile";
6460 stp
->error_no
= errno
;
6468 copy_stream_read(struct copy_stream_struct
*stp
, char *buf
, int len
, off_t offset
)
6472 if (offset
== (off_t
)-1)
6473 ss
= read(stp
->src_fd
, buf
, len
);
6476 ss
= pread(stp
->src_fd
, buf
, len
, offset
);
6478 stp
->notimp
= "pread";
6486 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
) {
6487 if (copy_stream_wait_read(stp
) == -1)
6491 if (errno
== ENOSYS
) {
6492 stp
->notimp
= "pread";
6495 stp
->syserr
= offset
== (off_t
)-1 ? "read" : "pread";
6496 stp
->error_no
= errno
;
6503 copy_stream_write(struct copy_stream_struct
*stp
, char *buf
, int len
)
6508 ss
= write(stp
->dst_fd
, buf
+off
, len
);
6510 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
) {
6511 if (copy_stream_wait_write(stp
) == -1)
6515 stp
->syserr
= "write";
6516 stp
->error_no
= errno
;
6527 copy_stream_read_write(struct copy_stream_struct
*stp
)
6538 copy_length
= stp
->copy_length
;
6539 use_eof
= copy_length
== (off_t
)-1;
6540 src_offset
= stp
->src_offset
;
6541 use_pread
= src_offset
!= (off_t
)-1;
6543 if (use_pread
&& stp
->close_src
) {
6545 r
= lseek(stp
->src_fd
, src_offset
, SEEK_SET
);
6546 if (r
== (off_t
)-1) {
6547 stp
->syserr
= "lseek";
6548 stp
->error_no
= errno
;
6551 src_offset
= (off_t
)-1;
6555 while (use_eof
|| 0 < copy_length
) {
6556 if (!use_eof
&& copy_length
< sizeof(buf
)) {
6563 ss
= copy_stream_read(stp
, buf
, len
, src_offset
);
6568 ss
= copy_stream_read(stp
, buf
, len
, (off_t
)-1);
6570 if (ss
<= 0) /* EOF or error */
6573 ret
= copy_stream_write(stp
, buf
, ss
);
6580 if (RUBY_VM_INTERRUPTED(stp
->th
))
6586 copy_stream_func(void *arg
)
6588 struct copy_stream_struct
*stp
= (struct copy_stream_struct
*)arg
;
6594 ret
= copy_stream_sendfile(stp
);
6596 goto finish
; /* error or success */
6599 copy_stream_read_write(stp
);
6608 copy_stream_fallback_body(VALUE arg
)
6610 struct copy_stream_struct
*stp
= (struct copy_stream_struct
*)arg
;
6611 const int buflen
= 16*1024;
6613 VALUE buf
= rb_str_buf_new(buflen
);
6614 long rest
= stp
->copy_length
;
6615 off_t off
= stp
->src_offset
;
6620 if (stp
->copy_length
== (off_t
)-1) {
6626 l
= buflen
< rest
? buflen
: rest
;
6628 if (stp
->src_fd
== -1) {
6629 rb_funcall(stp
->src
, id_readpartial
, 2, INT2FIX(l
), buf
);
6633 rb_thread_wait_fd(stp
->src_fd
);
6634 rb_str_resize(buf
, buflen
);
6635 ss
= copy_stream_read(stp
, RSTRING_PTR(buf
), l
, off
);
6640 rb_str_resize(buf
, ss
);
6641 if (off
!= (off_t
)-1)
6644 n
= rb_io_write(stp
->dst
, buf
);
6645 numwrote
= NUM2LONG(n
);
6646 stp
->total
+= numwrote
;
6654 copy_stream_fallback(struct copy_stream_struct
*stp
)
6656 if (stp
->src_fd
== -1 && stp
->src_offset
!= (off_t
)-1) {
6657 rb_raise(rb_eArgError
, "cannot specify src_offset for non-IO");
6659 rb_rescue2(copy_stream_fallback_body
, (VALUE
)stp
,
6660 (VALUE (*) (ANYARGS
))0, (VALUE
)0,
6661 rb_eEOFError
, (VALUE
)0);
6666 copy_stream_body(VALUE arg
)
6668 struct copy_stream_struct
*stp
= (struct copy_stream_struct
*)arg
;
6669 VALUE src_io
, dst_io
;
6670 rb_io_t
*src_fptr
= 0, *dst_fptr
= 0;
6673 stp
->th
= GET_THREAD();
6677 if (stp
->src
== argf
||
6678 !(TYPE(stp
->src
) == T_FILE
||
6679 rb_respond_to(stp
->src
, rb_intern("to_io")) ||
6680 TYPE(stp
->src
) == T_STRING
||
6681 rb_respond_to(stp
->src
, rb_intern("to_path")))) {
6685 src_io
= rb_check_convert_type(stp
->src
, T_FILE
, "IO", "to_io");
6686 if (NIL_P(src_io
)) {
6688 int flags
= O_RDONLY
;
6692 FilePathValue(stp
->src
);
6694 args
[1] = INT2NUM(flags
);
6695 src_io
= rb_class_new_instance(2, args
, rb_cFile
);
6699 GetOpenFile(src_io
, src_fptr
);
6700 rb_io_check_readable(src_fptr
);
6701 src_fd
= src_fptr
->fd
;
6703 stp
->src_fd
= src_fd
;
6705 if (stp
->dst
== argf
||
6706 !(TYPE(stp
->dst
) == T_FILE
||
6707 rb_respond_to(stp
->dst
, rb_intern("to_io")) ||
6708 TYPE(stp
->dst
) == T_STRING
||
6709 rb_respond_to(stp
->dst
, rb_intern("to_path")))) {
6713 dst_io
= rb_check_convert_type(stp
->dst
, T_FILE
, "IO", "to_io");
6714 if (NIL_P(dst_io
)) {
6716 int flags
= O_WRONLY
|O_CREAT
|O_TRUNC
;
6720 FilePathValue(stp
->dst
);
6722 args
[1] = INT2NUM(flags
);
6723 args
[2] = INT2FIX(0600);
6724 dst_io
= rb_class_new_instance(3, args
, rb_cFile
);
6729 dst_io
= GetWriteIO(dst_io
);
6732 GetOpenFile(dst_io
, dst_fptr
);
6733 rb_io_check_writable(dst_fptr
);
6734 dst_fd
= dst_fptr
->fd
;
6736 stp
->dst_fd
= dst_fd
;
6738 if (stp
->src_offset
== (off_t
)-1 && src_fptr
&& src_fptr
->rbuf_len
) {
6739 long len
= src_fptr
->rbuf_len
;
6741 if (stp
->copy_length
!= (off_t
)-1 && stp
->copy_length
< len
) {
6742 len
= stp
->copy_length
;
6744 str
= rb_str_buf_new(len
);
6745 rb_str_resize(str
,len
);
6746 read_buffered_data(RSTRING_PTR(str
), len
, src_fptr
);
6747 if (dst_fptr
) /* IO or filename */
6748 io_fwrite(str
, dst_fptr
);
6749 else /* others such as StringIO */
6750 rb_io_write(stp
->dst
, str
);
6752 if (stp
->copy_length
!= (off_t
)-1)
6753 stp
->copy_length
-= len
;
6756 if (dst_fptr
&& io_fflush(dst_fptr
) < 0) {
6757 rb_raise(rb_eIOError
, "flush failed");
6760 if (stp
->copy_length
== 0)
6763 if (src_fd
== -1 || dst_fd
== -1) {
6764 return copy_stream_fallback(stp
);
6767 rb_fd_init(&stp
->fds
);
6768 rb_fd_set(src_fd
, &stp
->fds
);
6769 rb_fd_set(dst_fd
, &stp
->fds
);
6771 return rb_thread_blocking_region(copy_stream_func
, (void*)stp
, RB_UBF_DFL
, 0);
6775 copy_stream_finalize(VALUE arg
)
6777 struct copy_stream_struct
*stp
= (struct copy_stream_struct
*)arg
;
6778 if (stp
->close_src
) {
6779 rb_io_close_m(stp
->src
);
6781 if (stp
->close_dst
) {
6782 rb_io_close_m(stp
->dst
);
6784 rb_fd_term(&stp
->fds
);
6786 errno
= stp
->error_no
;
6787 rb_sys_fail(stp
->syserr
);
6790 rb_raise(rb_eNotImpError
, "%s() not implemented", stp
->notimp
);
6797 * IO.copy_stream(src, dst)
6798 * IO.copy_stream(src, dst, copy_length)
6799 * IO.copy_stream(src, dst, copy_length, src_offset)
6801 * IO.copy_stream copies <i>src</i> to <i>dst</i>.
6802 * <i>src</i> and <i>dst</i> is either a filename or an IO.
6804 * This method returns the number of bytes copied.
6806 * If optional arguments are not given,
6807 * the start position of the copy is
6808 * the beginning of the filename or
6809 * the current file offset of the IO.
6810 * The end position of the copy is the end of file.
6812 * If <i>copy_length</i> is given,
6813 * No more than <i>copy_length</i> bytes are copied.
6815 * If <i>src_offset</i> is given,
6816 * it specifies the start position of the copy.
6818 * When <i>src_offset</i> is specified and
6819 * <i>src</i> is an IO,
6820 * IO.copy_stream doesn't move the current file offset.
6824 rb_io_s_copy_stream(int argc
, VALUE
*argv
, VALUE io
)
6826 VALUE src
, dst
, length
, src_offset
;
6827 struct copy_stream_struct st
;
6829 MEMZERO(&st
, struct copy_stream_struct
, 1);
6831 rb_scan_args(argc
, argv
, "22", &src
, &dst
, &length
, &src_offset
);
6837 st
.copy_length
= (off_t
)-1;
6839 st
.copy_length
= NUM2OFFT(length
);
6841 if (NIL_P(src_offset
))
6842 st
.src_offset
= (off_t
)-1;
6844 st
.src_offset
= NUM2OFFT(src_offset
);
6846 rb_ensure(copy_stream_body
, (VALUE
)&st
, copy_stream_finalize
, (VALUE
)&st
);
6848 return OFFT2NUM(st
.total
);
6853 * io.external_encoding => encoding
6855 * Returns the Encoding object that represents the encoding of the file.
6856 * If io is write mode and no encoding is specified, returns <code>nil</code>.
6860 rb_io_external_encoding(VALUE io
)
6864 GetOpenFile(io
, fptr
);
6866 return rb_enc_from_encoding(fptr
->enc2
);
6868 if (!fptr
->enc
&& fptr
->fd
== 0) {
6869 fptr
->enc
= rb_default_external_encoding();
6871 if (fptr
->mode
& FMODE_WRITABLE
) {
6873 return rb_enc_from_encoding(fptr
->enc
);
6876 return rb_enc_from_encoding(io_read_encoding(fptr
));
6881 * io.internal_encoding => encoding
6883 * Returns the Encoding of the internal string if conversion is
6884 * specified. Otherwise returns nil.
6888 rb_io_internal_encoding(VALUE io
)
6892 GetOpenFile(io
, fptr
);
6893 if (!fptr
->enc2
) return Qnil
;
6894 return rb_enc_from_encoding(io_read_encoding(fptr
));
6899 * io.set_encoding(ext_enc) => io
6900 * io.set_encoding("ext_enc:int_enc") => io
6901 * io.set_encoding(ext_enc, int_enc) => io
6903 * If single argument is specified, read string from io is tagged
6904 * with the encoding specified. If encoding is a colon separated two
6905 * encoding names "A:B", the read string is converted from encoding A
6906 * (external encoding) to encoding B (internal encoding), then tagged
6907 * with B. If two arguments are specified, those must be encoding
6908 * objects or encoding names, and the first one is the external encoding, and the
6909 * second one is the internal encoding.
6913 rb_io_set_encoding(int argc
, VALUE
*argv
, VALUE io
)
6918 rb_scan_args(argc
, argv
, "11", &v1
, &v2
);
6919 GetOpenFile(io
, fptr
);
6920 io_encoding_set(fptr
, argc
, v1
, v2
);
6925 argf_external_encoding(VALUE argf
)
6927 return rb_io_external_encoding(current_file
);
6931 argf_internal_encoding(VALUE argf
)
6933 return rb_io_internal_encoding(current_file
);
6937 argf_set_encoding(int argc
, VALUE
*argv
, VALUE argf
)
6942 rb_raise(rb_eArgError
, "no stream to set encoding");
6944 rb_io_set_encoding(argc
, argv
, current_file
);
6945 GetOpenFile(current_file
, fptr
);
6946 argf_enc
= fptr
->enc
;
6947 argf_enc2
= fptr
->enc2
;
6952 argf_tell(VALUE argf
)
6955 rb_raise(rb_eArgError
, "no stream to tell");
6958 return rb_io_tell(current_file
);
6962 argf_seek_m(int argc
, VALUE
*argv
, VALUE argf
)
6965 rb_raise(rb_eArgError
, "no stream to seek");
6967 ARGF_FORWARD(argc
, argv
);
6968 return rb_io_seek_m(argc
, argv
, current_file
);
6972 argf_set_pos(VALUE argf
, VALUE offset
)
6975 rb_raise(rb_eArgError
, "no stream to set position");
6977 ARGF_FORWARD(1, &offset
);
6978 return rb_io_set_pos(current_file
, offset
);
6982 argf_rewind(VALUE argf
)
6985 rb_raise(rb_eArgError
, "no stream to rewind");
6988 return rb_io_rewind(current_file
);
6992 argf_fileno(VALUE argf
)
6995 rb_raise(rb_eArgError
, "no stream");
6998 return rb_io_fileno(current_file
);
7002 argf_to_io(VALUE argf
)
7006 return current_file
;
7010 argf_eof(VALUE argf
)
7013 if (init_p
== 0) return Qtrue
;
7015 if (rb_io_eof(current_file
)) {
7023 argf_read(int argc
, VALUE
*argv
, VALUE argf
)
7025 VALUE tmp
, str
, length
;
7028 rb_scan_args(argc
, argv
, "02", &length
, &str
);
7029 if (!NIL_P(length
)) {
7030 len
= NUM2LONG(argv
[0]);
7034 rb_str_resize(str
,0);
7042 if (ARGF_GENERIC_INPUT_P()) {
7043 tmp
= argf_forward(argc
, argv
, argf
);
7046 tmp
= io_read(argc
, argv
, current_file
);
7048 if (NIL_P(str
)) str
= tmp
;
7049 else if (!NIL_P(tmp
)) rb_str_append(str
, tmp
);
7050 if (NIL_P(tmp
) || NIL_P(length
)) {
7052 argf_close(current_file
);
7057 else if (argc
>= 1) {
7058 if (RSTRING_LEN(str
) < len
) {
7059 len
-= RSTRING_LEN(str
);
7060 argv
[0] = INT2NUM(len
);
7067 struct argf_call_arg
{
7074 argf_forward_call(VALUE arg
)
7076 struct argf_call_arg
*p
= (struct argf_call_arg
*)arg
;
7077 argf_forward(p
->argc
, p
->argv
, p
->argf
);
7082 argf_readpartial(int argc
, VALUE
*argv
, VALUE argf
)
7084 VALUE tmp
, str
, length
;
7086 rb_scan_args(argc
, argv
, "11", &length
, &str
);
7093 rb_str_resize(str
, 0);
7096 if (ARGF_GENERIC_INPUT_P()) {
7097 struct argf_call_arg arg
;
7101 tmp
= rb_rescue2(argf_forward_call
, (VALUE
)&arg
,
7102 RUBY_METHOD_FUNC(0), Qnil
, rb_eEOFError
, (VALUE
)0);
7105 tmp
= io_getpartial(argc
, argv
, current_file
, 0);
7111 argf_close(current_file
);
7113 if (RARRAY_LEN(rb_argv
) == 0)
7116 str
= rb_str_new(NULL
, 0);
7123 argf_getc(VALUE argf
)
7128 if (!next_argv()) return Qnil
;
7129 if (ARGF_GENERIC_INPUT_P()) {
7130 ch
= rb_funcall3(current_file
, rb_intern("getc"), 0, 0);
7133 ch
= rb_io_getc(current_file
);
7135 if (NIL_P(ch
) && next_p
!= -1) {
7136 argf_close(current_file
);
7145 argf_getbyte(VALUE argf
)
7150 if (!next_argv()) return Qnil
;
7151 if (TYPE(current_file
) != T_FILE
) {
7152 ch
= rb_funcall3(current_file
, rb_intern("getbyte"), 0, 0);
7155 ch
= rb_io_getbyte(current_file
);
7157 if (NIL_P(ch
) && next_p
!= -1) {
7158 argf_close(current_file
);
7167 argf_readchar(VALUE argf
)
7172 if (!next_argv()) return Qnil
;
7173 if (TYPE(current_file
) != T_FILE
) {
7174 ch
= rb_funcall3(current_file
, rb_intern("getc"), 0, 0);
7177 ch
= rb_io_getc(current_file
);
7179 if (NIL_P(ch
) && next_p
!= -1) {
7180 argf_close(current_file
);
7189 argf_readbyte(VALUE argf
)
7193 NEXT_ARGF_FORWARD(0, 0);
7194 c
= argf_getbyte(argf
);
7202 argf_each_line(int argc
, VALUE
*argv
, VALUE argf
)
7204 RETURN_ENUMERATOR(argf
, argc
, argv
);
7206 if (!next_argv()) return Qnil
;
7207 rb_block_call(current_file
, rb_intern("each_line"), 0, 0, rb_yield
, 0);
7214 argf_each_byte(VALUE argf
)
7216 RETURN_ENUMERATOR(argf
, 0, 0);
7218 if (!next_argv()) return Qnil
;
7219 rb_block_call(current_file
, rb_intern("each_byte"), 0, 0, rb_yield
, 0);
7225 argf_each_char(VALUE argf
)
7227 RETURN_ENUMERATOR(argf
, 0, 0);
7229 if (!next_argv()) return Qnil
;
7230 rb_block_call(current_file
, rb_intern("each_char"), 0, 0, rb_yield
, 0);
7236 argf_filename(VALUE argf
)
7243 argf_filename_getter(ID id
, VALUE
*var
)
7245 return argf_filename(*var
);
7249 argf_file(VALUE argf
)
7252 return current_file
;
7256 argf_binmode_m(VALUE argf
)
7261 rb_io_binmode(current_file
);
7266 argf_skip(VALUE argf
)
7269 argf_close(current_file
);
7276 argf_close_m(VALUE argf
)
7279 argf_close(current_file
);
7288 argf_closed(VALUE argf
)
7292 return rb_io_closed(current_file
);
7296 argf_to_s(VALUE argf
)
7298 return rb_str_new2("ARGF");
7302 argf_inplace_mode_get(VALUE argf
)
7304 if (!ruby_inplace_mode
) return Qnil
;
7305 return rb_str_new2(ruby_inplace_mode
);
7309 opt_i_get(ID id
, VALUE
*var
)
7311 return argf_inplace_mode_get(*var
);
7315 argf_inplace_mode_set(VALUE argf
, VALUE val
)
7318 if (ruby_inplace_mode
) free(ruby_inplace_mode
);
7319 ruby_inplace_mode
= 0;
7323 if (ruby_inplace_mode
) free(ruby_inplace_mode
);
7324 ruby_inplace_mode
= 0;
7325 ruby_inplace_mode
= strdup(RSTRING_PTR(val
));
7331 opt_i_set(VALUE val
, ID id
, VALUE
*var
)
7333 argf_inplace_mode_set(*var
, val
);
7337 ruby_get_inplace_mode(void)
7339 return ruby_inplace_mode
;
7343 ruby_set_inplace_mode(const char *suffix
)
7345 if (ruby_inplace_mode
) free(ruby_inplace_mode
);
7346 ruby_inplace_mode
= 0;
7347 if (suffix
) ruby_inplace_mode
= strdup(suffix
);
7351 argf_argv(VALUE argf
)
7357 argf_argv_getter(ID id
, VALUE
*var
)
7359 return argf_argv(*var
);
7369 * Class <code>IO</code> is the basis for all input and output in Ruby.
7370 * An I/O stream may be <em>duplexed</em> (that is, bidirectional), and
7371 * so may use more than one native operating system stream.
7373 * Many of the examples in this section use class <code>File</code>,
7374 * the only standard subclass of <code>IO</code>. The two classes are
7375 * closely associated.
7377 * As used in this section, <em>portname</em> may take any of the
7380 * * A plain string represents a filename suitable for the underlying
7383 * * A string starting with ``<code>|</code>'' indicates a subprocess.
7384 * The remainder of the string following the ``<code>|</code>'' is
7385 * invoked as a process with appropriate input/output channels
7388 * * A string equal to ``<code>|-</code>'' will create another Ruby
7389 * instance as a subprocess.
7391 * Ruby will convert pathnames between different operating system
7392 * conventions if possible. For instance, on a Windows system the
7393 * filename ``<code>/gumby/ruby/test.rb</code>'' will be opened as
7394 * ``<code>\gumby\ruby\test.rb</code>''. When specifying a
7395 * Windows-style filename in a Ruby string, remember to escape the
7398 * "c:\\gumby\\ruby\\test.rb"
7400 * Our examples here will use the Unix-style forward slashes;
7401 * <code>File::SEPARATOR</code> can be used to get the
7402 * platform-specific separator character.
7404 * I/O ports may be opened in any one of several different modes, which
7405 * are shown in this section as <em>mode</em>. The mode may
7406 * either be a Fixnum or a String. If numeric, it should be
7407 * one of the operating system specific constants (O_RDONLY,
7408 * O_WRONLY, O_RDWR, O_APPEND and so on). See man open(2) for
7411 * If the mode is given as a String, it must be one of the
7412 * values listed in the following table.
7415 * -----+--------------------------------------------------------
7416 * "r" | Read-only, starts at beginning of file (default mode).
7417 * -----+--------------------------------------------------------
7418 * "r+" | Read-write, starts at beginning of file.
7419 * -----+--------------------------------------------------------
7420 * "w" | Write-only, truncates existing file
7421 * | to zero length or creates a new file for writing.
7422 * -----+--------------------------------------------------------
7423 * "w+" | Read-write, truncates existing file to zero length
7424 * | or creates a new file for reading and writing.
7425 * -----+--------------------------------------------------------
7426 * "a" | Write-only, starts at end of file if file exists,
7427 * | otherwise creates a new file for writing.
7428 * -----+--------------------------------------------------------
7429 * "a+" | Read-write, starts at end of file if file exists,
7430 * | otherwise creates a new file for reading and
7432 * -----+--------------------------------------------------------
7433 * "b" | (DOS/Windows only) Binary file mode (may appear with
7434 * | any of the key letters listed above).
7437 * The global constant ARGF (also accessible as $<) provides an
7438 * IO-like stream which allows access to all files mentioned on the
7439 * command line (or STDIN if no files are mentioned). ARGF provides
7440 * the methods <code>#path</code> and <code>#filename</code> to access
7441 * the name of the file currently being read.
7449 #include <sys/cygwin.h>
7450 static struct __cygwin_perfile pf
[] =
7452 {"", O_RDONLY
| O_BINARY
},
7453 {"", O_WRONLY
| O_BINARY
},
7454 {"", O_RDWR
| O_BINARY
},
7455 {"", O_APPEND
| O_BINARY
},
7458 cygwin_internal(CW_PERFILE
, pf
);
7461 rb_eIOError
= rb_define_class("IOError", rb_eStandardError
);
7462 rb_eEOFError
= rb_define_class("EOFError", rb_eIOError
);
7464 id_write
= rb_intern("write");
7465 id_read
= rb_intern("read");
7466 id_getc
= rb_intern("getc");
7467 id_flush
= rb_intern("flush");
7468 id_encode
= rb_intern("encode");
7469 id_readpartial
= rb_intern("readpartial");
7471 rb_define_global_function("syscall", rb_f_syscall
, -1);
7473 rb_define_global_function("open", rb_f_open
, -1);
7474 rb_define_global_function("printf", rb_f_printf
, -1);
7475 rb_define_global_function("print", rb_f_print
, -1);
7476 rb_define_global_function("putc", rb_f_putc
, 1);
7477 rb_define_global_function("puts", rb_f_puts
, -1);
7478 rb_define_global_function("gets", rb_f_gets
, -1);
7479 rb_define_global_function("readline", rb_f_readline
, -1);
7480 rb_define_global_function("select", rb_f_select
, -1);
7482 rb_define_global_function("readlines", rb_f_readlines
, -1);
7484 rb_define_global_function("`", rb_f_backquote
, 1);
7486 rb_define_global_function("p", rb_f_p
, -1);
7487 rb_define_method(rb_mKernel
, "display", rb_obj_display
, -1);
7489 rb_cIO
= rb_define_class("IO", rb_cObject
);
7490 rb_include_module(rb_cIO
, rb_mEnumerable
);
7492 rb_define_alloc_func(rb_cIO
, io_alloc
);
7493 rb_define_singleton_method(rb_cIO
, "new", rb_io_s_new
, -1);
7494 rb_define_singleton_method(rb_cIO
, "open", rb_io_s_open
, -1);
7495 rb_define_singleton_method(rb_cIO
, "sysopen", rb_io_s_sysopen
, -1);
7496 rb_define_singleton_method(rb_cIO
, "for_fd", rb_io_s_for_fd
, -1);
7497 rb_define_singleton_method(rb_cIO
, "popen", rb_io_s_popen
, -1);
7498 rb_define_singleton_method(rb_cIO
, "foreach", rb_io_s_foreach
, -1);
7499 rb_define_singleton_method(rb_cIO
, "readlines", rb_io_s_readlines
, -1);
7500 rb_define_singleton_method(rb_cIO
, "read", rb_io_s_read
, -1);
7501 rb_define_singleton_method(rb_cIO
, "select", rb_f_select
, -1);
7502 rb_define_singleton_method(rb_cIO
, "pipe", rb_io_s_pipe
, -1);
7503 rb_define_singleton_method(rb_cIO
, "try_convert", rb_io_s_try_convert
, 1);
7504 rb_define_singleton_method(rb_cIO
, "copy_stream", rb_io_s_copy_stream
, -1);
7506 rb_define_method(rb_cIO
, "initialize", rb_io_initialize
, -1);
7508 rb_output_fs
= Qnil
;
7509 rb_define_hooked_variable("$,", &rb_output_fs
, 0, rb_str_setter
);
7511 rb_global_variable(&rb_default_rs
);
7512 rb_rs
= rb_default_rs
= rb_str_new2("\n");
7513 rb_output_rs
= Qnil
;
7514 OBJ_FREEZE(rb_default_rs
); /* avoid modifying RS_default */
7515 rb_define_hooked_variable("$/", &rb_rs
, 0, rb_str_setter
);
7516 rb_define_hooked_variable("$-0", &rb_rs
, 0, rb_str_setter
);
7517 rb_define_hooked_variable("$\\", &rb_output_rs
, 0, rb_str_setter
);
7519 rb_define_virtual_variable("$_", rb_lastline_get
, rb_lastline_set
);
7521 rb_define_method(rb_cIO
, "initialize_copy", rb_io_init_copy
, 1);
7522 rb_define_method(rb_cIO
, "reopen", rb_io_reopen
, -1);
7524 rb_define_method(rb_cIO
, "print", rb_io_print
, -1);
7525 rb_define_method(rb_cIO
, "putc", rb_io_putc
, 1);
7526 rb_define_method(rb_cIO
, "puts", rb_io_puts
, -1);
7527 rb_define_method(rb_cIO
, "printf", rb_io_printf
, -1);
7529 rb_define_method(rb_cIO
, "each", rb_io_each_line
, -1);
7530 rb_define_method(rb_cIO
, "each_line", rb_io_each_line
, -1);
7531 rb_define_method(rb_cIO
, "each_byte", rb_io_each_byte
, 0);
7532 rb_define_method(rb_cIO
, "each_char", rb_io_each_char
, 0);
7533 rb_define_method(rb_cIO
, "lines", rb_io_lines
, -1);
7534 rb_define_method(rb_cIO
, "bytes", rb_io_bytes
, 0);
7535 rb_define_method(rb_cIO
, "chars", rb_io_chars
, 0);
7537 rb_define_method(rb_cIO
, "syswrite", rb_io_syswrite
, 1);
7538 rb_define_method(rb_cIO
, "sysread", rb_io_sysread
, -1);
7540 rb_define_method(rb_cIO
, "fileno", rb_io_fileno
, 0);
7541 rb_define_alias(rb_cIO
, "to_i", "fileno");
7542 rb_define_method(rb_cIO
, "to_io", rb_io_to_io
, 0);
7544 rb_define_method(rb_cIO
, "fsync", rb_io_fsync
, 0);
7545 rb_define_method(rb_cIO
, "sync", rb_io_sync
, 0);
7546 rb_define_method(rb_cIO
, "sync=", rb_io_set_sync
, 1);
7548 rb_define_method(rb_cIO
, "lineno", rb_io_lineno
, 0);
7549 rb_define_method(rb_cIO
, "lineno=", rb_io_set_lineno
, 1);
7551 rb_define_method(rb_cIO
, "readlines", rb_io_readlines
, -1);
7553 rb_define_method(rb_cIO
, "read_nonblock", io_read_nonblock
, -1);
7554 rb_define_method(rb_cIO
, "write_nonblock", rb_io_write_nonblock
, 1);
7555 rb_define_method(rb_cIO
, "readpartial", io_readpartial
, -1);
7556 rb_define_method(rb_cIO
, "read", io_read
, -1);
7557 rb_define_method(rb_cIO
, "write", io_write
, 1);
7558 rb_define_method(rb_cIO
, "gets", rb_io_gets_m
, -1);
7559 rb_define_method(rb_cIO
, "readline", rb_io_readline
, -1);
7560 rb_define_method(rb_cIO
, "getc", rb_io_getc
, 0);
7561 rb_define_method(rb_cIO
, "getbyte", rb_io_getbyte
, 0);
7562 rb_define_method(rb_cIO
, "readchar", rb_io_readchar
, 0);
7563 rb_define_method(rb_cIO
, "readbyte", rb_io_readbyte
, 0);
7564 rb_define_method(rb_cIO
, "ungetc",rb_io_ungetc
, 1);
7565 rb_define_method(rb_cIO
, "<<", rb_io_addstr
, 1);
7566 rb_define_method(rb_cIO
, "flush", rb_io_flush
, 0);
7567 rb_define_method(rb_cIO
, "tell", rb_io_tell
, 0);
7568 rb_define_method(rb_cIO
, "seek", rb_io_seek_m
, -1);
7569 rb_define_const(rb_cIO
, "SEEK_SET", INT2FIX(SEEK_SET
));
7570 rb_define_const(rb_cIO
, "SEEK_CUR", INT2FIX(SEEK_CUR
));
7571 rb_define_const(rb_cIO
, "SEEK_END", INT2FIX(SEEK_END
));
7572 rb_define_method(rb_cIO
, "rewind", rb_io_rewind
, 0);
7573 rb_define_method(rb_cIO
, "pos", rb_io_tell
, 0);
7574 rb_define_method(rb_cIO
, "pos=", rb_io_set_pos
, 1);
7575 rb_define_method(rb_cIO
, "eof", rb_io_eof
, 0);
7576 rb_define_method(rb_cIO
, "eof?", rb_io_eof
, 0);
7578 rb_define_method(rb_cIO
, "close_on_exec?", rb_io_close_on_exec_p
, 0);
7579 rb_define_method(rb_cIO
, "close_on_exec=", rb_io_set_close_on_exec
, 1);
7581 rb_define_method(rb_cIO
, "close", rb_io_close_m
, 0);
7582 rb_define_method(rb_cIO
, "closed?", rb_io_closed
, 0);
7583 rb_define_method(rb_cIO
, "close_read", rb_io_close_read
, 0);
7584 rb_define_method(rb_cIO
, "close_write", rb_io_close_write
, 0);
7586 rb_define_method(rb_cIO
, "isatty", rb_io_isatty
, 0);
7587 rb_define_method(rb_cIO
, "tty?", rb_io_isatty
, 0);
7588 rb_define_method(rb_cIO
, "binmode", rb_io_binmode_m
, 0);
7589 rb_define_method(rb_cIO
, "sysseek", rb_io_sysseek
, -1);
7591 rb_define_method(rb_cIO
, "ioctl", rb_io_ioctl
, -1);
7592 rb_define_method(rb_cIO
, "fcntl", rb_io_fcntl
, -1);
7593 rb_define_method(rb_cIO
, "pid", rb_io_pid
, 0);
7594 rb_define_method(rb_cIO
, "inspect", rb_io_inspect
, 0);
7596 rb_define_method(rb_cIO
, "external_encoding", rb_io_external_encoding
, 0);
7597 rb_define_method(rb_cIO
, "internal_encoding", rb_io_internal_encoding
, 0);
7598 rb_define_method(rb_cIO
, "set_encoding", rb_io_set_encoding
, -1);
7600 rb_define_variable("$stdin", &rb_stdin
);
7601 rb_stdin
= prep_stdio(stdin
, FMODE_READABLE
, rb_cIO
, "<STDIN>");
7602 rb_define_hooked_variable("$stdout", &rb_stdout
, 0, stdout_setter
);
7603 rb_stdout
= prep_stdio(stdout
, FMODE_WRITABLE
, rb_cIO
, "<STDOUT>");
7604 rb_define_hooked_variable("$stderr", &rb_stderr
, 0, stdout_setter
);
7605 rb_stderr
= prep_stdio(stderr
, FMODE_WRITABLE
|FMODE_SYNC
, rb_cIO
, "<STDERR>");
7606 rb_define_hooked_variable("$>", &rb_stdout
, 0, stdout_setter
);
7607 orig_stdout
= rb_stdout
;
7608 rb_deferr
= orig_stderr
= rb_stderr
;
7610 /* constants to hold original stdin/stdout/stderr */
7611 rb_define_global_const("STDIN", rb_stdin
);
7612 rb_define_global_const("STDOUT", rb_stdout
);
7613 rb_define_global_const("STDERR", rb_stderr
);
7615 rb_cARGF
= rb_class_new(rb_cObject
);
7616 rb_set_class_path(rb_cARGF
, rb_cObject
, "ARGF.class");
7617 rb_define_alloc_func(rb_cARGF
, argf_alloc
);
7619 rb_include_module(rb_cARGF
, rb_mEnumerable
);
7621 rb_define_method(rb_cARGF
, "initialize", argf_initialize
, -2);
7622 rb_define_method(rb_cARGF
, "initialize_copy", argf_initialize_copy
, 1);
7623 rb_define_method(rb_cARGF
, "to_s", argf_to_s
, 0);
7624 rb_define_method(rb_cARGF
, "argv", argf_argv
, 0);
7626 rb_define_method(rb_cARGF
, "fileno", argf_fileno
, 0);
7627 rb_define_method(rb_cARGF
, "to_i", argf_fileno
, 0);
7628 rb_define_method(rb_cARGF
, "to_io", argf_to_io
, 0);
7629 rb_define_method(rb_cARGF
, "each", argf_each_line
, -1);
7630 rb_define_method(rb_cARGF
, "each_line", argf_each_line
, -1);
7631 rb_define_method(rb_cARGF
, "each_byte", argf_each_byte
, 0);
7632 rb_define_method(rb_cARGF
, "each_char", argf_each_char
, 0);
7634 rb_define_method(rb_cARGF
, "read", argf_read
, -1);
7635 rb_define_method(rb_cARGF
, "readpartial", argf_readpartial
, -1);
7636 rb_define_method(rb_cARGF
, "readlines", argf_readlines
, -1);
7637 rb_define_method(rb_cARGF
, "to_a", argf_readlines
, -1);
7638 rb_define_method(rb_cARGF
, "gets", argf_gets
, -1);
7639 rb_define_method(rb_cARGF
, "readline", argf_readline
, -1);
7640 rb_define_method(rb_cARGF
, "getc", argf_getc
, 0);
7641 rb_define_method(rb_cARGF
, "getbyte", argf_getbyte
, 0);
7642 rb_define_method(rb_cARGF
, "readchar", argf_readchar
, 0);
7643 rb_define_method(rb_cARGF
, "readbyte", argf_readbyte
, 0);
7644 rb_define_method(rb_cARGF
, "tell", argf_tell
, 0);
7645 rb_define_method(rb_cARGF
, "seek", argf_seek_m
, -1);
7646 rb_define_method(rb_cARGF
, "rewind", argf_rewind
, 0);
7647 rb_define_method(rb_cARGF
, "pos", argf_tell
, 0);
7648 rb_define_method(rb_cARGF
, "pos=", argf_set_pos
, 1);
7649 rb_define_method(rb_cARGF
, "eof", argf_eof
, 0);
7650 rb_define_method(rb_cARGF
, "eof?", argf_eof
, 0);
7651 rb_define_method(rb_cARGF
, "binmode", argf_binmode_m
, 0);
7653 rb_define_method(rb_cARGF
, "filename", argf_filename
, 0);
7654 rb_define_method(rb_cARGF
, "path", argf_filename
, 0);
7655 rb_define_method(rb_cARGF
, "file", argf_file
, 0);
7656 rb_define_method(rb_cARGF
, "skip", argf_skip
, 0);
7657 rb_define_method(rb_cARGF
, "close", argf_close_m
, 0);
7658 rb_define_method(rb_cARGF
, "closed?", argf_closed
, 0);
7660 rb_define_method(rb_cARGF
, "lineno", argf_lineno
, 0);
7661 rb_define_method(rb_cARGF
, "lineno=", argf_set_lineno
, 1);
7663 rb_define_method(rb_cARGF
, "inplace_mode", argf_inplace_mode_get
, 0);
7664 rb_define_method(rb_cARGF
, "inplace_mode=", argf_inplace_mode_set
, 1);
7666 rb_define_method(rb_cARGF
, "external_encoding", argf_external_encoding
, 0);
7667 rb_define_method(rb_cARGF
, "internal_encoding", argf_internal_encoding
, 0);
7668 rb_define_method(rb_cARGF
, "set_encoding", argf_set_encoding
, -1);
7670 argf
= rb_class_new_instance(0, 0, rb_cARGF
);
7672 rb_define_readonly_variable("$<", &argf
);
7673 rb_define_global_const("ARGF", argf
);
7675 rb_define_hooked_variable("$.", &argf
, argf_lineno_getter
, argf_lineno_setter
);
7676 rb_define_hooked_variable("$FILENAME", &argf
, argf_filename_getter
, 0);
7677 filename
= rb_str_new2("-");
7679 rb_define_hooked_variable("$-i", &argf
, opt_i_get
, opt_i_set
);
7680 rb_define_hooked_variable("$*", &argf
, argf_argv_getter
, 0);
7682 #if defined (_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__)
7683 atexit(pipe_atexit
);
7688 rb_define_method(rb_cFile
, "initialize", rb_file_initialize
, -1);
7690 rb_file_const("RDONLY", INT2FIX(O_RDONLY
));
7691 rb_file_const("WRONLY", INT2FIX(O_WRONLY
));
7692 rb_file_const("RDWR", INT2FIX(O_RDWR
));
7693 rb_file_const("APPEND", INT2FIX(O_APPEND
));
7694 rb_file_const("CREAT", INT2FIX(O_CREAT
));
7695 rb_file_const("EXCL", INT2FIX(O_EXCL
));
7696 #if defined(O_NDELAY) || defined(O_NONBLOCK)
7698 rb_file_const("NONBLOCK", INT2FIX(O_NONBLOCK
));
7700 rb_file_const("NONBLOCK", INT2FIX(O_NDELAY
));
7703 rb_file_const("TRUNC", INT2FIX(O_TRUNC
));
7705 rb_file_const("NOCTTY", INT2FIX(O_NOCTTY
));
7708 rb_file_const("BINARY", INT2FIX(O_BINARY
));
7710 rb_file_const("BINARY", INT2FIX(0));
7713 rb_file_const("SYNC", INT2FIX(O_SYNC
));