Ruby  2.1.4p265(2014-10-27revision48166)
io.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  io.c -
4 
5  $Author: nagachika $
6  created at: Fri Oct 15 18:08:59 JST 1993
7 
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
11 
12 **********************************************************************/
13 
14 #include "ruby/ruby.h"
15 #include "ruby/io.h"
16 #include "ruby/thread.h"
17 #include "dln.h"
18 #include "internal.h"
19 #include "id.h"
20 #include <ctype.h>
21 #include <errno.h>
22 #include "ruby_atomic.h"
23 
24 #define free(x) xfree(x)
25 
26 #if defined(DOSISH) || defined(__CYGWIN__)
27 #include <io.h>
28 #endif
29 
30 #include <sys/types.h>
31 #if defined HAVE_NET_SOCKET_H
32 # include <net/socket.h>
33 #elif defined HAVE_SYS_SOCKET_H
34 # ifndef __native_client__
35 # include <sys/socket.h>
36 # endif
37 #endif
38 
39 #if defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32) || defined(__EMX__) || defined(__BEOS__) || defined(__HAIKU__)
40 # define NO_SAFE_RENAME
41 #endif
42 
43 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__sun) || defined(_nec_ews)
44 # define USE_SETVBUF
45 #endif
46 
47 #ifdef __QNXNTO__
48 #include "unix.h"
49 #endif
50 
51 #include <sys/types.h>
52 #if defined(HAVE_SYS_IOCTL_H) && !defined(_WIN32)
53 #include <sys/ioctl.h>
54 #endif
55 #if defined(__native_client__) && defined(NACL_NEWLIB)
56 # include "nacl/ioctl.h"
57 #endif
58 #if defined(HAVE_FCNTL_H) || defined(_WIN32)
59 #include <fcntl.h>
60 #elif defined(HAVE_SYS_FCNTL_H)
61 #include <sys/fcntl.h>
62 #endif
63 
64 #if !HAVE_OFF_T && !defined(off_t)
65 # define off_t long
66 #endif
67 
68 #include <sys/stat.h>
69 
70 /* EMX has sys/param.h, but.. */
71 #if defined(HAVE_SYS_PARAM_H) && !(defined(__EMX__) || defined(__HIUX_MPP__))
72 # include <sys/param.h>
73 #endif
74 
75 #if !defined NOFILE
76 # define NOFILE 64
77 #endif
78 
79 #ifdef HAVE_UNISTD_H
80 #include <unistd.h>
81 #endif
82 
83 #ifdef HAVE_SYSCALL_H
84 #include <syscall.h>
85 #elif defined HAVE_SYS_SYSCALL_H
86 #include <sys/syscall.h>
87 #endif
88 
89 #if defined(__BEOS__) || defined(__HAIKU__)
90 # ifndef NOFILE
91 # define NOFILE (OPEN_MAX)
92 # endif
93 #endif
94 
95 #include "ruby/util.h"
96 
97 #ifndef O_ACCMODE
98 #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
99 #endif
100 
101 #if SIZEOF_OFF_T > SIZEOF_LONG && !defined(HAVE_LONG_LONG)
102 # error off_t is bigger than long, but you have no long long...
103 #endif
104 
105 #ifndef PIPE_BUF
106 # ifdef _POSIX_PIPE_BUF
107 # define PIPE_BUF _POSIX_PIPE_BUF
108 # else
109 # define PIPE_BUF 512 /* is this ok? */
110 # endif
111 #endif
112 
113 #ifndef EWOULDBLOCK
114 # define EWOULDBLOCK EAGAIN
115 #endif
116 
117 #if defined(HAVE___SYSCALL) && (defined(__APPLE__) || defined(__OpenBSD__))
118 /* Mac OS X and OpenBSD have __syscall but don't define it in headers */
119 off_t __syscall(quad_t number, ...);
120 #endif
121 
122 #define IO_RBUF_CAPA_MIN 8192
123 #define IO_CBUF_CAPA_MIN (128*1024)
124 #define IO_RBUF_CAPA_FOR(fptr) (NEED_READCONV(fptr) ? IO_CBUF_CAPA_MIN : IO_RBUF_CAPA_MIN)
125 #define IO_WBUF_CAPA_MIN 8192
126 
127 /* define system APIs */
128 #ifdef _WIN32
129 #undef open
130 #define open rb_w32_uopen
131 #endif
132 
138 extern VALUE rb_eEAGAIN;
139 extern VALUE rb_eEWOULDBLOCK;
140 extern VALUE rb_eEINPROGRESS;
141 
148 
150 VALUE rb_deferr; /* rescue VIM plugin */
152 
157 
158 static VALUE argf;
159 
164 #ifdef SEEK_DATA
165 static VALUE sym_DATA;
166 #endif
167 #ifdef SEEK_HOLE
168 static VALUE sym_HOLE;
169 #endif
170 
171 struct argf {
173  long last_lineno; /* $. */
174  long lineno;
176  char *inplace;
177  struct rb_io_enc_t encs;
179 };
180 
182 void
184 {
185  struct stat buf;
187 
188  if (fstat(fd, &buf) != 0 && errno == EBADF) {
189  rb_bug("rb_update_max_fd: invalid fd (%d) given.", fd);
190  }
191 
192  while (max_file_descriptor < afd) {
194  }
195 }
196 
197 void
199 {
200  /* MinGW don't have F_GETFD and FD_CLOEXEC. [ruby-core:40281] */
201 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
202  int flags, flags2, ret;
203  flags = fcntl(fd, F_GETFD); /* should not fail except EBADF. */
204  if (flags == -1) {
205  rb_bug("rb_maygvl_fd_fix_cloexec: fcntl(%d, F_GETFD) failed: %s", fd, strerror(errno));
206  }
207  if (fd <= 2)
208  flags2 = flags & ~FD_CLOEXEC; /* Clear CLOEXEC for standard file descriptors: 0, 1, 2. */
209  else
210  flags2 = flags | FD_CLOEXEC; /* Set CLOEXEC for non-standard file descriptors: 3, 4, 5, ... */
211  if (flags != flags2) {
212  ret = fcntl(fd, F_SETFD, flags2);
213  if (ret == -1) {
214  rb_bug("rb_maygvl_fd_fix_cloexec: fcntl(%d, F_SETFD, %d) failed: %s", fd, flags2, strerror(errno));
215  }
216  }
217 #endif
218 }
219 
220 void
222 {
224  rb_update_max_fd(fd);
225 }
226 
227 int
228 rb_cloexec_open(const char *pathname, int flags, mode_t mode)
229 {
230  int ret;
231 #ifdef O_CLOEXEC
232  /* O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */
233  flags |= O_CLOEXEC;
234 #elif defined O_NOINHERIT
235  flags |= O_NOINHERIT;
236 #endif
237  ret = open(pathname, flags, mode);
238  if (ret == -1) return -1;
240  return ret;
241 }
242 
243 int
244 rb_cloexec_dup(int oldfd)
245 {
246  /* Don't allocate standard file descriptors: 0, 1, 2 */
247  return rb_cloexec_fcntl_dupfd(oldfd, 3);
248 }
249 
250 int
251 rb_cloexec_dup2(int oldfd, int newfd)
252 {
253  int ret;
254 
255  /* When oldfd == newfd, dup2 succeeds but dup3 fails with EINVAL.
256  * rb_cloexec_dup2 succeeds as dup2. */
257  if (oldfd == newfd) {
258  ret = newfd;
259  }
260  else {
261 #if defined(HAVE_DUP3) && defined(O_CLOEXEC)
262  static int try_dup3 = 1;
263  if (2 < newfd && try_dup3) {
264  ret = dup3(oldfd, newfd, O_CLOEXEC);
265  if (ret != -1)
266  return ret;
267  /* dup3 is available since Linux 2.6.27, glibc 2.9. */
268  if (errno == ENOSYS) {
269  try_dup3 = 0;
270  ret = dup2(oldfd, newfd);
271  }
272  }
273  else {
274  ret = dup2(oldfd, newfd);
275  }
276 #else
277  ret = dup2(oldfd, newfd);
278 #endif
279  if (ret == -1) return -1;
280  }
282  return ret;
283 }
284 
285 int
286 rb_cloexec_pipe(int fildes[2])
287 {
288  int ret;
289 
290 #if defined(HAVE_PIPE2)
291  static int try_pipe2 = 1;
292  if (try_pipe2) {
293  ret = pipe2(fildes, O_CLOEXEC);
294  if (ret != -1)
295  return ret;
296  /* pipe2 is available since Linux 2.6.27, glibc 2.9. */
297  if (errno == ENOSYS) {
298  try_pipe2 = 0;
299  ret = pipe(fildes);
300  }
301  }
302  else {
303  ret = pipe(fildes);
304  }
305 #else
306  ret = pipe(fildes);
307 #endif
308  if (ret == -1) return -1;
309 #ifdef __CYGWIN__
310  if (ret == 0 && fildes[1] == -1) {
311  close(fildes[0]);
312  fildes[0] = -1;
313  errno = ENFILE;
314  return -1;
315  }
316 #endif
317  rb_maygvl_fd_fix_cloexec(fildes[0]);
318  rb_maygvl_fd_fix_cloexec(fildes[1]);
319  return ret;
320 }
321 
322 int
323 rb_cloexec_fcntl_dupfd(int fd, int minfd)
324 {
325  int ret;
326 
327 #if defined(HAVE_FCNTL) && defined(F_DUPFD_CLOEXEC) && defined(F_DUPFD)
328  static int try_dupfd_cloexec = 1;
329  if (try_dupfd_cloexec) {
330  ret = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
331  if (ret != -1) {
332  if (ret <= 2)
334  return ret;
335  }
336  /* F_DUPFD_CLOEXEC is available since Linux 2.6.24. Linux 2.6.18 fails with EINVAL */
337  if (errno == EINVAL) {
338  ret = fcntl(fd, F_DUPFD, minfd);
339  if (ret != -1) {
340  try_dupfd_cloexec = 0;
341  }
342  }
343  }
344  else {
345  ret = fcntl(fd, F_DUPFD, minfd);
346  }
347 #elif defined(HAVE_FCNTL) && defined(F_DUPFD)
348  ret = fcntl(fd, F_DUPFD, minfd);
349 #elif defined(HAVE_DUP)
350  ret = dup(fd);
351  if (ret != -1 && ret < minfd) {
352  const int prev_fd = ret;
353  ret = rb_cloexec_fcntl_dupfd(fd, minfd);
354  close(prev_fd);
355  }
356  return ret;
357 #else
358 # error "dup() or fcntl(F_DUPFD) must be supported."
359 #endif
360  if (ret == -1) return -1;
362  return ret;
363 }
364 
365 #define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
366 #define ARGF argf_of(argf)
367 
368 #ifdef _STDIO_USES_IOSTREAM /* GNU libc */
369 # ifdef _IO_fpos_t
370 # define STDIO_READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end)
371 # else
372 # define STDIO_READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr)
373 # endif
374 #elif defined(FILE_COUNT)
375 # define STDIO_READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0)
376 #elif defined(FILE_READEND)
377 # define STDIO_READ_DATA_PENDING(fp) ((fp)->FILE_READPTR < (fp)->FILE_READEND)
378 #elif defined(__BEOS__) || defined(__HAIKU__)
379 # define STDIO_READ_DATA_PENDING(fp) ((fp)->_state._eof == 0)
380 #else
381 # define STDIO_READ_DATA_PENDING(fp) (!feof(fp))
382 #endif
383 
384 #define GetWriteIO(io) rb_io_get_write_io(io)
385 
386 #define READ_DATA_PENDING(fptr) ((fptr)->rbuf.len)
387 #define READ_DATA_PENDING_COUNT(fptr) ((fptr)->rbuf.len)
388 #define READ_DATA_PENDING_PTR(fptr) ((fptr)->rbuf.ptr+(fptr)->rbuf.off)
389 #define READ_DATA_BUFFERED(fptr) READ_DATA_PENDING(fptr)
390 
391 #define READ_CHAR_PENDING(fptr) ((fptr)->cbuf.len)
392 #define READ_CHAR_PENDING_COUNT(fptr) ((fptr)->cbuf.len)
393 #define READ_CHAR_PENDING_PTR(fptr) ((fptr)->cbuf.ptr+(fptr)->cbuf.off)
394 
395 #if defined(_WIN32)
396 #define WAIT_FD_IN_WIN32(fptr) \
397  (rb_w32_io_cancelable_p((fptr)->fd) ? 0 : rb_thread_wait_fd((fptr)->fd))
398 #else
399 #define WAIT_FD_IN_WIN32(fptr)
400 #endif
401 
402 #define READ_CHECK(fptr) do {\
403  if (!READ_DATA_PENDING(fptr)) {\
404  WAIT_FD_IN_WIN32(fptr);\
405  rb_io_check_closed(fptr);\
406  }\
407 } while(0)
408 
409 #ifndef S_ISSOCK
410 # ifdef _S_ISSOCK
411 # define S_ISSOCK(m) _S_ISSOCK(m)
412 # else
413 # ifdef _S_IFSOCK
414 # define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
415 # else
416 # ifdef S_IFSOCK
417 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
418 # endif
419 # endif
420 # endif
421 #endif
422 
423 static int io_fflush(rb_io_t *);
424 static rb_io_t *flush_before_seek(rb_io_t *fptr);
425 
426 #define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE)
427 #define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) ((fptr)->mode & FMODE_TEXTMODE)
428 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
429 /* Windows */
430 # define DEFAULT_TEXTMODE FMODE_TEXTMODE
431 # define TEXTMODE_NEWLINE_DECORATOR_ON_WRITE ECONV_CRLF_NEWLINE_DECORATOR
432 /*
433  * CRLF newline is set as default newline decorator.
434  * If only CRLF newline conversion is needed, we use binary IO process
435  * with OS's text mode for IO performance improvement.
436  * If encoding conversion is needed or a user sets text mode, we use encoding
437  * conversion IO process and universal newline decorator by default.
438  */
439 #define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || (fptr)->encs.ecflags & ~ECONV_CRLF_NEWLINE_DECORATOR)
440 #define NEED_WRITECONV(fptr) (((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || ((fptr)->encs.ecflags & ((ECONV_DECORATOR_MASK & ~ECONV_CRLF_NEWLINE_DECORATOR)|ECONV_STATEFUL_DECORATOR_MASK)))
441 #define SET_BINARY_MODE(fptr) setmode((fptr)->fd, O_BINARY)
442 
443 #define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr) do {\
444  if (NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {\
445  if (((fptr)->mode & FMODE_READABLE) &&\
446  !((fptr)->encs.ecflags & ECONV_NEWLINE_DECORATOR_MASK)) {\
447  setmode((fptr)->fd, O_BINARY);\
448  }\
449  else {\
450  setmode((fptr)->fd, O_TEXT);\
451  }\
452  }\
453 } while(0)
454 
455 #define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags) do {\
456  if ((enc2) && ((ecflags) & ECONV_DEFAULT_NEWLINE_DECORATOR)) {\
457  (ecflags) |= ECONV_UNIVERSAL_NEWLINE_DECORATOR;\
458  }\
459 } while(0)
460 
461 /*
462  * IO unread with taking care of removed '\r' in text mode.
463  */
464 static void
465 io_unread(rb_io_t *fptr)
466 {
467  off_t r, pos;
468  ssize_t read_size;
469  long i;
470  long newlines = 0;
471  long extra_max;
472  char *p;
473  char *buf;
474 
475  rb_io_check_closed(fptr);
476  if (fptr->rbuf.len == 0 || fptr->mode & FMODE_DUPLEX) {
477  return;
478  }
479 
480  errno = 0;
481  if (!rb_w32_fd_is_text(fptr->fd)) {
482  r = lseek(fptr->fd, -fptr->rbuf.len, SEEK_CUR);
483  if (r < 0 && errno) {
484  if (errno == ESPIPE)
485  fptr->mode |= FMODE_DUPLEX;
486  return;
487  }
488 
489  fptr->rbuf.off = 0;
490  fptr->rbuf.len = 0;
491  return;
492  }
493 
494  pos = lseek(fptr->fd, 0, SEEK_CUR);
495  if (pos < 0 && errno) {
496  if (errno == ESPIPE)
497  fptr->mode |= FMODE_DUPLEX;
498  return;
499  }
500 
501  /* add extra offset for removed '\r' in rbuf */
502  extra_max = (long)(pos - fptr->rbuf.len);
503  p = fptr->rbuf.ptr + fptr->rbuf.off;
504 
505  /* if the end of rbuf is '\r', rbuf doesn't have '\r' within rbuf.len */
506  if (*(fptr->rbuf.ptr + fptr->rbuf.capa - 1) == '\r') {
507  newlines++;
508  }
509 
510  for (i = 0; i < fptr->rbuf.len; i++) {
511  if (*p == '\n') newlines++;
512  if (extra_max == newlines) break;
513  p++;
514  }
515 
516  buf = ALLOC_N(char, fptr->rbuf.len + newlines);
517  while (newlines >= 0) {
518  r = lseek(fptr->fd, pos - fptr->rbuf.len - newlines, SEEK_SET);
519  if (newlines == 0) break;
520  if (r < 0) {
521  newlines--;
522  continue;
523  }
524  read_size = _read(fptr->fd, buf, fptr->rbuf.len + newlines);
525  if (read_size < 0) {
526  free(buf);
527  rb_sys_fail_path(fptr->pathv);
528  }
529  if (read_size == fptr->rbuf.len) {
530  lseek(fptr->fd, r, SEEK_SET);
531  break;
532  }
533  else {
534  newlines--;
535  }
536  }
537  free(buf);
538  fptr->rbuf.off = 0;
539  fptr->rbuf.len = 0;
540  return;
541 }
542 
543 /*
544  * We use io_seek to back cursor position when changing mode from text to binary,
545  * but stdin and pipe cannot seek back. Stdin and pipe read should use encoding
546  * conversion for working properly with mode change.
547  *
548  * Return previous translation mode.
549  */
550 static inline int
551 set_binary_mode_with_seek_cur(rb_io_t *fptr)
552 {
553  if (!rb_w32_fd_is_text(fptr->fd)) return O_BINARY;
554 
555  if (fptr->rbuf.len == 0 || fptr->mode & FMODE_DUPLEX) {
556  return setmode(fptr->fd, O_BINARY);
557  }
558  flush_before_seek(fptr);
559  return setmode(fptr->fd, O_BINARY);
560 }
561 #define SET_BINARY_MODE_WITH_SEEK_CUR(fptr) set_binary_mode_with_seek_cur(fptr)
562 
563 #else
564 /* Unix */
565 # define DEFAULT_TEXTMODE 0
566 #define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || NEED_NEWLINE_DECORATOR_ON_READ(fptr))
567 #define NEED_WRITECONV(fptr) (((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) || ((fptr)->encs.ecflags & (ECONV_DECORATOR_MASK|ECONV_STATEFUL_DECORATOR_MASK)))
568 #define SET_BINARY_MODE(fptr) (void)(fptr)
569 #define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr) (void)(fptr)
570 #define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags) ((void)(enc2), (void)(ecflags))
571 #define SET_BINARY_MODE_WITH_SEEK_CUR(fptr) (void)(fptr)
572 #endif
573 
574 #if !defined HAVE_SHUTDOWN && !defined shutdown
575 #define shutdown(a,b) 0
576 #endif
577 
578 #if defined(_WIN32)
579 #define is_socket(fd, path) rb_w32_is_socket(fd)
580 #elif !defined(S_ISSOCK)
581 #define is_socket(fd, path) 0
582 #else
583 static int
584 is_socket(int fd, VALUE path)
585 {
586  struct stat sbuf;
587  if (fstat(fd, &sbuf) < 0)
588  rb_sys_fail_path(path);
589  return S_ISSOCK(sbuf.st_mode);
590 }
591 #endif
592 
593 static const char closed_stream[] = "closed stream";
594 
595 void
597 {
598  rb_raise(rb_eEOFError, "end of file reached");
599 }
600 
601 VALUE
603 {
604  rb_check_frozen(io);
605  return io;
606 }
607 
608 void
610 {
611  if (!fptr) {
612  rb_raise(rb_eIOError, "uninitialized stream");
613  }
614 }
615 
616 void
618 {
620  if (fptr->fd < 0) {
621  rb_raise(rb_eIOError, closed_stream);
622  }
623 }
624 
625 
626 VALUE
628 {
629  return rb_convert_type(io, T_FILE, "IO", "to_io");
630 }
631 
632 VALUE
634 {
635  return rb_check_convert_type(io, T_FILE, "IO", "to_io");
636 }
637 
638 VALUE
640 {
641  VALUE write_io;
642  rb_io_check_initialized(RFILE(io)->fptr);
643  write_io = RFILE(io)->fptr->tied_io_for_writing;
644  if (write_io) {
645  return write_io;
646  }
647  return io;
648 }
649 
650 VALUE
652 {
653  VALUE write_io;
654  rb_io_check_initialized(RFILE(io)->fptr);
655  if (!RTEST(w)) {
656  w = 0;
657  }
658  else {
659  GetWriteIO(w);
660  }
661  write_io = RFILE(io)->fptr->tied_io_for_writing;
662  RFILE(io)->fptr->tied_io_for_writing = w;
663  return write_io ? write_io : Qnil;
664 }
665 
666 /*
667  * call-seq:
668  * IO.try_convert(obj) -> io or nil
669  *
670  * Try to convert <i>obj</i> into an IO, using to_io method.
671  * Returns converted IO or nil if <i>obj</i> cannot be converted
672  * for any reason.
673  *
674  * IO.try_convert(STDOUT) #=> STDOUT
675  * IO.try_convert("STDOUT") #=> nil
676  *
677  * require 'zlib'
678  * f = open("/tmp/zz.gz") #=> #<File:/tmp/zz.gz>
679  * z = Zlib::GzipReader.open(f) #=> #<Zlib::GzipReader:0x81d8744>
680  * IO.try_convert(z) #=> #<File:/tmp/zz.gz>
681  *
682  */
683 static VALUE
685 {
686  return rb_io_check_io(io);
687 }
688 
689 #if !(defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32))
690 static void
692 {
693  off_t r;
694  rb_io_check_closed(fptr);
695  if (fptr->rbuf.len == 0 || fptr->mode & FMODE_DUPLEX)
696  return;
697  /* xxx: target position may be negative if buffer is filled by ungetc */
698  errno = 0;
699  r = lseek(fptr->fd, -fptr->rbuf.len, SEEK_CUR);
700  if (r < 0 && errno) {
701  if (errno == ESPIPE)
702  fptr->mode |= FMODE_DUPLEX;
703  return;
704  }
705  fptr->rbuf.off = 0;
706  fptr->rbuf.len = 0;
707  return;
708 }
709 #endif
710 
711 static rb_encoding *io_input_encoding(rb_io_t *fptr);
712 
713 static void
715 {
716  long len = RSTRING_LEN(str);
717 
718  if (fptr->rbuf.ptr == NULL) {
719  const int min_capa = IO_RBUF_CAPA_FOR(fptr);
720  fptr->rbuf.off = 0;
721  fptr->rbuf.len = 0;
722 #if SIZEOF_LONG > SIZEOF_INT
723  if (len > INT_MAX)
724  rb_raise(rb_eIOError, "ungetbyte failed");
725 #endif
726  if (len > min_capa)
727  fptr->rbuf.capa = (int)len;
728  else
729  fptr->rbuf.capa = min_capa;
730  fptr->rbuf.ptr = ALLOC_N(char, fptr->rbuf.capa);
731  }
732  if (fptr->rbuf.capa < len + fptr->rbuf.len) {
733  rb_raise(rb_eIOError, "ungetbyte failed");
734  }
735  if (fptr->rbuf.off < len) {
736  MEMMOVE(fptr->rbuf.ptr+fptr->rbuf.capa-fptr->rbuf.len,
737  fptr->rbuf.ptr+fptr->rbuf.off,
738  char, fptr->rbuf.len);
739  fptr->rbuf.off = fptr->rbuf.capa-fptr->rbuf.len;
740  }
741  fptr->rbuf.off-=(int)len;
742  fptr->rbuf.len+=(int)len;
743  MEMMOVE(fptr->rbuf.ptr+fptr->rbuf.off, RSTRING_PTR(str), char, len);
744 }
745 
746 static rb_io_t *
748 {
749  if (io_fflush(fptr) < 0)
750  rb_sys_fail(0);
751  io_unread(fptr);
752  errno = 0;
753  return fptr;
754 }
755 
756 #define io_seek(fptr, ofs, whence) (errno = 0, lseek(flush_before_seek(fptr)->fd, (ofs), (whence)))
757 #define io_tell(fptr) lseek(flush_before_seek(fptr)->fd, 0, SEEK_CUR)
758 
759 #ifndef SEEK_CUR
760 # define SEEK_SET 0
761 # define SEEK_CUR 1
762 # define SEEK_END 2
763 #endif
764 
765 void
767 {
768  rb_io_check_closed(fptr);
769  if (!(fptr->mode & FMODE_READABLE)) {
770  rb_raise(rb_eIOError, "not opened for reading");
771  }
772  if (fptr->wbuf.len) {
773  if (io_fflush(fptr) < 0)
774  rb_sys_fail(0);
775  }
776  if (fptr->tied_io_for_writing) {
777  rb_io_t *wfptr;
778  GetOpenFile(fptr->tied_io_for_writing, wfptr);
779  if (io_fflush(wfptr) < 0)
780  rb_sys_fail(0);
781  }
782 }
783 
784 void
786 {
788  if (READ_CHAR_PENDING(fptr)) {
789  rb_raise(rb_eIOError, "byte oriented read for character buffered IO");
790  }
791 }
792 
793 void
795 {
797 }
798 
799 static rb_encoding*
801 {
802  if (fptr->encs.enc) {
803  return fptr->encs.enc;
804  }
806 }
807 
808 static rb_encoding*
810 {
811  if (fptr->encs.enc2) {
812  return fptr->encs.enc2;
813  }
814  return io_read_encoding(fptr);
815 }
816 
817 void
819 {
820  rb_io_check_closed(fptr);
821  if (!(fptr->mode & FMODE_WRITABLE)) {
822  rb_raise(rb_eIOError, "not opened for writing");
823  }
824  if (fptr->rbuf.len) {
825  io_unread(fptr);
826  }
827 }
828 
829 int
831 {
832  /* This function is used for bytes and chars. Confusing. */
833  if (READ_CHAR_PENDING(fptr))
834  return 1; /* should raise? */
835  return READ_DATA_PENDING(fptr);
836 }
837 
838 void
840 {
841  if (!STDIO_READ_DATA_PENDING(fp)) {
843  }
844 }
845 
846 void
848 {
849  if (!READ_DATA_PENDING(fptr)) {
850  rb_thread_wait_fd(fptr->fd);
851  }
852  return;
853 }
854 
855 static int
856 ruby_dup(int orig)
857 {
858  int fd;
859 
860  fd = rb_cloexec_dup(orig);
861  if (fd < 0) {
862  if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
863  rb_gc();
864  fd = rb_cloexec_dup(orig);
865  }
866  if (fd < 0) {
867  rb_sys_fail(0);
868  }
869  }
870  rb_update_max_fd(fd);
871  return fd;
872 }
873 
874 static VALUE
876 {
877  NEWOBJ_OF(io, struct RFile, klass, T_FILE);
878 
879  io->fptr = 0;
880 
881  return (VALUE)io;
882 }
883 
884 #ifndef S_ISREG
885 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
886 #endif
887 
888 static int
890 {
891 #if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(O_NONBLOCK)
892  int r;
893 #endif
894 
895  if (!(fptr->mode & FMODE_WSPLIT_INITIALIZED)) {
896  struct stat buf;
897  if (fstat(fptr->fd, &buf) == 0 &&
898  !S_ISREG(buf.st_mode)
899 #if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(O_NONBLOCK)
900  && (r = fcntl(fptr->fd, F_GETFL)) != -1 &&
901  !(r & O_NONBLOCK)
902 #endif
903  ) {
904  fptr->mode |= FMODE_WSPLIT;
905  }
907  }
908  return fptr->mode & FMODE_WSPLIT;
909 }
910 
912  int fd;
913  void *buf;
914  size_t capa;
915 };
916 
918  int fd;
919  const void *buf;
920  size_t capa;
921 };
922 
923 static VALUE
925 {
926  struct io_internal_read_struct *iis = ptr;
927  return read(iis->fd, iis->buf, iis->capa);
928 }
929 
930 static VALUE
932 {
933  struct io_internal_write_struct *iis = ptr;
934  return write(iis->fd, iis->buf, iis->capa);
935 }
936 
937 static void*
939 {
940  struct io_internal_write_struct *iis = ptr;
941  return (void*)(intptr_t)write(iis->fd, iis->buf, iis->capa);
942 }
943 
944 static ssize_t
945 rb_read_internal(int fd, void *buf, size_t count)
946 {
947  struct io_internal_read_struct iis;
948  iis.fd = fd;
949  iis.buf = buf;
950  iis.capa = count;
951 
952  return (ssize_t)rb_thread_io_blocking_region(internal_read_func, &iis, fd);
953 }
954 
955 static ssize_t
956 rb_write_internal(int fd, const void *buf, size_t count)
957 {
958  struct io_internal_write_struct iis;
959  iis.fd = fd;
960  iis.buf = buf;
961  iis.capa = count;
962 
963  return (ssize_t)rb_thread_io_blocking_region(internal_write_func, &iis, fd);
964 }
965 
966 static ssize_t
967 rb_write_internal2(int fd, const void *buf, size_t count)
968 {
969  struct io_internal_write_struct iis;
970  iis.fd = fd;
971  iis.buf = buf;
972  iis.capa = count;
973 
975  RUBY_UBF_IO, NULL);
976 }
977 
978 static long
980 {
981  if (PIPE_BUF < l &&
982  !rb_thread_alone() &&
983  wsplit_p(fptr)) {
984  l = PIPE_BUF;
985  }
986  return l;
987 }
988 
989 static VALUE
991 {
992  rb_io_t *fptr = arg;
993  long l = io_writable_length(fptr, fptr->wbuf.len);
994  ssize_t r = write(fptr->fd, fptr->wbuf.ptr+fptr->wbuf.off, (size_t)l);
995 
996  if (fptr->wbuf.len <= r) {
997  fptr->wbuf.off = 0;
998  fptr->wbuf.len = 0;
999  return 0;
1000  }
1001  if (0 <= r) {
1002  fptr->wbuf.off += (int)r;
1003  fptr->wbuf.len -= (int)r;
1004  errno = EAGAIN;
1005  }
1006  return (VALUE)-1;
1007 }
1008 
1009 static void*
1011 {
1013 
1014  /*
1015  * rb_thread_call_without_gvl2 uses 0 as interrupted.
1016  * So, we need to avoid to use 0.
1017  */
1018  return !result ? (void*)1 : (void*)result;
1019 }
1020 
1021 static VALUE
1023 {
1024  rb_io_t *fptr = (rb_io_t *)arg;
1026 }
1027 
1028 static VALUE
1030 {
1031  rb_io_t *fptr = (rb_io_t *)arg;
1032  VALUE ret;
1033 
1035  RUBY_UBF_IO, NULL);
1036 
1037  if (!ret) {
1038  /* pending async interrupt is there. */
1039  errno = EAGAIN;
1040  return -1;
1041  } else if (ret == 1) {
1042  return 0;
1043  } else
1044  return ret;
1045 }
1046 
1047 static inline int
1049 {
1050  if (fptr->write_lock) {
1051  if (rb_mutex_owned_p(fptr->write_lock))
1052  return (int)io_flush_buffer_async2((VALUE)fptr);
1053  else
1054  return (int)rb_mutex_synchronize(fptr->write_lock, io_flush_buffer_async2, (VALUE)fptr);
1055  }
1056  else {
1057  return (int)io_flush_buffer_async((VALUE)fptr);
1058  }
1059 }
1060 
1061 static int
1063 {
1064  rb_io_check_closed(fptr);
1065  if (fptr->wbuf.len == 0)
1066  return 0;
1067  rb_io_check_closed(fptr);
1068  while (fptr->wbuf.len > 0 && io_flush_buffer(fptr) != 0) {
1069  if (!rb_io_wait_writable(fptr->fd))
1070  return -1;
1071  rb_io_check_closed(fptr);
1072  }
1073  return 0;
1074 }
1075 
1076 int
1078 {
1079  if (f < 0) {
1080  rb_raise(rb_eIOError, closed_stream);
1081  }
1082  switch (errno) {
1083  case EINTR:
1084 #if defined(ERESTART)
1085  case ERESTART:
1086 #endif
1088  return TRUE;
1089 
1090  case EAGAIN:
1091 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
1092  case EWOULDBLOCK:
1093 #endif
1094  rb_thread_wait_fd(f);
1095  return TRUE;
1096 
1097  default:
1098  return FALSE;
1099  }
1100 }
1101 
1102 int
1104 {
1105  if (f < 0) {
1106  rb_raise(rb_eIOError, closed_stream);
1107  }
1108  switch (errno) {
1109  case EINTR:
1110 #if defined(ERESTART)
1111  case ERESTART:
1112 #endif
1113  /*
1114  * In old Linux, several special files under /proc and /sys don't handle
1115  * select properly. Thus we need avoid to call if don't use O_NONBLOCK.
1116  * Otherwise, we face nasty hang up. Sigh.
1117  * e.g. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
1118  * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
1119  * In EINTR case, we only need to call RUBY_VM_CHECK_INTS_BLOCKING().
1120  * Then rb_thread_check_ints() is enough.
1121  */
1123  return TRUE;
1124 
1125  case EAGAIN:
1126 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
1127  case EWOULDBLOCK:
1128 #endif
1130  return TRUE;
1131 
1132  default:
1133  return FALSE;
1134  }
1135 }
1136 
1137 static void
1139 {
1140  if (!fptr->writeconv_initialized) {
1141  const char *senc, *denc;
1142  rb_encoding *enc;
1143  int ecflags;
1144  VALUE ecopts;
1145 
1146  fptr->writeconv_initialized = 1;
1147 
1148  ecflags = fptr->encs.ecflags & ~ECONV_NEWLINE_DECORATOR_READ_MASK;
1149  ecopts = fptr->encs.ecopts;
1150 
1151  if (!fptr->encs.enc || (fptr->encs.enc == rb_ascii8bit_encoding() && !fptr->encs.enc2)) {
1152  /* no encoding conversion */
1153  fptr->writeconv_pre_ecflags = 0;
1154  fptr->writeconv_pre_ecopts = Qnil;
1155  fptr->writeconv = rb_econv_open_opts("", "", ecflags, ecopts);
1156  if (!fptr->writeconv)
1157  rb_exc_raise(rb_econv_open_exc("", "", ecflags));
1158  fptr->writeconv_asciicompat = Qnil;
1159  }
1160  else {
1161  enc = fptr->encs.enc2 ? fptr->encs.enc2 : fptr->encs.enc;
1163  if (!senc && !(fptr->encs.ecflags & ECONV_STATEFUL_DECORATOR_MASK)) {
1164  /* single conversion */
1165  fptr->writeconv_pre_ecflags = ecflags;
1166  fptr->writeconv_pre_ecopts = ecopts;
1167  fptr->writeconv = NULL;
1168  fptr->writeconv_asciicompat = Qnil;
1169  }
1170  else {
1171  /* double conversion */
1173  fptr->writeconv_pre_ecopts = ecopts;
1174  if (senc) {
1175  denc = rb_enc_name(enc);
1176  fptr->writeconv_asciicompat = rb_str_new2(senc);
1177  }
1178  else {
1179  senc = denc = "";
1181  }
1183  ecopts = fptr->encs.ecopts;
1184  fptr->writeconv = rb_econv_open_opts(senc, denc, ecflags, ecopts);
1185  if (!fptr->writeconv)
1186  rb_exc_raise(rb_econv_open_exc(senc, denc, ecflags));
1187  }
1188  }
1189  }
1190 }
1191 
1192 /* writing functions */
1196  const char *ptr;
1197  long length;
1198 };
1199 
1200 struct write_arg {
1203  int nosync;
1204 };
1205 
1206 static VALUE
1208 {
1209  struct binwrite_arg *p = (struct binwrite_arg *)arg;
1210  long l = io_writable_length(p->fptr, p->length);
1211  return rb_write_internal2(p->fptr->fd, p->ptr, l);
1212 }
1213 
1214 static long
1215 io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
1216 {
1217  long n, r, offset = 0;
1218 
1219  /* don't write anything if current thread has a pending interrupt. */
1221 
1222  if ((n = len) <= 0) return n;
1223  if (fptr->wbuf.ptr == NULL && !(!nosync && (fptr->mode & FMODE_SYNC))) {
1224  fptr->wbuf.off = 0;
1225  fptr->wbuf.len = 0;
1226  fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
1227  fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
1228  fptr->write_lock = rb_mutex_new();
1229  rb_mutex_allow_trap(fptr->write_lock, 1);
1230  }
1231  if ((!nosync && (fptr->mode & (FMODE_SYNC|FMODE_TTY))) ||
1232  (fptr->wbuf.ptr && fptr->wbuf.capa <= fptr->wbuf.len + len)) {
1233  struct binwrite_arg arg;
1234 
1235  /*
1236  * xxx: use writev to avoid double write if available
1237  * writev may help avoid context switch between "a" and "\n" in
1238  * STDERR.puts "a" [ruby-dev:25080] (rebroken since native threads
1239  * introduced in 1.9)
1240  */
1241  if (fptr->wbuf.len && fptr->wbuf.len+len <= fptr->wbuf.capa) {
1242  if (fptr->wbuf.capa < fptr->wbuf.off+fptr->wbuf.len+len) {
1243  MEMMOVE(fptr->wbuf.ptr, fptr->wbuf.ptr+fptr->wbuf.off, char, fptr->wbuf.len);
1244  fptr->wbuf.off = 0;
1245  }
1246  MEMMOVE(fptr->wbuf.ptr+fptr->wbuf.off+fptr->wbuf.len, ptr+offset, char, len);
1247  fptr->wbuf.len += (int)len;
1248  n = 0;
1249  }
1250  if (io_fflush(fptr) < 0)
1251  return -1L;
1252  if (n == 0)
1253  return len;
1254 
1255  rb_io_check_closed(fptr);
1256  arg.fptr = fptr;
1257  arg.str = str;
1258  retry:
1259  arg.ptr = ptr + offset;
1260  arg.length = n;
1261  if (fptr->write_lock) {
1263  }
1264  else {
1265  long l = io_writable_length(fptr, n);
1266  r = rb_write_internal(fptr->fd, ptr+offset, l);
1267  }
1268  /* xxx: other threads may modify given string. */
1269  if (r == n) return len;
1270  if (0 <= r) {
1271  offset += r;
1272  n -= r;
1273  errno = EAGAIN;
1274  }
1275  if (rb_io_wait_writable(fptr->fd)) {
1276  rb_io_check_closed(fptr);
1277  if (offset < len)
1278  goto retry;
1279  }
1280  return -1L;
1281  }
1282 
1283  if (fptr->wbuf.off) {
1284  if (fptr->wbuf.len)
1285  MEMMOVE(fptr->wbuf.ptr, fptr->wbuf.ptr+fptr->wbuf.off, char, fptr->wbuf.len);
1286  fptr->wbuf.off = 0;
1287  }
1288  MEMMOVE(fptr->wbuf.ptr+fptr->wbuf.off+fptr->wbuf.len, ptr+offset, char, len);
1289  fptr->wbuf.len += (int)len;
1290  return len;
1291 }
1292 
1293 # define MODE_BTMODE(a,b,c) ((fmode & FMODE_BINMODE) ? (b) : \
1294  (fmode & FMODE_TEXTMODE) ? (c) : (a))
1295 static VALUE
1297 {
1298  if (NEED_WRITECONV(fptr)) {
1299  VALUE common_encoding = Qnil;
1300  SET_BINARY_MODE(fptr);
1301 
1302  make_writeconv(fptr);
1303 
1304  if (fptr->writeconv) {
1305 #define fmode (fptr->mode)
1306  if (!NIL_P(fptr->writeconv_asciicompat))
1307  common_encoding = fptr->writeconv_asciicompat;
1308  else if (MODE_BTMODE(DEFAULT_TEXTMODE,0,1) && !rb_enc_asciicompat(rb_enc_get(str))) {
1309  rb_raise(rb_eArgError, "ASCII incompatible string written for text mode IO without encoding conversion: %s",
1310  rb_enc_name(rb_enc_get(str)));
1311  }
1312 #undef fmode
1313  }
1314  else {
1315  if (fptr->encs.enc2)
1316  common_encoding = rb_enc_from_encoding(fptr->encs.enc2);
1317  else if (fptr->encs.enc != rb_ascii8bit_encoding())
1318  common_encoding = rb_enc_from_encoding(fptr->encs.enc);
1319  }
1320 
1321  if (!NIL_P(common_encoding)) {
1322  str = rb_str_encode(str, common_encoding,
1324  }
1325 
1326  if (fptr->writeconv) {
1328  }
1329  }
1330 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
1331 #define fmode (fptr->mode)
1332  else if (MODE_BTMODE(DEFAULT_TEXTMODE,0,1)) {
1333  if ((fptr->mode & FMODE_READABLE) &&
1335  setmode(fptr->fd, O_BINARY);
1336  }
1337  else {
1338  setmode(fptr->fd, O_TEXT);
1339  }
1340  if (!rb_enc_asciicompat(rb_enc_get(str))) {
1341  rb_raise(rb_eArgError, "ASCII incompatible string written for text mode IO without encoding conversion: %s",
1342  rb_enc_name(rb_enc_get(str)));
1343  }
1344  }
1345 #undef fmode
1346 #endif
1347  return str;
1348 }
1349 
1350 static long
1351 io_fwrite(VALUE str, rb_io_t *fptr, int nosync)
1352 {
1353 #ifdef _WIN32
1354  if (fptr->mode & FMODE_TTY) {
1355  long len = rb_w32_write_console(str, fptr->fd);
1356  if (len > 0) return len;
1357  }
1358 #endif
1359  str = do_writeconv(str, fptr);
1360  return io_binwrite(str, RSTRING_PTR(str), RSTRING_LEN(str),
1361  fptr, nosync);
1362 }
1363 
1364 ssize_t
1365 rb_io_bufwrite(VALUE io, const void *buf, size_t size)
1366 {
1367  rb_io_t *fptr;
1368 
1369  GetOpenFile(io, fptr);
1370  rb_io_check_writable(fptr);
1371  return (ssize_t)io_binwrite(0, buf, (long)size, fptr, 0);
1372 }
1373 
1374 static VALUE
1375 io_write(VALUE io, VALUE str, int nosync)
1376 {
1377  rb_io_t *fptr;
1378  long n;
1379  VALUE tmp;
1380 
1381  io = GetWriteIO(io);
1382  str = rb_obj_as_string(str);
1383  tmp = rb_io_check_io(io);
1384  if (NIL_P(tmp)) {
1385  /* port is not IO, call write method for it. */
1386  return rb_funcall(io, id_write, 1, str);
1387  }
1388  io = tmp;
1389  if (RSTRING_LEN(str) == 0) return INT2FIX(0);
1390 
1391  str = rb_str_new_frozen(str);
1392 
1393  GetOpenFile(io, fptr);
1394  rb_io_check_writable(fptr);
1395 
1396  n = io_fwrite(str, fptr, nosync);
1397  if (n == -1L) rb_sys_fail_path(fptr->pathv);
1398 
1399  return LONG2FIX(n);
1400 }
1401 
1402 /*
1403  * call-seq:
1404  * ios.write(string) -> integer
1405  *
1406  * Writes the given string to <em>ios</em>. The stream must be opened
1407  * for writing. If the argument is not a string, it will be converted
1408  * to a string using <code>to_s</code>. Returns the number of bytes
1409  * written.
1410  *
1411  * count = $stdout.write("This is a test\n")
1412  * puts "That was #{count} bytes of data"
1413  *
1414  * <em>produces:</em>
1415  *
1416  * This is a test
1417  * That was 15 bytes of data
1418  */
1419 
1420 static VALUE
1422 {
1423  return io_write(io, str, 0);
1424 }
1425 
1426 VALUE
1428 {
1429  return rb_funcallv(io, id_write, 1, &str);
1430 }
1431 
1432 /*
1433  * call-seq:
1434  * ios << obj -> ios
1435  *
1436  * String Output---Writes <i>obj</i> to <em>ios</em>.
1437  * <i>obj</i> will be converted to a string using
1438  * <code>to_s</code>.
1439  *
1440  * $stdout << "Hello " << "world!\n"
1441  *
1442  * <em>produces:</em>
1443  *
1444  * Hello world!
1445  */
1446 
1447 
1448 VALUE
1450 {
1451  rb_io_write(io, str);
1452  return io;
1453 }
1454 
1455 #ifdef HAVE_FSYNC
1456 static VALUE
1457 nogvl_fsync(void *ptr)
1458 {
1459  rb_io_t *fptr = ptr;
1460 
1461  return (VALUE)fsync(fptr->fd);
1462 }
1463 #endif
1464 
1465 VALUE
1466 rb_io_flush_raw(VALUE io, int sync)
1467 {
1468  rb_io_t *fptr;
1469 
1470  if (!RB_TYPE_P(io, T_FILE)) {
1471  return rb_funcall(io, id_flush, 0);
1472  }
1473 
1474  io = GetWriteIO(io);
1475  GetOpenFile(io, fptr);
1476 
1477  if (fptr->mode & FMODE_WRITABLE) {
1478  if (io_fflush(fptr) < 0)
1479  rb_sys_fail(0);
1480 #ifdef _WIN32
1481  if (sync && GetFileType((HANDLE)rb_w32_get_osfhandle(fptr->fd)) == FILE_TYPE_DISK) {
1482  rb_thread_io_blocking_region(nogvl_fsync, fptr, fptr->fd);
1483  }
1484 #endif
1485  }
1486  if (fptr->mode & FMODE_READABLE) {
1487  io_unread(fptr);
1488  }
1489 
1490  return io;
1491 }
1492 
1493 /*
1494  * call-seq:
1495  * ios.flush -> ios
1496  *
1497  * Flushes any buffered data within <em>ios</em> to the underlying
1498  * operating system (note that this is Ruby internal buffering only;
1499  * the OS may buffer the data as well).
1500  *
1501  * $stdout.print "no newline"
1502  * $stdout.flush
1503  *
1504  * <em>produces:</em>
1505  *
1506  * no newline
1507  */
1508 
1509 VALUE
1511 {
1512  return rb_io_flush_raw(io, 1);
1513 }
1514 
1515 /*
1516  * call-seq:
1517  * ios.pos -> integer
1518  * ios.tell -> integer
1519  *
1520  * Returns the current offset (in bytes) of <em>ios</em>.
1521  *
1522  * f = File.new("testfile")
1523  * f.pos #=> 0
1524  * f.gets #=> "This is line one\n"
1525  * f.pos #=> 17
1526  */
1527 
1528 static VALUE
1530 {
1531  rb_io_t *fptr;
1532  off_t pos;
1533 
1534  GetOpenFile(io, fptr);
1535  pos = io_tell(fptr);
1536  if (pos < 0 && errno) rb_sys_fail_path(fptr->pathv);
1537  pos -= fptr->rbuf.len;
1538  return OFFT2NUM(pos);
1539 }
1540 
1541 static VALUE
1542 rb_io_seek(VALUE io, VALUE offset, int whence)
1543 {
1544  rb_io_t *fptr;
1545  off_t pos;
1546 
1547  pos = NUM2OFFT(offset);
1548  GetOpenFile(io, fptr);
1549  pos = io_seek(fptr, pos, whence);
1550  if (pos < 0 && errno) rb_sys_fail_path(fptr->pathv);
1551 
1552  return INT2FIX(0);
1553 }
1554 
1555 static int
1557 {
1558  if (vwhence == sym_SET)
1559  return SEEK_SET;
1560  if (vwhence == sym_CUR)
1561  return SEEK_CUR;
1562  if (vwhence == sym_END)
1563  return SEEK_END;
1564 #ifdef SEEK_DATA
1565  if (vwhence == sym_DATA)
1566  return SEEK_DATA;
1567 #endif
1568 #ifdef SEEK_HOLE
1569  if (vwhence == sym_HOLE)
1570  return SEEK_HOLE;
1571 #endif
1572  return NUM2INT(vwhence);
1573 }
1574 
1575 /*
1576  * call-seq:
1577  * ios.seek(amount, whence=IO::SEEK_SET) -> 0
1578  *
1579  * Seeks to a given offset <i>anInteger</i> in the stream according to
1580  * the value of <i>whence</i>:
1581  *
1582  * :CUR or IO::SEEK_CUR | Seeks to _amount_ plus current position
1583  * ----------------------+--------------------------------------------------
1584  * :END or IO::SEEK_END | Seeks to _amount_ plus end of stream (you
1585  * | probably want a negative value for _amount_)
1586  * ----------------------+--------------------------------------------------
1587  * :SET or IO::SEEK_SET | Seeks to the absolute location given by _amount_
1588  *
1589  * Example:
1590  *
1591  * f = File.new("testfile")
1592  * f.seek(-13, IO::SEEK_END) #=> 0
1593  * f.readline #=> "And so on...\n"
1594  */
1595 
1596 static VALUE
1598 {
1599  VALUE offset, ptrname;
1600  int whence = SEEK_SET;
1601 
1602  if (rb_scan_args(argc, argv, "11", &offset, &ptrname) == 2) {
1603  whence = interpret_seek_whence(ptrname);
1604  }
1605 
1606  return rb_io_seek(io, offset, whence);
1607 }
1608 
1609 /*
1610  * call-seq:
1611  * ios.pos = integer -> integer
1612  *
1613  * Seeks to the given position (in bytes) in <em>ios</em>.
1614  * It is not guaranteed that seeking to the right position when <em>ios</em>
1615  * is textmode.
1616  *
1617  * f = File.new("testfile")
1618  * f.pos = 17
1619  * f.gets #=> "This is line two\n"
1620  */
1621 
1622 static VALUE
1624 {
1625  rb_io_t *fptr;
1626  off_t pos;
1627 
1628  pos = NUM2OFFT(offset);
1629  GetOpenFile(io, fptr);
1630  pos = io_seek(fptr, pos, SEEK_SET);
1631  if (pos < 0 && errno) rb_sys_fail_path(fptr->pathv);
1632 
1633  return OFFT2NUM(pos);
1634 }
1635 
1636 static void clear_readconv(rb_io_t *fptr);
1637 
1638 /*
1639  * call-seq:
1640  * ios.rewind -> 0
1641  *
1642  * Positions <em>ios</em> to the beginning of input, resetting
1643  * <code>lineno</code> to zero.
1644  *
1645  * f = File.new("testfile")
1646  * f.readline #=> "This is line one\n"
1647  * f.rewind #=> 0
1648  * f.lineno #=> 0
1649  * f.readline #=> "This is line one\n"
1650  *
1651  * Note that it cannot be used with streams such as pipes, ttys, and sockets.
1652  */
1653 
1654 static VALUE
1656 {
1657  rb_io_t *fptr;
1658 
1659  GetOpenFile(io, fptr);
1660  if (io_seek(fptr, 0L, 0) < 0 && errno) rb_sys_fail_path(fptr->pathv);
1661  if (io == ARGF.current_file) {
1662  ARGF.lineno -= fptr->lineno;
1663  }
1664  fptr->lineno = 0;
1665  if (fptr->readconv) {
1666  clear_readconv(fptr);
1667  }
1668 
1669  return INT2FIX(0);
1670 }
1671 
1672 static int
1674 {
1675  ssize_t r;
1676 
1677  if (fptr->rbuf.ptr == NULL) {
1678  fptr->rbuf.off = 0;
1679  fptr->rbuf.len = 0;
1680  fptr->rbuf.capa = IO_RBUF_CAPA_FOR(fptr);
1681  fptr->rbuf.ptr = ALLOC_N(char, fptr->rbuf.capa);
1682 #ifdef _WIN32
1683  fptr->rbuf.capa--;
1684 #endif
1685  }
1686  if (fptr->rbuf.len == 0) {
1687  retry:
1688  {
1689  r = rb_read_internal(fptr->fd, fptr->rbuf.ptr, fptr->rbuf.capa);
1690  }
1691  if (r < 0) {
1692  if (rb_io_wait_readable(fptr->fd))
1693  goto retry;
1694  {
1695  VALUE path = rb_sprintf("fd:%d ", fptr->fd);
1696  if (!NIL_P(fptr->pathv)) {
1697  rb_str_append(path, fptr->pathv);
1698  }
1699  rb_sys_fail_path(path);
1700  }
1701  }
1702  fptr->rbuf.off = 0;
1703  fptr->rbuf.len = (int)r; /* r should be <= rbuf_capa */
1704  if (r == 0)
1705  return -1; /* EOF */
1706  }
1707  return 0;
1708 }
1709 
1710 /*
1711  * call-seq:
1712  * ios.eof -> true or false
1713  * ios.eof? -> true or false
1714  *
1715  * Returns true if <em>ios</em> is at end of file that means
1716  * there are no more data to read.
1717  * The stream must be opened for reading or an <code>IOError</code> will be
1718  * raised.
1719  *
1720  * f = File.new("testfile")
1721  * dummy = f.readlines
1722  * f.eof #=> true
1723  *
1724  * If <em>ios</em> is a stream such as pipe or socket, <code>IO#eof?</code>
1725  * blocks until the other end sends some data or closes it.
1726  *
1727  * r, w = IO.pipe
1728  * Thread.new { sleep 1; w.close }
1729  * r.eof? #=> true after 1 second blocking
1730  *
1731  * r, w = IO.pipe
1732  * Thread.new { sleep 1; w.puts "a" }
1733  * r.eof? #=> false after 1 second blocking
1734  *
1735  * r, w = IO.pipe
1736  * r.eof? # blocks forever
1737  *
1738  * Note that <code>IO#eof?</code> reads data to the input byte buffer.
1739  * So <code>IO#sysread</code> may not behave as you intend with
1740  * <code>IO#eof?</code>, unless you call <code>IO#rewind</code>
1741  * first (which is not available for some streams).
1742  */
1743 
1744 VALUE
1746 {
1747  rb_io_t *fptr;
1748 
1749  GetOpenFile(io, fptr);
1751 
1752  if (READ_CHAR_PENDING(fptr)) return Qfalse;
1753  if (READ_DATA_PENDING(fptr)) return Qfalse;
1754  READ_CHECK(fptr);
1755 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
1756  if (!NEED_READCONV(fptr) && NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
1757  return eof(fptr->fd) ? Qtrue : Qfalse;
1758  }
1759 #endif
1760  if (io_fillbuf(fptr) < 0) {
1761  return Qtrue;
1762  }
1763  return Qfalse;
1764 }
1765 
1766 /*
1767  * call-seq:
1768  * ios.sync -> true or false
1769  *
1770  * Returns the current ``sync mode'' of <em>ios</em>. When sync mode is
1771  * true, all output is immediately flushed to the underlying operating
1772  * system and is not buffered by Ruby internally. See also
1773  * <code>IO#fsync</code>.
1774  *
1775  * f = File.new("testfile")
1776  * f.sync #=> false
1777  */
1778 
1779 static VALUE
1781 {
1782  rb_io_t *fptr;
1783 
1784  io = GetWriteIO(io);
1785  GetOpenFile(io, fptr);
1786  return (fptr->mode & FMODE_SYNC) ? Qtrue : Qfalse;
1787 }
1788 
1789 #ifdef HAVE_FSYNC
1790 
1791 /*
1792  * call-seq:
1793  * ios.sync = boolean -> boolean
1794  *
1795  * Sets the ``sync mode'' to <code>true</code> or <code>false</code>.
1796  * When sync mode is true, all output is immediately flushed to the
1797  * underlying operating system and is not buffered internally. Returns
1798  * the new state. See also <code>IO#fsync</code>.
1799  *
1800  * f = File.new("testfile")
1801  * f.sync = true
1802  *
1803  * <em>(produces no output)</em>
1804  */
1805 
1806 static VALUE
1807 rb_io_set_sync(VALUE io, VALUE sync)
1808 {
1809  rb_io_t *fptr;
1810 
1811  io = GetWriteIO(io);
1812  GetOpenFile(io, fptr);
1813  if (RTEST(sync)) {
1814  fptr->mode |= FMODE_SYNC;
1815  }
1816  else {
1817  fptr->mode &= ~FMODE_SYNC;
1818  }
1819  return sync;
1820 }
1821 
1822 /*
1823  * call-seq:
1824  * ios.fsync -> 0 or nil
1825  *
1826  * Immediately writes all buffered data in <em>ios</em> to disk.
1827  * Note that <code>fsync</code> differs from
1828  * using <code>IO#sync=</code>. The latter ensures that data is flushed
1829  * from Ruby's buffers, but does not guarantee that the underlying
1830  * operating system actually writes it to disk.
1831  *
1832  * <code>NotImplementedError</code> is raised
1833  * if the underlying operating system does not support <em>fsync(2)</em>.
1834  */
1835 
1836 static VALUE
1837 rb_io_fsync(VALUE io)
1838 {
1839  rb_io_t *fptr;
1840 
1841  io = GetWriteIO(io);
1842  GetOpenFile(io, fptr);
1843 
1844  if (io_fflush(fptr) < 0)
1845  rb_sys_fail(0);
1846 # ifndef _WIN32 /* already called in io_fflush() */
1847  if ((int)rb_thread_io_blocking_region(nogvl_fsync, fptr, fptr->fd) < 0)
1848  rb_sys_fail_path(fptr->pathv);
1849 # endif
1850  return INT2FIX(0);
1851 }
1852 #else
1853 # define rb_io_fsync rb_f_notimplement
1854 # define rb_io_sync rb_f_notimplement
1855 static VALUE
1857 {
1858  rb_notimplement();
1859  UNREACHABLE;
1860 }
1861 #endif
1862 
1863 #ifdef HAVE_FDATASYNC
1864 static VALUE
1865 nogvl_fdatasync(void *ptr)
1866 {
1867  rb_io_t *fptr = ptr;
1868 
1869  return (VALUE)fdatasync(fptr->fd);
1870 }
1871 
1872 /*
1873  * call-seq:
1874  * ios.fdatasync -> 0 or nil
1875  *
1876  * Immediately writes all buffered data in <em>ios</em> to disk.
1877  *
1878  * If the underlying operating system does not support <em>fdatasync(2)</em>,
1879  * <code>IO#fsync</code> is called instead (which might raise a
1880  * <code>NotImplementedError</code>).
1881  */
1882 
1883 static VALUE
1885 {
1886  rb_io_t *fptr;
1887 
1888  io = GetWriteIO(io);
1889  GetOpenFile(io, fptr);
1890 
1891  if (io_fflush(fptr) < 0)
1892  rb_sys_fail(0);
1893 
1894  if ((int)rb_thread_io_blocking_region(nogvl_fdatasync, fptr, fptr->fd) == 0)
1895  return INT2FIX(0);
1896 
1897  /* fall back */
1898  return rb_io_fsync(io);
1899 }
1900 #else
1901 #define rb_io_fdatasync rb_io_fsync
1902 #endif
1903 
1904 /*
1905  * call-seq:
1906  * ios.fileno -> fixnum
1907  * ios.to_i -> fixnum
1908  *
1909  * Returns an integer representing the numeric file descriptor for
1910  * <em>ios</em>.
1911  *
1912  * $stdin.fileno #=> 0
1913  * $stdout.fileno #=> 1
1914  */
1915 
1916 static VALUE
1918 {
1919  rb_io_t *fptr = RFILE(io)->fptr;
1920  int fd;
1921 
1922  rb_io_check_closed(fptr);
1923  fd = fptr->fd;
1924  return INT2FIX(fd);
1925 }
1926 
1927 
1928 /*
1929  * call-seq:
1930  * ios.pid -> fixnum
1931  *
1932  * Returns the process ID of a child process associated with
1933  * <em>ios</em>. This will be set by <code>IO.popen</code>.
1934  *
1935  * pipe = IO.popen("-")
1936  * if pipe
1937  * $stderr.puts "In parent, child pid is #{pipe.pid}"
1938  * else
1939  * $stderr.puts "In child, pid is #{$$}"
1940  * end
1941  *
1942  * <em>produces:</em>
1943  *
1944  * In child, pid is 26209
1945  * In parent, child pid is 26209
1946  */
1947 
1948 static VALUE
1950 {
1951  rb_io_t *fptr;
1952 
1953  GetOpenFile(io, fptr);
1954  if (!fptr->pid)
1955  return Qnil;
1956  return PIDT2NUM(fptr->pid);
1957 }
1958 
1959 
1960 /*
1961  * call-seq:
1962  * ios.inspect -> string
1963  *
1964  * Return a string describing this IO object.
1965  */
1966 
1967 static VALUE
1969 {
1970  rb_io_t *fptr;
1971  VALUE result;
1972  static const char closed[] = " (closed)";
1973 
1974  fptr = RFILE(obj)->fptr;
1975  if (!fptr) return rb_any_to_s(obj);
1976  result = rb_str_new_cstr("#<");
1977  rb_str_append(result, rb_class_name(CLASS_OF(obj)));
1978  rb_str_cat2(result, ":");
1979  if (NIL_P(fptr->pathv)) {
1980  if (fptr->fd < 0) {
1981  rb_str_cat(result, closed+1, strlen(closed)-1);
1982  }
1983  else {
1984  rb_str_catf(result, "fd %d", fptr->fd);
1985  }
1986  }
1987  else {
1988  rb_str_append(result, fptr->pathv);
1989  if (fptr->fd < 0) {
1990  rb_str_cat(result, closed, strlen(closed));
1991  }
1992  }
1993  return rb_str_cat2(result, ">");
1994 }
1995 
1996 /*
1997  * call-seq:
1998  * ios.to_io -> ios
1999  *
2000  * Returns <em>ios</em>.
2001  */
2002 
2003 static VALUE
2005 {
2006  return io;
2007 }
2008 
2009 /* reading functions */
2010 static long
2011 read_buffered_data(char *ptr, long len, rb_io_t *fptr)
2012 {
2013  int n;
2014 
2015  n = READ_DATA_PENDING_COUNT(fptr);
2016  if (n <= 0) return 0;
2017  if (n > len) n = (int)len;
2018  MEMMOVE(ptr, fptr->rbuf.ptr+fptr->rbuf.off, char, n);
2019  fptr->rbuf.off += n;
2020  fptr->rbuf.len -= n;
2021  return n;
2022 }
2023 
2024 static long
2025 io_bufread(char *ptr, long len, rb_io_t *fptr)
2026 {
2027  long offset = 0;
2028  long n = len;
2029  long c;
2030 
2031  if (READ_DATA_PENDING(fptr) == 0) {
2032  while (n > 0) {
2033  again:
2034  c = rb_read_internal(fptr->fd, ptr+offset, n);
2035  if (c == 0) break;
2036  if (c < 0) {
2037  if (rb_io_wait_readable(fptr->fd))
2038  goto again;
2039  return -1;
2040  }
2041  offset += c;
2042  if ((n -= c) <= 0) break;
2043  }
2044  return len - n;
2045  }
2046 
2047  while (n > 0) {
2048  c = read_buffered_data(ptr+offset, n, fptr);
2049  if (c > 0) {
2050  offset += c;
2051  if ((n -= c) <= 0) break;
2052  }
2053  rb_io_check_closed(fptr);
2054  if (io_fillbuf(fptr) < 0) {
2055  break;
2056  }
2057  }
2058  return len - n;
2059 }
2060 
2061 static void io_setstrbuf(VALUE *str, long len);
2062 
2063 struct bufread_arg {
2064  char *str_ptr;
2065  long len;
2067 };
2068 
2069 static VALUE
2071 {
2072  struct bufread_arg *p = (struct bufread_arg *)arg;
2073  p->len = io_bufread(p->str_ptr, p->len, p->fptr);
2074  return Qundef;
2075 }
2076 
2077 static long
2078 io_fread(VALUE str, long offset, long size, rb_io_t *fptr)
2079 {
2080  long len;
2081  struct bufread_arg arg;
2082 
2083  io_setstrbuf(&str, offset + size);
2084  arg.str_ptr = RSTRING_PTR(str) + offset;
2085  arg.len = size;
2086  arg.fptr = fptr;
2088  len = arg.len;
2089  if (len < 0) rb_sys_fail_path(fptr->pathv);
2090  return len;
2091 }
2092 
2093 ssize_t
2094 rb_io_bufread(VALUE io, void *buf, size_t size)
2095 {
2096  rb_io_t *fptr;
2097 
2098  GetOpenFile(io, fptr);
2099  rb_io_check_readable(fptr);
2100  return (ssize_t)io_bufread(buf, (long)size, fptr);
2101 }
2102 
2103 #define SMALLBUF 100
2104 
2105 static long
2107 {
2108  struct stat st;
2109  off_t siz = READ_DATA_PENDING_COUNT(fptr);
2110  off_t pos;
2111 
2112  if (fstat(fptr->fd, &st) == 0 && S_ISREG(st.st_mode)
2113 #if defined(__BEOS__) || defined(__HAIKU__)
2114  && (st.st_dev > 3)
2115 #endif
2116  )
2117  {
2118  if (io_fflush(fptr) < 0)
2119  rb_sys_fail(0);
2120  pos = lseek(fptr->fd, 0, SEEK_CUR);
2121  if (st.st_size >= pos && pos >= 0) {
2122  siz += st.st_size - pos;
2123  if (siz > LONG_MAX) {
2124  rb_raise(rb_eIOError, "file too big for single read");
2125  }
2126  }
2127  }
2128  else {
2129  siz += BUFSIZ;
2130  }
2131  return (long)siz;
2132 }
2133 
2134 static VALUE
2136 {
2137  OBJ_TAINT(str);
2138  rb_enc_associate(str, io_read_encoding(fptr));
2139  return str;
2140 }
2141 
2142 static void
2144 {
2145  if (!fptr->readconv) {
2146  int ecflags;
2147  VALUE ecopts;
2148  const char *sname, *dname;
2149  ecflags = fptr->encs.ecflags & ~ECONV_NEWLINE_DECORATOR_WRITE_MASK;
2150  ecopts = fptr->encs.ecopts;
2151  if (fptr->encs.enc2) {
2152  sname = rb_enc_name(fptr->encs.enc2);
2153  dname = rb_enc_name(fptr->encs.enc);
2154  }
2155  else {
2156  sname = dname = "";
2157  }
2158  fptr->readconv = rb_econv_open_opts(sname, dname, ecflags, ecopts);
2159  if (!fptr->readconv)
2160  rb_exc_raise(rb_econv_open_exc(sname, dname, ecflags));
2161  fptr->cbuf.off = 0;
2162  fptr->cbuf.len = 0;
2163  if (size < IO_CBUF_CAPA_MIN) size = IO_CBUF_CAPA_MIN;
2164  fptr->cbuf.capa = size;
2165  fptr->cbuf.ptr = ALLOC_N(char, fptr->cbuf.capa);
2166  }
2167 }
2168 
2169 #define MORE_CHAR_SUSPENDED Qtrue
2170 #define MORE_CHAR_FINISHED Qnil
2171 static VALUE
2172 fill_cbuf(rb_io_t *fptr, int ec_flags)
2173 {
2174  const unsigned char *ss, *sp, *se;
2175  unsigned char *ds, *dp, *de;
2176  rb_econv_result_t res;
2177  int putbackable;
2178  int cbuf_len0;
2179  VALUE exc;
2180 
2181  ec_flags |= ECONV_PARTIAL_INPUT;
2182 
2183  if (fptr->cbuf.len == fptr->cbuf.capa)
2184  return MORE_CHAR_SUSPENDED; /* cbuf full */
2185  if (fptr->cbuf.len == 0)
2186  fptr->cbuf.off = 0;
2187  else if (fptr->cbuf.off + fptr->cbuf.len == fptr->cbuf.capa) {
2188  memmove(fptr->cbuf.ptr, fptr->cbuf.ptr+fptr->cbuf.off, fptr->cbuf.len);
2189  fptr->cbuf.off = 0;
2190  }
2191 
2192  cbuf_len0 = fptr->cbuf.len;
2193 
2194  while (1) {
2195  ss = sp = (const unsigned char *)fptr->rbuf.ptr + fptr->rbuf.off;
2196  se = sp + fptr->rbuf.len;
2197  ds = dp = (unsigned char *)fptr->cbuf.ptr + fptr->cbuf.off + fptr->cbuf.len;
2198  de = (unsigned char *)fptr->cbuf.ptr + fptr->cbuf.capa;
2199  res = rb_econv_convert(fptr->readconv, &sp, se, &dp, de, ec_flags);
2200  fptr->rbuf.off += (int)(sp - ss);
2201  fptr->rbuf.len -= (int)(sp - ss);
2202  fptr->cbuf.len += (int)(dp - ds);
2203 
2204  putbackable = rb_econv_putbackable(fptr->readconv);
2205  if (putbackable) {
2206  rb_econv_putback(fptr->readconv, (unsigned char *)fptr->rbuf.ptr + fptr->rbuf.off - putbackable, putbackable);
2207  fptr->rbuf.off -= putbackable;
2208  fptr->rbuf.len += putbackable;
2209  }
2210 
2211  exc = rb_econv_make_exception(fptr->readconv);
2212  if (!NIL_P(exc))
2213  return exc;
2214 
2215  if (cbuf_len0 != fptr->cbuf.len)
2216  return MORE_CHAR_SUSPENDED;
2217 
2218  if (res == econv_finished) {
2219  return MORE_CHAR_FINISHED;
2220  }
2221 
2222  if (res == econv_source_buffer_empty) {
2223  if (fptr->rbuf.len == 0) {
2224  READ_CHECK(fptr);
2225  if (io_fillbuf(fptr) == -1) {
2226  if (!fptr->readconv) {
2227  return MORE_CHAR_FINISHED;
2228  }
2229  ds = dp = (unsigned char *)fptr->cbuf.ptr + fptr->cbuf.off + fptr->cbuf.len;
2230  de = (unsigned char *)fptr->cbuf.ptr + fptr->cbuf.capa;
2231  res = rb_econv_convert(fptr->readconv, NULL, NULL, &dp, de, 0);
2232  fptr->cbuf.len += (int)(dp - ds);
2234  break;
2235  }
2236  }
2237  }
2238  }
2239  if (cbuf_len0 != fptr->cbuf.len)
2240  return MORE_CHAR_SUSPENDED;
2241 
2242  return MORE_CHAR_FINISHED;
2243 }
2244 
2245 static VALUE
2247 {
2248  VALUE v;
2249  v = fill_cbuf(fptr, ECONV_AFTER_OUTPUT);
2250  if (v != MORE_CHAR_SUSPENDED && v != MORE_CHAR_FINISHED)
2251  rb_exc_raise(v);
2252  return v;
2253 }
2254 
2255 static VALUE
2256 io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
2257 {
2258  VALUE str = Qnil;
2259  if (strp) {
2260  str = *strp;
2261  if (NIL_P(str)) {
2262  *strp = str = rb_str_new(fptr->cbuf.ptr+fptr->cbuf.off, len);
2263  }
2264  else {
2265  rb_str_cat(str, fptr->cbuf.ptr+fptr->cbuf.off, len);
2266  }
2267  OBJ_TAINT(str);
2268  rb_enc_associate(str, fptr->encs.enc);
2269  }
2270  fptr->cbuf.off += len;
2271  fptr->cbuf.len -= len;
2272  /* xxx: set coderange */
2273  if (fptr->cbuf.len == 0)
2274  fptr->cbuf.off = 0;
2275  else if (fptr->cbuf.capa/2 < fptr->cbuf.off) {
2276  memmove(fptr->cbuf.ptr, fptr->cbuf.ptr+fptr->cbuf.off, fptr->cbuf.len);
2277  fptr->cbuf.off = 0;
2278  }
2279  return str;
2280 }
2281 
2282 static void
2283 io_setstrbuf(VALUE *str, long len)
2284 {
2285 #ifdef _WIN32
2286  len = (len + 1) & ~1L; /* round up for wide char */
2287 #endif
2288  if (NIL_P(*str)) {
2289  *str = rb_str_new(0, 0);
2290  }
2291  else {
2292  VALUE s = StringValue(*str);
2293  long clen = RSTRING_LEN(s);
2294  if (clen >= len) {
2295  rb_str_modify(s);
2296  return;
2297  }
2298  len -= clen;
2299  }
2300  rb_str_modify_expand(*str, len);
2301 }
2302 
2303 static void
2305 {
2306  if (RSTRING_LEN(str) != n) {
2307  rb_str_modify(str);
2308  rb_str_set_len(str, n);
2309  }
2310 }
2311 
2312 static VALUE
2313 read_all(rb_io_t *fptr, long siz, VALUE str)
2314 {
2315  long bytes;
2316  long n;
2317  long pos;
2318  rb_encoding *enc;
2319  int cr;
2320 
2321  if (NEED_READCONV(fptr)) {
2322  int first = !NIL_P(str);
2323  SET_BINARY_MODE(fptr);
2324  io_setstrbuf(&str,0);
2325  make_readconv(fptr, 0);
2326  while (1) {
2327  VALUE v;
2328  if (fptr->cbuf.len) {
2329  if (first) rb_str_set_len(str, first = 0);
2330  io_shift_cbuf(fptr, fptr->cbuf.len, &str);
2331  }
2332  v = fill_cbuf(fptr, 0);
2333  if (v != MORE_CHAR_SUSPENDED && v != MORE_CHAR_FINISHED) {
2334  if (fptr->cbuf.len) {
2335  if (first) rb_str_set_len(str, first = 0);
2336  io_shift_cbuf(fptr, fptr->cbuf.len, &str);
2337  }
2338  rb_exc_raise(v);
2339  }
2340  if (v == MORE_CHAR_FINISHED) {
2341  clear_readconv(fptr);
2342  if (first) rb_str_set_len(str, first = 0);
2343  return io_enc_str(str, fptr);
2344  }
2345  }
2346  }
2347 
2349  bytes = 0;
2350  pos = 0;
2351 
2352  enc = io_read_encoding(fptr);
2353  cr = 0;
2354 
2355  if (siz == 0) siz = BUFSIZ;
2356  io_setstrbuf(&str,siz);
2357  for (;;) {
2358  READ_CHECK(fptr);
2359  n = io_fread(str, bytes, siz - bytes, fptr);
2360  if (n == 0 && bytes == 0) {
2361  rb_str_set_len(str, 0);
2362  break;
2363  }
2364  bytes += n;
2365  rb_str_set_len(str, bytes);
2366  if (cr != ENC_CODERANGE_BROKEN)
2367  pos += rb_str_coderange_scan_restartable(RSTRING_PTR(str) + pos, RSTRING_PTR(str) + bytes, enc, &cr);
2368  if (bytes < siz) break;
2369  siz += BUFSIZ;
2370  rb_str_modify_expand(str, BUFSIZ);
2371  }
2372  str = io_enc_str(str, fptr);
2373  ENC_CODERANGE_SET(str, cr);
2374  return str;
2375 }
2376 
2377 void
2379 {
2380  int oflags;
2381 #ifdef F_GETFL
2382  oflags = fcntl(fptr->fd, F_GETFL);
2383  if (oflags == -1) {
2384  rb_sys_fail_path(fptr->pathv);
2385  }
2386 #else
2387  oflags = 0;
2388 #endif
2389  if ((oflags & O_NONBLOCK) == 0) {
2390  oflags |= O_NONBLOCK;
2391  if (fcntl(fptr->fd, F_SETFL, oflags) == -1) {
2392  rb_sys_fail_path(fptr->pathv);
2393  }
2394  }
2395 }
2396 
2397 void
2398 rb_readwrite_sys_fail(int writable, const char *mesg);
2399 
2401  int fd;
2402  char *str_ptr;
2403  long len;
2404 };
2405 
2406 static VALUE
2408 {
2409  struct read_internal_arg *p = (struct read_internal_arg *)arg;
2410  p->len = rb_read_internal(p->fd, p->str_ptr, p->len);
2411  return Qundef;
2412 }
2413 
2414 static VALUE
2415 io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock, int no_exception)
2416 {
2417  rb_io_t *fptr;
2418  VALUE length, str;
2419  long n, len;
2420  struct read_internal_arg arg;
2421 
2422  rb_scan_args(argc, argv, "11:", &length, &str, NULL);
2423 
2424  if ((len = NUM2LONG(length)) < 0) {
2425  rb_raise(rb_eArgError, "negative length %ld given", len);
2426  }
2427 
2428  io_setstrbuf(&str,len);
2429  OBJ_TAINT(str);
2430 
2431  GetOpenFile(io, fptr);
2433 
2434  if (len == 0)
2435  return str;
2436 
2437  if (!nonblock)
2438  READ_CHECK(fptr);
2439  n = read_buffered_data(RSTRING_PTR(str), len, fptr);
2440  if (n <= 0) {
2441  again:
2442  if (nonblock) {
2443  rb_io_set_nonblock(fptr);
2444  }
2445  io_setstrbuf(&str, len);
2446  arg.fd = fptr->fd;
2447  arg.str_ptr = RSTRING_PTR(str);
2448  arg.len = len;
2450  n = arg.len;
2451  if (n < 0) {
2452  if (!nonblock && rb_io_wait_readable(fptr->fd))
2453  goto again;
2454  if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) {
2455  if (no_exception)
2456  return ID2SYM(rb_intern("wait_readable"));
2457  else
2458  rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "read would block");
2459  }
2460  rb_sys_fail_path(fptr->pathv);
2461  }
2462  }
2463  io_set_read_length(str, n);
2464 
2465  if (n == 0)
2466  return Qnil;
2467  else
2468  return str;
2469 }
2470 
2471 /*
2472  * call-seq:
2473  * ios.readpartial(maxlen) -> string
2474  * ios.readpartial(maxlen, outbuf) -> outbuf
2475  *
2476  * Reads at most <i>maxlen</i> bytes from the I/O stream.
2477  * It blocks only if <em>ios</em> has no data immediately available.
2478  * It doesn't block if some data available.
2479  * If the optional <i>outbuf</i> argument is present,
2480  * it must reference a String, which will receive the data.
2481  * The <i>outbuf</i> will contain only the received data after the method call
2482  * even if it is not empty at the beginning.
2483  * It raises <code>EOFError</code> on end of file.
2484  *
2485  * readpartial is designed for streams such as pipe, socket, tty, etc.
2486  * It blocks only when no data immediately available.
2487  * This means that it blocks only when following all conditions hold.
2488  * * the byte buffer in the IO object is empty.
2489  * * the content of the stream is empty.
2490  * * the stream is not reached to EOF.
2491  *
2492  * When readpartial blocks, it waits data or EOF on the stream.
2493  * If some data is reached, readpartial returns with the data.
2494  * If EOF is reached, readpartial raises EOFError.
2495  *
2496  * When readpartial doesn't blocks, it returns or raises immediately.
2497  * If the byte buffer is not empty, it returns the data in the buffer.
2498  * Otherwise if the stream has some content,
2499  * it returns the data in the stream.
2500  * Otherwise if the stream is reached to EOF, it raises EOFError.
2501  *
2502  * r, w = IO.pipe # buffer pipe content
2503  * w << "abc" # "" "abc".
2504  * r.readpartial(4096) #=> "abc" "" ""
2505  * r.readpartial(4096) # blocks because buffer and pipe is empty.
2506  *
2507  * r, w = IO.pipe # buffer pipe content
2508  * w << "abc" # "" "abc"
2509  * w.close # "" "abc" EOF
2510  * r.readpartial(4096) #=> "abc" "" EOF
2511  * r.readpartial(4096) # raises EOFError
2512  *
2513  * r, w = IO.pipe # buffer pipe content
2514  * w << "abc\ndef\n" # "" "abc\ndef\n"
2515  * r.gets #=> "abc\n" "def\n" ""
2516  * w << "ghi\n" # "def\n" "ghi\n"
2517  * r.readpartial(4096) #=> "def\n" "" "ghi\n"
2518  * r.readpartial(4096) #=> "ghi\n" "" ""
2519  *
2520  * Note that readpartial behaves similar to sysread.
2521  * The differences are:
2522  * * If the byte buffer is not empty, read from the byte buffer instead of "sysread for buffered IO (IOError)".
2523  * * It doesn't cause Errno::EWOULDBLOCK and Errno::EINTR. When readpartial meets EWOULDBLOCK and EINTR by read system call, readpartial retry the system call.
2524  *
2525  * The later means that readpartial is nonblocking-flag insensitive.
2526  * It blocks on the situation IO#sysread causes Errno::EWOULDBLOCK as if the fd is blocking mode.
2527  *
2528  */
2529 
2530 static VALUE
2532 {
2533  VALUE ret;
2534 
2535  ret = io_getpartial(argc, argv, io, 0, 0);
2536  if (NIL_P(ret))
2537  rb_eof_error();
2538  return ret;
2539 }
2540 
2541 /*
2542  * call-seq:
2543  * ios.read_nonblock(maxlen) -> string
2544  * ios.read_nonblock(maxlen, outbuf) -> outbuf
2545  *
2546  * Reads at most <i>maxlen</i> bytes from <em>ios</em> using
2547  * the read(2) system call after O_NONBLOCK is set for
2548  * the underlying file descriptor.
2549  *
2550  * If the optional <i>outbuf</i> argument is present,
2551  * it must reference a String, which will receive the data.
2552  * The <i>outbuf</i> will contain only the received data after the method call
2553  * even if it is not empty at the beginning.
2554  *
2555  * read_nonblock just calls the read(2) system call.
2556  * It causes all errors the read(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc.
2557  * The caller should care such errors.
2558  *
2559  * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN,
2560  * it is extended by IO::WaitReadable.
2561  * So IO::WaitReadable can be used to rescue the exceptions for retrying read_nonblock.
2562  *
2563  * read_nonblock causes EOFError on EOF.
2564  *
2565  * If the read byte buffer is not empty,
2566  * read_nonblock reads from the buffer like readpartial.
2567  * In this case, the read(2) system call is not called.
2568  *
2569  * When read_nonblock raises an exception kind of IO::WaitReadable,
2570  * read_nonblock should not be called
2571  * until io is readable for avoiding busy loop.
2572  * This can be done as follows.
2573  *
2574  * # emulates blocking read (readpartial).
2575  * begin
2576  * result = io.read_nonblock(maxlen)
2577  * rescue IO::WaitReadable
2578  * IO.select([io])
2579  * retry
2580  * end
2581  *
2582  * Although IO#read_nonblock doesn't raise IO::WaitWritable.
2583  * OpenSSL::Buffering#read_nonblock can raise IO::WaitWritable.
2584  * If IO and SSL should be used polymorphically,
2585  * IO::WaitWritable should be rescued too.
2586  * See the document of OpenSSL::Buffering#read_nonblock for sample code.
2587  *
2588  * Note that this method is identical to readpartial
2589  * except the non-blocking flag is set.
2590  */
2591 
2592 static VALUE
2594 {
2595  VALUE ret;
2596  VALUE opts = Qnil;
2597  int no_exception = 0;
2598 
2599  rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
2600 
2601  if (!NIL_P(opts) && Qfalse == rb_hash_aref(opts, sym_exception))
2602  no_exception = 1;
2603 
2604  ret = io_getpartial(argc, argv, io, 1, no_exception);
2605 
2606  if (NIL_P(ret)) {
2607  if (no_exception)
2608  return Qnil;
2609  else
2610  rb_eof_error();
2611  }
2612  return ret;
2613 }
2614 
2615 static VALUE
2616 io_write_nonblock(VALUE io, VALUE str, int no_exception)
2617 {
2618  rb_io_t *fptr;
2619  long n;
2620 
2621  if (!RB_TYPE_P(str, T_STRING))
2622  str = rb_obj_as_string(str);
2623 
2624  io = GetWriteIO(io);
2625  GetOpenFile(io, fptr);
2626  rb_io_check_writable(fptr);
2627 
2628  if (io_fflush(fptr) < 0)
2629  rb_sys_fail(0);
2630 
2631  rb_io_set_nonblock(fptr);
2632  n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
2633 
2634  if (n == -1) {
2635  if (errno == EWOULDBLOCK || errno == EAGAIN) {
2636  if (no_exception) {
2637  return ID2SYM(rb_intern("wait_writable"));
2638  } else {
2639  rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "write would block");
2640  }
2641  }
2642  rb_sys_fail_path(fptr->pathv);
2643  }
2644 
2645  return LONG2FIX(n);
2646 }
2647 
2648 /*
2649  * call-seq:
2650  * ios.write_nonblock(string) -> integer
2651  * ios.write_nonblock(string [, options]) -> integer
2652  *
2653  * Writes the given string to <em>ios</em> using
2654  * the write(2) system call after O_NONBLOCK is set for
2655  * the underlying file descriptor.
2656  *
2657  * It returns the number of bytes written.
2658  *
2659  * write_nonblock just calls the write(2) system call.
2660  * It causes all errors the write(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc.
2661  * The result may also be smaller than string.length (partial write).
2662  * The caller should care such errors and partial write.
2663  *
2664  * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN,
2665  * it is extended by IO::WaitWritable.
2666  * So IO::WaitWritable can be used to rescue the exceptions for retrying write_nonblock.
2667  *
2668  * # Creates a pipe.
2669  * r, w = IO.pipe
2670  *
2671  * # write_nonblock writes only 65536 bytes and return 65536.
2672  * # (The pipe size is 65536 bytes on this environment.)
2673  * s = "a" * 100000
2674  * p w.write_nonblock(s) #=> 65536
2675  *
2676  * # write_nonblock cannot write a byte and raise EWOULDBLOCK (EAGAIN).
2677  * p w.write_nonblock("b") # Resource temporarily unavailable (Errno::EAGAIN)
2678  *
2679  * If the write buffer is not empty, it is flushed at first.
2680  *
2681  * When write_nonblock raises an exception kind of IO::WaitWritable,
2682  * write_nonblock should not be called
2683  * until io is writable for avoiding busy loop.
2684  * This can be done as follows.
2685  *
2686  * begin
2687  * result = io.write_nonblock(string)
2688  * rescue IO::WaitWritable, Errno::EINTR
2689  * IO.select(nil, [io])
2690  * retry
2691  * end
2692  *
2693  * Note that this doesn't guarantee to write all data in string.
2694  * The length written is reported as result and it should be checked later.
2695  *
2696  * On some platforms such as Windows, write_nonblock is not supported
2697  * according to the kind of the IO object.
2698  * In such cases, write_nonblock raises <code>Errno::EBADF</code>.
2699  *
2700  * By specifying `exception: false`, the options hash allows you to indicate
2701  * that write_nonblock should not raise an IO::WaitWritable exception, but
2702  * return the symbol :wait_writable instead.
2703  *
2704  */
2705 
2706 static VALUE
2708 {
2709  VALUE str;
2710  VALUE opts = Qnil;
2711  int no_exceptions = 0;
2712 
2713  rb_scan_args(argc, argv, "10:", &str, &opts);
2714 
2715  if (!NIL_P(opts) && Qfalse == rb_hash_aref(opts, sym_exception))
2716  no_exceptions = 1;
2717 
2718  return io_write_nonblock(io, str, no_exceptions);
2719 }
2720 
2721 /*
2722  * call-seq:
2723  * ios.read([length [, outbuf]]) -> string, outbuf, or nil
2724  *
2725  * Reads <i>length</i> bytes from the I/O stream.
2726  *
2727  * <i>length</i> must be a non-negative integer or <code>nil</code>.
2728  *
2729  * If <i>length</i> is a positive integer,
2730  * it try to read <i>length</i> bytes without any conversion (binary mode).
2731  * It returns <code>nil</code> or a string whose length is 1 to <i>length</i> bytes.
2732  * <code>nil</code> means it met EOF at beginning.
2733  * The 1 to <i>length</i>-1 bytes string means it met EOF after reading the result.
2734  * The <i>length</i> bytes string means it doesn't meet EOF.
2735  * The resulted string is always ASCII-8BIT encoding.
2736  *
2737  * If <i>length</i> is omitted or is <code>nil</code>,
2738  * it reads until EOF and the encoding conversion is applied.
2739  * It returns a string even if EOF is met at beginning.
2740  *
2741  * If <i>length</i> is zero, it returns <code>""</code>.
2742  *
2743  * If the optional <i>outbuf</i> argument is present, it must reference
2744  * a String, which will receive the data.
2745  * The <i>outbuf</i> will contain only the received data after the method call
2746  * even if it is not empty at the beginning.
2747  *
2748  * At end of file, it returns <code>nil</code> or <code>""</code>
2749  * depend on <i>length</i>.
2750  * <code><i>ios</i>.read()</code> and
2751  * <code><i>ios</i>.read(nil)</code> returns <code>""</code>.
2752  * <code><i>ios</i>.read(<i>positive-integer</i>)</code> returns <code>nil</code>.
2753  *
2754  * f = File.new("testfile")
2755  * f.read(16) #=> "This is line one"
2756  *
2757  * # reads whole file
2758  * open("file") {|f|
2759  * data = f.read # This returns a string even if the file is empty.
2760  * ...
2761  * }
2762  *
2763  * # iterate over fixed length records.
2764  * open("fixed-record-file") {|f|
2765  * while record = f.read(256)
2766  * ...
2767  * end
2768  * }
2769  *
2770  * # iterate over variable length records.
2771  * # record is prefixed by 32-bit length.
2772  * open("variable-record-file") {|f|
2773  * while len = f.read(4)
2774  * len = len.unpack("N")[0] # 32-bit length
2775  * record = f.read(len) # This returns a string even if len is 0.
2776  * end
2777  * }
2778  *
2779  * Note that this method behaves like fread() function in C.
2780  * This means it retry to invoke read(2) system call to read data with the specified length (or until EOF).
2781  * This behavior is preserved even if <i>ios</i> is non-blocking mode.
2782  * (This method is non-blocking flag insensitive as other methods.)
2783  * If you need the behavior like single read(2) system call,
2784  * consider readpartial, read_nonblock and sysread.
2785  */
2786 
2787 static VALUE
2789 {
2790  rb_io_t *fptr;
2791  long n, len;
2792  VALUE length, str;
2793 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
2794  int previous_mode;
2795 #endif
2796 
2797  rb_scan_args(argc, argv, "02", &length, &str);
2798 
2799  if (NIL_P(length)) {
2800  GetOpenFile(io, fptr);
2802  return read_all(fptr, remain_size(fptr), str);
2803  }
2804  len = NUM2LONG(length);
2805  if (len < 0) {
2806  rb_raise(rb_eArgError, "negative length %ld given", len);
2807  }
2808 
2809  io_setstrbuf(&str,len);
2810 
2811  GetOpenFile(io, fptr);
2813  if (len == 0) {
2814  io_set_read_length(str, 0);
2815  return str;
2816  }
2817 
2818  READ_CHECK(fptr);
2819 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
2820  previous_mode = set_binary_mode_with_seek_cur(fptr);
2821 #endif
2822  n = io_fread(str, 0, len, fptr);
2823  io_set_read_length(str, n);
2824 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
2825  if (previous_mode == O_TEXT) {
2826  setmode(fptr->fd, O_TEXT);
2827  }
2828 #endif
2829  if (n == 0) return Qnil;
2830  OBJ_TAINT(str);
2831 
2832  return str;
2833 }
2834 
2835 static void
2836 rscheck(const char *rsptr, long rslen, VALUE rs)
2837 {
2838  if (!rs) return;
2839  if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
2840  rb_raise(rb_eRuntimeError, "rs modified");
2841 }
2842 
2843 static int
2844 appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
2845 {
2846  VALUE str = *strp;
2847  long limit = *lp;
2848 
2849  if (NEED_READCONV(fptr)) {
2850  SET_BINARY_MODE(fptr);
2851  make_readconv(fptr, 0);
2852  do {
2853  const char *p, *e;
2854  int searchlen = READ_CHAR_PENDING_COUNT(fptr);
2855  if (searchlen) {
2856  p = READ_CHAR_PENDING_PTR(fptr);
2857  if (0 < limit && limit < searchlen)
2858  searchlen = (int)limit;
2859  e = memchr(p, delim, searchlen);
2860  if (e) {
2861  int len = (int)(e-p+1);
2862  if (NIL_P(str))
2863  *strp = str = rb_str_new(p, len);
2864  else
2865  rb_str_buf_cat(str, p, len);
2866  fptr->cbuf.off += len;
2867  fptr->cbuf.len -= len;
2868  limit -= len;
2869  *lp = limit;
2870  return delim;
2871  }
2872 
2873  if (NIL_P(str))
2874  *strp = str = rb_str_new(p, searchlen);
2875  else
2876  rb_str_buf_cat(str, p, searchlen);
2877  fptr->cbuf.off += searchlen;
2878  fptr->cbuf.len -= searchlen;
2879  limit -= searchlen;
2880 
2881  if (limit == 0) {
2882  *lp = limit;
2883  return (unsigned char)RSTRING_PTR(str)[RSTRING_LEN(str)-1];
2884  }
2885  }
2886  } while (more_char(fptr) != MORE_CHAR_FINISHED);
2887  clear_readconv(fptr);
2888  *lp = limit;
2889  return EOF;
2890  }
2891 
2893  do {
2894  long pending = READ_DATA_PENDING_COUNT(fptr);
2895  if (pending > 0) {
2896  const char *p = READ_DATA_PENDING_PTR(fptr);
2897  const char *e;
2898  long last;
2899 
2900  if (limit > 0 && pending > limit) pending = limit;
2901  e = memchr(p, delim, pending);
2902  if (e) pending = e - p + 1;
2903  if (!NIL_P(str)) {
2904  last = RSTRING_LEN(str);
2905  rb_str_resize(str, last + pending);
2906  }
2907  else {
2908  last = 0;
2909  *strp = str = rb_str_buf_new(pending);
2910  rb_str_set_len(str, pending);
2911  }
2912  read_buffered_data(RSTRING_PTR(str) + last, pending, fptr); /* must not fail */
2913  limit -= pending;
2914  *lp = limit;
2915  if (e) return delim;
2916  if (limit == 0)
2917  return (unsigned char)RSTRING_PTR(str)[RSTRING_LEN(str)-1];
2918  }
2919  READ_CHECK(fptr);
2920  } while (io_fillbuf(fptr) >= 0);
2921  *lp = limit;
2922  return EOF;
2923 }
2924 
2925 static inline int
2926 swallow(rb_io_t *fptr, int term)
2927 {
2928  if (NEED_READCONV(fptr)) {
2929  rb_encoding *enc = io_read_encoding(fptr);
2930  int needconv = rb_enc_mbminlen(enc) != 1;
2931  SET_BINARY_MODE(fptr);
2932  make_readconv(fptr, 0);
2933  do {
2934  size_t cnt;
2935  while ((cnt = READ_CHAR_PENDING_COUNT(fptr)) > 0) {
2936  const char *p = READ_CHAR_PENDING_PTR(fptr);
2937  int i;
2938  if (!needconv) {
2939  if (*p != term) return TRUE;
2940  i = (int)cnt;
2941  while (--i && *++p == term);
2942  }
2943  else {
2944  const char *e = p + cnt;
2945  if (rb_enc_ascget(p, e, &i, enc) != term) return TRUE;
2946  while ((p += i) < e && rb_enc_ascget(p, e, &i, enc) == term);
2947  i = (int)(e - p);
2948  }
2949  io_shift_cbuf(fptr, (int)cnt - i, NULL);
2950  }
2951  } while (more_char(fptr) != MORE_CHAR_FINISHED);
2952  return FALSE;
2953  }
2954 
2956  do {
2957  size_t cnt;
2958  while ((cnt = READ_DATA_PENDING_COUNT(fptr)) > 0) {
2959  char buf[1024];
2960  const char *p = READ_DATA_PENDING_PTR(fptr);
2961  int i;
2962  if (cnt > sizeof buf) cnt = sizeof buf;
2963  if (*p != term) return TRUE;
2964  i = (int)cnt;
2965  while (--i && *++p == term);
2966  if (!read_buffered_data(buf, cnt - i, fptr)) /* must not fail */
2967  rb_sys_fail_path(fptr->pathv);
2968  }
2969  READ_CHECK(fptr);
2970  } while (io_fillbuf(fptr) == 0);
2971  return FALSE;
2972 }
2973 
2974 static VALUE
2976 {
2977  VALUE str = Qnil;
2978  int len = 0;
2979  long pos = 0;
2980  int cr = 0;
2981 
2982  do {
2983  int pending = READ_DATA_PENDING_COUNT(fptr);
2984 
2985  if (pending > 0) {
2986  const char *p = READ_DATA_PENDING_PTR(fptr);
2987  const char *e;
2988 
2989  e = memchr(p, '\n', pending);
2990  if (e) {
2991  pending = (int)(e - p + 1);
2992  }
2993  if (NIL_P(str)) {
2994  str = rb_str_new(p, pending);
2995  fptr->rbuf.off += pending;
2996  fptr->rbuf.len -= pending;
2997  }
2998  else {
2999  rb_str_resize(str, len + pending);
3000  read_buffered_data(RSTRING_PTR(str)+len, pending, fptr);
3001  }
3002  len += pending;
3003  if (cr != ENC_CODERANGE_BROKEN)
3004  pos += rb_str_coderange_scan_restartable(RSTRING_PTR(str) + pos, RSTRING_PTR(str) + len, enc, &cr);
3005  if (e) break;
3006  }
3007  READ_CHECK(fptr);
3008  } while (io_fillbuf(fptr) >= 0);
3009  if (NIL_P(str)) return Qnil;
3010 
3011  str = io_enc_str(str, fptr);
3012  ENC_CODERANGE_SET(str, cr);
3013  fptr->lineno++;
3014  if (io == ARGF.current_file) {
3015  ARGF.lineno++;
3016  ARGF.last_lineno = ARGF.lineno;
3017  }
3018  else {
3019  ARGF.last_lineno = fptr->lineno;
3020  }
3021 
3022  return str;
3023 }
3024 
3025 static void
3026 prepare_getline_args(int argc, VALUE *argv, VALUE *rsp, long *limit, VALUE io)
3027 {
3028  VALUE rs = rb_rs, lim = Qnil;
3029  rb_io_t *fptr;
3030 
3031  if (argc == 1) {
3032  VALUE tmp = Qnil;
3033 
3034  if (NIL_P(argv[0]) || !NIL_P(tmp = rb_check_string_type(argv[0]))) {
3035  rs = tmp;
3036  }
3037  else {
3038  lim = argv[0];
3039  }
3040  }
3041  else if (2 <= argc) {
3042  rb_scan_args(argc, argv, "2", &rs, &lim);
3043  if (!NIL_P(rs))
3044  StringValue(rs);
3045  }
3046  if (!NIL_P(rs)) {
3047  rb_encoding *enc_rs, *enc_io;
3048 
3049  GetOpenFile(io, fptr);
3050  enc_rs = rb_enc_get(rs);
3051  enc_io = io_read_encoding(fptr);
3052  if (enc_io != enc_rs &&
3054  (RSTRING_LEN(rs) > 0 && !rb_enc_asciicompat(enc_io)))) {
3055  if (rs == rb_default_rs) {
3056  rs = rb_enc_str_new(0, 0, enc_io);
3057  rb_str_buf_cat_ascii(rs, "\n");
3058  }
3059  else {
3060  rb_raise(rb_eArgError, "encoding mismatch: %s IO with %s RS",
3061  rb_enc_name(enc_io),
3062  rb_enc_name(enc_rs));
3063  }
3064  }
3065  }
3066  *rsp = rs;
3067  *limit = NIL_P(lim) ? -1L : NUM2LONG(lim);
3068 }
3069 
3070 static VALUE
3071 rb_io_getline_1(VALUE rs, long limit, VALUE io)
3072 {
3073  VALUE str = Qnil;
3074  rb_io_t *fptr;
3075  int nolimit = 0;
3076  rb_encoding *enc;
3077 
3078  GetOpenFile(io, fptr);
3080  if (NIL_P(rs) && limit < 0) {
3081  str = read_all(fptr, 0, Qnil);
3082  if (RSTRING_LEN(str) == 0) return Qnil;
3083  }
3084  else if (limit == 0) {
3085  return rb_enc_str_new(0, 0, io_read_encoding(fptr));
3086  }
3087  else if (rs == rb_default_rs && limit < 0 && !NEED_READCONV(fptr) &&
3088  rb_enc_asciicompat(enc = io_read_encoding(fptr))) {
3090  return rb_io_getline_fast(fptr, enc, io);
3091  }
3092  else {
3093  int c, newline = -1;
3094  const char *rsptr = 0;
3095  long rslen = 0;
3096  int rspara = 0;
3097  int extra_limit = 16;
3098 
3099  SET_BINARY_MODE(fptr);
3100  enc = io_read_encoding(fptr);
3101 
3102  if (!NIL_P(rs)) {
3103  rslen = RSTRING_LEN(rs);
3104  if (rslen == 0) {
3105  rsptr = "\n\n";
3106  rslen = 2;
3107  rspara = 1;
3108  swallow(fptr, '\n');
3109  rs = 0;
3110  if (!rb_enc_asciicompat(enc)) {
3111  rs = rb_usascii_str_new(rsptr, rslen);
3112  rs = rb_str_encode(rs, rb_enc_from_encoding(enc), 0, Qnil);
3113  OBJ_FREEZE(rs);
3114  rsptr = RSTRING_PTR(rs);
3115  rslen = RSTRING_LEN(rs);
3116  }
3117  }
3118  else {
3119  rsptr = RSTRING_PTR(rs);
3120  }
3121  newline = (unsigned char)rsptr[rslen - 1];
3122  }
3123 
3124  /* MS - Optimisation */
3125  while ((c = appendline(fptr, newline, &str, &limit)) != EOF) {
3126  const char *s, *p, *pp, *e;
3127 
3128  if (c == newline) {
3129  if (RSTRING_LEN(str) < rslen) continue;
3130  s = RSTRING_PTR(str);
3131  e = RSTRING_END(str);
3132  p = e - rslen;
3133  pp = rb_enc_left_char_head(s, p, e, enc);
3134  if (pp != p) continue;
3135  if (!rspara) rscheck(rsptr, rslen, rs);
3136  if (memcmp(p, rsptr, rslen) == 0) break;
3137  }
3138  if (limit == 0) {
3139  s = RSTRING_PTR(str);
3140  p = RSTRING_END(str);
3141  pp = rb_enc_left_char_head(s, p-1, p, enc);
3142  if (extra_limit &&
3144  /* relax the limit while incomplete character.
3145  * extra_limit limits the relax length */
3146  limit = 1;
3147  extra_limit--;
3148  }
3149  else {
3150  nolimit = 1;
3151  break;
3152  }
3153  }
3154  }
3155 
3156  if (rspara && c != EOF)
3157  swallow(fptr, '\n');
3158  if (!NIL_P(str))
3159  str = io_enc_str(str, fptr);
3160  }
3161 
3162  if (!NIL_P(str) && !nolimit) {
3163  fptr->lineno++;
3164  if (io == ARGF.current_file) {
3165  ARGF.lineno++;
3166  ARGF.last_lineno = ARGF.lineno;
3167  }
3168  else {
3169  ARGF.last_lineno = fptr->lineno;
3170  }
3171  }
3172 
3173  return str;
3174 }
3175 
3176 static VALUE
3178 {
3179  VALUE rs;
3180  long limit;
3181 
3182  prepare_getline_args(argc, argv, &rs, &limit, io);
3183  return rb_io_getline_1(rs, limit, io);
3184 }
3185 
3186 VALUE
3188 {
3189  return rb_io_getline_1(rb_default_rs, -1, io);
3190 }
3191 
3192 /*
3193  * call-seq:
3194  * ios.gets(sep=$/) -> string or nil
3195  * ios.gets(limit) -> string or nil
3196  * ios.gets(sep, limit) -> string or nil
3197  *
3198  * Reads the next ``line'' from the I/O stream; lines are separated by
3199  * <i>sep</i>. A separator of <code>nil</code> reads the entire
3200  * contents, and a zero-length separator reads the input a paragraph at
3201  * a time (two successive newlines in the input separate paragraphs).
3202  * The stream must be opened for reading or an <code>IOError</code>
3203  * will be raised. The line read in will be returned and also assigned
3204  * to <code>$_</code>. Returns <code>nil</code> if called at end of
3205  * file. If the first argument is an integer, or optional second
3206  * argument is given, the returning string would not be longer than the
3207  * given value in bytes.
3208  *
3209  * File.new("testfile").gets #=> "This is line one\n"
3210  * $_ #=> "This is line one\n"
3211  */
3212 
3213 static VALUE
3215 {
3216  VALUE str;
3217 
3218  str = rb_io_getline(argc, argv, io);
3219  rb_lastline_set(str);
3220 
3221  return str;
3222 }
3223 
3224 /*
3225  * call-seq:
3226  * ios.lineno -> integer
3227  *
3228  * Returns the current line number in <em>ios</em>. The stream must be
3229  * opened for reading. <code>lineno</code> counts the number of times
3230  * #gets is called rather than the number of newlines encountered. The two
3231  * values will differ if #gets is called with a separator other than newline.
3232  *
3233  * Methods that use <code>$/</code> like #each, #lines and #readline will
3234  * also increment <code>lineno</code>.
3235  *
3236  * See also the <code>$.</code> variable.
3237  *
3238  * f = File.new("testfile")
3239  * f.lineno #=> 0
3240  * f.gets #=> "This is line one\n"
3241  * f.lineno #=> 1
3242  * f.gets #=> "This is line two\n"
3243  * f.lineno #=> 2
3244  */
3245 
3246 static VALUE
3248 {
3249  rb_io_t *fptr;
3250 
3251  GetOpenFile(io, fptr);
3253  return INT2NUM(fptr->lineno);
3254 }
3255 
3256 /*
3257  * call-seq:
3258  * ios.lineno = integer -> integer
3259  *
3260  * Manually sets the current line number to the given value.
3261  * <code>$.</code> is updated only on the next read.
3262  *
3263  * f = File.new("testfile")
3264  * f.gets #=> "This is line one\n"
3265  * $. #=> 1
3266  * f.lineno = 1000
3267  * f.lineno #=> 1000
3268  * $. #=> 1 # lineno of last read
3269  * f.gets #=> "This is line two\n"
3270  * $. #=> 1001 # lineno of last read
3271  */
3272 
3273 static VALUE
3275 {
3276  rb_io_t *fptr;
3277 
3278  GetOpenFile(io, fptr);
3280  fptr->lineno = NUM2INT(lineno);
3281  return lineno;
3282 }
3283 
3284 /*
3285  * call-seq:
3286  * ios.readline(sep=$/) -> string
3287  * ios.readline(limit) -> string
3288  * ios.readline(sep, limit) -> string
3289  *
3290  * Reads a line as with <code>IO#gets</code>, but raises an
3291  * <code>EOFError</code> on end of file.
3292  */
3293 
3294 static VALUE
3296 {
3297  VALUE line = rb_io_gets_m(argc, argv, io);
3298 
3299  if (NIL_P(line)) {
3300  rb_eof_error();
3301  }
3302  return line;
3303 }
3304 
3305 /*
3306  * call-seq:
3307  * ios.readlines(sep=$/) -> array
3308  * ios.readlines(limit) -> array
3309  * ios.readlines(sep, limit) -> array
3310  *
3311  * Reads all of the lines in <em>ios</em>, and returns them in
3312  * <i>anArray</i>. Lines are separated by the optional <i>sep</i>. If
3313  * <i>sep</i> is <code>nil</code>, the rest of the stream is returned
3314  * as a single record. If the first argument is an integer, or
3315  * optional second argument is given, the returning string would not be
3316  * longer than the given value in bytes. The stream must be opened for
3317  * reading or an <code>IOError</code> will be raised.
3318  *
3319  * f = File.new("testfile")
3320  * f.readlines[0] #=> "This is line one\n"
3321  */
3322 
3323 static VALUE
3325 {
3326  VALUE line, ary, rs;
3327  long limit;
3328 
3329  prepare_getline_args(argc, argv, &rs, &limit, io);
3330  if (limit == 0)
3331  rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
3332  ary = rb_ary_new();
3333  while (!NIL_P(line = rb_io_getline_1(rs, limit, io))) {
3334  rb_ary_push(ary, line);
3335  }
3336  return ary;
3337 }
3338 
3339 /*
3340  * call-seq:
3341  * ios.each(sep=$/) {|line| block } -> ios
3342  * ios.each(limit) {|line| block } -> ios
3343  * ios.each(sep,limit) {|line| block } -> ios
3344  * ios.each(...) -> an_enumerator
3345  *
3346  * ios.each_line(sep=$/) {|line| block } -> ios
3347  * ios.each_line(limit) {|line| block } -> ios
3348  * ios.each_line(sep,limit) {|line| block } -> ios
3349  * ios.each_line(...) -> an_enumerator
3350  *
3351  * Executes the block for every line in <em>ios</em>, where lines are
3352  * separated by <i>sep</i>. <em>ios</em> must be opened for
3353  * reading or an <code>IOError</code> will be raised.
3354  *
3355  * If no block is given, an enumerator is returned instead.
3356  *
3357  * f = File.new("testfile")
3358  * f.each {|line| puts "#{f.lineno}: #{line}" }
3359  *
3360  * <em>produces:</em>
3361  *
3362  * 1: This is line one
3363  * 2: This is line two
3364  * 3: This is line three
3365  * 4: And so on...
3366  */
3367 
3368 static VALUE
3370 {
3371  VALUE str, rs;
3372  long limit;
3373 
3374  RETURN_ENUMERATOR(io, argc, argv);
3375  prepare_getline_args(argc, argv, &rs, &limit, io);
3376  if (limit == 0)
3377  rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
3378  while (!NIL_P(str = rb_io_getline_1(rs, limit, io))) {
3379  rb_yield(str);
3380  }
3381  return io;
3382 }
3383 
3384 /*
3385  * This is a deprecated alias for <code>each_line</code>.
3386  */
3387 
3388 static VALUE
3390 {
3391  rb_warn("IO#lines is deprecated; use #each_line instead");
3392  if (!rb_block_given_p())
3393  return rb_enumeratorize(io, ID2SYM(rb_intern("each_line")), argc, argv);
3394  return rb_io_each_line(argc, argv, io);
3395 }
3396 
3397 /*
3398  * call-seq:
3399  * ios.each_byte {|byte| block } -> ios
3400  * ios.each_byte -> an_enumerator
3401  *
3402  * Calls the given block once for each byte (0..255) in <em>ios</em>,
3403  * passing the byte as an argument. The stream must be opened for
3404  * reading or an <code>IOError</code> will be raised.
3405  *
3406  * If no block is given, an enumerator is returned instead.
3407  *
3408  * f = File.new("testfile")
3409  * checksum = 0
3410  * f.each_byte {|x| checksum ^= x } #=> #<File:testfile>
3411  * checksum #=> 12
3412  */
3413 
3414 static VALUE
3416 {
3417  rb_io_t *fptr;
3418 
3419  RETURN_ENUMERATOR(io, 0, 0);
3420  GetOpenFile(io, fptr);
3421 
3422  do {
3423  while (fptr->rbuf.len > 0) {
3424  char *p = fptr->rbuf.ptr + fptr->rbuf.off++;
3425  fptr->rbuf.len--;
3426  rb_yield(INT2FIX(*p & 0xff));
3427  errno = 0;
3428  }
3430  READ_CHECK(fptr);
3431  } while (io_fillbuf(fptr) >= 0);
3432  return io;
3433 }
3434 
3435 /*
3436  * This is a deprecated alias for <code>each_byte</code>.
3437  */
3438 
3439 static VALUE
3441 {
3442  rb_warn("IO#bytes is deprecated; use #each_byte instead");
3443  if (!rb_block_given_p())
3444  return rb_enumeratorize(io, ID2SYM(rb_intern("each_byte")), 0, 0);
3445  return rb_io_each_byte(io);
3446 }
3447 
3448 static VALUE
3450 {
3451  int r, n, cr = 0;
3452  VALUE str;
3453 
3454  if (NEED_READCONV(fptr)) {
3455  VALUE str = Qnil;
3456  rb_encoding *read_enc = io_read_encoding(fptr);
3457 
3458  SET_BINARY_MODE(fptr);
3459  make_readconv(fptr, 0);
3460 
3461  while (1) {
3462  if (fptr->cbuf.len) {
3463  r = rb_enc_precise_mbclen(fptr->cbuf.ptr+fptr->cbuf.off,
3464  fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
3465  read_enc);
3466  if (!MBCLEN_NEEDMORE_P(r))
3467  break;
3468  if (fptr->cbuf.len == fptr->cbuf.capa) {
3469  rb_raise(rb_eIOError, "too long character");
3470  }
3471  }
3472 
3473  if (more_char(fptr) == MORE_CHAR_FINISHED) {
3474  if (fptr->cbuf.len == 0) {
3475  clear_readconv(fptr);
3476  return Qnil;
3477  }
3478  /* return an unit of an incomplete character just before EOF */
3479  str = rb_enc_str_new(fptr->cbuf.ptr+fptr->cbuf.off, 1, read_enc);
3480  fptr->cbuf.off += 1;
3481  fptr->cbuf.len -= 1;
3482  if (fptr->cbuf.len == 0) clear_readconv(fptr);
3484  return str;
3485  }
3486  }
3487  if (MBCLEN_INVALID_P(r)) {
3488  r = rb_enc_mbclen(fptr->cbuf.ptr+fptr->cbuf.off,
3489  fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
3490  read_enc);
3491  io_shift_cbuf(fptr, r, &str);
3492  cr = ENC_CODERANGE_BROKEN;
3493  }
3494  else {
3495  io_shift_cbuf(fptr, MBCLEN_CHARFOUND_LEN(r), &str);
3496  cr = ENC_CODERANGE_VALID;
3497  if (MBCLEN_CHARFOUND_LEN(r) == 1 && rb_enc_asciicompat(read_enc) &&
3498  ISASCII(RSTRING_PTR(str)[0])) {
3499  cr = ENC_CODERANGE_7BIT;
3500  }
3501  }
3502  str = io_enc_str(str, fptr);
3503  ENC_CODERANGE_SET(str, cr);
3504  return str;
3505  }
3506 
3508  if (io_fillbuf(fptr) < 0) {
3509  return Qnil;
3510  }
3511  if (rb_enc_asciicompat(enc) && ISASCII(fptr->rbuf.ptr[fptr->rbuf.off])) {
3512  str = rb_str_new(fptr->rbuf.ptr+fptr->rbuf.off, 1);
3513  fptr->rbuf.off += 1;
3514  fptr->rbuf.len -= 1;
3515  cr = ENC_CODERANGE_7BIT;
3516  }
3517  else {
3518  r = rb_enc_precise_mbclen(fptr->rbuf.ptr+fptr->rbuf.off, fptr->rbuf.ptr+fptr->rbuf.off+fptr->rbuf.len, enc);
3519  if (MBCLEN_CHARFOUND_P(r) &&
3520  (n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf.len) {
3521  str = rb_str_new(fptr->rbuf.ptr+fptr->rbuf.off, n);
3522  fptr->rbuf.off += n;
3523  fptr->rbuf.len -= n;
3524  cr = ENC_CODERANGE_VALID;
3525  }
3526  else if (MBCLEN_NEEDMORE_P(r)) {
3527  str = rb_str_new(fptr->rbuf.ptr+fptr->rbuf.off, fptr->rbuf.len);
3528  fptr->rbuf.len = 0;
3529  getc_needmore:
3530  if (io_fillbuf(fptr) != -1) {
3531  rb_str_cat(str, fptr->rbuf.ptr+fptr->rbuf.off, 1);
3532  fptr->rbuf.off++;
3533  fptr->rbuf.len--;
3534  r = rb_enc_precise_mbclen(RSTRING_PTR(str), RSTRING_PTR(str)+RSTRING_LEN(str), enc);
3535  if (MBCLEN_NEEDMORE_P(r)) {
3536  goto getc_needmore;
3537  }
3538  else if (MBCLEN_CHARFOUND_P(r)) {
3539  cr = ENC_CODERANGE_VALID;
3540  }
3541  }
3542  }
3543  else {
3544  str = rb_str_new(fptr->rbuf.ptr+fptr->rbuf.off, 1);
3545  fptr->rbuf.off++;
3546  fptr->rbuf.len--;
3547  }
3548  }
3549  if (!cr) cr = ENC_CODERANGE_BROKEN;
3550  str = io_enc_str(str, fptr);
3551  ENC_CODERANGE_SET(str, cr);
3552  return str;
3553 }
3554 
3555 /*
3556  * call-seq:
3557  * ios.each_char {|c| block } -> ios
3558  * ios.each_char -> an_enumerator
3559  *
3560  * Calls the given block once for each character in <em>ios</em>,
3561  * passing the character as an argument. The stream must be opened for
3562  * reading or an <code>IOError</code> will be raised.
3563  *
3564  * If no block is given, an enumerator is returned instead.
3565  *
3566  * f = File.new("testfile")
3567  * f.each_char {|c| print c, ' ' } #=> #<File:testfile>
3568  */
3569 
3570 static VALUE
3572 {
3573  rb_io_t *fptr;
3574  rb_encoding *enc;
3575  VALUE c;
3576 
3577  RETURN_ENUMERATOR(io, 0, 0);
3578  GetOpenFile(io, fptr);
3580 
3581  enc = io_input_encoding(fptr);
3582  READ_CHECK(fptr);
3583  while (!NIL_P(c = io_getc(fptr, enc))) {
3584  rb_yield(c);
3585  }
3586  return io;
3587 }
3588 
3589 /*
3590  * This is a deprecated alias for <code>each_char</code>.
3591  */
3592 
3593 static VALUE
3595 {
3596  rb_warn("IO#chars is deprecated; use #each_char instead");
3597  if (!rb_block_given_p())
3598  return rb_enumeratorize(io, ID2SYM(rb_intern("each_char")), 0, 0);
3599  return rb_io_each_char(io);
3600 }
3601 
3602 
3603 /*
3604  * call-seq:
3605  * ios.each_codepoint {|c| block } -> ios
3606  * ios.codepoints {|c| block } -> ios
3607  * ios.each_codepoint -> an_enumerator
3608  * ios.codepoints -> an_enumerator
3609  *
3610  * Passes the <code>Integer</code> ordinal of each character in <i>ios</i>,
3611  * passing the codepoint as an argument. The stream must be opened for
3612  * reading or an <code>IOError</code> will be raised.
3613  *
3614  * If no block is given, an enumerator is returned instead.
3615  *
3616  */
3617 
3618 static VALUE
3620 {
3621  rb_io_t *fptr;
3622  rb_encoding *enc;
3623  unsigned int c;
3624  int r, n;
3625 
3626  RETURN_ENUMERATOR(io, 0, 0);
3627  GetOpenFile(io, fptr);
3629 
3630  READ_CHECK(fptr);
3631  if (NEED_READCONV(fptr)) {
3632  SET_BINARY_MODE(fptr);
3633  for (;;) {
3634  make_readconv(fptr, 0);
3635  for (;;) {
3636  if (fptr->cbuf.len) {
3637  if (fptr->encs.enc)
3638  r = rb_enc_precise_mbclen(fptr->cbuf.ptr+fptr->cbuf.off,
3639  fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
3640  fptr->encs.enc);
3641  else
3643  if (!MBCLEN_NEEDMORE_P(r))
3644  break;
3645  if (fptr->cbuf.len == fptr->cbuf.capa) {
3646  rb_raise(rb_eIOError, "too long character");
3647  }
3648  }
3649  if (more_char(fptr) == MORE_CHAR_FINISHED) {
3650  clear_readconv(fptr);
3651  /* ignore an incomplete character before EOF */
3652  return io;
3653  }
3654  }
3655  if (MBCLEN_INVALID_P(r)) {
3656  rb_raise(rb_eArgError, "invalid byte sequence in %s",
3657  rb_enc_name(fptr->encs.enc));
3658  }
3659  n = MBCLEN_CHARFOUND_LEN(r);
3660  if (fptr->encs.enc) {
3661  c = rb_enc_codepoint(fptr->cbuf.ptr+fptr->cbuf.off,
3662  fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
3663  fptr->encs.enc);
3664  }
3665  else {
3666  c = (unsigned char)fptr->cbuf.ptr[fptr->cbuf.off];
3667  }
3668  fptr->cbuf.off += n;
3669  fptr->cbuf.len -= n;
3670  rb_yield(UINT2NUM(c));
3671  }
3672  }
3674  enc = io_input_encoding(fptr);
3675  while (io_fillbuf(fptr) >= 0) {
3676  r = rb_enc_precise_mbclen(fptr->rbuf.ptr+fptr->rbuf.off,
3677  fptr->rbuf.ptr+fptr->rbuf.off+fptr->rbuf.len, enc);
3678  if (MBCLEN_CHARFOUND_P(r) &&
3679  (n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf.len) {
3680  c = rb_enc_codepoint(fptr->rbuf.ptr+fptr->rbuf.off,
3681  fptr->rbuf.ptr+fptr->rbuf.off+fptr->rbuf.len, enc);
3682  fptr->rbuf.off += n;
3683  fptr->rbuf.len -= n;
3684  rb_yield(UINT2NUM(c));
3685  }
3686  else if (MBCLEN_INVALID_P(r)) {
3687  rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc));
3688  }
3689  else {
3690  continue;
3691  }
3692  }
3693  return io;
3694 }
3695 
3696 /*
3697  * This is a deprecated alias for <code>each_codepoint</code>.
3698  */
3699 
3700 static VALUE
3702 {
3703  rb_warn("IO#codepoints is deprecated; use #each_codepoint instead");
3704  if (!rb_block_given_p())
3705  return rb_enumeratorize(io, ID2SYM(rb_intern("each_codepoint")), 0, 0);
3706  return rb_io_each_codepoint(io);
3707 }
3708 
3709 
3710 /*
3711  * call-seq:
3712  * ios.getc -> string or nil
3713  *
3714  * Reads a one-character string from <em>ios</em>. Returns
3715  * <code>nil</code> if called at end of file.
3716  *
3717  * f = File.new("testfile")
3718  * f.getc #=> "h"
3719  * f.getc #=> "e"
3720  */
3721 
3722 static VALUE
3724 {
3725  rb_io_t *fptr;
3726  rb_encoding *enc;
3727 
3728  GetOpenFile(io, fptr);
3730 
3731  enc = io_input_encoding(fptr);
3732  READ_CHECK(fptr);
3733  return io_getc(fptr, enc);
3734 }
3735 
3736 /*
3737  * call-seq:
3738  * ios.readchar -> string
3739  *
3740  * Reads a one-character string from <em>ios</em>. Raises an
3741  * <code>EOFError</code> on end of file.
3742  *
3743  * f = File.new("testfile")
3744  * f.readchar #=> "h"
3745  * f.readchar #=> "e"
3746  */
3747 
3748 static VALUE
3750 {
3751  VALUE c = rb_io_getc(io);
3752 
3753  if (NIL_P(c)) {
3754  rb_eof_error();
3755  }
3756  return c;
3757 }
3758 
3759 /*
3760  * call-seq:
3761  * ios.getbyte -> fixnum or nil
3762  *
3763  * Gets the next 8-bit byte (0..255) from <em>ios</em>. Returns
3764  * <code>nil</code> if called at end of file.
3765  *
3766  * f = File.new("testfile")
3767  * f.getbyte #=> 84
3768  * f.getbyte #=> 104
3769  */
3770 
3771 VALUE
3773 {
3774  rb_io_t *fptr;
3775  int c;
3776 
3777  GetOpenFile(io, fptr);
3779  READ_CHECK(fptr);
3780  if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && RB_TYPE_P(rb_stdout, T_FILE)) {
3781  rb_io_t *ofp;
3782  GetOpenFile(rb_stdout, ofp);
3783  if (ofp->mode & FMODE_TTY) {
3785  }
3786  }
3787  if (io_fillbuf(fptr) < 0) {
3788  return Qnil;
3789  }
3790  fptr->rbuf.off++;
3791  fptr->rbuf.len--;
3792  c = (unsigned char)fptr->rbuf.ptr[fptr->rbuf.off-1];
3793  return INT2FIX(c & 0xff);
3794 }
3795 
3796 /*
3797  * call-seq:
3798  * ios.readbyte -> fixnum
3799  *
3800  * Reads a byte as with <code>IO#getbyte</code>, but raises an
3801  * <code>EOFError</code> on end of file.
3802  */
3803 
3804 static VALUE
3806 {
3807  VALUE c = rb_io_getbyte(io);
3808 
3809  if (NIL_P(c)) {
3810  rb_eof_error();
3811  }
3812  return c;
3813 }
3814 
3815 /*
3816  * call-seq:
3817  * ios.ungetbyte(string) -> nil
3818  * ios.ungetbyte(integer) -> nil
3819  *
3820  * Pushes back bytes (passed as a parameter) onto <em>ios</em>,
3821  * such that a subsequent buffered read will return it. Only one byte
3822  * may be pushed back before a subsequent read operation (that is,
3823  * you will be able to read only the last of several bytes that have been pushed
3824  * back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).
3825  *
3826  * f = File.new("testfile") #=> #<File:testfile>
3827  * b = f.getbyte #=> 0x38
3828  * f.ungetbyte(b) #=> nil
3829  * f.getbyte #=> 0x38
3830  */
3831 
3832 VALUE
3834 {
3835  rb_io_t *fptr;
3836 
3837  GetOpenFile(io, fptr);
3839  if (NIL_P(b)) return Qnil;
3840  if (FIXNUM_P(b)) {
3841  char cc = FIX2INT(b);
3842  b = rb_str_new(&cc, 1);
3843  }
3844  else {
3845  SafeStringValue(b);
3846  }
3847  io_ungetbyte(b, fptr);
3848  return Qnil;
3849 }
3850 
3851 /*
3852  * call-seq:
3853  * ios.ungetc(string) -> nil
3854  *
3855  * Pushes back one character (passed as a parameter) onto <em>ios</em>,
3856  * such that a subsequent buffered character read will return it. Only one character
3857  * may be pushed back before a subsequent read operation (that is,
3858  * you will be able to read only the last of several characters that have been pushed
3859  * back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).
3860  *
3861  * f = File.new("testfile") #=> #<File:testfile>
3862  * c = f.getc #=> "8"
3863  * f.ungetc(c) #=> nil
3864  * f.getc #=> "8"
3865  */
3866 
3867 VALUE
3869 {
3870  rb_io_t *fptr;
3871  long len;
3872 
3873  GetOpenFile(io, fptr);
3875  if (NIL_P(c)) return Qnil;
3876  if (FIXNUM_P(c)) {
3877  c = rb_enc_uint_chr(FIX2UINT(c), io_read_encoding(fptr));
3878  }
3879  else if (RB_TYPE_P(c, T_BIGNUM)) {
3880  c = rb_enc_uint_chr(NUM2UINT(c), io_read_encoding(fptr));
3881  }
3882  else {
3883  SafeStringValue(c);
3884  }
3885  if (NEED_READCONV(fptr)) {
3886  SET_BINARY_MODE(fptr);
3887  len = RSTRING_LEN(c);
3888 #if SIZEOF_LONG > SIZEOF_INT
3889  if (len > INT_MAX)
3890  rb_raise(rb_eIOError, "ungetc failed");
3891 #endif
3892  make_readconv(fptr, (int)len);
3893  if (fptr->cbuf.capa - fptr->cbuf.len < len)
3894  rb_raise(rb_eIOError, "ungetc failed");
3895  if (fptr->cbuf.off < len) {
3896  MEMMOVE(fptr->cbuf.ptr+fptr->cbuf.capa-fptr->cbuf.len,
3897  fptr->cbuf.ptr+fptr->cbuf.off,
3898  char, fptr->cbuf.len);
3899  fptr->cbuf.off = fptr->cbuf.capa-fptr->cbuf.len;
3900  }
3901  fptr->cbuf.off -= (int)len;
3902  fptr->cbuf.len += (int)len;
3903  MEMMOVE(fptr->cbuf.ptr+fptr->cbuf.off, RSTRING_PTR(c), char, len);
3904  }
3905  else {
3907  io_ungetbyte(c, fptr);
3908  }
3909  return Qnil;
3910 }
3911 
3912 /*
3913  * call-seq:
3914  * ios.isatty -> true or false
3915  * ios.tty? -> true or false
3916  *
3917  * Returns <code>true</code> if <em>ios</em> is associated with a
3918  * terminal device (tty), <code>false</code> otherwise.
3919  *
3920  * File.new("testfile").isatty #=> false
3921  * File.new("/dev/tty").isatty #=> true
3922  */
3923 
3924 static VALUE
3926 {
3927  rb_io_t *fptr;
3928 
3929  GetOpenFile(io, fptr);
3930  if (isatty(fptr->fd) == 0)
3931  return Qfalse;
3932  return Qtrue;
3933 }
3934 
3935 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
3936 /*
3937  * call-seq:
3938  * ios.close_on_exec? -> true or false
3939  *
3940  * Returns <code>true</code> if <em>ios</em> will be closed on exec.
3941  *
3942  * f = open("/dev/null")
3943  * f.close_on_exec? #=> false
3944  * f.close_on_exec = true
3945  * f.close_on_exec? #=> true
3946  * f.close_on_exec = false
3947  * f.close_on_exec? #=> false
3948  */
3949 
3950 static VALUE
3952 {
3953  rb_io_t *fptr;
3954  VALUE write_io;
3955  int fd, ret;
3956 
3957  write_io = GetWriteIO(io);
3958  if (io != write_io) {
3959  GetOpenFile(write_io, fptr);
3960  if (fptr && 0 <= (fd = fptr->fd)) {
3961  if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
3962  if (!(ret & FD_CLOEXEC)) return Qfalse;
3963  }
3964  }
3965 
3966  GetOpenFile(io, fptr);
3967  if (fptr && 0 <= (fd = fptr->fd)) {
3968  if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
3969  if (!(ret & FD_CLOEXEC)) return Qfalse;
3970  }
3971  return Qtrue;
3972 }
3973 #else
3974 #define rb_io_close_on_exec_p rb_f_notimplement
3975 #endif
3976 
3977 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
3978 /*
3979  * call-seq:
3980  * ios.close_on_exec = bool -> true or false
3981  *
3982  * Sets a close-on-exec flag.
3983  *
3984  * f = open("/dev/null")
3985  * f.close_on_exec = true
3986  * system("cat", "/proc/self/fd/#{f.fileno}") # cat: /proc/self/fd/3: No such file or directory
3987  * f.closed? #=> false
3988  *
3989  * Ruby sets close-on-exec flags of all file descriptors by default
3990  * since Ruby 2.0.0.
3991  * So you don't need to set by yourself.
3992  * Also, unsetting a close-on-exec flag can cause file descriptor leak
3993  * if another thread use fork() and exec() (via system() method for example).
3994  * If you really needs file descriptor inheritance to child process,
3995  * use spawn()'s argument such as fd=>fd.
3996  */
3997 
3998 static VALUE
4000 {
4001  int flag = RTEST(arg) ? FD_CLOEXEC : 0;
4002  rb_io_t *fptr;
4003  VALUE write_io;
4004  int fd, ret;
4005 
4006  write_io = GetWriteIO(io);
4007  if (io != write_io) {
4008  GetOpenFile(write_io, fptr);
4009  if (fptr && 0 <= (fd = fptr->fd)) {
4010  if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
4011  if ((ret & FD_CLOEXEC) != flag) {
4012  ret = (ret & ~FD_CLOEXEC) | flag;
4013  ret = fcntl(fd, F_SETFD, ret);
4014  if (ret == -1) rb_sys_fail_path(fptr->pathv);
4015  }
4016  }
4017 
4018  }
4019 
4020  GetOpenFile(io, fptr);
4021  if (fptr && 0 <= (fd = fptr->fd)) {
4022  if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
4023  if ((ret & FD_CLOEXEC) != flag) {
4024  ret = (ret & ~FD_CLOEXEC) | flag;
4025  ret = fcntl(fd, F_SETFD, ret);
4026  if (ret == -1) rb_sys_fail_path(fptr->pathv);
4027  }
4028  }
4029  return Qnil;
4030 }
4031 #else
4032 #define rb_io_set_close_on_exec rb_f_notimplement
4033 #endif
4034 
4035 #define FMODE_PREP (1<<16)
4036 #define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
4037 #define PREP_STDIO_NAME(f) (RSTRING_PTR((f)->pathv))
4038 
4039 static VALUE
4040 finish_writeconv(rb_io_t *fptr, int noalloc)
4041 {
4042  unsigned char *ds, *dp, *de;
4043  rb_econv_result_t res;
4044 
4045  if (!fptr->wbuf.ptr) {
4046  unsigned char buf[1024];
4047  long r;
4048 
4050  while (res == econv_destination_buffer_full) {
4051  ds = dp = buf;
4052  de = buf + sizeof(buf);
4053  res = rb_econv_convert(fptr->writeconv, NULL, NULL, &dp, de, 0);
4054  while (dp-ds) {
4055  retry:
4056  if (fptr->write_lock && rb_mutex_owned_p(fptr->write_lock))
4057  r = rb_write_internal2(fptr->fd, ds, dp-ds);
4058  else
4059  r = rb_write_internal(fptr->fd, ds, dp-ds);
4060  if (r == dp-ds)
4061  break;
4062  if (0 <= r) {
4063  ds += r;
4064  }
4065  if (rb_io_wait_writable(fptr->fd)) {
4066  if (fptr->fd < 0)
4067  return noalloc ? Qtrue : rb_exc_new3(rb_eIOError, rb_str_new_cstr(closed_stream));
4068  goto retry;
4069  }
4070  return noalloc ? Qtrue : INT2NUM(errno);
4071  }
4072  if (res == econv_invalid_byte_sequence ||
4073  res == econv_incomplete_input ||
4074  res == econv_undefined_conversion) {
4075  return noalloc ? Qtrue : rb_econv_make_exception(fptr->writeconv);
4076  }
4077  }
4078 
4079  return Qnil;
4080  }
4081 
4083  while (res == econv_destination_buffer_full) {
4084  if (fptr->wbuf.len == fptr->wbuf.capa) {
4085  if (io_fflush(fptr) < 0)
4086  return noalloc ? Qtrue : INT2NUM(errno);
4087  }
4088 
4089  ds = dp = (unsigned char *)fptr->wbuf.ptr + fptr->wbuf.off + fptr->wbuf.len;
4090  de = (unsigned char *)fptr->wbuf.ptr + fptr->wbuf.capa;
4091  res = rb_econv_convert(fptr->writeconv, NULL, NULL, &dp, de, 0);
4092  fptr->wbuf.len += (int)(dp - ds);
4093  if (res == econv_invalid_byte_sequence ||
4094  res == econv_incomplete_input ||
4095  res == econv_undefined_conversion) {
4096  return noalloc ? Qtrue : rb_econv_make_exception(fptr->writeconv);
4097  }
4098  }
4099  return Qnil;
4100 }
4101 
4104  int noalloc;
4105 };
4106 
4107 static VALUE
4109 {
4110  struct finish_writeconv_arg *p = (struct finish_writeconv_arg *)arg;
4111  return finish_writeconv(p->fptr, p->noalloc);
4112 }
4113 
4114 static void*
4115 nogvl_close(void *ptr)
4116 {
4117  int *fd = ptr;
4118 
4119  return (void*)(intptr_t)close(*fd);
4120 }
4121 
4122 static int
4123 maygvl_close(int fd, int keepgvl)
4124 {
4125  if (keepgvl)
4126  return close(fd);
4127 
4128  /*
4129  * close() may block for certain file types (NFS, SO_LINGER sockets,
4130  * inotify), so let other threads run.
4131  */
4133 }
4134 
4135 static void*
4136 nogvl_fclose(void *ptr)
4137 {
4138  FILE *file = ptr;
4139 
4140  return (void*)(intptr_t)fclose(file);
4141 }
4142 
4143 static int
4144 maygvl_fclose(FILE *file, int keepgvl)
4145 {
4146  if (keepgvl)
4147  return fclose(file);
4148 
4150 }
4151 
4152 static void
4153 fptr_finalize(rb_io_t *fptr, int noraise)
4154 {
4155  VALUE err = Qnil;
4156  int fd = fptr->fd;
4157  FILE *stdio_file = fptr->stdio_file;
4158 
4159  if (fptr->writeconv) {
4160  if (fptr->write_lock && !noraise) {
4161  struct finish_writeconv_arg arg;
4162  arg.fptr = fptr;
4163  arg.noalloc = noraise;
4165  }
4166  else {
4167  err = finish_writeconv(fptr, noraise);
4168  }
4169  }
4170  if (fptr->wbuf.len) {
4171  if (noraise) {
4172  if ((int)io_flush_buffer_sync(fptr) < 0 && NIL_P(err))
4173  err = Qtrue;
4174  }
4175  else {
4176  if (io_fflush(fptr) < 0 && NIL_P(err))
4177  err = INT2NUM(errno);
4178  }
4179  }
4180 
4181  fptr->fd = -1;
4182  fptr->stdio_file = 0;
4183  fptr->mode &= ~(FMODE_READABLE|FMODE_WRITABLE);
4184 
4185  if (IS_PREP_STDIO(fptr) || fd <= 2) {
4186  /* need to keep FILE objects of stdin, stdout and stderr */
4187  }
4188  else if (stdio_file) {
4189  /* stdio_file is deallocated anyway
4190  * even if fclose failed. */
4191  if ((maygvl_fclose(stdio_file, noraise) < 0) && NIL_P(err))
4192  err = noraise ? Qtrue : INT2NUM(errno);
4193  }
4194  else if (0 <= fd) {
4195  /* fptr->fd may be closed even if close fails.
4196  * POSIX doesn't specify it.
4197  * We assumes it is closed. */
4198  if ((maygvl_close(fd, noraise) < 0) && NIL_P(err))
4199  err = noraise ? Qtrue : INT2NUM(errno);
4200  }
4201 
4202  if (!NIL_P(err) && !noraise) {
4203  switch (TYPE(err)) {
4204  case T_FIXNUM:
4205  case T_BIGNUM:
4206  errno = NUM2INT(err);
4207  rb_sys_fail_path(fptr->pathv);
4208 
4209  default:
4210  rb_exc_raise(err);
4211  }
4212  }
4213 }
4214 
4215 static void
4216 rb_io_fptr_cleanup(rb_io_t *fptr, int noraise)
4217 {
4218  if (fptr->finalize) {
4219  (*fptr->finalize)(fptr, noraise);
4220  }
4221  else {
4222  fptr_finalize(fptr, noraise);
4223  }
4224 }
4225 
4226 static void
4228 {
4229  if (fptr->readconv) {
4230  rb_econv_close(fptr->readconv);
4231  fptr->readconv = NULL;
4232  }
4233  if (fptr->cbuf.ptr) {
4234  free(fptr->cbuf.ptr);
4235  fptr->cbuf.ptr = NULL;
4236  }
4237 }
4238 
4239 static void
4241 {
4242  if (fptr->writeconv) {
4243  rb_econv_close(fptr->writeconv);
4244  fptr->writeconv = NULL;
4245  }
4246  fptr->writeconv_initialized = 0;
4247 }
4248 
4249 static void
4251 {
4252  clear_readconv(fptr);
4253  clear_writeconv(fptr);
4254 }
4255 
4256 int
4258 {
4259  if (!fptr) return 0;
4260  fptr->pathv = Qnil;
4261  if (0 <= fptr->fd)
4262  rb_io_fptr_cleanup(fptr, TRUE);
4263  fptr->write_lock = 0;
4264  if (fptr->rbuf.ptr) {
4265  free(fptr->rbuf.ptr);
4266  fptr->rbuf.ptr = 0;
4267  }
4268  if (fptr->wbuf.ptr) {
4269  free(fptr->wbuf.ptr);
4270  fptr->wbuf.ptr = 0;
4271  }
4272  clear_codeconv(fptr);
4273  free(fptr);
4274  return 1;
4275 }
4276 
4277 size_t rb_econv_memsize(rb_econv_t *);
4278 
4279 RUBY_FUNC_EXPORTED size_t
4281 {
4282  size_t size = sizeof(rb_io_t);
4283  size += fptr->rbuf.capa;
4284  size += fptr->wbuf.capa;
4285  size += fptr->cbuf.capa;
4286  if (fptr->readconv) size += rb_econv_memsize(fptr->readconv);
4287  if (fptr->writeconv) size += rb_econv_memsize(fptr->writeconv);
4288  return size;
4289 }
4290 
4291 VALUE
4293 {
4294  rb_io_t *fptr;
4295  int fd;
4296  VALUE write_io;
4297  rb_io_t *write_fptr;
4298 
4299  write_io = GetWriteIO(io);
4300  if (io != write_io) {
4301  write_fptr = RFILE(write_io)->fptr;
4302  if (write_fptr && 0 <= write_fptr->fd) {
4303  rb_io_fptr_cleanup(write_fptr, TRUE);
4304  }
4305  }
4306 
4307  fptr = RFILE(io)->fptr;
4308  if (!fptr) return Qnil;
4309  if (fptr->fd < 0) return Qnil;
4310 
4311  fd = fptr->fd;
4312  rb_thread_fd_close(fd);
4313  rb_io_fptr_cleanup(fptr, FALSE);
4314 
4315  if (fptr->pid) {
4317  rb_syswait(fptr->pid);
4318  fptr->pid = 0;
4319  }
4320 
4321  return Qnil;
4322 }
4323 
4324 /*
4325  * call-seq:
4326  * ios.close -> nil
4327  *
4328  * Closes <em>ios</em> and flushes any pending writes to the operating
4329  * system. The stream is unavailable for any further data operations;
4330  * an <code>IOError</code> is raised if such an attempt is made. I/O
4331  * streams are automatically closed when they are claimed by the
4332  * garbage collector.
4333  *
4334  * If <em>ios</em> is opened by <code>IO.popen</code>,
4335  * <code>close</code> sets <code>$?</code>.
4336  */
4337 
4338 static VALUE
4340 {
4341  rb_io_check_closed(RFILE(io)->fptr);
4342  rb_io_close(io);
4343  return Qnil;
4344 }
4345 
4346 static VALUE
4348 {
4349  rb_check_funcall(io, rb_intern("close"), 0, 0);
4350  return io;
4351 }
4352 
4353 static VALUE
4355 {
4356  enum {mesg_len = sizeof(closed_stream)-1};
4357  VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
4358  if (!RB_TYPE_P(mesg, T_STRING) ||
4359  RSTRING_LEN(mesg) != mesg_len ||
4360  memcmp(RSTRING_PTR(mesg), closed_stream, mesg_len)) {
4361  rb_exc_raise(exc);
4362  }
4363  return io;
4364 }
4365 
4366 static VALUE
4368 {
4369  VALUE closed = rb_check_funcall(io, rb_intern("closed?"), 0, 0);
4370  if (closed != Qundef && RTEST(closed)) return io;
4372  rb_eIOError, (VALUE)0);
4373  return io;
4374 }
4375 
4376 /*
4377  * call-seq:
4378  * ios.closed? -> true or false
4379  *
4380  * Returns <code>true</code> if <em>ios</em> is completely closed (for
4381  * duplex streams, both reader and writer), <code>false</code>
4382  * otherwise.
4383  *
4384  * f = File.new("testfile")
4385  * f.close #=> nil
4386  * f.closed? #=> true
4387  * f = IO.popen("/bin/sh","r+")
4388  * f.close_write #=> nil
4389  * f.closed? #=> false
4390  * f.close_read #=> nil
4391  * f.closed? #=> true
4392  */
4393 
4394 
4395 static VALUE
4397 {
4398  rb_io_t *fptr;
4399  VALUE write_io;
4400  rb_io_t *write_fptr;
4401 
4402  write_io = GetWriteIO(io);
4403  if (io != write_io) {
4404  write_fptr = RFILE(write_io)->fptr;
4405  if (write_fptr && 0 <= write_fptr->fd) {
4406  return Qfalse;
4407  }
4408  }
4409 
4410  fptr = RFILE(io)->fptr;
4412  return 0 <= fptr->fd ? Qfalse : Qtrue;
4413 }
4414 
4415 /*
4416  * call-seq:
4417  * ios.close_read -> nil
4418  *
4419  * Closes the read end of a duplex I/O stream (i.e., one that contains
4420  * both a read and a write stream, such as a pipe). Will raise an
4421  * <code>IOError</code> if the stream is not duplexed.
4422  *
4423  * f = IO.popen("/bin/sh","r+")
4424  * f.close_read
4425  * f.readlines
4426  *
4427  * <em>produces:</em>
4428  *
4429  * prog.rb:3:in `readlines': not opened for reading (IOError)
4430  * from prog.rb:3
4431  */
4432 
4433 static VALUE
4435 {
4436  rb_io_t *fptr;
4437  VALUE write_io;
4438 
4439  GetOpenFile(io, fptr);
4440  if (is_socket(fptr->fd, fptr->pathv)) {
4441 #ifndef SHUT_RD
4442 # define SHUT_RD 0
4443 #endif
4444  if (shutdown(fptr->fd, SHUT_RD) < 0)
4445  rb_sys_fail_path(fptr->pathv);
4446  fptr->mode &= ~FMODE_READABLE;
4447  if (!(fptr->mode & FMODE_WRITABLE))
4448  return rb_io_close(io);
4449  return Qnil;
4450  }
4451 
4452  write_io = GetWriteIO(io);
4453  if (io != write_io) {
4454  rb_io_t *wfptr;
4455  GetOpenFile(write_io, wfptr);
4456  wfptr->pid = fptr->pid;
4457  fptr->pid = 0;
4458  RFILE(io)->fptr = wfptr;
4459  /* bind to write_io temporarily to get rid of memory/fd leak */
4460  fptr->tied_io_for_writing = 0;
4461  fptr->mode &= ~FMODE_DUPLEX;
4462  RFILE(write_io)->fptr = fptr;
4463  rb_io_fptr_cleanup(fptr, FALSE);
4464  /* should not finalize fptr because another thread may be reading it */
4465  return Qnil;
4466  }
4467 
4468  if (fptr->mode & FMODE_WRITABLE) {
4469  rb_raise(rb_eIOError, "closing non-duplex IO for reading");
4470  }
4471  return rb_io_close(io);
4472 }
4473 
4474 /*
4475  * call-seq:
4476  * ios.close_write -> nil
4477  *
4478  * Closes the write end of a duplex I/O stream (i.e., one that contains
4479  * both a read and a write stream, such as a pipe). Will raise an
4480  * <code>IOError</code> if the stream is not duplexed.
4481  *
4482  * f = IO.popen("/bin/sh","r+")
4483  * f.close_write
4484  * f.print "nowhere"
4485  *
4486  * <em>produces:</em>
4487  *
4488  * prog.rb:3:in `write': not opened for writing (IOError)
4489  * from prog.rb:3:in `print'
4490  * from prog.rb:3
4491  */
4492 
4493 static VALUE
4495 {
4496  rb_io_t *fptr;
4497  VALUE write_io;
4498 
4499  write_io = GetWriteIO(io);
4500  GetOpenFile(write_io, fptr);
4501  if (is_socket(fptr->fd, fptr->pathv)) {
4502 #ifndef SHUT_WR
4503 # define SHUT_WR 1
4504 #endif
4505  if (shutdown(fptr->fd, SHUT_WR) < 0)
4506  rb_sys_fail_path(fptr->pathv);
4507  fptr->mode &= ~FMODE_WRITABLE;
4508  if (!(fptr->mode & FMODE_READABLE))
4509  return rb_io_close(write_io);
4510  return Qnil;
4511  }
4512 
4513  if (fptr->mode & FMODE_READABLE) {
4514  rb_raise(rb_eIOError, "closing non-duplex IO for writing");
4515  }
4516 
4517  if (io != write_io) {
4518  GetOpenFile(io, fptr);
4519  fptr->tied_io_for_writing = 0;
4520  fptr->mode &= ~FMODE_DUPLEX;
4521  }
4522  rb_io_close(write_io);
4523  return Qnil;
4524 }
4525 
4526 /*
4527  * call-seq:
4528  * ios.sysseek(offset, whence=IO::SEEK_SET) -> integer
4529  *
4530  * Seeks to a given <i>offset</i> in the stream according to the value
4531  * of <i>whence</i> (see <code>IO#seek</code> for values of
4532  * <i>whence</i>). Returns the new offset into the file.
4533  *
4534  * f = File.new("testfile")
4535  * f.sysseek(-13, IO::SEEK_END) #=> 53
4536  * f.sysread(10) #=> "And so on."
4537  */
4538 
4539 static VALUE
4541 {
4542  VALUE offset, ptrname;
4543  int whence = SEEK_SET;
4544  rb_io_t *fptr;
4545  off_t pos;
4546 
4547  if (rb_scan_args(argc, argv, "11", &offset, &ptrname) == 2) {
4548  whence = interpret_seek_whence(ptrname);
4549  }
4550  pos = NUM2OFFT(offset);
4551  GetOpenFile(io, fptr);
4552  if ((fptr->mode & FMODE_READABLE) &&
4553  (READ_DATA_BUFFERED(fptr) || READ_CHAR_PENDING(fptr))) {
4554  rb_raise(rb_eIOError, "sysseek for buffered IO");
4555  }
4556  if ((fptr->mode & FMODE_WRITABLE) && fptr->wbuf.len) {
4557  rb_warn("sysseek for buffered IO");
4558  }
4559  errno = 0;
4560  pos = lseek(fptr->fd, pos, whence);
4561  if (pos == -1 && errno) rb_sys_fail_path(fptr->pathv);
4562 
4563  return OFFT2NUM(pos);
4564 }
4565 
4566 /*
4567  * call-seq:
4568  * ios.syswrite(string) -> integer
4569  *
4570  * Writes the given string to <em>ios</em> using a low-level write.
4571  * Returns the number of bytes written. Do not mix with other methods
4572  * that write to <em>ios</em> or you may get unpredictable results.
4573  * Raises <code>SystemCallError</code> on error.
4574  *
4575  * f = File.new("out", "w")
4576  * f.syswrite("ABCDEF") #=> 6
4577  */
4578 
4579 static VALUE
4581 {
4582  rb_io_t *fptr;
4583  long n;
4584 
4585  if (!RB_TYPE_P(str, T_STRING))
4586  str = rb_obj_as_string(str);
4587 
4588  io = GetWriteIO(io);
4589  GetOpenFile(io, fptr);
4590  rb_io_check_writable(fptr);
4591 
4592  str = rb_str_new_frozen(str);
4593 
4594  if (fptr->wbuf.len) {
4595  rb_warn("syswrite for buffered IO");
4596  }
4597 
4598  n = rb_write_internal(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
4599  RB_GC_GUARD(str);
4600 
4601  if (n == -1) rb_sys_fail_path(fptr->pathv);
4602 
4603  return LONG2FIX(n);
4604 }
4605 
4606 /*
4607  * call-seq:
4608  * ios.sysread(maxlen[, outbuf]) -> string
4609  *
4610  * Reads <i>maxlen</i> bytes from <em>ios</em> using a low-level
4611  * read and returns them as a string. Do not mix with other methods
4612  * that read from <em>ios</em> or you may get unpredictable results.
4613  * If the optional <i>outbuf</i> argument is present, it must reference
4614  * a String, which will receive the data.
4615  * The <i>outbuf</i> will contain only the received data after the method call
4616  * even if it is not empty at the beginning.
4617  * Raises <code>SystemCallError</code> on error and
4618  * <code>EOFError</code> at end of file.
4619  *
4620  * f = File.new("testfile")
4621  * f.sysread(16) #=> "This is line one"
4622  */
4623 
4624 static VALUE
4626 {
4627  VALUE len, str;
4628  rb_io_t *fptr;
4629  long n, ilen;
4630  struct read_internal_arg arg;
4631 
4632  rb_scan_args(argc, argv, "11", &len, &str);
4633  ilen = NUM2LONG(len);
4634 
4635  io_setstrbuf(&str,ilen);
4636  if (ilen == 0) return str;
4637 
4638  GetOpenFile(io, fptr);
4640 
4641  if (READ_DATA_BUFFERED(fptr)) {
4642  rb_raise(rb_eIOError, "sysread for buffered IO");
4643  }
4644 
4645  n = fptr->fd;
4646 
4647  /*
4648  * FIXME: removing rb_thread_wait_fd() here changes sysread semantics
4649  * on non-blocking IOs. However, it's still currently possible
4650  * for sysread to raise Errno::EAGAIN if another thread read()s
4651  * the IO after we return from rb_thread_wait_fd() but before
4652  * we call read()
4653  */
4654  rb_thread_wait_fd(fptr->fd);
4655 
4656  rb_io_check_closed(fptr);
4657 
4658  io_setstrbuf(&str, ilen);
4659  rb_str_locktmp(str);
4660  arg.fd = fptr->fd;
4661  arg.str_ptr = RSTRING_PTR(str);
4662  arg.len = ilen;
4664  n = arg.len;
4665 
4666  if (n == -1) {
4667  rb_sys_fail_path(fptr->pathv);
4668  }
4669  io_set_read_length(str, n);
4670  if (n == 0 && ilen > 0) {
4671  rb_eof_error();
4672  }
4673  OBJ_TAINT(str);
4674 
4675  return str;
4676 }
4677 
4678 VALUE
4680 {
4681  rb_io_t *fptr;
4682 
4683  GetOpenFile(io, fptr);
4684  if (fptr->readconv)
4685  rb_econv_binmode(fptr->readconv);
4686  if (fptr->writeconv)
4687  rb_econv_binmode(fptr->writeconv);
4688  fptr->mode |= FMODE_BINMODE;
4689  fptr->mode &= ~FMODE_TEXTMODE;
4691 #ifdef O_BINARY
4692  if (!fptr->readconv) {
4694  }
4695  else {
4696  setmode(fptr->fd, O_BINARY);
4697  }
4698 #endif
4699  return io;
4700 }
4701 
4702 static void
4704 {
4705  if (fptr->readconv) {
4706  rb_econv_close(fptr->readconv);
4707  fptr->readconv = NULL;
4708  }
4709  if (fptr->writeconv) {
4710  rb_econv_close(fptr->writeconv);
4711  fptr->writeconv = NULL;
4712  }
4713  fptr->mode |= FMODE_BINMODE;
4714  fptr->mode &= ~FMODE_TEXTMODE;
4716 
4717  fptr->encs.enc = rb_ascii8bit_encoding();
4718  fptr->encs.enc2 = NULL;
4719  fptr->encs.ecflags = 0;
4720  fptr->encs.ecopts = Qnil;
4721  clear_codeconv(fptr);
4722 }
4723 
4724 VALUE
4726 {
4727  rb_io_t *fptr;
4728 
4729  GetOpenFile(io, fptr);
4730  io_ascii8bit_binmode(fptr);
4731 
4732  return io;
4733 }
4734 
4735 /*
4736  * call-seq:
4737  * ios.binmode -> ios
4738  *
4739  * Puts <em>ios</em> into binary mode.
4740  * Once a stream is in binary mode, it cannot be reset to nonbinary mode.
4741  *
4742  * - newline conversion disabled
4743  * - encoding conversion disabled
4744  * - content is treated as ASCII-8BIT
4745  *
4746  */
4747 
4748 static VALUE
4750 {
4751  VALUE write_io;
4752 
4754 
4755  write_io = GetWriteIO(io);
4756  if (write_io != io)
4757  rb_io_ascii8bit_binmode(write_io);
4758  return io;
4759 }
4760 
4761 /*
4762  * call-seq:
4763  * ios.binmode? -> true or false
4764  *
4765  * Returns <code>true</code> if <em>ios</em> is binmode.
4766  */
4767 static VALUE
4769 {
4770  rb_io_t *fptr;
4771  GetOpenFile(io, fptr);
4772  return fptr->mode & FMODE_BINMODE ? Qtrue : Qfalse;
4773 }
4774 
4775 static const char*
4777 {
4778  if (fmode & FMODE_APPEND) {
4779  if ((fmode & FMODE_READWRITE) == FMODE_READWRITE) {
4780  return MODE_BTMODE("a+", "ab+", "at+");
4781  }
4782  return MODE_BTMODE("a", "ab", "at");
4783  }
4784  switch (fmode & FMODE_READWRITE) {
4785  default:
4786  rb_raise(rb_eArgError, "invalid access fmode 0x%x", fmode);
4787  case FMODE_READABLE:
4788  return MODE_BTMODE("r", "rb", "rt");
4789  case FMODE_WRITABLE:
4790  return MODE_BTMODE("w", "wb", "wt");
4791  case FMODE_READWRITE:
4792  if (fmode & FMODE_CREATE) {
4793  return MODE_BTMODE("w+", "wb+", "wt+");
4794  }
4795  return MODE_BTMODE("r+", "rb+", "rt+");
4796  }
4797 }
4798 
4799 static int
4800 io_encname_bom_p(const char *name, long len)
4801 {
4802  static const char bom_prefix[] = "bom|utf-";
4803  enum {bom_prefix_len = (int)sizeof(bom_prefix) - 1};
4804  if (!len) {
4805  const char *p = strchr(name, ':');
4806  len = p ? (long)(p - name) : (long)strlen(name);
4807  }
4808  return len > bom_prefix_len && STRNCASECMP(name, bom_prefix, bom_prefix_len) == 0;
4809 }
4810 
4811 int
4812 rb_io_modestr_fmode(const char *modestr)
4813 {
4814  int fmode = 0;
4815  const char *m = modestr, *p = NULL;
4816 
4817  switch (*m++) {
4818  case 'r':
4819  fmode |= FMODE_READABLE;
4820  break;
4821  case 'w':
4823  break;
4824  case 'a':
4826  break;
4827  default:
4828  error:
4829  rb_raise(rb_eArgError, "invalid access mode %s", modestr);
4830  }
4831 
4832  while (*m) {
4833  switch (*m++) {
4834  case 'b':
4835  fmode |= FMODE_BINMODE;
4836  break;
4837  case 't':
4838  fmode |= FMODE_TEXTMODE;
4839  break;
4840  case '+':
4841  fmode |= FMODE_READWRITE;
4842  break;
4843  default:
4844  goto error;
4845  case ':':
4846  p = m;
4847  goto finished;
4848  }
4849  }
4850 
4851  finished:
4852  if ((fmode & FMODE_BINMODE) && (fmode & FMODE_TEXTMODE))
4853  goto error;
4854  if (p && io_encname_bom_p(p, 0))
4855  fmode |= FMODE_SETENC_BY_BOM;
4856 
4857  return fmode;
4858 }
4859 
4860 int
4862 {
4863  int fmode = 0;
4864 
4865  switch (oflags & (O_RDONLY|O_WRONLY|O_RDWR)) {
4866  case O_RDONLY:
4867  fmode = FMODE_READABLE;
4868  break;
4869  case O_WRONLY:
4870  fmode = FMODE_WRITABLE;
4871  break;
4872  case O_RDWR:
4873  fmode = FMODE_READWRITE;
4874  break;
4875  }
4876 
4877  if (oflags & O_APPEND) {
4878  fmode |= FMODE_APPEND;
4879  }
4880  if (oflags & O_TRUNC) {
4881  fmode |= FMODE_TRUNC;
4882  }
4883  if (oflags & O_CREAT) {
4884  fmode |= FMODE_CREATE;
4885  }
4886 #ifdef O_BINARY
4887  if (oflags & O_BINARY) {
4888  fmode |= FMODE_BINMODE;
4889  }
4890 #endif
4891 
4892  return fmode;
4893 }
4894 
4895 static int
4897 {
4898  int oflags = 0;
4899 
4900  switch (fmode & FMODE_READWRITE) {
4901  case FMODE_READABLE:
4902  oflags |= O_RDONLY;
4903  break;
4904  case FMODE_WRITABLE:
4905  oflags |= O_WRONLY;
4906  break;
4907  case FMODE_READWRITE:
4908  oflags |= O_RDWR;
4909  break;
4910  }
4911 
4912  if (fmode & FMODE_APPEND) {
4913  oflags |= O_APPEND;
4914  }
4915  if (fmode & FMODE_TRUNC) {
4916  oflags |= O_TRUNC;
4917  }
4918  if (fmode & FMODE_CREATE) {
4919  oflags |= O_CREAT;
4920  }
4921 #ifdef O_BINARY
4922  if (fmode & FMODE_BINMODE) {
4923  oflags |= O_BINARY;
4924  }
4925 #endif
4926 
4927  return oflags;
4928 }
4929 
4930 int
4931 rb_io_modestr_oflags(const char *modestr)
4932 {
4933  return rb_io_fmode_oflags(rb_io_modestr_fmode(modestr));
4934 }
4935 
4936 static const char*
4938 {
4939 #ifdef O_BINARY
4940 # define MODE_BINARY(a,b) ((oflags & O_BINARY) ? (b) : (a))
4941 #else
4942 # define MODE_BINARY(a,b) (a)
4943 #endif
4944  int accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR);
4945  if (oflags & O_APPEND) {
4946  if (accmode == O_WRONLY) {
4947  return MODE_BINARY("a", "ab");
4948  }
4949  if (accmode == O_RDWR) {
4950  return MODE_BINARY("a+", "ab+");
4951  }
4952  }
4953  switch (oflags & (O_RDONLY|O_WRONLY|O_RDWR)) {
4954  default:
4955  rb_raise(rb_eArgError, "invalid access oflags 0x%x", oflags);
4956  case O_RDONLY:
4957  return MODE_BINARY("r", "rb");
4958  case O_WRONLY:
4959  return MODE_BINARY("w", "wb");
4960  case O_RDWR:
4961  return MODE_BINARY("r+", "rb+");
4962  }
4963 }
4964 
4965 /*
4966  * Convert external/internal encodings to enc/enc2
4967  * NULL => use default encoding
4968  * Qnil => no encoding specified (internal only)
4969  */
4970 static void
4972 {
4973  int default_ext = 0;
4974 
4975  if (ext == NULL) {
4977  default_ext = 1;
4978  }
4979  if (ext == rb_ascii8bit_encoding()) {
4980  /* If external is ASCII-8BIT, no transcoding */
4981  intern = NULL;
4982  }
4983  else if (intern == NULL) {
4984  intern = rb_default_internal_encoding();
4985  }
4986  if (intern == NULL || intern == (rb_encoding *)Qnil ||
4987  (!(fmode & FMODE_SETENC_BY_BOM) && (intern == ext))) {
4988  /* No internal encoding => use external + no transcoding */
4989  *enc = (default_ext && intern != ext) ? NULL : ext;
4990  *enc2 = NULL;
4991  }
4992  else {
4993  *enc = intern;
4994  *enc2 = ext;
4995  }
4996 }
4997 
4998 static void
5000 {
5001  rb_warn("Unsupported encoding %s ignored", name);
5002 }
5003 
5004 static void
5005 parse_mode_enc(const char *estr, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
5006 {
5007  const char *p;
5008  char encname[ENCODING_MAXNAMELEN+1];
5009  int idx, idx2;
5010  int fmode = fmode_p ? *fmode_p : 0;
5011  rb_encoding *ext_enc, *int_enc;
5012 
5013  /* parse estr as "enc" or "enc2:enc" or "enc:-" */
5014 
5015  p = strrchr(estr, ':');
5016  if (p) {
5017  long len = (p++) - estr;
5018  if (len == 0 || len > ENCODING_MAXNAMELEN)
5019  idx = -1;
5020  else {
5021  if (io_encname_bom_p(estr, len)) {
5022  fmode |= FMODE_SETENC_BY_BOM;
5023  estr += 4;
5024  len -= 4;
5025  }
5026  memcpy(encname, estr, len);
5027  encname[len] = '\0';
5028  estr = encname;
5029  idx = rb_enc_find_index(encname);
5030  }
5031  }
5032  else {
5033  long len = strlen(estr);
5034  if (io_encname_bom_p(estr, len)) {
5035  fmode |= FMODE_SETENC_BY_BOM;
5036  estr += 4;
5037  len -= 4;
5038  memcpy(encname, estr, len);
5039  encname[len] = '\0';
5040  estr = encname;
5041  }
5042  idx = rb_enc_find_index(estr);
5043  }
5044  if (fmode_p) *fmode_p = fmode;
5045 
5046  if (idx >= 0)
5047  ext_enc = rb_enc_from_index(idx);
5048  else {
5049  if (idx != -2)
5050  unsupported_encoding(estr);
5051  ext_enc = NULL;
5052  }
5053 
5054  int_enc = NULL;
5055  if (p) {
5056  if (*p == '-' && *(p+1) == '\0') {
5057  /* Special case - "-" => no transcoding */
5058  int_enc = (rb_encoding *)Qnil;
5059  }
5060  else {
5061  idx2 = rb_enc_find_index(p);
5062  if (idx2 < 0)
5064  else if (!(fmode & FMODE_SETENC_BY_BOM) && (idx2 == idx)) {
5065  int_enc = (rb_encoding *)Qnil;
5066  }
5067  else
5068  int_enc = rb_enc_from_index(idx2);
5069  }
5070  }
5071 
5072  rb_io_ext_int_to_encs(ext_enc, int_enc, enc_p, enc2_p, fmode);
5073 }
5074 
5075 int
5076 rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
5077 {
5078  VALUE encoding=Qnil, extenc=Qundef, intenc=Qundef, tmp;
5079  int extracted = 0;
5080  rb_encoding *extencoding = NULL;
5081  rb_encoding *intencoding = NULL;
5082 
5083  if (!NIL_P(opt)) {
5084  VALUE v;
5085  v = rb_hash_lookup2(opt, sym_encoding, Qnil);
5086  if (v != Qnil) encoding = v;
5087  v = rb_hash_lookup2(opt, sym_extenc, Qundef);
5088  if (v != Qnil) extenc = v;
5089  v = rb_hash_lookup2(opt, sym_intenc, Qundef);
5090  if (v != Qundef) intenc = v;
5091  }
5092  if ((extenc != Qundef || intenc != Qundef) && !NIL_P(encoding)) {
5093  if (!NIL_P(ruby_verbose)) {
5094  int idx = rb_to_encoding_index(encoding);
5095  rb_warn("Ignoring encoding parameter '%s': %s_encoding is used",
5096  idx < 0 ? StringValueCStr(encoding) : rb_enc_name(rb_enc_from_index(idx)),
5097  extenc == Qundef ? "internal" : "external");
5098  }
5099  encoding = Qnil;
5100  }
5101  if (extenc != Qundef && !NIL_P(extenc)) {
5102  extencoding = rb_to_encoding(extenc);
5103  }
5104  if (intenc != Qundef) {
5105  if (NIL_P(intenc)) {
5106  /* internal_encoding: nil => no transcoding */
5107  intencoding = (rb_encoding *)Qnil;
5108  }
5109  else if (!NIL_P(tmp = rb_check_string_type(intenc))) {
5110  char *p = StringValueCStr(tmp);
5111 
5112  if (*p == '-' && *(p+1) == '\0') {
5113  /* Special case - "-" => no transcoding */
5114  intencoding = (rb_encoding *)Qnil;
5115  }
5116  else {
5117  intencoding = rb_to_encoding(intenc);
5118  }
5119  }
5120  else {
5121  intencoding = rb_to_encoding(intenc);
5122  }
5123  if (extencoding == intencoding) {
5124  intencoding = (rb_encoding *)Qnil;
5125  }
5126  }
5127  if (!NIL_P(encoding)) {
5128  extracted = 1;
5129  if (!NIL_P(tmp = rb_check_string_type(encoding))) {
5130  parse_mode_enc(StringValueCStr(tmp), enc_p, enc2_p, fmode_p);
5131  }
5132  else {
5133  rb_io_ext_int_to_encs(rb_to_encoding(encoding), NULL, enc_p, enc2_p, 0);
5134  }
5135  }
5136  else if (extenc != Qundef || intenc != Qundef) {
5137  extracted = 1;
5138  rb_io_ext_int_to_encs(extencoding, intencoding, enc_p, enc2_p, 0);
5139  }
5140  return extracted;
5141 }
5142 
5143 typedef struct rb_io_enc_t convconfig_t;
5144 
5145 static void
5146 validate_enc_binmode(int *fmode_p, int ecflags, rb_encoding *enc, rb_encoding *enc2)
5147 {
5148  int fmode = *fmode_p;
5149 
5150  if ((fmode & FMODE_READABLE) &&
5151  !enc2 &&
5152  !(fmode & FMODE_BINMODE) &&
5154  rb_raise(rb_eArgError, "ASCII incompatible encoding needs binmode");
5155 
5156  if (!(fmode & FMODE_BINMODE) &&
5158  fmode |= DEFAULT_TEXTMODE;
5159  *fmode_p = fmode;
5160  }
5161 #if !DEFAULT_TEXTMODE
5162  else if (!(ecflags & ECONV_NEWLINE_DECORATOR_MASK)) {
5163  fmode &= ~FMODE_TEXTMODE;
5164  *fmode_p = fmode;
5165  }
5166 #endif
5167 }
5168 
5169 static void
5171 {
5172  if (!NIL_P(opthash)) {
5173  VALUE v;
5174  v = rb_hash_aref(opthash, sym_textmode);
5175  if (!NIL_P(v)) {
5176  if (*fmode & FMODE_TEXTMODE)
5177  rb_raise(rb_eArgError, "textmode specified twice");
5178  if (*fmode & FMODE_BINMODE)
5179  rb_raise(rb_eArgError, "both textmode and binmode specified");
5180  if (RTEST(v))
5181  *fmode |= FMODE_TEXTMODE;
5182  }
5183  v = rb_hash_aref(opthash, sym_binmode);
5184  if (!NIL_P(v)) {
5185  if (*fmode & FMODE_BINMODE)
5186  rb_raise(rb_eArgError, "binmode specified twice");
5187  if (*fmode & FMODE_TEXTMODE)
5188  rb_raise(rb_eArgError, "both textmode and binmode specified");
5189  if (RTEST(v))
5190  *fmode |= FMODE_BINMODE;
5191  }
5192 
5193  if ((*fmode & FMODE_BINMODE) && (*fmode & FMODE_TEXTMODE))
5194  rb_raise(rb_eArgError, "both textmode and binmode specified");
5195  }
5196 }
5197 
5198 static void
5199 rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
5200  int *oflags_p, int *fmode_p, convconfig_t *convconfig_p)
5201 {
5202  VALUE vmode;
5203  int oflags, fmode;
5204  rb_encoding *enc, *enc2;
5205  int ecflags;
5206  VALUE ecopts;
5207  int has_enc = 0, has_vmode = 0;
5208  VALUE intmode;
5209 
5210  vmode = *vmode_p;
5211 
5212  /* Set to defaults */
5213  rb_io_ext_int_to_encs(NULL, NULL, &enc, &enc2, 0);
5214 
5215  vmode_handle:
5216  if (NIL_P(vmode)) {
5217  fmode = FMODE_READABLE;
5218  oflags = O_RDONLY;
5219  }
5220  else if (!NIL_P(intmode = rb_check_to_integer(vmode, "to_int"))) {
5221  vmode = intmode;
5222  oflags = NUM2INT(intmode);
5223  fmode = rb_io_oflags_fmode(oflags);
5224  }
5225  else {
5226  const char *p;
5227 
5228  SafeStringValue(vmode);
5229  p = StringValueCStr(vmode);
5230  fmode = rb_io_modestr_fmode(p);
5231  oflags = rb_io_fmode_oflags(fmode);
5232  p = strchr(p, ':');
5233  if (p) {
5234  has_enc = 1;
5235  parse_mode_enc(p+1, &enc, &enc2, &fmode);
5236  }
5237  else {
5238  rb_encoding *e;
5239 
5240  e = (fmode & FMODE_BINMODE) ? rb_ascii8bit_encoding() : NULL;
5241  rb_io_ext_int_to_encs(e, NULL, &enc, &enc2, fmode);
5242  }
5243  }
5244 
5245  if (NIL_P(opthash)) {
5246  ecflags = (fmode & FMODE_READABLE) ?
5249 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
5250  ecflags |= (fmode & FMODE_WRITABLE) ?
5251  MODE_BTMODE(TEXTMODE_NEWLINE_DECORATOR_ON_WRITE,
5252  0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
5253 #endif
5255  ecopts = Qnil;
5256  }
5257  else {
5258  VALUE v;
5259  extract_binmode(opthash, &fmode);
5260  if (fmode & FMODE_BINMODE) {
5261 #ifdef O_BINARY
5262  oflags |= O_BINARY;
5263 #endif
5264  if (!has_enc)
5265  rb_io_ext_int_to_encs(rb_ascii8bit_encoding(), NULL, &enc, &enc2, fmode);
5266  }
5267 #if DEFAULT_TEXTMODE
5268  else if (NIL_P(vmode)) {
5269  fmode |= DEFAULT_TEXTMODE;
5270  }
5271 #endif
5272  if (!has_vmode) {
5273  v = rb_hash_aref(opthash, sym_mode);
5274  if (!NIL_P(v)) {
5275  if (!NIL_P(vmode)) {
5276  rb_raise(rb_eArgError, "mode specified twice");
5277  }
5278  has_vmode = 1;
5279  vmode = v;
5280  goto vmode_handle;
5281  }
5282  }
5283  v = rb_hash_aref(opthash, sym_perm);
5284  if (!NIL_P(v)) {
5285  if (vperm_p) {
5286  if (!NIL_P(*vperm_p)) {
5287  rb_raise(rb_eArgError, "perm specified twice");
5288  }
5289  *vperm_p = v;
5290  }
5291  else {
5292  /* perm no use, just ignore */
5293  }
5294  }
5295  ecflags = (fmode & FMODE_READABLE) ?
5298 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
5299  ecflags |= (fmode & FMODE_WRITABLE) ?
5300  MODE_BTMODE(TEXTMODE_NEWLINE_DECORATOR_ON_WRITE,
5301  0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
5302 #endif
5303 
5304  if (rb_io_extract_encoding_option(opthash, &enc, &enc2, &fmode)) {
5305  if (has_enc) {
5306  rb_raise(rb_eArgError, "encoding specified twice");
5307  }
5308  }
5310  ecflags = rb_econv_prepare_options(opthash, &ecopts, ecflags);
5311  }
5312 
5313  validate_enc_binmode(&fmode, ecflags, enc, enc2);
5314 
5315  *vmode_p = vmode;
5316 
5317  *oflags_p = oflags;
5318  *fmode_p = fmode;
5319  convconfig_p->enc = enc;
5320  convconfig_p->enc2 = enc2;
5321  convconfig_p->ecflags = ecflags;
5322  convconfig_p->ecopts = ecopts;
5323 }
5324 
5327  int oflags;
5329 };
5330 
5331 static void *
5332 sysopen_func(void *ptr)
5333 {
5334  const struct sysopen_struct *data = ptr;
5335  const char *fname = RSTRING_PTR(data->fname);
5336  return (void *)(VALUE)rb_cloexec_open(fname, data->oflags, data->perm);
5337 }
5338 
5339 static inline int
5341 {
5342  int fd;
5344  if (0 <= fd)
5345  rb_update_max_fd(fd);
5346  return fd;
5347 }
5348 
5349 static int
5351 {
5352  int fd;
5353  struct sysopen_struct data;
5354 
5355  data.fname = rb_str_encode_ospath(fname);
5356  data.oflags = oflags;
5357  data.perm = perm;
5358 
5359  fd = rb_sysopen_internal(&data);
5360  if (fd < 0) {
5361  if (errno == EMFILE || errno == ENFILE) {
5362  rb_gc();
5363  fd = rb_sysopen_internal(&data);
5364  }
5365  if (fd < 0) {
5366  rb_sys_fail_path(fname);
5367  }
5368  }
5369  return fd;
5370 }
5371 
5372 FILE *
5373 rb_fdopen(int fd, const char *modestr)
5374 {
5375  FILE *file;
5376 
5377 #if defined(__sun)
5378  errno = 0;
5379 #endif
5380  file = fdopen(fd, modestr);
5381  if (!file) {
5382  if (
5383 #if defined(__sun)
5384  errno == 0 ||
5385 #endif
5386  errno == EMFILE || errno == ENFILE) {
5387  rb_gc();
5388 #if defined(__sun)
5389  errno = 0;
5390 #endif
5391  file = fdopen(fd, modestr);
5392  }
5393  if (!file) {
5394 #ifdef _WIN32
5395  if (errno == 0) errno = EINVAL;
5396 #elif defined(__sun)
5397  if (errno == 0) errno = EMFILE;
5398 #endif
5399  rb_sys_fail(0);
5400  }
5401  }
5402 
5403  /* xxx: should be _IONBF? A buffer in FILE may have trouble. */
5404 #ifdef USE_SETVBUF
5405  if (setvbuf(file, NULL, _IOFBF, 0) != 0)
5406  rb_warn("setvbuf() can't be honoured (fd=%d)", fd);
5407 #endif
5408  return file;
5409 }
5410 
5411 static void
5413 {
5414  if (isatty(fptr->fd))
5415  fptr->mode |= FMODE_TTY|FMODE_DUPLEX;
5416 }
5417 
5419 static void io_encoding_set(rb_io_t *, VALUE, VALUE, VALUE);
5420 
5421 static int
5423 {
5424  VALUE b1, b2, b3, b4;
5425 
5426  if (NIL_P(b1 = rb_io_getbyte(io))) return 0;
5427  switch (b1) {
5428  case INT2FIX(0xEF):
5429  if (NIL_P(b2 = rb_io_getbyte(io))) break;
5430  if (b2 == INT2FIX(0xBB) && !NIL_P(b3 = rb_io_getbyte(io))) {
5431  if (b3 == INT2FIX(0xBF)) {
5432  return rb_utf8_encindex();
5433  }
5434  rb_io_ungetbyte(io, b3);
5435  }
5436  rb_io_ungetbyte(io, b2);
5437  break;
5438 
5439  case INT2FIX(0xFE):
5440  if (NIL_P(b2 = rb_io_getbyte(io))) break;
5441  if (b2 == INT2FIX(0xFF)) {
5442  return ENCINDEX_UTF_16BE;
5443  }
5444  rb_io_ungetbyte(io, b2);
5445  break;
5446 
5447  case INT2FIX(0xFF):
5448  if (NIL_P(b2 = rb_io_getbyte(io))) break;
5449  if (b2 == INT2FIX(0xFE)) {
5450  b3 = rb_io_getbyte(io);
5451  if (b3 == INT2FIX(0) && !NIL_P(b4 = rb_io_getbyte(io))) {
5452  if (b4 == INT2FIX(0)) {
5453  return ENCINDEX_UTF_32LE;
5454  }
5455  rb_io_ungetbyte(io, b4);
5456  rb_io_ungetbyte(io, b3);
5457  }
5458  else {
5459  rb_io_ungetbyte(io, b3);
5460  return ENCINDEX_UTF_16LE;
5461  }
5462  }
5463  rb_io_ungetbyte(io, b2);
5464  break;
5465 
5466  case INT2FIX(0):
5467  if (NIL_P(b2 = rb_io_getbyte(io))) break;
5468  if (b2 == INT2FIX(0) && !NIL_P(b3 = rb_io_getbyte(io))) {
5469  if (b3 == INT2FIX(0xFE) && !NIL_P(b4 = rb_io_getbyte(io))) {
5470  if (b4 == INT2FIX(0xFF)) {
5471  return ENCINDEX_UTF_32BE;
5472  }
5473  rb_io_ungetbyte(io, b4);
5474  }
5475  rb_io_ungetbyte(io, b3);
5476  }
5477  rb_io_ungetbyte(io, b2);
5478  break;
5479  }
5480  rb_io_ungetbyte(io, b1);
5481  return 0;
5482 }
5483 
5484 static void
5486 {
5487  int idx = io_strip_bom(io);
5488  rb_io_t *fptr;
5489 
5490  GetOpenFile(io, fptr);
5491  if (idx) {
5494  }
5495  else {
5496  fptr->encs.enc2 = NULL;
5497  }
5498 }
5499 
5500 static VALUE
5501 rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode, convconfig_t *convconfig, mode_t perm)
5502 {
5503  rb_io_t *fptr;
5504  convconfig_t cc;
5505  if (!convconfig) {
5506  /* Set to default encodings */
5507  rb_io_ext_int_to_encs(NULL, NULL, &cc.enc, &cc.enc2, fmode);
5508  cc.ecflags = 0;
5509  cc.ecopts = Qnil;
5510  convconfig = &cc;
5511  }
5512  validate_enc_binmode(&fmode, convconfig->ecflags,
5513  convconfig->enc, convconfig->enc2);
5514 
5515  MakeOpenFile(io, fptr);
5516  fptr->mode = fmode;
5517  fptr->encs = *convconfig;
5518  fptr->pathv = rb_str_new_frozen(filename);
5519  fptr->fd = rb_sysopen(fptr->pathv, oflags, perm);
5520  io_check_tty(fptr);
5522 
5523  return io;
5524 }
5525 
5526 static VALUE
5527 rb_file_open_internal(VALUE io, VALUE filename, const char *modestr)
5528 {
5529  int fmode = rb_io_modestr_fmode(modestr);
5530  const char *p = strchr(modestr, ':');
5531  convconfig_t convconfig;
5532 
5533  if (p) {
5534  parse_mode_enc(p+1, &convconfig.enc, &convconfig.enc2, &fmode);
5535  }
5536  else {
5537  rb_encoding *e;
5538  /* Set to default encodings */
5539 
5540  e = (fmode & FMODE_BINMODE) ? rb_ascii8bit_encoding() : NULL;
5541  rb_io_ext_int_to_encs(e, NULL, &convconfig.enc, &convconfig.enc2, fmode);
5542  convconfig.ecflags = 0;
5543  convconfig.ecopts = Qnil;
5544  }
5545 
5546  return rb_file_open_generic(io, filename,
5547  rb_io_fmode_oflags(fmode),
5548  fmode,
5549  &convconfig,
5550  0666);
5551 }
5552 
5553 VALUE
5554 rb_file_open_str(VALUE fname, const char *modestr)
5555 {
5556  FilePathValue(fname);
5557  return rb_file_open_internal(io_alloc(rb_cFile), fname, modestr);
5558 }
5559 
5560 VALUE
5561 rb_file_open(const char *fname, const char *modestr)
5562 {
5563  return rb_file_open_internal(io_alloc(rb_cFile), rb_str_new_cstr(fname), modestr);
5564 }
5565 
5566 #if defined(__CYGWIN__) || !defined(HAVE_FORK)
5567 static struct pipe_list {
5569  struct pipe_list *next;
5570 } *pipe_list;
5571 
5572 static void
5574 {
5575  struct pipe_list *list;
5576 
5577  list = ALLOC(struct pipe_list);
5578  list->fptr = fptr;
5579  list->next = pipe_list;
5580  pipe_list = list;
5581 }
5582 
5583 static void
5585 {
5586  struct pipe_list *list = pipe_list;
5587  struct pipe_list *tmp;
5588 
5589  if (list->fptr == fptr) {
5590  pipe_list = list->next;
5591  free(list);
5592  return;
5593  }
5594 
5595  while (list->next) {
5596  if (list->next->fptr == fptr) {
5597  tmp = list->next;
5598  list->next = list->next->next;
5599  free(tmp);
5600  return;
5601  }
5602  list = list->next;
5603  }
5604 }
5605 
5606 static void
5608 {
5609  struct pipe_list *list = pipe_list;
5610  struct pipe_list *tmp;
5611 
5612  while (list) {
5613  tmp = list->next;
5614  rb_io_fptr_finalize(list->fptr);
5615  list = tmp;
5616  }
5617 }
5618 
5619 static void
5620 pipe_finalize(rb_io_t *fptr, int noraise)
5621 {
5622 #if !defined(HAVE_FORK) && !defined(_WIN32)
5623  int status = 0;
5624  if (fptr->stdio_file) {
5625  status = pclose(fptr->stdio_file);
5626  }
5627  fptr->fd = -1;
5628  fptr->stdio_file = 0;
5629  rb_last_status_set(status, fptr->pid);
5630 #else
5631  fptr_finalize(fptr, noraise);
5632 #endif
5633  pipe_del_fptr(fptr);
5634 }
5635 #endif
5636 
5637 void
5639 {
5641  fptr->mode |= FMODE_SYNC;
5642 }
5643 
5644 void
5646 {
5647  rb_io_synchronized(fptr);
5648 }
5649 
5650 int
5651 rb_pipe(int *pipes)
5652 {
5653  int ret;
5654  ret = rb_cloexec_pipe(pipes);
5655  if (ret == -1) {
5656  if (errno == EMFILE || errno == ENFILE) {
5657  rb_gc();
5658  ret = rb_cloexec_pipe(pipes);
5659  }
5660  }
5661  if (ret == 0) {
5662  rb_update_max_fd(pipes[0]);
5663  rb_update_max_fd(pipes[1]);
5664  }
5665  return ret;
5666 }
5667 
5668 #ifdef _WIN32
5669 #define HAVE_SPAWNV 1
5670 #define spawnv(mode, cmd, args) rb_w32_uaspawn((mode), (cmd), (args))
5671 #define spawn(mode, cmd) rb_w32_uspawn((mode), (cmd), 0)
5672 #endif
5673 
5674 #if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
5675 struct popen_arg {
5676  VALUE execarg_obj;
5677  struct rb_execarg *eargp;
5678  int modef;
5679  int pair[2];
5680  int write_pair[2];
5681 };
5682 #endif
5683 
5684 #ifdef HAVE_FORK
5685 static void
5686 popen_redirect(struct popen_arg *p)
5687 {
5688  if ((p->modef & FMODE_READABLE) && (p->modef & FMODE_WRITABLE)) {
5689  close(p->write_pair[1]);
5690  if (p->write_pair[0] != 0) {
5691  dup2(p->write_pair[0], 0);
5692  close(p->write_pair[0]);
5693  }
5694  close(p->pair[0]);
5695  if (p->pair[1] != 1) {
5696  dup2(p->pair[1], 1);
5697  close(p->pair[1]);
5698  }
5699  }
5700  else if (p->modef & FMODE_READABLE) {
5701  close(p->pair[0]);
5702  if (p->pair[1] != 1) {
5703  dup2(p->pair[1], 1);
5704  close(p->pair[1]);
5705  }
5706  }
5707  else {
5708  close(p->pair[1]);
5709  if (p->pair[0] != 0) {
5710  dup2(p->pair[0], 0);
5711  close(p->pair[0]);
5712  }
5713  }
5714 }
5715 
5716 #if defined(__linux__)
5717 /* Linux /proc/self/status contains a line: "FDSize:\t<nnn>\n"
5718  * Since /proc may not be available, linux_get_maxfd is just a hint.
5719  * This function, linux_get_maxfd, must be async-signal-safe.
5720  * I.e. opendir() is not usable.
5721  *
5722  * Note that memchr() and memcmp is *not* async-signal-safe in POSIX.
5723  * However they are easy to re-implement in async-signal-safe manner.
5724  * (Also note that there is missing/memcmp.c.)
5725  */
5726 static int
5727 linux_get_maxfd(void)
5728 {
5729  int fd;
5730  char buf[4096], *p, *np, *e;
5731  ssize_t ss;
5732  fd = rb_cloexec_open("/proc/self/status", O_RDONLY|O_NOCTTY, 0);
5733  if (fd == -1) return -1;
5734  ss = read(fd, buf, sizeof(buf));
5735  if (ss == -1) goto err;
5736  p = buf;
5737  e = buf + ss;
5738  while ((int)sizeof("FDSize:\t0\n")-1 <= e-p &&
5739  (np = memchr(p, '\n', e-p)) != NULL) {
5740  if (memcmp(p, "FDSize:", sizeof("FDSize:")-1) == 0) {
5741  int fdsize;
5742  p += sizeof("FDSize:")-1;
5743  *np = '\0';
5744  fdsize = (int)ruby_strtoul(p, (char **)NULL, 10);
5745  close(fd);
5746  return fdsize;
5747  }
5748  p = np+1;
5749  }
5750  /* fall through */
5751 
5752  err:
5753  close(fd);
5754  return -1;
5755 }
5756 #endif
5757 
5758 /* This function should be async-signal-safe. */
5759 void
5760 rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
5761 {
5762  int fd, ret;
5763  int max = (int)max_file_descriptor;
5764 #ifdef F_MAXFD
5765  /* F_MAXFD is available since NetBSD 2.0. */
5766  ret = fcntl(0, F_MAXFD); /* async-signal-safe */
5767  if (ret != -1)
5768  maxhint = max = ret;
5769 #elif defined(__linux__)
5770  ret = linux_get_maxfd();
5771  if (maxhint < ret)
5772  maxhint = ret;
5773  /* maxhint = max = ret; if (ret == -1) abort(); // test */
5774 #endif
5775  if (max < maxhint)
5776  max = maxhint;
5777  for (fd = lowfd; fd <= max; fd++) {
5778  if (!NIL_P(noclose_fds) &&
5779  RTEST(rb_hash_lookup(noclose_fds, INT2FIX(fd)))) /* async-signal-safe */
5780  continue;
5781  ret = fcntl(fd, F_GETFD); /* async-signal-safe */
5782  if (ret != -1 && !(ret & FD_CLOEXEC)) {
5783  fcntl(fd, F_SETFD, ret|FD_CLOEXEC); /* async-signal-safe */
5784  }
5785 #define CONTIGUOUS_CLOSED_FDS 20
5786  if (ret != -1) {
5787  if (max < fd + CONTIGUOUS_CLOSED_FDS)
5788  max = fd + CONTIGUOUS_CLOSED_FDS;
5789  }
5790  }
5791 }
5792 
5793 static int
5794 popen_exec(void *pp, char *errmsg, size_t errmsg_len)
5795 {
5796  struct popen_arg *p = (struct popen_arg*)pp;
5797 
5798  return rb_exec_async_signal_safe(p->eargp, errmsg, errmsg_len);
5799 }
5800 #endif
5801 
5802 static VALUE
5803 pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convconfig)
5804 {
5805  struct rb_execarg *eargp = NIL_P(execarg_obj) ? NULL : rb_execarg_get(execarg_obj);
5806  VALUE prog = eargp ? (eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name) : Qfalse ;
5807  rb_pid_t pid = 0;
5808  rb_io_t *fptr;
5809  VALUE port;
5810  rb_io_t *write_fptr;
5811  VALUE write_port;
5812 #if defined(HAVE_FORK)
5813  int status;
5814  char errmsg[80] = { '\0' };
5815 #endif
5816 #if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
5817  struct popen_arg arg;
5818  int e = 0;
5819 #endif
5820 #if defined(HAVE_SPAWNV)
5821 # if defined(HAVE_SPAWNVE)
5822 # define DO_SPAWN(cmd, args, envp) ((args) ? \
5823  spawnve(P_NOWAIT, (cmd), (args), (envp)) : \
5824  spawne(P_NOWAIT, (cmd), (envp)))
5825 # else
5826 # define DO_SPAWN(cmd, args, envp) ((args) ? \
5827  spawnv(P_NOWAIT, (cmd), (args)) : \
5828  spawn(P_NOWAIT, (cmd)))
5829 # endif
5830 # if !defined(HAVE_FORK)
5831  char **args = NULL;
5832 # if defined(HAVE_SPAWNVE)
5833  char **envp = NULL;
5834 # endif
5835 # endif
5836 #endif
5837 #if !defined(HAVE_FORK)
5838  struct rb_execarg sarg, *sargp = &sarg;
5839 #endif
5840  FILE *fp = 0;
5841  int fd = -1;
5842  int write_fd = -1;
5843 #if !defined(HAVE_FORK)
5844  const char *cmd = 0;
5845 #if !defined(HAVE_SPAWNV)
5846  int argc;
5847  VALUE *argv;
5848 #endif
5849 
5850  if (prog)
5851  cmd = StringValueCStr(prog);
5852 #endif
5853 
5854 #if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
5855  arg.execarg_obj = execarg_obj;
5856  arg.eargp = eargp;
5857  arg.modef = fmode;
5858  arg.pair[0] = arg.pair[1] = -1;
5859  arg.write_pair[0] = arg.write_pair[1] = -1;
5860 # if !defined(HAVE_FORK)
5861  if (eargp && !eargp->use_shell) {
5862  args = ARGVSTR2ARGV(eargp->invoke.cmd.argv_str);
5863  }
5864 # endif
5865  switch (fmode & (FMODE_READABLE|FMODE_WRITABLE)) {
5867  if (rb_pipe(arg.write_pair) < 0)
5868  rb_sys_fail_str(prog);
5869  if (rb_pipe(arg.pair) < 0) {
5870  int e = errno;
5871  close(arg.write_pair[0]);
5872  close(arg.write_pair[1]);
5873  errno = e;
5874  rb_sys_fail_str(prog);
5875  }
5876  if (eargp) {
5877  rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(arg.write_pair[0]));
5878  rb_execarg_addopt(execarg_obj, INT2FIX(1), INT2FIX(arg.pair[1]));
5879  }
5880  break;
5881  case FMODE_READABLE:
5882  if (rb_pipe(arg.pair) < 0)
5883  rb_sys_fail_str(prog);
5884  if (eargp)
5885  rb_execarg_addopt(execarg_obj, INT2FIX(1), INT2FIX(arg.pair[1]));
5886  break;
5887  case FMODE_WRITABLE:
5888  if (rb_pipe(arg.pair) < 0)
5889  rb_sys_fail_str(prog);
5890  if (eargp)
5891  rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(arg.pair[0]));
5892  break;
5893  default:
5894  rb_sys_fail_str(prog);
5895  }
5896  if (!NIL_P(execarg_obj)) {
5897  rb_execarg_fixup(execarg_obj);
5898 # if defined(HAVE_FORK)
5899  pid = rb_fork_async_signal_safe(&status, popen_exec, &arg, arg.eargp->redirect_fds, errmsg, sizeof(errmsg));
5900 # else
5901  rb_execarg_run_options(eargp, sargp, NULL, 0);
5902 # if defined(HAVE_SPAWNVE)
5903  if (eargp->envp_str) envp = (char **)RSTRING_PTR(eargp->envp_str);
5904 # endif
5905  while ((pid = DO_SPAWN(cmd, args, envp)) == -1) {
5906  /* exec failed */
5907  switch (e = errno) {
5908  case EAGAIN:
5909 # if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
5910  case EWOULDBLOCK:
5911 # endif
5912  rb_thread_sleep(1);
5913  continue;
5914  }
5915  break;
5916  }
5917  if (eargp)
5918  rb_execarg_run_options(sargp, NULL, NULL, 0);
5919 # endif
5920  }
5921  else {
5922 # if defined(HAVE_FORK)
5923  pid = rb_fork_ruby(&status);
5924  if (pid == 0) { /* child */
5925  rb_thread_atfork();
5926  popen_redirect(&arg);
5929  return Qnil;
5930  }
5931 # else
5932  rb_notimplement();
5933 # endif
5934  }
5935 
5936  /* parent */
5937  if (pid == -1) {
5938 # if defined(HAVE_FORK)
5939  e = errno;
5940 # endif
5941  close(arg.pair[0]);
5942  close(arg.pair[1]);
5944  close(arg.write_pair[0]);
5945  close(arg.write_pair[1]);
5946  }
5947  errno = e;
5948 # if defined(HAVE_FORK)
5949  if (errmsg[0])
5950  rb_sys_fail(errmsg);
5951 # endif
5952  rb_sys_fail_str(prog);
5953  }
5954  if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) {
5955  close(arg.pair[1]);
5956  fd = arg.pair[0];
5957  close(arg.write_pair[0]);
5958  write_fd = arg.write_pair[1];
5959  }
5960  else if (fmode & FMODE_READABLE) {
5961  close(arg.pair[1]);
5962  fd = arg.pair[0];
5963  }
5964  else {
5965  close(arg.pair[0]);
5966  fd = arg.pair[1];
5967  }
5968 #else
5969  if (argc) {
5970  prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
5971  cmd = StringValueCStr(prog);
5972  }
5973  if (!NIL_P(execarg_obj)) {
5974  rb_execarg_fixup(execarg_obj);
5975  rb_execarg_run_options(eargp, sargp, NULL, 0);
5976  }
5977  fp = popen(cmd, modestr);
5978  if (eargp)
5979  rb_execarg_run_options(sargp, NULL, NULL, 0);
5980  if (!fp) rb_sys_fail_path(prog);
5981  fd = fileno(fp);
5982 #endif
5983 
5984  port = io_alloc(rb_cIO);
5985  MakeOpenFile(port, fptr);
5986  fptr->fd = fd;
5987  fptr->stdio_file = fp;
5988  fptr->mode = fmode | FMODE_SYNC|FMODE_DUPLEX;
5989  if (convconfig) {
5990  fptr->encs = *convconfig;
5991 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
5994  }
5995 #endif
5996  }
5997  else {
5998  if (NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
6000  }
6001 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
6002  if (NEED_NEWLINE_DECORATOR_ON_WRITE(fptr)) {
6003  fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
6004  }
6005 #endif
6006  }
6007  fptr->pid = pid;
6008 
6009  if (0 <= write_fd) {
6010  write_port = io_alloc(rb_cIO);
6011  MakeOpenFile(write_port, write_fptr);
6012  write_fptr->fd = write_fd;
6013  write_fptr->mode = (fmode & ~FMODE_READABLE)| FMODE_SYNC|FMODE_DUPLEX;
6014  fptr->mode &= ~FMODE_WRITABLE;
6015  fptr->tied_io_for_writing = write_port;
6016  rb_ivar_set(port, rb_intern("@tied_io_for_writing"), write_port);
6017  }
6018 
6019 #if defined (__CYGWIN__) || !defined(HAVE_FORK)
6020  fptr->finalize = pipe_finalize;
6021  pipe_add_fptr(fptr);
6022 #endif
6023  return port;
6024 }
6025 
6026 static int
6028 {
6029  if (RSTRING_LEN(prog) == 1 && RSTRING_PTR(prog)[0] == '-') {
6030 #if !defined(HAVE_FORK)
6032  "fork() function is unimplemented on this machine");
6033 #else
6034  return TRUE;
6035 #endif
6036  }
6037  return FALSE;
6038 }
6039 
6040 static VALUE
6041 pipe_open_s(VALUE prog, const char *modestr, int fmode, convconfig_t *convconfig)
6042 {
6043  int argc = 1;
6044  VALUE *argv = &prog;
6045  VALUE execarg_obj = Qnil;
6046 
6047  if (!is_popen_fork(prog))
6048  execarg_obj = rb_execarg_new(argc, argv, TRUE);
6049  return pipe_open(execarg_obj, modestr, fmode, convconfig);
6050 }
6051 
6052 /*
6053  * call-seq:
6054  * IO.popen([env,] cmd, mode="r" [, opt]) -> io
6055  * IO.popen([env,] cmd, mode="r" [, opt]) {|io| block } -> obj
6056  *
6057  * Runs the specified command as a subprocess; the subprocess's
6058  * standard input and output will be connected to the returned
6059  * <code>IO</code> object.
6060  *
6061  * The PID of the started process can be obtained by IO#pid method.
6062  *
6063  * _cmd_ is a string or an array as follows.
6064  *
6065  * cmd:
6066  * "-" : fork
6067  * commandline : command line string which is passed to a shell
6068  * [env, cmdname, arg1, ..., opts] : command name and zero or more arguments (no shell)
6069  * [env, [cmdname, argv0], arg1, ..., opts] : command name, argv[0] and zero or more arguments (no shell)
6070  * (env and opts are optional.)
6071  *
6072  * If _cmd_ is a +String+ ``<code>-</code>'',
6073  * then a new instance of Ruby is started as the subprocess.
6074  *
6075  * If <i>cmd</i> is an +Array+ of +String+,
6076  * then it will be used as the subprocess's +argv+ bypassing a shell.
6077  * The array can contains a hash at first for environments and
6078  * a hash at last for options similar to <code>spawn</code>.
6079  *
6080  * The default mode for the new file object is ``r'',
6081  * but <i>mode</i> may be set to any of the modes listed in the description for class IO.
6082  * The last argument <i>opt</i> qualifies <i>mode</i>.
6083  *
6084  * # set IO encoding
6085  * IO.popen("nkf -e filename", :external_encoding=>"EUC-JP") {|nkf_io|
6086  * euc_jp_string = nkf_io.read
6087  * }
6088  *
6089  * # merge standard output and standard error using
6090  * # spawn option. See the document of Kernel.spawn.
6091  * IO.popen(["ls", "/", :err=>[:child, :out]]) {|ls_io|
6092  * ls_result_with_error = ls_io.read
6093  * }
6094  *
6095  * # spawn options can be mixed with IO options
6096  * IO.popen(["ls", "/"], :err=>[:child, :out]) {|ls_io|
6097  * ls_result_with_error = ls_io.read
6098  * }
6099  *
6100  * Raises exceptions which <code>IO.pipe</code> and
6101  * <code>Kernel.spawn</code> raise.
6102  *
6103  * If a block is given, Ruby will run the command as a child connected
6104  * to Ruby with a pipe. Ruby's end of the pipe will be passed as a
6105  * parameter to the block.
6106  * At the end of block, Ruby close the pipe and sets <code>$?</code>.
6107  * In this case <code>IO.popen</code> returns
6108  * the value of the block.
6109  *
6110  * If a block is given with a _cmd_ of ``<code>-</code>'',
6111  * the block will be run in two separate processes: once in the parent,
6112  * and once in a child. The parent process will be passed the pipe
6113  * object as a parameter to the block, the child version of the block
6114  * will be passed <code>nil</code>, and the child's standard in and
6115  * standard out will be connected to the parent through the pipe. Not
6116  * available on all platforms.
6117  *
6118  * f = IO.popen("uname")
6119  * p f.readlines
6120  * f.close
6121  * puts "Parent is #{Process.pid}"
6122  * IO.popen("date") { |f| puts f.gets }
6123  * IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f.inspect}"}
6124  * p $?
6125  * IO.popen(%w"sed -e s|^|<foo>| -e s&$&;zot;&", "r+") {|f|
6126  * f.puts "bar"; f.close_write; puts f.gets
6127  * }
6128  *
6129  * <em>produces:</em>
6130  *
6131  * ["Linux\n"]
6132  * Parent is 21346
6133  * Thu Jan 15 22:41:19 JST 2009
6134  * 21346 is here, f is #<IO:fd 3>
6135  * 21352 is here, f is nil
6136  * #<Process::Status: pid 21352 exit 0>
6137  * <foo>bar;zot;
6138  */
6139 
6140 static VALUE
6142 {
6143  const char *modestr;
6144  VALUE pname, pmode = Qnil, port, tmp, opt = Qnil, env = Qnil, execarg_obj = Qnil;
6145  int oflags, fmode;
6146  convconfig_t convconfig;
6147 
6148  if (argc > 1 && !NIL_P(opt = rb_check_hash_type(argv[argc-1]))) --argc;
6149  if (argc > 1 && !NIL_P(env = rb_check_hash_type(argv[0]))) --argc, ++argv;
6150  switch (argc) {
6151  case 2:
6152  pmode = argv[1];
6153  case 1:
6154  pname = argv[0];
6155  break;
6156  default:
6157  {
6158  int ex = !NIL_P(opt);
6159  rb_error_arity(argc + ex, 1 + ex, 2 + ex);
6160  }
6161  }
6162 
6163  tmp = rb_check_array_type(pname);
6164  if (!NIL_P(tmp)) {
6165  long len = RARRAY_LEN(tmp);
6166 #if SIZEOF_LONG > SIZEOF_INT
6167  if (len > INT_MAX) {
6168  rb_raise(rb_eArgError, "too many arguments");
6169  }
6170 #endif
6171  tmp = rb_ary_dup(tmp);
6172  RBASIC_CLEAR_CLASS(tmp);
6173  execarg_obj = rb_execarg_new((int)len, RARRAY_PTR(tmp), FALSE);
6174  rb_ary_clear(tmp);
6175  }
6176  else {
6177  SafeStringValue(pname);
6178  execarg_obj = Qnil;
6179  if (!is_popen_fork(pname))
6180  execarg_obj = rb_execarg_new(1, &pname, TRUE);
6181  }
6182  if (!NIL_P(execarg_obj)) {
6183  if (!NIL_P(opt))
6184  opt = rb_execarg_extract_options(execarg_obj, opt);
6185  if (!NIL_P(env))
6186  rb_execarg_setenv(execarg_obj, env);
6187  }
6188  rb_io_extract_modeenc(&pmode, 0, opt, &oflags, &fmode, &convconfig);
6189  modestr = rb_io_oflags_modestr(oflags);
6190 
6191  port = pipe_open(execarg_obj, modestr, fmode, &convconfig);
6192  if (NIL_P(port)) {
6193  /* child */
6194  if (rb_block_given_p()) {
6195  rb_yield(Qnil);
6198  _exit(0);
6199  }
6200  return Qnil;
6201  }
6202  RBASIC_SET_CLASS(port, klass);
6203  if (rb_block_given_p()) {
6204  return rb_ensure(rb_yield, port, io_close, port);
6205  }
6206  return port;
6207 }
6208 
6209 static void
6211  VALUE *fname_p, int *oflags_p, int *fmode_p,
6212  convconfig_t *convconfig_p, mode_t *perm_p)
6213 {
6214  VALUE opt, fname, vmode, vperm;
6215  int oflags, fmode;
6216  mode_t perm;
6217 
6218  argc = rb_scan_args(argc, argv, "12:", &fname, &vmode, &vperm, &opt);
6219  FilePathValue(fname);
6220 
6221  rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, convconfig_p);
6222 
6223  perm = NIL_P(vperm) ? 0666 : NUM2MODET(vperm);
6224 
6225  *fname_p = fname;
6226  *oflags_p = oflags;
6227  *fmode_p = fmode;
6228  *perm_p = perm;
6229 }
6230 
6231 static VALUE
6233 {
6234  VALUE fname;
6235  int oflags, fmode;
6236  convconfig_t convconfig;
6237  mode_t perm;
6238 
6239  rb_scan_open_args(argc, argv, &fname, &oflags, &fmode, &convconfig, &perm);
6240  rb_file_open_generic(io, fname, oflags, fmode, &convconfig, perm);
6241 
6242  return io;
6243 }
6244 
6245 
6246 /*
6247  * Document-method: File::open
6248  *
6249  * call-seq:
6250  * File.open(filename, mode="r" [, opt]) -> file
6251  * File.open(filename [, mode [, perm]] [, opt]) -> file
6252  * File.open(filename, mode="r" [, opt]) {|file| block } -> obj
6253  * File.open(filename [, mode [, perm]] [, opt]) {|file| block } -> obj
6254  *
6255  * With no associated block, <code>File.open</code> is a synonym for
6256  * File.new. If the optional code block is given, it will
6257  * be passed the opened +file+ as an argument and the File object will
6258  * automatically be closed when the block terminates. The value of the block
6259  * will be returned from <code>File.open</code>.
6260  *
6261  * If a file is being created, its initial permissions may be set using the
6262  * +perm+ parameter. See File.new for further discussion.
6263  *
6264  * See IO.new for a description of the +mode+ and +opt+ parameters.
6265  */
6266 
6267 /*
6268  * Document-method: IO::open
6269  *
6270  * call-seq:
6271  * IO.open(fd, mode="r" [, opt]) -> io
6272  * IO.open(fd, mode="r" [, opt]) { |io| block } -> obj
6273  *
6274  * With no associated block, <code>IO.open</code> is a synonym for IO.new. If
6275  * the optional code block is given, it will be passed +io+ as an argument,
6276  * and the IO object will automatically be closed when the block terminates.
6277  * In this instance, IO.open returns the value of the block.
6278  *
6279  * See IO.new for a description of the +fd+, +mode+ and +opt+ parameters.
6280  */
6281 
6282 static VALUE
6284 {
6285  VALUE io = rb_class_new_instance(argc, argv, klass);
6286 
6287  if (rb_block_given_p()) {
6288  return rb_ensure(rb_yield, io, io_close, io);
6289  }
6290 
6291  return io;
6292 }
6293 
6294 /*
6295  * call-seq:
6296  * IO.sysopen(path, [mode, [perm]]) -> fixnum
6297  *
6298  * Opens the given path, returning the underlying file descriptor as a
6299  * <code>Fixnum</code>.
6300  *
6301  * IO.sysopen("testfile") #=> 3
6302  */
6303 
6304 static VALUE
6306 {
6307  VALUE fname, vmode, vperm;
6308  VALUE intmode;
6309  int oflags, fd;
6310  mode_t perm;
6311 
6312  rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm);
6313  FilePathValue(fname);
6314 
6315  if (NIL_P(vmode))
6316  oflags = O_RDONLY;
6317  else if (!NIL_P(intmode = rb_check_to_integer(vmode, "to_int")))
6318  oflags = NUM2INT(intmode);
6319  else {
6320  SafeStringValue(vmode);
6321  oflags = rb_io_modestr_oflags(StringValueCStr(vmode));
6322  }
6323  if (NIL_P(vperm)) perm = 0666;
6324  else perm = NUM2MODET(vperm);
6325 
6326  RB_GC_GUARD(fname) = rb_str_new4(fname);
6327  fd = rb_sysopen(fname, oflags, perm);
6328  return INT2NUM(fd);
6329 }
6330 
6331 static VALUE
6332 check_pipe_command(VALUE filename_or_command)
6333 {
6334  char *s = RSTRING_PTR(filename_or_command);
6335  long l = RSTRING_LEN(filename_or_command);
6336  char *e = s + l;
6337  int chlen;
6338 
6339  if (rb_enc_ascget(s, e, &chlen, rb_enc_get(filename_or_command)) == '|') {
6340  VALUE cmd = rb_str_new(s+chlen, l-chlen);
6341  OBJ_INFECT(cmd, filename_or_command);
6342  return cmd;
6343  }
6344  return Qnil;
6345 }
6346 
6347 /*
6348  * call-seq:
6349  * open(path [, mode [, perm]] [, opt]) -> io or nil
6350  * open(path [, mode [, perm]] [, opt]) {|io| block } -> obj
6351  *
6352  * Creates an IO object connected to the given stream, file, or subprocess.
6353  *
6354  * If +path+ does not start with a pipe character (<code>|</code>), treat it
6355  * as the name of a file to open using the specified mode (defaulting to
6356  * "r").
6357  *
6358  * The +mode+ is either a string or an integer. If it is an integer, it
6359  * must be bitwise-or of open(2) flags, such as File::RDWR or File::EXCL. If
6360  * it is a string, it is either "fmode", "fmode:ext_enc", or
6361  * "fmode:ext_enc:int_enc".
6362  *
6363  * See the documentation of IO.new for full documentation of the +mode+ string
6364  * directives.
6365  *
6366  * If a file is being created, its initial permissions may be set using the
6367  * +perm+ parameter. See File.new and the open(2) and chmod(2) man pages for
6368  * a description of permissions.
6369  *
6370  * If a block is specified, it will be invoked with the IO object as a
6371  * parameter, and the IO will be automatically closed when the block
6372  * terminates. The call returns the value of the block.
6373  *
6374  * If +path+ starts with a pipe character (<code>"|"</code>), a subprocess is
6375  * created, connected to the caller by a pair of pipes. The returned IO
6376  * object may be used to write to the standard input and read from the
6377  * standard output of this subprocess.
6378  *
6379  * If the command following the pipe is a single minus sign
6380  * (<code>"|-"</code>), Ruby forks, and this subprocess is connected to the
6381  * parent. If the command is not <code>"-"</code>, the subprocess runs the
6382  * command.
6383  *
6384  * When the subprocess is ruby (opened via <code>"|-"</code>), the +open+
6385  * call returns +nil+. If a block is associated with the open call, that
6386  * block will run twice --- once in the parent and once in the child.
6387  *
6388  * The block parameter will be an IO object in the parent and +nil+ in the
6389  * child. The parent's +IO+ object will be connected to the child's $stdin
6390  * and $stdout. The subprocess will be terminated at the end of the block.
6391  *
6392  * === Examples
6393  *
6394  * Reading from "testfile":
6395  *
6396  * open("testfile") do |f|
6397  * print f.gets
6398  * end
6399  *
6400  * Produces:
6401  *
6402  * This is line one
6403  *
6404  * Open a subprocess and read its output:
6405  *
6406  * cmd = open("|date")
6407  * print cmd.gets
6408  * cmd.close
6409  *
6410  * Produces:
6411  *
6412  * Wed Apr 9 08:56:31 CDT 2003
6413  *
6414  * Open a subprocess running the same Ruby program:
6415  *
6416  * f = open("|-", "w+")
6417  * if f == nil
6418  * puts "in Child"
6419  * exit
6420  * else
6421  * puts "Got: #{f.gets}"
6422  * end
6423  *
6424  * Produces:
6425  *
6426  * Got: in Child
6427  *
6428  * Open a subprocess using a block to receive the IO object:
6429  *
6430  * open "|-" do |f|
6431  * if f then
6432  * # parent process
6433  * puts "Got: #{f.gets}"
6434  * else
6435  * # child process
6436  * puts "in Child"
6437  * end
6438  * end
6439  *
6440  * Produces:
6441  *
6442  * Got: in Child
6443  */
6444 
6445 static VALUE
6447 {
6448  ID to_open = 0;
6449  int redirect = FALSE;
6450 
6451  if (argc >= 1) {
6452  CONST_ID(to_open, "to_open");
6453  if (rb_respond_to(argv[0], to_open)) {
6454  redirect = TRUE;
6455  }
6456  else {
6457  VALUE tmp = argv[0];
6458  FilePathValue(tmp);
6459  if (NIL_P(tmp)) {
6460  redirect = TRUE;
6461  }
6462  else {
6463  VALUE cmd = check_pipe_command(tmp);
6464  if (!NIL_P(cmd)) {
6465  argv[0] = cmd;
6466  return rb_io_s_popen(argc, argv, rb_cIO);
6467  }
6468  }
6469  }
6470  }
6471  if (redirect) {
6472  VALUE io = rb_funcall2(argv[0], to_open, argc-1, argv+1);
6473 
6474  if (rb_block_given_p()) {
6475  return rb_ensure(rb_yield, io, io_close, io);
6476  }
6477  return io;
6478  }
6479  return rb_io_s_open(argc, argv, rb_cFile);
6480 }
6481 
6482 static VALUE
6483 rb_io_open(VALUE filename, VALUE vmode, VALUE vperm, VALUE opt)
6484 {
6485  VALUE cmd;
6486  int oflags, fmode;
6487  convconfig_t convconfig;
6488  mode_t perm;
6489 
6490  rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, &convconfig);
6491  perm = NIL_P(vperm) ? 0666 : NUM2MODET(vperm);
6492 
6493  if (!NIL_P(cmd = check_pipe_command(filename))) {
6494  return pipe_open_s(cmd, rb_io_oflags_modestr(oflags), fmode, &convconfig);
6495  }
6496  else {
6497  return rb_file_open_generic(io_alloc(rb_cFile), filename,
6498  oflags, fmode, &convconfig, perm);
6499  }
6500 }
6501 
6502 static VALUE
6504 {
6505  VALUE io;
6506 
6507  io = io_alloc(rb_cFile);
6508  rb_open_file(argc, argv, io);
6509  return io;
6510 }
6511 
6512 static VALUE
6514 {
6515  rb_io_t *fptr, *orig;
6516  int fd, fd2;
6517  off_t pos = 0;
6518 
6519  nfile = rb_io_get_io(nfile);
6520  GetOpenFile(io, fptr);
6521  GetOpenFile(nfile, orig);
6522 
6523  if (fptr == orig) return io;
6524  if (IS_PREP_STDIO(fptr)) {
6525  if ((fptr->stdio_file == stdin && !(orig->mode & FMODE_READABLE)) ||
6526  (fptr->stdio_file == stdout && !(orig->mode & FMODE_WRITABLE)) ||
6527  (fptr->stdio_file == stderr && !(orig->mode & FMODE_WRITABLE))) {
6529  "%s can't change access mode from \"%s\" to \"%s\"",
6531  rb_io_fmode_modestr(orig->mode));
6532  }
6533  }
6534  if (fptr->mode & FMODE_WRITABLE) {
6535  if (io_fflush(fptr) < 0)
6536  rb_sys_fail(0);
6537  }
6538  else {
6539  io_tell(fptr);
6540  }
6541  if (orig->mode & FMODE_READABLE) {
6542  pos = io_tell(orig);
6543  }
6544  if (orig->mode & FMODE_WRITABLE) {
6545  if (io_fflush(orig) < 0)
6546  rb_sys_fail(0);
6547  }
6548 
6549  /* copy rb_io_t structure */
6550  fptr->mode = orig->mode | (fptr->mode & FMODE_PREP);
6551  fptr->pid = orig->pid;
6552  fptr->lineno = orig->lineno;
6553  if (RTEST(orig->pathv)) fptr->pathv = orig->pathv;
6554  else if (!IS_PREP_STDIO(fptr)) fptr->pathv = Qnil;
6555  fptr->finalize = orig->finalize;
6556 #if defined (__CYGWIN__) || !defined(HAVE_FORK)
6557  if (fptr->finalize == pipe_finalize)
6558  pipe_add_fptr(fptr);
6559 #endif
6560 
6561  fd = fptr->fd;
6562  fd2 = orig->fd;
6563  if (fd != fd2) {
6564  if (IS_PREP_STDIO(fptr) || fd <= 2 || !fptr->stdio_file) {
6565  /* need to keep FILE objects of stdin, stdout and stderr */
6566  if (rb_cloexec_dup2(fd2, fd) < 0)
6567  rb_sys_fail_path(orig->pathv);
6568  rb_update_max_fd(fd);
6569  }
6570  else {
6571  fclose(fptr->stdio_file);
6572  fptr->stdio_file = 0;
6573  fptr->fd = -1;
6574  if (rb_cloexec_dup2(fd2, fd) < 0)
6575  rb_sys_fail_path(orig->pathv);
6576  rb_update_max_fd(fd);
6577  fptr->fd = fd;
6578  }
6579  rb_thread_fd_close(fd);
6580  if ((orig->mode & FMODE_READABLE) && pos >= 0) {
6581  if (io_seek(fptr, pos, SEEK_SET) < 0 && errno) {
6582  rb_sys_fail_path(fptr->pathv);
6583  }
6584  if (io_seek(orig, pos, SEEK_SET) < 0 && errno) {
6585  rb_sys_fail_path(orig->pathv);
6586  }
6587  }
6588  }
6589 
6590  if (fptr->mode & FMODE_BINMODE) {
6591  rb_io_binmode(io);
6592  }
6593 
6594  RBASIC_SET_CLASS(io, rb_obj_class(nfile));
6595  return io;
6596 }
6597 
6598 /*
6599  * call-seq:
6600  * ios.reopen(other_IO) -> ios
6601  * ios.reopen(path, mode_str) -> ios
6602  *
6603  * Reassociates <em>ios</em> with the I/O stream given in
6604  * <i>other_IO</i> or to a new stream opened on <i>path</i>. This may
6605  * dynamically change the actual class of this stream.
6606  *
6607  * f1 = File.new("testfile")
6608  * f2 = File.new("testfile")
6609  * f2.readlines[0] #=> "This is line one\n"
6610  * f2.reopen(f1) #=> #<File:testfile>
6611  * f2.readlines[0] #=> "This is line one\n"
6612  */
6613 
6614 static VALUE
6616 {
6617  VALUE fname, nmode, opt;
6618  int oflags;
6619  rb_io_t *fptr;
6620 
6621  if (rb_scan_args(argc, argv, "11:", &fname, &nmode, &opt) == 1) {
6622  VALUE tmp = rb_io_check_io(fname);
6623  if (!NIL_P(tmp)) {
6624  return io_reopen(file, tmp);
6625  }
6626  }
6627 
6628  FilePathValue(fname);
6629  rb_io_taint_check(file);
6630  fptr = RFILE(file)->fptr;
6631  if (!fptr) {
6632  fptr = RFILE(file)->fptr = ALLOC(rb_io_t);
6633  MEMZERO(fptr, rb_io_t, 1);
6634  }
6635 
6636  if (!NIL_P(nmode) || !NIL_P(opt)) {
6637  int fmode;
6638  convconfig_t convconfig;
6639 
6640  rb_io_extract_modeenc(&nmode, 0, opt, &oflags, &fmode, &convconfig);
6641  if (IS_PREP_STDIO(fptr) &&
6642  ((fptr->mode & FMODE_READWRITE) & (fmode & FMODE_READWRITE)) !=
6643  (fptr->mode & FMODE_READWRITE)) {
6645  "%s can't change access mode from \"%s\" to \"%s\"",
6647  rb_io_fmode_modestr(fmode));
6648  }
6649  fptr->mode = fmode;
6650  fptr->encs = convconfig;
6651  }
6652  else {
6653  oflags = rb_io_fmode_oflags(fptr->mode);
6654  }
6655 
6656  fptr->pathv = rb_str_new_frozen(fname);
6657  if (fptr->fd < 0) {
6658  fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666);
6659  fptr->stdio_file = 0;
6660  return file;
6661  }
6662 
6663  if (fptr->mode & FMODE_WRITABLE) {
6664  if (io_fflush(fptr) < 0)
6665  rb_sys_fail(0);
6666  }
6667  fptr->rbuf.off = fptr->rbuf.len = 0;
6668 
6669  if (fptr->stdio_file) {
6670  if (freopen(RSTRING_PTR(fptr->pathv), rb_io_oflags_modestr(oflags), fptr->stdio_file) == 0) {
6671  rb_sys_fail_path(fptr->pathv);
6672  }
6673  fptr->fd = fileno(fptr->stdio_file);
6674  rb_fd_fix_cloexec(fptr->fd);
6675 #ifdef USE_SETVBUF
6676  if (setvbuf(fptr->stdio_file, NULL, _IOFBF, 0) != 0)
6677  rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
6678 #endif
6679  if (fptr->stdio_file == stderr) {
6680  if (setvbuf(fptr->stdio_file, NULL, _IONBF, BUFSIZ) != 0)
6681  rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
6682  }
6683  else if (fptr->stdio_file == stdout && isatty(fptr->fd)) {
6684  if (setvbuf(fptr->stdio_file, NULL, _IOLBF, BUFSIZ) != 0)
6685  rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
6686  }
6687  }
6688  else {
6689  int tmpfd = rb_sysopen(fptr->pathv, oflags, 0666);
6690  int err = 0;
6691  if (rb_cloexec_dup2(tmpfd, fptr->fd) < 0)
6692  err = errno;
6693  (void)close(tmpfd);
6694  if (err) {
6695  rb_syserr_fail_path(err, fptr->pathv);
6696  }
6697  }
6698 
6699  return file;
6700 }
6701 
6702 /* :nodoc: */
6703 static VALUE
6705 {
6706  rb_io_t *fptr, *orig;
6707  int fd;
6708  VALUE write_io;
6709  off_t pos;
6710 
6711  io = rb_io_get_io(io);
6712  if (!OBJ_INIT_COPY(dest, io)) return dest;
6713  GetOpenFile(io, orig);
6714  MakeOpenFile(dest, fptr);
6715 
6716  rb_io_flush(io);
6717 
6718  /* copy rb_io_t structure */
6719  fptr->mode = orig->mode & ~FMODE_PREP;
6720  fptr->encs = orig->encs;
6721  fptr->pid = orig->pid;
6722  fptr->lineno = orig->lineno;
6723  if (!NIL_P(orig->pathv)) fptr->pathv = orig->pathv;
6724  fptr->finalize = orig->finalize;
6725 #if defined (__CYGWIN__) || !defined(HAVE_FORK)
6726  if (fptr->finalize == pipe_finalize)
6727  pipe_add_fptr(fptr);
6728 #endif
6729 
6730  fd = ruby_dup(orig->fd);
6731  fptr->fd = fd;
6732  pos = io_tell(orig);
6733  if (0 <= pos)
6734  io_seek(fptr, pos, SEEK_SET);
6735  if (fptr->mode & FMODE_BINMODE) {
6736  rb_io_binmode(dest);
6737  }
6738 
6739  write_io = GetWriteIO(io);
6740  if (io != write_io) {
6741  write_io = rb_obj_dup(write_io);
6742  fptr->tied_io_for_writing = write_io;
6743  rb_ivar_set(dest, rb_intern("@tied_io_for_writing"), write_io);
6744  }
6745 
6746  return dest;
6747 }
6748 
6749 /*
6750  * call-seq:
6751  * ios.printf(format_string [, obj, ...]) -> nil
6752  *
6753  * Formats and writes to <em>ios</em>, converting parameters under
6754  * control of the format string. See <code>Kernel#sprintf</code>
6755  * for details.
6756  */
6757 
6758 VALUE
6760 {
6761  rb_io_write(out, rb_f_sprintf(argc, argv));
6762  return Qnil;
6763 }
6764 
6765 /*
6766  * call-seq:
6767  * printf(io, string [, obj ... ]) -> nil
6768  * printf(string [, obj ... ]) -> nil
6769  *
6770  * Equivalent to:
6771  * io.write(sprintf(string, obj, ...))
6772  * or
6773  * $stdout.write(sprintf(string, obj, ...))
6774  */
6775 
6776 static VALUE
6778 {
6779  VALUE out;
6780 
6781  if (argc == 0) return Qnil;
6782  if (RB_TYPE_P(argv[0], T_STRING)) {
6783  out = rb_stdout;
6784  }
6785  else {
6786  out = argv[0];
6787  argv++;
6788  argc--;
6789  }
6790  rb_io_write(out, rb_f_sprintf(argc, argv));
6791 
6792  return Qnil;
6793 }
6794 
6795 /*
6796  * call-seq:
6797  * ios.print() -> nil
6798  * ios.print(obj, ...) -> nil
6799  *
6800  * Writes the given object(s) to <em>ios</em>. The stream must be
6801  * opened for writing. If the output field separator (<code>$,</code>)
6802  * is not <code>nil</code>, it will be inserted between each object.
6803  * If the output record separator (<code>$\</code>)
6804  * is not <code>nil</code>, it will be appended to the output. If no
6805  * arguments are given, prints <code>$_</code>. Objects that aren't
6806  * strings will be converted by calling their <code>to_s</code> method.
6807  * With no argument, prints the contents of the variable <code>$_</code>.
6808  * Returns <code>nil</code>.
6809  *
6810  * $stdout.print("This is ", 100, " percent.\n")
6811  *
6812  * <em>produces:</em>
6813  *
6814  * This is 100 percent.
6815  */
6816 
6817 VALUE
6819 {
6820  int i;
6821  VALUE line;
6822 
6823  /* if no argument given, print `$_' */
6824  if (argc == 0) {
6825  argc = 1;
6826  line = rb_lastline_get();
6827  argv = &line;
6828  }
6829  for (i=0; i<argc; i++) {
6830  if (!NIL_P(rb_output_fs) && i>0) {
6831  rb_io_write(out, rb_output_fs);
6832  }
6833  rb_io_write(out, argv[i]);
6834  }
6835  if (argc > 0 && !NIL_P(rb_output_rs)) {
6836  rb_io_write(out, rb_output_rs);
6837  }
6838 
6839  return Qnil;
6840 }
6841 
6842 /*
6843  * call-seq:
6844  * print(obj, ...) -> nil
6845  *
6846  * Prints each object in turn to <code>$stdout</code>. If the output
6847  * field separator (<code>$,</code>) is not +nil+, its
6848  * contents will appear between each field. If the output record
6849  * separator (<code>$\</code>) is not +nil+, it will be
6850  * appended to the output. If no arguments are given, prints
6851  * <code>$_</code>. Objects that aren't strings will be converted by
6852  * calling their <code>to_s</code> method.
6853  *
6854  * print "cat", [1,2,3], 99, "\n"
6855  * $, = ", "
6856  * $\ = "\n"
6857  * print "cat", [1,2,3], 99
6858  *
6859  * <em>produces:</em>
6860  *
6861  * cat12399
6862  * cat, 1, 2, 3, 99
6863  */
6864 
6865 static VALUE
6867 {
6868  rb_io_print(argc, argv, rb_stdout);
6869  return Qnil;
6870 }
6871 
6872 /*
6873  * call-seq:
6874  * ios.putc(obj) -> obj
6875  *
6876  * If <i>obj</i> is <code>Numeric</code>, write the character whose code is
6877  * the least-significant byte of <i>obj</i>, otherwise write the first byte
6878  * of the string representation of <i>obj</i> to <em>ios</em>. Note: This
6879  * method is not safe for use with multi-byte characters as it will truncate
6880  * them.
6881  *
6882  * $stdout.putc "A"
6883  * $stdout.putc 65
6884  *
6885  * <em>produces:</em>
6886  *
6887  * AA
6888  */
6889 
6890 static VALUE
6892 {
6893  VALUE str;
6894  if (RB_TYPE_P(ch, T_STRING)) {
6895  str = rb_str_substr(ch, 0, 1);
6896  }
6897  else {
6898  char c = NUM2CHR(ch);
6899  str = rb_str_new(&c, 1);
6900  }
6901  rb_io_write(io, str);
6902  return ch;
6903 }
6904 
6905 /*
6906  * call-seq:
6907  * putc(int) -> int
6908  *
6909  * Equivalent to:
6910  *
6911  * $stdout.putc(int)
6912  *
6913  * Refer to the documentation for IO#putc for important information regarding
6914  * multi-byte characters.
6915  */
6916 
6917 static VALUE
6919 {
6920  if (recv == rb_stdout) {
6921  return rb_io_putc(recv, ch);
6922  }
6923  return rb_funcall2(rb_stdout, rb_intern("putc"), 1, &ch);
6924 }
6925 
6926 
6927 static int
6929 {
6930  long len = RSTRING_LEN(str);
6931  const char *ptr = RSTRING_PTR(str);
6933  int n;
6934 
6935  if (len == 0) return 0;
6936  if ((n = rb_enc_mbminlen(enc)) == 1) {
6937  return ptr[len - 1] == c;
6938  }
6939  return rb_enc_ascget(ptr + ((len - 1) / n) * n, ptr + len, &n, enc) == c;
6940 }
6941 
6942 static VALUE
6944 {
6945  VALUE tmp;
6946  long i;
6947 
6948  if (recur) {
6949  tmp = rb_str_new2("[...]");
6950  rb_io_puts(1, &tmp, out);
6951  return Qtrue;
6952  }
6953  ary = rb_check_array_type(ary);
6954  if (NIL_P(ary)) return Qfalse;
6955  for (i=0; i<RARRAY_LEN(ary); i++) {
6956  tmp = RARRAY_AREF(ary, i);
6957  rb_io_puts(1, &tmp, out);
6958  }
6959  return Qtrue;
6960 }
6961 
6962 /*
6963  * call-seq:
6964  * ios.puts(obj, ...) -> nil
6965  *
6966  * Writes the given objects to <em>ios</em> as with
6967  * <code>IO#print</code>. Writes a record separator (typically a
6968  * newline) after any that do not already end with a newline sequence.
6969  * If called with an array argument, writes each element on a new line.
6970  * If called without arguments, outputs a single record separator.
6971  *
6972  * $stdout.puts("this", "is", "a", "test")
6973  *
6974  * <em>produces:</em>
6975  *
6976  * this
6977  * is
6978  * a
6979  * test
6980  */
6981 
6982 VALUE
6984 {
6985  int i;
6986  VALUE line;
6987 
6988  /* if no argument given, print newline. */
6989  if (argc == 0) {
6990  rb_io_write(out, rb_default_rs);
6991  return Qnil;
6992  }
6993  for (i=0; i<argc; i++) {
6994  if (RB_TYPE_P(argv[i], T_STRING)) {
6995  line = argv[i];
6996  goto string;
6997  }
6998  if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
6999  continue;
7000  }
7001  line = rb_obj_as_string(argv[i]);
7002  string:
7003  rb_io_write(out, line);
7004  if (RSTRING_LEN(line) == 0 ||
7005  !str_end_with_asciichar(line, '\n')) {
7006  rb_io_write(out, rb_default_rs);
7007  }
7008  }
7009 
7010  return Qnil;
7011 }
7012 
7013 /*
7014  * call-seq:
7015  * puts(obj, ...) -> nil
7016  *
7017  * Equivalent to
7018  *
7019  * $stdout.puts(obj, ...)
7020  */
7021 
7022 static VALUE
7024 {
7025  if (recv == rb_stdout) {
7026  return rb_io_puts(argc, argv, recv);
7027  }
7028  return rb_funcall2(rb_stdout, rb_intern("puts"), argc, argv);
7029 }
7030 
7031 void
7032 rb_p(VALUE obj) /* for debug print within C code */
7033 {
7034  VALUE str = rb_obj_as_string(rb_inspect(obj));
7035  if (RB_TYPE_P(rb_stdout, T_FILE) &&
7037  io_write(rb_stdout, str, 1);
7039  }
7040  else {
7041  rb_io_write(rb_stdout, str);
7043  }
7044 }
7045 
7046 struct rb_f_p_arg {
7047  int argc;
7049 };
7050 
7051 static VALUE
7053 {
7054  struct rb_f_p_arg *arg1 = (struct rb_f_p_arg*)arg;
7055  int argc = arg1->argc;
7056  VALUE *argv = arg1->argv;
7057  int i;
7058  VALUE ret = Qnil;
7059 
7060  for (i=0; i<argc; i++) {
7061  rb_p(argv[i]);
7062  }
7063  if (argc == 1) {
7064  ret = argv[0];
7065  }
7066  else if (argc > 1) {
7067  ret = rb_ary_new4(argc, argv);
7068  }
7069  if (RB_TYPE_P(rb_stdout, T_FILE)) {
7071  }
7072  return ret;
7073 }
7074 
7075 /*
7076  * call-seq:
7077  * p(obj) -> obj
7078  * p(obj1, obj2, ...) -> [obj, ...]
7079  * p() -> nil
7080  *
7081  * For each object, directly writes _obj_.+inspect+ followed by a
7082  * newline to the program's standard output.
7083  *
7084  * S = Struct.new(:name, :state)
7085  * s = S['dave', 'TX']
7086  * p s
7087  *
7088  * <em>produces:</em>
7089  *
7090  * #<S name="dave", state="TX">
7091  */
7092 
7093 static VALUE
7095 {
7096  struct rb_f_p_arg arg;
7097  arg.argc = argc;
7098  arg.argv = argv;
7099 
7100  return rb_uninterruptible(rb_f_p_internal, (VALUE)&arg);
7101 }
7102 
7103 /*
7104  * call-seq:
7105  * obj.display(port=$>) -> nil
7106  *
7107  * Prints <i>obj</i> on the given port (default <code>$></code>).
7108  * Equivalent to:
7109  *
7110  * def display(port=$>)
7111  * port.write self
7112  * end
7113  *
7114  * For example:
7115  *
7116  * 1.display
7117  * "cat".display
7118  * [ 4, 5, 6 ].display
7119  * puts
7120  *
7121  * <em>produces:</em>
7122  *
7123  * 1cat456
7124  */
7125 
7126 static VALUE
7128 {
7129  VALUE out;
7130 
7131  if (argc == 0) {
7132  out = rb_stdout;
7133  }
7134  else {
7135  rb_scan_args(argc, argv, "01", &out);
7136  }
7137  rb_io_write(out, self);
7138 
7139  return Qnil;
7140 }
7141 
7142 void
7143 rb_write_error2(const char *mesg, long len)
7144 {
7145  if (rb_stderr == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0) {
7146  if (fwrite(mesg, sizeof(char), (size_t)len, stderr) < (size_t)len) {
7147  /* failed to write to stderr, what can we do? */
7148  return;
7149  }
7150  }
7151  else {
7152  rb_io_write(rb_stderr, rb_str_new(mesg, len));
7153  }
7154 }
7155 
7156 void
7157 rb_write_error(const char *mesg)
7158 {
7159  rb_write_error2(mesg, strlen(mesg));
7160 }
7161 
7162 void
7164 {
7165  /* a stopgap measure for the time being */
7166  if (rb_stderr == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0) {
7167  size_t len = (size_t)RSTRING_LEN(mesg);
7168  if (fwrite(RSTRING_PTR(mesg), sizeof(char), len, stderr) < len) {
7169  RB_GC_GUARD(mesg);
7170  return;
7171  }
7172  }
7173  else {
7174  /* may unlock GVL, and */
7175  rb_io_write(rb_stderr, mesg);
7176  }
7177 }
7178 
7179 static void
7181 {
7182  if (!rb_respond_to(val, mid)) {
7183  rb_raise(rb_eTypeError, "%s must have %s method, %s given",
7184  rb_id2name(id), rb_id2name(mid),
7185  rb_obj_classname(val));
7186  }
7187 }
7188 
7189 static void
7190 stdout_setter(VALUE val, ID id, VALUE *variable)
7191 {
7192  must_respond_to(id_write, val, id);
7193  *variable = val;
7194 }
7195 
7196 static VALUE
7197 prep_io(int fd, int fmode, VALUE klass, const char *path)
7198 {
7199  rb_io_t *fp;
7200  VALUE io = io_alloc(klass);
7201 
7202  MakeOpenFile(io, fp);
7203  fp->fd = fd;
7204 #ifdef __CYGWIN__
7205  if (!isatty(fd)) {
7206  fmode |= FMODE_BINMODE;
7207  setmode(fd, O_BINARY);
7208  }
7209 #endif
7210  fp->mode = fmode;
7211  io_check_tty(fp);
7212  if (path) fp->pathv = rb_obj_freeze(rb_str_new_cstr(path));
7213  rb_update_max_fd(fd);
7214 
7215  return io;
7216 }
7217 
7218 VALUE
7219 rb_io_fdopen(int fd, int oflags, const char *path)
7220 {
7221  VALUE klass = rb_cIO;
7222 
7223  if (path && strcmp(path, "-")) klass = rb_cFile;
7224  return prep_io(fd, rb_io_oflags_fmode(oflags), klass, path);
7225 }
7226 
7227 static VALUE
7228 prep_stdio(FILE *f, int fmode, VALUE klass, const char *path)
7229 {
7230  rb_io_t *fptr;
7231  VALUE io = prep_io(fileno(f), fmode|FMODE_PREP|DEFAULT_TEXTMODE, klass, path);
7232 
7233  GetOpenFile(io, fptr);
7235 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
7236  fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
7237  if (fmode & FMODE_READABLE) {
7239  }
7240 #endif
7241  fptr->stdio_file = f;
7242 
7243  return io;
7244 }
7245 
7246 FILE *
7248 {
7249  if (!fptr->stdio_file) {
7250  int oflags = rb_io_fmode_oflags(fptr->mode);
7251  fptr->stdio_file = rb_fdopen(fptr->fd, rb_io_oflags_modestr(oflags));
7252  }
7253  return fptr->stdio_file;
7254 }
7255 
7256 /*
7257  * call-seq:
7258  * IO.new(fd [, mode] [, opt]) -> io
7259  *
7260  * Returns a new IO object (a stream) for the given integer file descriptor
7261  * +fd+ and +mode+ string. +opt+ may be used to specify parts of +mode+ in a
7262  * more readable fashion. See also IO.sysopen and IO.for_fd.
7263  *
7264  * IO.new is called by various File and IO opening methods such as IO::open,
7265  * Kernel#open, and File::open.
7266  *
7267  * === Open Mode
7268  *
7269  * When +mode+ is an integer it must be combination of the modes defined in
7270  * File::Constants (+File::RDONLY+, +File::WRONLY | File::CREAT+). See the
7271  * open(2) man page for more information.
7272  *
7273  * When +mode+ is a string it must be in one of the following forms:
7274  *
7275  * fmode
7276  * fmode ":" ext_enc
7277  * fmode ":" ext_enc ":" int_enc
7278  * fmode ":" "BOM|UTF-*"
7279  *
7280  * +fmode+ is an IO open mode string, +ext_enc+ is the external encoding for
7281  * the IO and +int_enc+ is the internal encoding.
7282  *
7283  * ==== IO Open Mode
7284  *
7285  * Ruby allows the following open modes:
7286  *
7287  * "r" Read-only, starts at beginning of file (default mode).
7288  *
7289  * "r+" Read-write, starts at beginning of file.
7290  *
7291  * "w" Write-only, truncates existing file
7292  * to zero length or creates a new file for writing.
7293  *
7294  * "w+" Read-write, truncates existing file to zero length
7295  * or creates a new file for reading and writing.
7296  *
7297  * "a" Write-only, each write call appends data at end of file.
7298  * Creates a new file for writing if file does not exist.
7299  *
7300  * "a+" Read-write, each write call appends data at end of file.
7301  * Creates a new file for reading and writing if file does
7302  * not exist.
7303  *
7304  * The following modes must be used separately, and along with one or more of
7305  * the modes seen above.
7306  *
7307  * "b" Binary file mode
7308  * Suppresses EOL <-> CRLF conversion on Windows. And
7309  * sets external encoding to ASCII-8BIT unless explicitly
7310  * specified.
7311  *
7312  * "t" Text file mode
7313  *
7314  * When the open mode of original IO is read only, the mode cannot be
7315  * changed to be writable. Similarly, the open mode cannot be changed from
7316  * write only to readable.
7317  *
7318  * When such a change is attempted the error is raised in different locations
7319  * according to the platform.
7320  *
7321  * === IO Encoding
7322  *
7323  * When +ext_enc+ is specified, strings read will be tagged by the encoding
7324  * when reading, and strings output will be converted to the specified
7325  * encoding when writing.
7326  *
7327  * When +ext_enc+ and +int_enc+ are specified read strings will be converted
7328  * from +ext_enc+ to +int_enc+ upon input, and written strings will be
7329  * converted from +int_enc+ to +ext_enc+ upon output. See Encoding for
7330  * further details of transcoding on input and output.
7331  *
7332  * If "BOM|UTF-8", "BOM|UTF-16LE" or "BOM|UTF16-BE" are used, ruby checks for
7333  * a Unicode BOM in the input document to help determine the encoding. For
7334  * UTF-16 encodings the file open mode must be binary. When present, the BOM
7335  * is stripped and the external encoding from the BOM is used. When the BOM
7336  * is missing the given Unicode encoding is used as +ext_enc+. (The BOM-set
7337  * encoding option is case insensitive, so "bom|utf-8" is also valid.)
7338  *
7339  * === Options
7340  *
7341  * +opt+ can be used instead of +mode+ for improved readability. The
7342  * following keys are supported:
7343  *
7344  * :mode ::
7345  * Same as +mode+ parameter
7346  *
7347  * :\external_encoding ::
7348  * External encoding for the IO. "-" is a synonym for the default external
7349  * encoding.
7350  *
7351  * :\internal_encoding ::
7352  * Internal encoding for the IO. "-" is a synonym for the default internal
7353  * encoding.
7354  *
7355  * If the value is nil no conversion occurs.
7356  *
7357  * :encoding ::
7358  * Specifies external and internal encodings as "extern:intern".
7359  *
7360  * :textmode ::
7361  * If the value is truth value, same as "t" in argument +mode+.
7362  *
7363  * :binmode ::
7364  * If the value is truth value, same as "b" in argument +mode+.
7365  *
7366  * :autoclose ::
7367  * If the value is +false+, the +fd+ will be kept open after this IO
7368  * instance gets finalized.
7369  *
7370  * Also, +opt+ can have same keys in String#encode for controlling conversion
7371  * between the external encoding and the internal encoding.
7372  *
7373  * === Example 1
7374  *
7375  * fd = IO.sysopen("/dev/tty", "w")
7376  * a = IO.new(fd,"w")
7377  * $stderr.puts "Hello"
7378  * a.puts "World"
7379  *
7380  * Produces:
7381  *
7382  * Hello
7383  * World
7384  *
7385  * === Example 2
7386  *
7387  * require 'fcntl'
7388  *
7389  * fd = STDERR.fcntl(Fcntl::F_DUPFD)
7390  * io = IO.new(fd, mode: 'w:UTF-16LE', cr_newline: true)
7391  * io.puts "Hello, World!"
7392  *
7393  * fd = STDERR.fcntl(Fcntl::F_DUPFD)
7394  * io = IO.new(fd, mode: 'w', cr_newline: true,
7395  * external_encoding: Encoding::UTF_16LE)
7396  * io.puts "Hello, World!"
7397  *
7398  * Both of above print "Hello, World!" in UTF-16LE to standard error output
7399  * with converting EOL generated by <code>puts</code> to CR.
7400  */
7401 
7402 static VALUE
7404 {
7405  VALUE fnum, vmode;
7406  rb_io_t *fp;
7407  int fd, fmode, oflags = O_RDONLY;
7408  convconfig_t convconfig;
7409  VALUE opt;
7410 #if defined(HAVE_FCNTL) && defined(F_GETFL)
7411  int ofmode;
7412 #else
7413  struct stat st;
7414 #endif
7415 
7416 
7417  argc = rb_scan_args(argc, argv, "11:", &fnum, &vmode, &opt);
7418  rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &fmode, &convconfig);
7419 
7420  fd = NUM2INT(fnum);
7421  if (rb_reserved_fd_p(fd)) {
7422  rb_raise(rb_eArgError, "The given fd is not accessible because RubyVM reserves it");
7423  }
7424 #if defined(HAVE_FCNTL) && defined(F_GETFL)
7425  oflags = fcntl(fd, F_GETFL);
7426  if (oflags == -1) rb_sys_fail(0);
7427 #else
7428  if (fstat(fd, &st) == -1) rb_sys_fail(0);
7429 #endif
7430  rb_update_max_fd(fd);
7431 #if defined(HAVE_FCNTL) && defined(F_GETFL)
7432  ofmode = rb_io_oflags_fmode(oflags);
7433  if (NIL_P(vmode)) {
7434  fmode = ofmode;
7435  }
7436  else if ((~ofmode & fmode) & FMODE_READWRITE) {
7437  VALUE error = INT2FIX(EINVAL);
7439  }
7440 #endif
7441  if (!NIL_P(opt) && rb_hash_aref(opt, sym_autoclose) == Qfalse) {
7442  fmode |= FMODE_PREP;
7443  }
7444  MakeOpenFile(io, fp);
7445  fp->fd = fd;
7446  fp->mode = fmode;
7447  fp->encs = convconfig;
7448  clear_codeconv(fp);
7449  io_check_tty(fp);
7450  if (fileno(stdin) == fd)
7451  fp->stdio_file = stdin;
7452  else if (fileno(stdout) == fd)
7453  fp->stdio_file = stdout;
7454  else if (fileno(stderr) == fd)
7455  fp->stdio_file = stderr;
7456 
7458  return io;
7459 }
7460 
7461 /*
7462  * call-seq:
7463  * File.new(filename, mode="r" [, opt]) -> file
7464  * File.new(filename [, mode [, perm]] [, opt]) -> file
7465  *
7466  * Opens the file named by +filename+ according to the given +mode+ and
7467  * returns a new File object.
7468  *
7469  * See IO.new for a description of +mode+ and +opt+.
7470  *
7471  * If a file is being created, permission bits may be given in +perm+. These
7472  * mode and permission bits are platform dependent; on Unix systems, see
7473  * open(2) and chmod(2) man pages for details.
7474  *
7475  * === Examples
7476  *
7477  * f = File.new("testfile", "r")
7478  * f = File.new("newfile", "w+")
7479  * f = File.new("newfile", File::CREAT|File::TRUNC|File::RDWR, 0644)
7480  */
7481 
7482 static VALUE
7484 {
7485  if (RFILE(io)->fptr) {
7486  rb_raise(rb_eRuntimeError, "reinitializing File");
7487  }
7488  if (0 < argc && argc < 3) {
7489  VALUE fd = rb_check_convert_type(argv[0], T_FIXNUM, "Fixnum", "to_int");
7490 
7491  if (!NIL_P(fd)) {
7492  argv[0] = fd;
7493  return rb_io_initialize(argc, argv, io);
7494  }
7495  }
7496  rb_open_file(argc, argv, io);
7497 
7498  return io;
7499 }
7500 
7501 /* :nodoc: */
7502 static VALUE
7504 {
7505  if (rb_block_given_p()) {
7506  const char *cname = rb_class2name(klass);
7507 
7508  rb_warn("%s::new() does not take block; use %s::open() instead",
7509  cname, cname);
7510  }
7511  return rb_class_new_instance(argc, argv, klass);
7512 }
7513 
7514 
7515 /*
7516  * call-seq:
7517  * IO.for_fd(fd, mode [, opt]) -> io
7518  *
7519  * Synonym for <code>IO.new</code>.
7520  *
7521  */
7522 
7523 static VALUE
7525 {
7526  VALUE io = rb_obj_alloc(klass);
7527  rb_io_initialize(argc, argv, io);
7528  return io;
7529 }
7530 
7531 /*
7532  * call-seq:
7533  * ios.autoclose? -> true or false
7534  *
7535  * Returns +true+ if the underlying file descriptor of _ios_ will be
7536  * closed automatically at its finalization, otherwise +false+.
7537  */
7538 
7539 static VALUE
7541 {
7542  rb_io_t *fptr = RFILE(io)->fptr;
7543  rb_io_check_closed(fptr);
7544  return (fptr->mode & FMODE_PREP) ? Qfalse : Qtrue;
7545 }
7546 
7547 /*
7548  * call-seq:
7549  * io.autoclose = bool -> true or false
7550  *
7551  * Sets auto-close flag.
7552  *
7553  * f = open("/dev/null")
7554  * IO.for_fd(f.fileno)
7555  * # ...
7556  * f.gets # may cause IOError
7557  *
7558  * f = open("/dev/null")
7559  * IO.for_fd(f.fileno).autoclose = true
7560  * # ...
7561  * f.gets # won't cause IOError
7562  */
7563 
7564 static VALUE
7566 {
7567  rb_io_t *fptr;
7568  GetOpenFile(io, fptr);
7569  if (!RTEST(autoclose))
7570  fptr->mode |= FMODE_PREP;
7571  else
7572  fptr->mode &= ~FMODE_PREP;
7573  return io;
7574 }
7575 
7576 static void
7577 argf_mark(void *ptr)
7578 {
7579  struct argf *p = ptr;
7580  rb_gc_mark(p->filename);
7582  rb_gc_mark(p->argv);
7583  rb_gc_mark(p->encs.ecopts);
7584 }
7585 
7586 static void
7587 argf_free(void *ptr)
7588 {
7589  struct argf *p = ptr;
7590  xfree(p->inplace);
7591  xfree(p);
7592 }
7593 
7594 static size_t
7595 argf_memsize(const void *ptr)
7596 {
7597  const struct argf *p = ptr;
7598  size_t size = sizeof(*p);
7599  if (!ptr) return 0;
7600  if (p->inplace) size += strlen(p->inplace) + 1;
7601  return size;
7602 }
7603 
7604 static const rb_data_type_t argf_type = {
7605  "ARGF",
7608 };
7609 
7610 static inline void
7611 argf_init(struct argf *p, VALUE v)
7612 {
7613  p->filename = Qnil;
7614  p->current_file = Qnil;
7615  p->lineno = 0;
7616  p->argv = v;
7617 }
7618 
7619 static VALUE
7621 {
7622  struct argf *p;
7623  VALUE argf = TypedData_Make_Struct(klass, struct argf, &argf_type, p);
7624 
7625  argf_init(p, Qnil);
7626  return argf;
7627 }
7628 
7629 #undef rb_argv
7630 
7631 /* :nodoc: */
7632 static VALUE
7634 {
7635  memset(&ARGF, 0, sizeof(ARGF));
7636  argf_init(&ARGF, argv);
7637 
7638  return argf;
7639 }
7640 
7641 /* :nodoc: */
7642 static VALUE
7644 {
7645  if (!OBJ_INIT_COPY(argf, orig)) return argf;
7646  ARGF = argf_of(orig);
7647  ARGF.argv = rb_obj_dup(ARGF.argv);
7648  if (ARGF.inplace) {
7649  const char *inplace = ARGF.inplace;
7650  ARGF.inplace = 0;
7651  ARGF.inplace = ruby_strdup(inplace);
7652  }
7653  return argf;
7654 }
7655 
7656 /*
7657  * call-seq:
7658  * ARGF.lineno = integer -> integer
7659  *
7660  * Sets the line number of +ARGF+ as a whole to the given +Integer+.
7661  *
7662  * +ARGF+ sets the line number automatically as you read data, so normally
7663  * you will not need to set it explicitly. To access the current line number
7664  * use +ARGF.lineno+.
7665  *
7666  * For example:
7667  *
7668  * ARGF.lineno #=> 0
7669  * ARGF.readline #=> "This is line 1\n"
7670  * ARGF.lineno #=> 1
7671  * ARGF.lineno = 0 #=> 0
7672  * ARGF.lineno #=> 0
7673  */
7674 static VALUE
7676 {
7677  ARGF.lineno = NUM2INT(val);
7678  ARGF.last_lineno = ARGF.lineno;
7679  return Qnil;
7680 }
7681 
7682 /*
7683  * call-seq:
7684  * ARGF.lineno -> integer
7685  *
7686  * Returns the current line number of ARGF as a whole. This value
7687  * can be set manually with +ARGF.lineno=+.
7688  *
7689  * For example:
7690  *
7691  * ARGF.lineno #=> 0
7692  * ARGF.readline #=> "This is line 1\n"
7693  * ARGF.lineno #=> 1
7694  */
7695 static VALUE
7697 {
7698  return INT2FIX(ARGF.lineno);
7699 }
7700 
7701 static VALUE
7703 {
7704  return rb_funcall3(ARGF.current_file, rb_frame_this_func(), argc, argv);
7705 }
7706 
7707 #define next_argv() argf_next_argv(argf)
7708 #define ARGF_GENERIC_INPUT_P() \
7709  (ARGF.current_file == rb_stdin && !RB_TYPE_P(ARGF.current_file, T_FILE))
7710 #define ARGF_FORWARD(argc, argv) do {\
7711  if (ARGF_GENERIC_INPUT_P())\
7712  return argf_forward((argc), (argv), argf);\
7713 } while (0)
7714 #define NEXT_ARGF_FORWARD(argc, argv) do {\
7715  if (!next_argv()) return Qnil;\
7716  ARGF_FORWARD((argc), (argv));\
7717 } while (0)
7718 
7719 static void
7721 {
7722  VALUE file = ARGF.current_file;
7723  if (file == rb_stdin) return;
7724  if (RB_TYPE_P(file, T_FILE)) {
7725  rb_io_set_write_io(file, Qnil);
7726  }
7727  rb_funcall3(file, rb_intern("close"), 0, 0);
7728  ARGF.init_p = -1;
7729 }
7730 
7731 static int
7733 {
7734  char *fn;
7735  rb_io_t *fptr;
7736  int stdout_binmode = 0;
7737  int fmode;
7738 
7739  if (RB_TYPE_P(rb_stdout, T_FILE)) {
7740  GetOpenFile(rb_stdout, fptr);
7741  if (fptr->mode & FMODE_BINMODE)
7742  stdout_binmode = 1;
7743  }
7744 
7745  if (ARGF.init_p == 0) {
7746  if (!NIL_P(ARGF.argv) && RARRAY_LEN(ARGF.argv) > 0) {
7747  ARGF.next_p = 1;
7748  }
7749  else {
7750  ARGF.next_p = -1;
7751  }
7752  ARGF.init_p = 1;
7753  }
7754  else {
7755  if (NIL_P(ARGF.argv)) {
7756  ARGF.next_p = -1;
7757  }
7758  else if (ARGF.next_p == -1 && RARRAY_LEN(ARGF.argv) > 0) {
7759  ARGF.next_p = 1;
7760  }
7761  }
7762 
7763  if (ARGF.next_p == 1) {
7764  retry:
7765  if (RARRAY_LEN(ARGF.argv) > 0) {
7766  ARGF.filename = rb_ary_shift(ARGF.argv);
7767  fn = StringValueCStr(ARGF.filename);
7768  if (strlen(fn) == 1 && fn[0] == '-') {
7769  ARGF.current_file = rb_stdin;
7770  if (ARGF.inplace) {
7771  rb_warn("Can't do inplace edit for stdio; skipping");
7772  goto retry;
7773  }
7774  }
7775  else {
7776  VALUE write_io = Qnil;
7777  int fr = rb_sysopen(ARGF.filename, O_RDONLY, 0);
7778 
7779  if (ARGF.inplace) {
7780  struct stat st;
7781 #ifndef NO_SAFE_RENAME
7782  struct stat st2;
7783 #endif
7784  VALUE str;
7785  int fw;
7786 
7789  }
7790  fstat(fr, &st);
7791  if (*ARGF.inplace) {
7792  str = rb_str_new2(fn);
7793  rb_str_cat2(str, ARGF.inplace);
7794 #ifdef NO_SAFE_RENAME
7795  (void)close(fr);
7796  (void)unlink(RSTRING_PTR(str));
7797  if (rename(fn, RSTRING_PTR(str)) < 0) {
7798  rb_warn("Can't rename %s to %s: %s, skipping file",
7799  fn, RSTRING_PTR(str), strerror(errno));
7800  goto retry;
7801  }
7802  fr = rb_sysopen(str, O_RDONLY, 0);
7803 #else
7804  if (rename(fn, RSTRING_PTR(str)) < 0) {
7805  rb_warn("Can't rename %s to %s: %s, skipping file",
7806  fn, RSTRING_PTR(str), strerror(errno));
7807  close(fr);
7808  goto retry;
7809  }
7810 #endif
7811  }
7812  else {
7813 #ifdef NO_SAFE_RENAME
7814  rb_fatal("Can't do inplace edit without backup");
7815 #else
7816  if (unlink(fn) < 0) {
7817  rb_warn("Can't remove %s: %s, skipping file",
7818  fn, strerror(errno));
7819  close(fr);
7820  goto retry;
7821  }
7822 #endif
7823  }
7824  fw = rb_sysopen(ARGF.filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
7825 #ifndef NO_SAFE_RENAME
7826  fstat(fw, &st2);
7827 #ifdef HAVE_FCHMOD
7828  fchmod(fw, st.st_mode);
7829 #else
7830  chmod(fn, st.st_mode);
7831 #endif
7832  if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) {
7833  int err;
7834 #ifdef HAVE_FCHOWN
7835  err = fchown(fw, st.st_uid, st.st_gid);
7836 #else
7837  err = chown(fn, st.st_uid, st.st_gid);
7838 #endif
7839  if (err && getuid() == 0 && st2.st_uid == 0) {
7840  const char *wkfn = RSTRING_PTR(ARGF.filename);
7841  rb_warn("Can't set owner/group of %s to same as %s: %s, skipping file",
7842  wkfn, fn, strerror(errno));
7843  (void)close(fr);
7844  (void)close(fw);
7845  (void)unlink(wkfn);
7846  goto retry;
7847  }
7848  }
7849 #endif
7850  write_io = prep_io(fw, FMODE_WRITABLE, rb_cFile, fn);
7851  rb_stdout = write_io;
7852  if (stdout_binmode) rb_io_binmode(rb_stdout);
7853  }
7854  fmode = FMODE_READABLE;
7855  if (!ARGF.binmode) {
7856  fmode |= DEFAULT_TEXTMODE;
7857  }
7858  ARGF.current_file = prep_io(fr, fmode, rb_cFile, fn);
7859  if (!NIL_P(write_io)) {
7860  rb_io_set_write_io(ARGF.current_file, write_io);
7861  }
7862  }
7863  if (ARGF.binmode) rb_io_ascii8bit_binmode(ARGF.current_file);
7864  GetOpenFile(ARGF.current_file, fptr);
7865  if (ARGF.encs.enc) {
7866  fptr->encs = ARGF.encs;
7867  clear_codeconv(fptr);
7868  }
7869  else {
7871  if (!ARGF.binmode) {
7873 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
7874  fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
7875 #endif
7876  }
7877  }
7878  ARGF.next_p = 0;
7879  }
7880  else {
7881  ARGF.next_p = 1;
7882  return FALSE;
7883  }
7884  }
7885  else if (ARGF.next_p == -1) {
7886  ARGF.current_file = rb_stdin;
7887  ARGF.filename = rb_str_new2("-");
7888  if (ARGF.inplace) {
7889  rb_warn("Can't do inplace edit for stdio");
7891  }
7892  }
7893  if (ARGF.init_p == -1) ARGF.init_p = 1;
7894  return TRUE;
7895 }
7896 
7897 static VALUE
7899 {
7900  VALUE line;
7901  long lineno = ARGF.lineno;
7902 
7903  retry:
7904  if (!next_argv()) return Qnil;
7905  if (ARGF_GENERIC_INPUT_P()) {
7906  line = rb_funcall3(ARGF.current_file, idGets, argc, argv);
7907  }
7908  else {
7909  if (argc == 0 && rb_rs == rb_default_rs) {
7910  line = rb_io_gets(ARGF.current_file);
7911  }
7912  else {
7913  line = rb_io_getline(argc, argv, ARGF.current_file);
7914  }
7915  if (NIL_P(line) && ARGF.next_p != -1) {
7916  argf_close(argf);
7917  ARGF.next_p = 1;
7918  goto retry;
7919  }
7920  }
7921  if (!NIL_P(line)) {
7922  ARGF.lineno = ++lineno;
7923  ARGF.last_lineno = ARGF.lineno;
7924  }
7925  return line;
7926 }
7927 
7928 static VALUE
7930 {
7931  VALUE argf = *var;
7932  return INT2FIX(ARGF.last_lineno);
7933 }
7934 
7935 static void
7937 {
7938  VALUE argf = *var;
7939  int n = NUM2INT(val);
7940  ARGF.last_lineno = ARGF.lineno = n;
7941 }
7942 
7943 static VALUE argf_gets(int, VALUE *, VALUE);
7944 
7945 /*
7946  * call-seq:
7947  * gets(sep=$/) -> string or nil
7948  * gets(limit) -> string or nil
7949  * gets(sep,limit) -> string or nil
7950  *
7951  * Returns (and assigns to <code>$_</code>) the next line from the list
7952  * of files in +ARGV+ (or <code>$*</code>), or from standard input if
7953  * no files are present on the command line. Returns +nil+ at end of
7954  * file. The optional argument specifies the record separator. The
7955  * separator is included with the contents of each record. A separator
7956  * of +nil+ reads the entire contents, and a zero-length separator
7957  * reads the input one paragraph at a time, where paragraphs are
7958  * divided by two consecutive newlines. If the first argument is an
7959  * integer, or optional second argument is given, the returning string
7960  * would not be longer than the given value in bytes. If multiple
7961  * filenames are present in +ARGV+, +gets(nil)+ will read the contents
7962  * one file at a time.
7963  *
7964  * ARGV << "testfile"
7965  * print while gets
7966  *
7967  * <em>produces:</em>
7968  *
7969  * This is line one
7970  * This is line two
7971  * This is line three
7972  * And so on...
7973  *
7974  * The style of programming using <code>$_</code> as an implicit
7975  * parameter is gradually losing favor in the Ruby community.
7976  */
7977 
7978 static VALUE
7980 {
7981  if (recv == argf) {
7982  return argf_gets(argc, argv, argf);
7983  }
7984  return rb_funcall2(argf, idGets, argc, argv);
7985 }
7986 
7987 /*
7988  * call-seq:
7989  * ARGF.gets(sep=$/) -> string or nil
7990  * ARGF.gets(limit) -> string or nil
7991  * ARGF.gets(sep, limit) -> string or nil
7992  *
7993  * Returns the next line from the current file in +ARGF+.
7994  *
7995  * By default lines are assumed to be separated by +$/+; to use a different
7996  * character as a separator, supply it as a +String+ for the _sep_ argument.
7997  *
7998  * The optional _limit_ argument specifies how many characters of each line
7999  * to return. By default all characters are returned.
8000  *
8001  */
8002 static VALUE
8004 {
8005  VALUE line;
8006 
8007  line = argf_getline(argc, argv, argf);
8008  rb_lastline_set(line);
8009 
8010  return line;
8011 }
8012 
8013 VALUE
8014 rb_gets(void)
8015 {
8016  VALUE line;
8017 
8018  if (rb_rs != rb_default_rs) {
8019  return rb_f_gets(0, 0, argf);
8020  }
8021 
8022  retry:
8023  if (!next_argv()) return Qnil;
8024  line = rb_io_gets(ARGF.current_file);
8025  if (NIL_P(line) && ARGF.next_p != -1) {
8026  rb_io_close(ARGF.current_file);
8027  ARGF.next_p = 1;
8028  goto retry;
8029  }
8030  rb_lastline_set(line);
8031  if (!NIL_P(line)) {
8032  ARGF.lineno++;
8033  ARGF.last_lineno = ARGF.lineno;
8034  }
8035 
8036  return line;
8037 }
8038 
8039 static VALUE argf_readline(int, VALUE *, VALUE);
8040 
8041 /*
8042  * call-seq:
8043  * readline(sep=$/) -> string
8044  * readline(limit) -> string
8045  * readline(sep, limit) -> string
8046  *
8047  * Equivalent to <code>Kernel::gets</code>, except
8048  * +readline+ raises +EOFError+ at end of file.
8049  */
8050 
8051 static VALUE
8053 {
8054  if (recv == argf) {
8055  return argf_readline(argc, argv, argf);
8056  }
8057  return rb_funcall2(argf, rb_intern("readline"), argc, argv);
8058 }
8059 
8060 
8061 /*
8062  * call-seq:
8063  * ARGF.readline(sep=$/) -> string
8064  * ARGF.readline(limit) -> string
8065  * ARGF.readline(sep, limit) -> string
8066  *
8067  * Returns the next line from the current file in +ARGF+.
8068  *
8069  * By default lines are assumed to be separated by +$/+; to use a different
8070  * character as a separator, supply it as a +String+ for the _sep_ argument.
8071  *
8072  * The optional _limit_ argument specifies how many characters of each line
8073  * to return. By default all characters are returned.
8074  *
8075  * An +EOFError+ is raised at the end of the file.
8076  */
8077 static VALUE
8079 {
8080  VALUE line;
8081 
8082  if (!next_argv()) rb_eof_error();
8083  ARGF_FORWARD(argc, argv);
8084  line = argf_gets(argc, argv, argf);
8085  if (NIL_P(line)) {
8086  rb_eof_error();
8087  }
8088 
8089  return line;
8090 }
8091 
8092 static VALUE argf_readlines(int, VALUE *, VALUE);
8093 
8094 /*
8095  * call-seq:
8096  * readlines(sep=$/) -> array
8097  * readlines(limit) -> array
8098  * readlines(sep,limit) -> array
8099  *
8100  * Returns an array containing the lines returned by calling
8101  * <code>Kernel.gets(<i>sep</i>)</code> until the end of file.
8102  */
8103 
8104 static VALUE
8106 {
8107  if (recv == argf) {
8108  return argf_readlines(argc, argv, argf);
8109  }
8110  return rb_funcall2(argf, rb_intern("readlines"), argc, argv);
8111 }
8112 
8113 /*
8114  * call-seq:
8115  * ARGF.readlines(sep=$/) -> array
8116  * ARGF.readlines(limit) -> array
8117  * ARGF.readlines(sep, limit) -> array
8118  *
8119  * ARGF.to_a(sep=$/) -> array
8120  * ARGF.to_a(limit) -> array
8121  * ARGF.to_a(sep, limit) -> array
8122  *
8123  * Reads +ARGF+'s current file in its entirety, returning an +Array+ of its
8124  * lines, one line per element. Lines are assumed to be separated by _sep_.
8125  *
8126  * lines = ARGF.readlines
8127  * lines[0] #=> "This is line one\n"
8128  */
8129 static VALUE
8131 {
8132  long lineno = ARGF.lineno;
8133  VALUE lines, ary;
8134 
8135  ary = rb_ary_new();
8136  while (next_argv()) {
8137  if (ARGF_GENERIC_INPUT_P()) {
8138  lines = rb_funcall3(ARGF.current_file, rb_intern("readlines"), argc, argv);
8139  }
8140  else {
8141  lines = rb_io_readlines(argc, argv, ARGF.current_file);
8142  argf_close(argf);
8143  }
8144  ARGF.next_p = 1;
8145  rb_ary_concat(ary, lines);
8146  ARGF.lineno = lineno + RARRAY_LEN(ary);
8147  ARGF.last_lineno = ARGF.lineno;
8148  }
8149  ARGF.init_p = 0;
8150  return ary;
8151 }
8152 
8153 /*
8154  * call-seq:
8155  * `cmd` -> string
8156  *
8157  * Returns the standard output of running _cmd_ in a subshell.
8158  * The built-in syntax <code>%x{...}</code> uses
8159  * this method. Sets <code>$?</code> to the process status.
8160  *
8161  * `date` #=> "Wed Apr 9 08:56:30 CDT 2003\n"
8162  * `ls testdir`.split[1] #=> "main.rb"
8163  * `echo oops && exit 99` #=> "oops\n"
8164  * $?.exitstatus #=> 99
8165  */
8166 
8167 static VALUE
8169 {
8170  volatile VALUE port;
8171  VALUE result;
8172  rb_io_t *fptr;
8173 
8174  SafeStringValue(str);
8176  port = pipe_open_s(str, "r", FMODE_READABLE|DEFAULT_TEXTMODE, NULL);
8177  if (NIL_P(port)) return rb_str_new(0,0);
8178 
8179  GetOpenFile(port, fptr);
8180  result = read_all(fptr, remain_size(fptr), Qnil);
8181  rb_io_close(port);
8182 
8183  return result;
8184 }
8185 
8186 #ifdef HAVE_SYS_SELECT_H
8187 #include <sys/select.h>
8188 #endif
8189 
8190 static VALUE
8191 select_internal(VALUE read, VALUE write, VALUE except, struct timeval *tp, rb_fdset_t *fds)
8192 {
8193  VALUE res, list;
8194  rb_fdset_t *rp, *wp, *ep;
8195  rb_io_t *fptr;
8196  long i;
8197  int max = 0, n;
8198  int pending = 0;
8199  struct timeval timerec;
8200 
8201  if (!NIL_P(read)) {
8202  Check_Type(read, T_ARRAY);
8203  for (i=0; i<RARRAY_LEN(read); i++) {
8204  GetOpenFile(rb_io_get_io(RARRAY_AREF(read, i)), fptr);
8205  rb_fd_set(fptr->fd, &fds[0]);
8206  if (READ_DATA_PENDING(fptr) || READ_CHAR_PENDING(fptr)) { /* check for buffered data */
8207  pending++;
8208  rb_fd_set(fptr->fd, &fds[3]);
8209  }
8210  if (max < fptr->fd) max = fptr->fd;
8211  }
8212  if (pending) { /* no blocking if there's buffered data */
8213  timerec.tv_sec = timerec.tv_usec = 0;
8214  tp = &timerec;
8215  }
8216  rp = &fds[0];
8217  }
8218  else
8219  rp = 0;
8220 
8221  if (!NIL_P(write)) {
8222  Check_Type(write, T_ARRAY);
8223  for (i=0; i<RARRAY_LEN(write); i++) {
8224  VALUE write_io = GetWriteIO(rb_io_get_io(RARRAY_AREF(write, i)));
8225  GetOpenFile(write_io, fptr);
8226  rb_fd_set(fptr->fd, &fds[1]);
8227  if (max < fptr->fd) max = fptr->fd;
8228  }
8229  wp = &fds[1];
8230  }
8231  else
8232  wp = 0;
8233 
8234  if (!NIL_P(except)) {
8235  Check_Type(except, T_ARRAY);
8236  for (i=0; i<RARRAY_LEN(except); i++) {
8237  VALUE io = rb_io_get_io(RARRAY_AREF(except, i));
8238  VALUE write_io = GetWriteIO(io);
8239  GetOpenFile(io, fptr);
8240  rb_fd_set(fptr->fd, &fds[2]);
8241  if (max < fptr->fd) max = fptr->fd;
8242  if (io != write_io) {
8243  GetOpenFile(write_io, fptr);
8244  rb_fd_set(fptr->fd, &fds[2]);
8245  if (max < fptr->fd) max = fptr->fd;
8246  }
8247  }
8248  ep = &fds[2];
8249  }
8250  else {
8251  ep = 0;
8252  }
8253 
8254  max++;
8255 
8256  n = rb_thread_fd_select(max, rp, wp, ep, tp);
8257  if (n < 0) {
8258  rb_sys_fail(0);
8259  }
8260  if (!pending && n == 0) return Qnil; /* returns nil on timeout */
8261 
8262  res = rb_ary_new2(3);
8263  rb_ary_push(res, rp?rb_ary_new():rb_ary_new2(0));
8264  rb_ary_push(res, wp?rb_ary_new():rb_ary_new2(0));
8265  rb_ary_push(res, ep?rb_ary_new():rb_ary_new2(0));
8266 
8267  if (rp) {
8268  list = RARRAY_AREF(res, 0);
8269  for (i=0; i< RARRAY_LEN(read); i++) {
8270  VALUE obj = rb_ary_entry(read, i);
8271  VALUE io = rb_io_get_io(obj);
8272  GetOpenFile(io, fptr);
8273  if (rb_fd_isset(fptr->fd, &fds[0]) ||
8274  rb_fd_isset(fptr->fd, &fds[3])) {
8275  rb_ary_push(list, obj);
8276  }
8277  }
8278  }
8279 
8280  if (wp) {
8281  list = RARRAY_AREF(res, 1);
8282  for (i=0; i< RARRAY_LEN(write); i++) {
8283  VALUE obj = rb_ary_entry(write, i);
8284  VALUE io = rb_io_get_io(obj);
8285  VALUE write_io = GetWriteIO(io);
8286  GetOpenFile(write_io, fptr);
8287  if (rb_fd_isset(fptr->fd, &fds[1])) {
8288  rb_ary_push(list, obj);
8289  }
8290  }
8291  }
8292 
8293  if (ep) {
8294  list = RARRAY_AREF(res, 2);
8295  for (i=0; i< RARRAY_LEN(except); i++) {
8296  VALUE obj = rb_ary_entry(except, i);
8297  VALUE io = rb_io_get_io(obj);
8298  VALUE write_io = GetWriteIO(io);
8299  GetOpenFile(io, fptr);
8300  if (rb_fd_isset(fptr->fd, &fds[2])) {
8301  rb_ary_push(list, obj);
8302  }
8303  else if (io != write_io) {
8304  GetOpenFile(write_io, fptr);
8305  if (rb_fd_isset(fptr->fd, &fds[2])) {
8306  rb_ary_push(list, obj);
8307  }
8308  }
8309  }
8310  }
8311 
8312  return res; /* returns an empty array on interrupt */
8313 }
8314 
8315 struct select_args {
8317  struct timeval *timeout;
8319 };
8320 
8321 static VALUE
8323 {
8324  struct select_args *p = (struct select_args *)arg;
8325 
8326  return select_internal(p->read, p->write, p->except, p->timeout, p->fdsets);
8327 }
8328 
8329 static VALUE
8331 {
8332  struct select_args *p = (struct select_args *)arg;
8333  int i;
8334 
8335  for (i = 0; i < numberof(p->fdsets); ++i)
8336  rb_fd_term(&p->fdsets[i]);
8337  return Qnil;
8338 }
8339 
8342 
8343 #ifdef HAVE_POSIX_FADVISE
8344 struct io_advise_struct {
8345  int fd;
8346  off_t offset;
8347  off_t len;
8348  int advice;
8349 };
8350 
8351 static VALUE
8352 io_advise_internal(void *arg)
8353 {
8354  struct io_advise_struct *ptr = arg;
8355  return posix_fadvise(ptr->fd, ptr->offset, ptr->len, ptr->advice);
8356 }
8357 
8358 static VALUE
8359 io_advise_sym_to_const(VALUE sym)
8360 {
8361 #ifdef POSIX_FADV_NORMAL
8362  if (sym == sym_normal)
8363  return INT2NUM(POSIX_FADV_NORMAL);
8364 #endif
8365 
8366 #ifdef POSIX_FADV_RANDOM
8367  if (sym == sym_random)
8368  return INT2NUM(POSIX_FADV_RANDOM);
8369 #endif
8370 
8371 #ifdef POSIX_FADV_SEQUENTIAL
8372  if (sym == sym_sequential)
8373  return INT2NUM(POSIX_FADV_SEQUENTIAL);
8374 #endif
8375 
8376 #ifdef POSIX_FADV_WILLNEED
8377  if (sym == sym_willneed)
8378  return INT2NUM(POSIX_FADV_WILLNEED);
8379 #endif
8380 
8381 #ifdef POSIX_FADV_DONTNEED
8382  if (sym == sym_dontneed)
8383  return INT2NUM(POSIX_FADV_DONTNEED);
8384 #endif
8385 
8386 #ifdef POSIX_FADV_NOREUSE
8387  if (sym == sym_noreuse)
8388  return INT2NUM(POSIX_FADV_NOREUSE);
8389 #endif
8390 
8391  return Qnil;
8392 }
8393 
8394 static VALUE
8395 do_io_advise(rb_io_t *fptr, VALUE advice, off_t offset, off_t len)
8396 {
8397  int rv;
8398  struct io_advise_struct ias;
8399  VALUE num_adv;
8400 
8401  num_adv = io_advise_sym_to_const(advice);
8402 
8403  /*
8404  * The platform doesn't support this hint. We don't raise exception, instead
8405  * silently ignore it. Because IO::advise is only hint.
8406  */
8407  if (NIL_P(num_adv))
8408  return Qnil;
8409 
8410  ias.fd = fptr->fd;
8411  ias.advice = NUM2INT(num_adv);
8412  ias.offset = offset;
8413  ias.len = len;
8414 
8415  rv = (int)rb_thread_io_blocking_region(io_advise_internal, &ias, fptr->fd);
8416  if (rv) {
8417  /* posix_fadvise(2) doesn't set errno. On success it returns 0; otherwise
8418  it returns the error code. */
8419  rb_syserr_fail_str(rv, fptr->pathv);
8420  }
8421 
8422  return Qnil;
8423 }
8424 
8425 #endif /* HAVE_POSIX_FADVISE */
8426 
8427 static void
8429 {
8430  if (!SYMBOL_P(advice))
8431  rb_raise(rb_eTypeError, "advice must be a Symbol");
8432 
8433  if (advice != sym_normal &&
8434  advice != sym_sequential &&
8435  advice != sym_random &&
8436  advice != sym_willneed &&
8437  advice != sym_dontneed &&
8438  advice != sym_noreuse) {
8439  VALUE symname = rb_inspect(advice);
8440  rb_raise(rb_eNotImpError, "Unsupported advice: %s",
8441  StringValuePtr(symname));
8442  }
8443 }
8444 
8445 /*
8446  * call-seq:
8447  * ios.advise(advice, offset=0, len=0) -> nil
8448  *
8449  * Announce an intention to access data from the current file in a
8450  * specific pattern. On platforms that do not support the
8451  * <em>posix_fadvise(2)</em> system call, this method is a no-op.
8452  *
8453  * _advice_ is one of the following symbols:
8454  *
8455  * :normal:: No advice to give; the default assumption for an open file.
8456  * :sequential:: The data will be accessed sequentially
8457  * with lower offsets read before higher ones.
8458  * :random:: The data will be accessed in random order.
8459  * :willneed:: The data will be accessed in the near future.
8460  * :dontneed:: The data will not be accessed in the near future.
8461  * :noreuse:: The data will only be accessed once.
8462  *
8463  * The semantics of a piece of advice are platform-dependent. See
8464  * <em>man 2 posix_fadvise</em> for details.
8465  *
8466  * "data" means the region of the current file that begins at
8467  * _offset_ and extends for _len_ bytes. If _len_ is 0, the region
8468  * ends at the last byte of the file. By default, both _offset_ and
8469  * _len_ are 0, meaning that the advice applies to the entire file.
8470  *
8471  * If an error occurs, one of the following exceptions will be raised:
8472  *
8473  * <code>IOError</code>:: The <code>IO</code> stream is closed.
8474  * <code>Errno::EBADF</code>::
8475  * The file descriptor of the current file is invalid.
8476  * <code>Errno::EINVAL</code>:: An invalid value for _advice_ was given.
8477  * <code>Errno::ESPIPE</code>::
8478  * The file descriptor of the current file refers to a FIFO or
8479  * pipe. (Linux raises <code>Errno::EINVAL</code> in this case).
8480  * <code>TypeError</code>::
8481  * Either _advice_ was not a Symbol, or one of the
8482  * other arguments was not an <code>Integer</code>.
8483  * <code>RangeError</code>:: One of the arguments given was too big/small.
8484  *
8485  * This list is not exhaustive; other Errno:: exceptions are also possible.
8486  */
8487 static VALUE
8489 {
8490  VALUE advice, offset, len;
8491  off_t off, l;
8492  rb_io_t *fptr;
8493 
8494  rb_scan_args(argc, argv, "12", &advice, &offset, &len);
8495  advice_arg_check(advice);
8496 
8497  io = GetWriteIO(io);
8498  GetOpenFile(io, fptr);
8499 
8500  off = NIL_P(offset) ? 0 : NUM2OFFT(offset);
8501  l = NIL_P(len) ? 0 : NUM2OFFT(len);
8502 
8503 #ifdef HAVE_POSIX_FADVISE
8504  return do_io_advise(fptr, advice, off, l);
8505 #else
8506  ((void)off, (void)l); /* Ignore all hint */
8507  return Qnil;
8508 #endif
8509 }
8510 
8511 /*
8512  * call-seq:
8513  * IO.select(read_array
8514  * [, write_array
8515  * [, error_array
8516  * [, timeout]]]) -> array or nil
8517  *
8518  * Calls select(2) system call.
8519  * It monitors given arrays of <code>IO</code> objects, waits one or more
8520  * of <code>IO</code> objects ready for reading, are ready for writing,
8521  * and have pending exceptions respectively, and returns an array that
8522  * contains arrays of those IO objects. It will return <code>nil</code>
8523  * if optional <i>timeout</i> value is given and no <code>IO</code> object
8524  * is ready in <i>timeout</i> seconds.
8525  *
8526  * <code>IO.select</code> peeks the buffer of <code>IO</code> objects for testing readability.
8527  * If the <code>IO</code> buffer is not empty,
8528  * <code>IO.select</code> immediately notify readability.
8529  * This "peek" is only happen for <code>IO</code> objects.
8530  * It is not happen for IO-like objects such as OpenSSL::SSL::SSLSocket.
8531  *
8532  * The best way to use <code>IO.select</code> is invoking it
8533  * after nonblocking methods such as <code>read_nonblock</code>, <code>write_nonblock</code>, etc.
8534  * The methods raises an exception which is extended by
8535  * <code>IO::WaitReadable</code> or <code>IO::WaitWritable</code>.
8536  * The modules notify how the caller should wait with <code>IO.select</code>.
8537  * If <code>IO::WaitReadable</code> is raised, the caller should wait for reading.
8538  * If <code>IO::WaitWritable</code> is raised, the caller should wait for writing.
8539  *
8540  * So, blocking read (<code>readpartial</code>) can be emulated using
8541  * <code>read_nonblock</code> and <code>IO.select</code> as follows:
8542  *
8543  * begin
8544  * result = io_like.read_nonblock(maxlen)
8545  * rescue IO::WaitReadable
8546  * IO.select([io_like])
8547  * retry
8548  * rescue IO::WaitWritable
8549  * IO.select(nil, [io_like])
8550  * retry
8551  * end
8552  *
8553  * Especially, the combination of nonblocking methods and
8554  * <code>IO.select</code> is preferred for <code>IO</code> like
8555  * objects such as <code>OpenSSL::SSL::SSLSocket</code>.
8556  * It has <code>to_io</code> method to return underlying <code>IO</code> object.
8557  * <code>IO.select</code> calls <code>to_io</code> to obtain the file descriptor to wait.
8558  *
8559  * This means that readability notified by <code>IO.select</code> doesn't mean
8560  * readability from <code>OpenSSL::SSL::SSLSocket</code> object.
8561  *
8562  * Most possible situation is <code>OpenSSL::SSL::SSLSocket</code> buffers some data.
8563  * <code>IO.select</code> doesn't see the buffer.
8564  * So <code>IO.select</code> can block when <code>OpenSSL::SSL::SSLSocket#readpartial</code> doesn't block.
8565  *
8566  * However several more complicated situation exists.
8567  *
8568  * SSL is a protocol which is sequence of records.
8569  * The record consists multiple bytes.
8570  * So, the remote side of SSL sends a partial record,
8571  * <code>IO.select</code> notifies readability but
8572  * <code>OpenSSL::SSL::SSLSocket</code> cannot decrypt a byte and
8573  * <code>OpenSSL::SSL::SSLSocket#readpartial</code> will blocks.
8574  *
8575  * Also, the remote side can request SSL renegotiation which forces
8576  * the local SSL engine writes some data.
8577  * This means <code>OpenSSL::SSL::SSLSocket#readpartial</code> may
8578  * invoke <code>write</code> system call and it can block.
8579  * In such situation, <code>OpenSSL::SSL::SSLSocket#read_nonblock</code>
8580  * raises IO::WaitWritable instead of blocking.
8581  * So, the caller should wait for ready for writability as above example.
8582  *
8583  * The combination of nonblocking methods and <code>IO.select</code> is
8584  * also useful for streams such as tty, pipe socket socket when
8585  * multiple process read form a stream.
8586  *
8587  * Finally, Linux kernel developers doesn't guarantee that
8588  * readability of select(2) means readability of following read(2) even
8589  * for single process.
8590  * See select(2) manual on GNU/Linux system.
8591  *
8592  * Invoking <code>IO.select</code> before <code>IO#readpartial</code> works well in usual.
8593  * However it is not the best way to use <code>IO.select</code>.
8594  *
8595  * The writability notified by select(2) doesn't show
8596  * how many bytes writable.
8597  * <code>IO#write</code> method blocks until given whole string is written.
8598  * So, <code>IO#write(two or more bytes)</code> can block after writability is notified by <code>IO.select</code>.
8599  * <code>IO#write_nonblock</code> is required to avoid the blocking.
8600  *
8601  * Blocking write (<code>write</code>) can be emulated using
8602  * <code>write_nonblock</code> and <code>IO.select</code> as follows:
8603  * IO::WaitReadable should also be rescued for SSL renegotiation in <code>OpenSSL::SSL::SSLSocket</code>.
8604  *
8605  * while 0 < string.bytesize
8606  * begin
8607  * written = io_like.write_nonblock(string)
8608  * rescue IO::WaitReadable
8609  * IO.select([io_like])
8610  * retry
8611  * rescue IO::WaitWritable
8612  * IO.select(nil, [io_like])
8613  * retry
8614  * end
8615  * string = string.byteslice(written..-1)
8616  * end
8617  *
8618  * === Parameters
8619  * read_array:: an array of <code>IO</code> objects that wait until ready for read
8620  * write_array:: an array of <code>IO</code> objects that wait until ready for write
8621  * error_array:: an array of <code>IO</code> objects that wait for exceptions
8622  * timeout:: a numeric value in second
8623  *
8624  * === Example
8625  *
8626  * rp, wp = IO.pipe
8627  * mesg = "ping "
8628  * 100.times {
8629  * # IO.select follows IO#read. Not the best way to use IO.select.
8630  * rs, ws, = IO.select([rp], [wp])
8631  * if r = rs[0]
8632  * ret = r.read(5)
8633  * print ret
8634  * case ret
8635  * when /ping/
8636  * mesg = "pong\n"
8637  * when /pong/
8638  * mesg = "ping "
8639  * end
8640  * end
8641  * if w = ws[0]
8642  * w.write(mesg)
8643  * end
8644  * }
8645  *
8646  * <em>produces:</em>
8647  *
8648  * ping pong
8649  * ping pong
8650  * ping pong
8651  * (snipped)
8652  * ping
8653  */
8654 
8655 static VALUE
8657 {
8658  VALUE timeout;
8659  struct select_args args;
8660  struct timeval timerec;
8661  int i;
8662 
8663  rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout);
8664  if (NIL_P(timeout)) {
8665  args.timeout = 0;
8666  }
8667  else {
8668  timerec = rb_time_interval(timeout);
8669  args.timeout = &timerec;
8670  }
8671 
8672  for (i = 0; i < numberof(args.fdsets); ++i)
8673  rb_fd_init(&args.fdsets[i]);
8674 
8675  return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
8676 }
8677 
8678 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
8679  typedef unsigned long ioctl_req_t;
8680 # define NUM2IOCTLREQ(num) NUM2ULONG(num)
8681 #else
8682  typedef int ioctl_req_t;
8683 # define NUM2IOCTLREQ(num) NUM2INT(num)
8684 #endif
8685 
8686 struct ioctl_arg {
8687  int fd;
8688  ioctl_req_t cmd;
8689  long narg;
8690 };
8691 
8692 static VALUE
8693 nogvl_ioctl(void *ptr)
8694 {
8695  struct ioctl_arg *arg = ptr;
8696 
8697  return (VALUE)ioctl(arg->fd, arg->cmd, arg->narg);
8698 }
8699 
8700 static int
8701 do_ioctl(int fd, ioctl_req_t cmd, long narg)
8702 {
8703  int retval;
8704  struct ioctl_arg arg;
8705 
8706  arg.fd = fd;
8707  arg.cmd = cmd;
8708  arg.narg = narg;
8709 
8710  retval = (int)rb_thread_io_blocking_region(nogvl_ioctl, &arg, fd);
8711 
8712  return retval;
8713 }
8714 
8715 #define DEFULT_IOCTL_NARG_LEN (256)
8716 
8717 #if defined(__linux__) && defined(_IOC_SIZE)
8718 static long
8719 linux_iocparm_len(ioctl_req_t cmd)
8720 {
8721  long len;
8722 
8723  if ((cmd & 0xFFFF0000) == 0) {
8724  /* legacy and unstructured ioctl number. */
8725  return DEFULT_IOCTL_NARG_LEN;
8726  }
8727 
8728  len = _IOC_SIZE(cmd);
8729 
8730  /* paranoia check for silly drivers which don't keep ioctl convention */
8731  if (len < DEFULT_IOCTL_NARG_LEN)
8732  len = DEFULT_IOCTL_NARG_LEN;
8733 
8734  return len;
8735 }
8736 #endif
8737 
8738 static long
8739 ioctl_narg_len(ioctl_req_t cmd)
8740 {
8741  long len;
8742 
8743 #ifdef IOCPARM_MASK
8744 #ifndef IOCPARM_LEN
8745 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
8746 #endif
8747 #endif
8748 #ifdef IOCPARM_LEN
8749  len = IOCPARM_LEN(cmd); /* on BSDish systems we're safe */
8750 #elif defined(__linux__) && defined(_IOC_SIZE)
8751  len = linux_iocparm_len(cmd);
8752 #else
8753  /* otherwise guess at what's safe */
8754  len = DEFULT_IOCTL_NARG_LEN;
8755 #endif
8756 
8757  return len;
8758 }
8759 
8760 #ifdef HAVE_FCNTL
8761 #ifdef __linux__
8762 typedef long fcntl_arg_t;
8763 #else
8764 /* posix */
8765 typedef int fcntl_arg_t;
8766 #endif
8767 
8768 static long
8769 fcntl_narg_len(int cmd)
8770 {
8771  long len;
8772 
8773  switch (cmd) {
8774 #ifdef F_DUPFD
8775  case F_DUPFD:
8776  len = sizeof(fcntl_arg_t);
8777  break;
8778 #endif
8779 #ifdef F_DUP2FD /* bsd specific */
8780  case F_DUP2FD:
8781  len = sizeof(int);
8782  break;
8783 #endif
8784 #ifdef F_DUPFD_CLOEXEC /* linux specific */
8785  case F_DUPFD_CLOEXEC:
8786  len = sizeof(fcntl_arg_t);
8787  break;
8788 #endif
8789 #ifdef F_GETFD
8790  case F_GETFD:
8791  len = 1;
8792  break;
8793 #endif
8794 #ifdef F_SETFD
8795  case F_SETFD:
8796  len = sizeof(fcntl_arg_t);
8797  break;
8798 #endif
8799 #ifdef F_GETFL
8800  case F_GETFL:
8801  len = 1;
8802  break;
8803 #endif
8804 #ifdef F_SETFL
8805  case F_SETFL:
8806  len = sizeof(fcntl_arg_t);
8807  break;
8808 #endif
8809 #ifdef F_GETOWN
8810  case F_GETOWN:
8811  len = 1;
8812  break;
8813 #endif
8814 #ifdef F_SETOWN
8815  case F_SETOWN:
8816  len = sizeof(fcntl_arg_t);
8817  break;
8818 #endif
8819 #ifdef F_GETOWN_EX /* linux specific */
8820  case F_GETOWN_EX:
8821  len = sizeof(struct f_owner_ex);
8822  break;
8823 #endif
8824 #ifdef F_SETOWN_EX /* linux specific */
8825  case F_SETOWN_EX:
8826  len = sizeof(struct f_owner_ex);
8827  break;
8828 #endif
8829 #ifdef F_GETLK
8830  case F_GETLK:
8831  len = sizeof(struct flock);
8832  break;
8833 #endif
8834 #ifdef F_SETLK
8835  case F_SETLK:
8836  len = sizeof(struct flock);
8837  break;
8838 #endif
8839 #ifdef F_SETLKW
8840  case F_SETLKW:
8841  len = sizeof(struct flock);
8842  break;
8843 #endif
8844 #ifdef F_READAHEAD /* bsd specific */
8845  case F_READAHEAD:
8846  len = sizeof(int);
8847  break;
8848 #endif
8849 #ifdef F_RDAHEAD /* Darwin specific */
8850  case F_RDAHEAD:
8851  len = sizeof(int);
8852  break;
8853 #endif
8854 #ifdef F_GETSIG /* linux specific */
8855  case F_GETSIG:
8856  len = 1;
8857  break;
8858 #endif
8859 #ifdef F_SETSIG /* linux specific */
8860  case F_SETSIG:
8861  len = sizeof(fcntl_arg_t);
8862  break;
8863 #endif
8864 #ifdef F_GETLEASE /* linux specific */
8865  case F_GETLEASE:
8866  len = 1;
8867  break;
8868 #endif
8869 #ifdef F_SETLEASE /* linux specific */
8870  case F_SETLEASE:
8871  len = sizeof(fcntl_arg_t);
8872  break;
8873 #endif
8874 #ifdef F_NOTIFY /* linux specific */
8875  case F_NOTIFY:
8876  len = sizeof(fcntl_arg_t);
8877  break;
8878 #endif
8879 
8880  default:
8881  len = 256;
8882  break;
8883  }
8884 
8885  return len;
8886 }
8887 #else /* HAVE_FCNTL */
8888 static long
8890 {
8891  return 0;
8892 }
8893 #endif /* HAVE_FCNTL */
8894 
8895 static long
8896 setup_narg(ioctl_req_t cmd, VALUE *argp, int io_p)
8897 {
8898  long narg = 0;
8899  VALUE arg = *argp;
8900 
8901  if (NIL_P(arg) || arg == Qfalse) {
8902  narg = 0;
8903  }
8904  else if (FIXNUM_P(arg)) {
8905  narg = FIX2LONG(arg);
8906  }
8907  else if (arg == Qtrue) {
8908  narg = 1;
8909  }
8910  else {
8911  VALUE tmp = rb_check_string_type(arg);
8912 
8913  if (NIL_P(tmp)) {
8914  narg = NUM2LONG(arg);
8915  }
8916  else {
8917  long len;
8918 
8919  *argp = arg = tmp;
8920  if (io_p)
8921  len = ioctl_narg_len(cmd);
8922  else
8923  len = fcntl_narg_len((int)cmd);
8924  rb_str_modify(arg);
8925 
8926  /* expand for data + sentinel. */
8927  if (RSTRING_LEN(arg) < len+1) {
8928  rb_str_resize(arg, len+1);
8929  }
8930  /* a little sanity check here */
8931  RSTRING_PTR(arg)[RSTRING_LEN(arg) - 1] = 17;
8932  narg = (long)(SIGNED_VALUE)RSTRING_PTR(arg);
8933  }
8934  }
8935 
8936  return narg;
8937 }
8938 
8939 static VALUE
8940 rb_ioctl(VALUE io, VALUE req, VALUE arg)
8941 {
8942  ioctl_req_t cmd = NUM2IOCTLREQ(req);
8943  rb_io_t *fptr;
8944  long narg;
8945  int retval;
8946 
8947  rb_secure(2);
8948 
8949  narg = setup_narg(cmd, &arg, 1);
8950  GetOpenFile(io, fptr);
8951  retval = do_ioctl(fptr->fd, cmd, narg);
8952  if (retval < 0) rb_sys_fail_path(fptr->pathv);
8953  if (RB_TYPE_P(arg, T_STRING)) {
8954  if (RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] != 17)
8955  rb_raise(rb_eArgError, "return value overflowed string");
8956  RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] = '\0';
8957  }
8958 
8959  return INT2NUM(retval);
8960 }
8961 
8962 /*
8963  * call-seq:
8964  * ios.ioctl(integer_cmd, arg) -> integer
8965  *
8966  * Provides a mechanism for issuing low-level commands to control or
8967  * query I/O devices. Arguments and results are platform dependent. If
8968  * <i>arg</i> is a number, its value is passed directly. If it is a
8969  * string, it is interpreted as a binary sequence of bytes. On Unix
8970  * platforms, see <code>ioctl(2)</code> for details. Not implemented on
8971  * all platforms.
8972  */
8973 
8974 static VALUE
8976 {
8977  VALUE req, arg;
8978 
8979  rb_scan_args(argc, argv, "11", &req, &arg);
8980  return rb_ioctl(io, req, arg);
8981 }
8982 
8983 #ifdef HAVE_FCNTL
8984 struct fcntl_arg {
8985  int fd;
8986  int cmd;
8987  long narg;
8988 };
8989 
8990 static VALUE
8991 nogvl_fcntl(void *ptr)
8992 {
8993  struct fcntl_arg *arg = ptr;
8994 
8995 #if defined(F_DUPFD)
8996  if (arg->cmd == F_DUPFD)
8997  return (VALUE)rb_cloexec_fcntl_dupfd(arg->fd, (int)arg->narg);
8998 #endif
8999  return (VALUE)fcntl(arg->fd, arg->cmd, arg->narg);
9000 }
9001 
9002 static int
9003 do_fcntl(int fd, int cmd, long narg)
9004 {
9005  int retval;
9006  struct fcntl_arg arg;
9007 
9008  arg.fd = fd;
9009  arg.cmd = cmd;
9010  arg.narg = narg;
9011 
9012  retval = (int)rb_thread_io_blocking_region(nogvl_fcntl, &arg, fd);
9013 #if defined(F_DUPFD)
9014  if (retval != -1 && cmd == F_DUPFD) {
9015  rb_update_max_fd(retval);
9016  }
9017 #endif
9018 
9019  return retval;
9020 }
9021 
9022 static VALUE
9023 rb_fcntl(VALUE io, VALUE req, VALUE arg)
9024 {
9025  int cmd = NUM2INT(req);
9026  rb_io_t *fptr;
9027  long narg;
9028  int retval;
9029 
9030  rb_secure(2);
9031 
9032  narg = setup_narg(cmd, &arg, 0);
9033  GetOpenFile(io, fptr);
9034  retval = do_fcntl(fptr->fd, cmd, narg);
9035  if (retval < 0) rb_sys_fail_path(fptr->pathv);
9036  if (RB_TYPE_P(arg, T_STRING)) {
9037  if (RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] != 17)
9038  rb_raise(rb_eArgError, "return value overflowed string");
9039  RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] = '\0';
9040  }
9041 
9042  if (cmd == F_SETFL) {
9043  if (narg & O_NONBLOCK) {
9044  fptr->mode |= FMODE_WSPLIT_INITIALIZED;
9045  fptr->mode &= ~FMODE_WSPLIT;
9046  }
9047  else {
9049  }
9050  }
9051 
9052  return INT2NUM(retval);
9053 }
9054 
9055 /*
9056  * call-seq:
9057  * ios.fcntl(integer_cmd, arg) -> integer
9058  *
9059  * Provides a mechanism for issuing low-level commands to control or
9060  * query file-oriented I/O streams. Arguments and results are platform
9061  * dependent. If <i>arg</i> is a number, its value is passed
9062  * directly. If it is a string, it is interpreted as a binary sequence
9063  * of bytes (<code>Array#pack</code> might be a useful way to build this
9064  * string). On Unix platforms, see <code>fcntl(2)</code> for details.
9065  * Not implemented on all platforms.
9066  */
9067 
9068 static VALUE
9069 rb_io_fcntl(int argc, VALUE *argv, VALUE io)
9070 {
9071  VALUE req, arg;
9072 
9073  rb_scan_args(argc, argv, "11", &req, &arg);
9074  return rb_fcntl(io, req, arg);
9075 }
9076 #else
9077 #define rb_io_fcntl rb_f_notimplement
9078 #endif
9079 
9080 #if defined(HAVE_SYSCALL) || defined(HAVE___SYSCALL)
9081 /*
9082  * call-seq:
9083  * syscall(num [, args...]) -> integer
9084  *
9085  * Calls the operating system function identified by _num_ and
9086  * returns the result of the function or raises SystemCallError if
9087  * it failed.
9088  *
9089  * Arguments for the function can follow _num_. They must be either
9090  * +String+ objects or +Integer+ objects. A +String+ object is passed
9091  * as a pointer to the byte sequence. An +Integer+ object is passed
9092  * as an integer whose bit size is same as a pointer.
9093  * Up to nine parameters may be passed (14 on the Atari-ST).
9094  *
9095  * The function identified by _num_ is system
9096  * dependent. On some Unix systems, the numbers may be obtained from a
9097  * header file called <code>syscall.h</code>.
9098  *
9099  * syscall 4, 1, "hello\n", 6 # '4' is write(2) on our box
9100  *
9101  * <em>produces:</em>
9102  *
9103  * hello
9104  *
9105  *
9106  * Calling +syscall+ on a platform which does not have any way to
9107  * an arbitrary system function just fails with NotImplementedError.
9108  *
9109  * Note::
9110  * +syscall+ is essentially unsafe and unportable. Feel free to shoot your foot.
9111  * DL (Fiddle) library is preferred for safer and a bit more portable programming.
9112  */
9113 
9114 static VALUE
9115 rb_f_syscall(int argc, VALUE *argv)
9116 {
9117 #ifdef atarist
9118  VALUE arg[13]; /* yes, we really need that many ! */
9119 #else
9120  VALUE arg[8];
9121 #endif
9122 #if SIZEOF_VOIDP == 8 && defined(HAVE___SYSCALL) && SIZEOF_INT != 8 /* mainly *BSD */
9123 # define SYSCALL __syscall
9124 # define NUM2SYSCALLID(x) NUM2LONG(x)
9125 # define RETVAL2NUM(x) LONG2NUM(x)
9126 # if SIZEOF_LONG == 8
9127  long num, retval = -1;
9128 # elif SIZEOF_LONG_LONG == 8
9129  long long num, retval = -1;
9130 # else
9131 # error ---->> it is asserted that __syscall takes the first argument and returns retval in 64bit signed integer. <<----
9132 # endif
9133 #elif defined(__linux__)
9134 # define SYSCALL syscall
9135 # define NUM2SYSCALLID(x) NUM2LONG(x)
9136 # define RETVAL2NUM(x) LONG2NUM(x)
9137  /*
9138  * Linux man page says, syscall(2) function prototype is below.
9139  *
9140  * int syscall(int number, ...);
9141  *
9142  * But, it's incorrect. Actual one takes and returned long. (see unistd.h)
9143  */
9144  long num, retval = -1;
9145 #else
9146 # define SYSCALL syscall
9147 # define NUM2SYSCALLID(x) NUM2INT(x)
9148 # define RETVAL2NUM(x) INT2NUM(x)
9149  int num, retval = -1;
9150 #endif
9151  int i;
9152 
9153  if (RTEST(ruby_verbose)) {
9154  rb_warning("We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
9155  }
9156 
9157  rb_secure(2);
9158  if (argc == 0)
9159  rb_raise(rb_eArgError, "too few arguments for syscall");
9160  if (argc > numberof(arg))
9161  rb_raise(rb_eArgError, "too many arguments for syscall");
9162  num = NUM2SYSCALLID(argv[0]); ++argv;
9163  for (i = argc - 1; i--; ) {
9164  VALUE v = rb_check_string_type(argv[i]);
9165 
9166  if (!NIL_P(v)) {
9167  SafeStringValue(v);
9168  rb_str_modify(v);
9169  arg[i] = (VALUE)StringValueCStr(v);
9170  }
9171  else {
9172  arg[i] = (VALUE)NUM2LONG(argv[i]);
9173  }
9174  }
9175 
9176  switch (argc) {
9177  case 1:
9178  retval = SYSCALL(num);
9179  break;
9180  case 2:
9181  retval = SYSCALL(num, arg[0]);
9182  break;
9183  case 3:
9184  retval = SYSCALL(num, arg[0],arg[1]);
9185  break;
9186  case 4:
9187  retval = SYSCALL(num, arg[0],arg[1],arg[2]);
9188  break;
9189  case 5:
9190  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3]);
9191  break;
9192  case 6:
9193  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4]);
9194  break;
9195  case 7:
9196  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
9197  break;
9198  case 8:
9199  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
9200  break;
9201 #ifdef atarist
9202  case 9:
9203  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9204  arg[7]);
9205  break;
9206  case 10:
9207  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9208  arg[7], arg[8]);
9209  break;
9210  case 11:
9211  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9212  arg[7], arg[8], arg[9]);
9213  break;
9214  case 12:
9215  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9216  arg[7], arg[8], arg[9], arg[10]);
9217  break;
9218  case 13:
9219  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9220  arg[7], arg[8], arg[9], arg[10], arg[11]);
9221  break;
9222  case 14:
9223  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9224  arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]);
9225  break;
9226 #endif
9227  }
9228 
9229  if (retval == -1)
9230  rb_sys_fail(0);
9231  return RETVAL2NUM(retval);
9232 #undef SYSCALL
9233 #undef NUM2SYSCALLID
9234 #undef RETVAL2NUM
9235 }
9236 #else
9237 #define rb_f_syscall rb_f_notimplement
9238 #endif
9239 
9240 static VALUE
9242 {
9243  return rb_class_new_instance(2, (VALUE*)args+1, *(VALUE*)args);
9244 }
9245 
9246 static rb_encoding *
9248 {
9249  rb_encoding *enc = rb_find_encoding(v);
9250  if (!enc) unsupported_encoding(StringValueCStr(v));
9251  return enc;
9252 }
9253 
9254 static void
9256 {
9257  rb_encoding *enc, *enc2;
9258  int ecflags = fptr->encs.ecflags;
9259  VALUE ecopts, tmp;
9260 
9261  if (!NIL_P(v2)) {
9262  enc2 = find_encoding(v1);
9263  tmp = rb_check_string_type(v2);
9264  if (!NIL_P(tmp)) {
9265  if (RSTRING_LEN(tmp) == 1 && RSTRING_PTR(tmp)[0] == '-') {
9266  /* Special case - "-" => no transcoding */
9267  enc = enc2;
9268  enc2 = NULL;
9269  }
9270  else
9271  enc = find_encoding(v2);
9272  if (enc == enc2) {
9273  /* Special case - "-" => no transcoding */
9274  enc2 = NULL;
9275  }
9276  }
9277  else {
9278  enc = find_encoding(v2);
9279  if (enc == enc2) {
9280  /* Special case - "-" => no transcoding */
9281  enc2 = NULL;
9282  }
9283  }
9285  ecflags = rb_econv_prepare_options(opt, &ecopts, ecflags);
9286  }
9287  else {
9288  if (NIL_P(v1)) {
9289  /* Set to default encodings */
9290  rb_io_ext_int_to_encs(NULL, NULL, &enc, &enc2, 0);
9292  ecopts = Qnil;
9293  }
9294  else {
9295  tmp = rb_check_string_type(v1);
9296  if (!NIL_P(tmp) && rb_enc_asciicompat(rb_enc_get(tmp))) {
9297  parse_mode_enc(RSTRING_PTR(tmp), &enc, &enc2, NULL);
9299  ecflags = rb_econv_prepare_options(opt, &ecopts, ecflags);
9300  }
9301  else {
9302  rb_io_ext_int_to_encs(find_encoding(v1), NULL, &enc, &enc2, 0);
9304  ecopts = Qnil;
9305  }
9306  }
9307  }
9308  validate_enc_binmode(&fptr->mode, ecflags, enc, enc2);
9309  fptr->encs.enc = enc;
9310  fptr->encs.enc2 = enc2;
9311  fptr->encs.ecflags = ecflags;
9312  fptr->encs.ecopts = ecopts;
9313  clear_codeconv(fptr);
9314 
9315 }
9316 
9317 static VALUE
9319 {
9320  VALUE *rwp = (VALUE *)rw;
9321  return rb_ensure(io_close, rwp[0], io_close, rwp[1]);
9322 }
9323 
9324 /*
9325  * call-seq:
9326  * IO.pipe -> [read_io, write_io]
9327  * IO.pipe(ext_enc) -> [read_io, write_io]
9328  * IO.pipe("ext_enc:int_enc" [, opt]) -> [read_io, write_io]
9329  * IO.pipe(ext_enc, int_enc [, opt]) -> [read_io, write_io]
9330  *
9331  * IO.pipe(...) {|read_io, write_io| ... }
9332  *
9333  * Creates a pair of pipe endpoints (connected to each other) and
9334  * returns them as a two-element array of <code>IO</code> objects:
9335  * <code>[</code> <i>read_io</i>, <i>write_io</i> <code>]</code>.
9336  *
9337  * If a block is given, the block is called and
9338  * returns the value of the block.
9339  * <i>read_io</i> and <i>write_io</i> are sent to the block as arguments.
9340  * If read_io and write_io are not closed when the block exits, they are closed.
9341  * i.e. closing read_io and/or write_io doesn't cause an error.
9342  *
9343  * Not available on all platforms.
9344  *
9345  * If an encoding (encoding name or encoding object) is specified as an optional argument,
9346  * read string from pipe is tagged with the encoding specified.
9347  * If the argument is a colon separated two encoding names "A:B",
9348  * the read string is converted from encoding A (external encoding)
9349  * to encoding B (internal encoding), then tagged with B.
9350  * If two optional arguments are specified, those must be
9351  * encoding objects or encoding names,
9352  * and the first one is the external encoding,
9353  * and the second one is the internal encoding.
9354  * If the external encoding and the internal encoding is specified,
9355  * optional hash argument specify the conversion option.
9356  *
9357  * In the example below, the two processes close the ends of the pipe
9358  * that they are not using. This is not just a cosmetic nicety. The
9359  * read end of a pipe will not generate an end of file condition if
9360  * there are any writers with the pipe still open. In the case of the
9361  * parent process, the <code>rd.read</code> will never return if it
9362  * does not first issue a <code>wr.close</code>.
9363  *
9364  * rd, wr = IO.pipe
9365  *
9366  * if fork
9367  * wr.close
9368  * puts "Parent got: <#{rd.read}>"
9369  * rd.close
9370  * Process.wait
9371  * else
9372  * rd.close
9373  * puts "Sending message to parent"
9374  * wr.write "Hi Dad"
9375  * wr.close
9376  * end
9377  *
9378  * <em>produces:</em>
9379  *
9380  * Sending message to parent
9381  * Parent got: <Hi Dad>
9382  */
9383 
9384 static VALUE
9386 {
9387  int pipes[2], state;
9388  VALUE r, w, args[3], v1, v2;
9389  VALUE opt;
9390  rb_io_t *fptr, *fptr2;
9391  int fmode = 0;
9392  VALUE ret;
9393 
9394  argc = rb_scan_args(argc, argv, "02:", &v1, &v2, &opt);
9395  if (rb_pipe(pipes) == -1)
9396  rb_sys_fail(0);
9397 
9398  args[0] = klass;
9399  args[1] = INT2NUM(pipes[0]);
9400  args[2] = INT2FIX(O_RDONLY);
9401  r = rb_protect(io_new_instance, (VALUE)args, &state);
9402  if (state) {
9403  close(pipes[0]);
9404  close(pipes[1]);
9405  rb_jump_tag(state);
9406  }
9407  GetOpenFile(r, fptr);
9408  io_encoding_set(fptr, v1, v2, opt);
9409  args[1] = INT2NUM(pipes[1]);
9410  args[2] = INT2FIX(O_WRONLY);
9411  w = rb_protect(io_new_instance, (VALUE)args, &state);
9412  if (state) {
9413  close(pipes[1]);
9414  if (!NIL_P(r)) rb_io_close(r);
9415  rb_jump_tag(state);
9416  }
9417  GetOpenFile(w, fptr2);
9418  rb_io_synchronized(fptr2);
9419 
9420  extract_binmode(opt, &fmode);
9421 #if DEFAULT_TEXTMODE
9422  if ((fptr->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
9423  fptr->mode &= ~FMODE_TEXTMODE;
9424  setmode(fptr->fd, O_BINARY);
9425  }
9426 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
9429  }
9430 #endif
9431 #endif
9432  fptr->mode |= fmode;
9433 #if DEFAULT_TEXTMODE
9434  if ((fptr2->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
9435  fptr2->mode &= ~FMODE_TEXTMODE;
9436  setmode(fptr2->fd, O_BINARY);
9437  }
9438 #endif
9439  fptr2->mode |= fmode;
9440 
9441  ret = rb_assoc_new(r, w);
9442  if (rb_block_given_p()) {
9443  VALUE rw[2];
9444  rw[0] = r;
9445  rw[1] = w;
9446  return rb_ensure(rb_yield, ret, pipe_pair_close, (VALUE)rw);
9447  }
9448  return ret;
9449 }
9450 
9451 struct foreach_arg {
9452  int argc;
9455 };
9456 
9457 static void
9458 open_key_args(int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg)
9459 {
9460  VALUE path, v;
9461 
9462  path = *argv++;
9463  argc--;
9464  FilePathValue(path);
9465  arg->io = 0;
9466  arg->argc = argc;
9467  arg->argv = argv;
9468  if (NIL_P(opt)) {
9469  arg->io = rb_io_open(path, INT2NUM(O_RDONLY), INT2FIX(0666), Qnil);
9470  return;
9471  }
9472  v = rb_hash_aref(opt, sym_open_args);
9473  if (!NIL_P(v)) {
9474  VALUE args;
9475  long n;
9476 
9477  v = rb_convert_type(v, T_ARRAY, "Array", "to_ary");
9478  n = RARRAY_LEN(v) + 1;
9479 #if SIZEOF_LONG > SIZEOF_INT
9480  if (n > INT_MAX) {
9481  rb_raise(rb_eArgError, "too many arguments");
9482  }
9483 #endif
9484  args = rb_ary_tmp_new(n);
9485  rb_ary_push(args, path);
9486  rb_ary_concat(args, v);
9487  arg->io = rb_io_open_with_args((int)n, RARRAY_CONST_PTR(args));
9488  rb_ary_clear(args); /* prevent from GC */
9489  return;
9490  }
9491  arg->io = rb_io_open(path, Qnil, Qnil, opt);
9492 }
9493 
9494 static VALUE
9496 {
9497  VALUE str;
9498 
9499  while (!NIL_P(str = rb_io_gets_m(arg->argc, arg->argv, arg->io))) {
9500  rb_yield(str);
9501  }
9502  return Qnil;
9503 }
9504 
9505 /*
9506  * call-seq:
9507  * IO.foreach(name, sep=$/ [, open_args]) {|line| block } -> nil
9508  * IO.foreach(name, limit [, open_args]) {|line| block } -> nil
9509  * IO.foreach(name, sep, limit [, open_args]) {|line| block } -> nil
9510  * IO.foreach(...) -> an_enumerator
9511  *
9512  * Executes the block for every line in the named I/O port, where lines
9513  * are separated by <em>sep</em>.
9514  *
9515  * If no block is given, an enumerator is returned instead.
9516  *
9517  * IO.foreach("testfile") {|x| print "GOT ", x }
9518  *
9519  * <em>produces:</em>
9520  *
9521  * GOT This is line one
9522  * GOT This is line two
9523  * GOT This is line three
9524  * GOT And so on...
9525  *
9526  * If the last argument is a hash, it's the keyword argument to open.
9527  * See <code>IO.read</code> for detail.
9528  *
9529  */
9530 
9531 static VALUE
9533 {
9534  VALUE opt;
9535  int orig_argc = argc;
9536  struct foreach_arg arg;
9537 
9538  argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
9539  RETURN_ENUMERATOR(self, orig_argc, argv);
9540  open_key_args(argc, argv, opt, &arg);
9541  if (NIL_P(arg.io)) return Qnil;
9542  return rb_ensure(io_s_foreach, (VALUE)&arg, rb_io_close, arg.io);
9543 }
9544 
9545 static VALUE
9547 {
9548  return rb_io_readlines(arg->argc, arg->argv, arg->io);
9549 }
9550 
9551 /*
9552  * call-seq:
9553  * IO.readlines(name, sep=$/ [, open_args]) -> array
9554  * IO.readlines(name, limit [, open_args]) -> array
9555  * IO.readlines(name, sep, limit [, open_args]) -> array
9556  *
9557  * Reads the entire file specified by <i>name</i> as individual
9558  * lines, and returns those lines in an array. Lines are separated by
9559  * <i>sep</i>.
9560  *
9561  * a = IO.readlines("testfile")
9562  * a[0] #=> "This is line one\n"
9563  *
9564  * If the last argument is a hash, it's the keyword argument to open.
9565  * See <code>IO.read</code> for detail.
9566  *
9567  */
9568 
9569 static VALUE
9571 {
9572  VALUE opt;
9573  struct foreach_arg arg;
9574 
9575  argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
9576  open_key_args(argc, argv, opt, &arg);
9577  if (NIL_P(arg.io)) return Qnil;
9578  return rb_ensure(io_s_readlines, (VALUE)&arg, rb_io_close, arg.io);
9579 }
9580 
9581 static VALUE
9583 {
9584  return io_read(arg->argc, arg->argv, arg->io);
9585 }
9586 
9587 struct seek_arg {
9590  int mode;
9591 };
9592 
9593 static VALUE
9595 {
9596  struct seek_arg *arg = (struct seek_arg *)argp;
9597  rb_io_binmode(arg->io);
9598  return rb_io_seek(arg->io, arg->offset, arg->mode);
9599 }
9600 
9601 /*
9602  * call-seq:
9603  * IO.read(name, [length [, offset]] ) -> string
9604  * IO.read(name, [length [, offset]], open_args) -> string
9605  *
9606  * Opens the file, optionally seeks to the given +offset+, then returns
9607  * +length+ bytes (defaulting to the rest of the file). <code>read</code>
9608  * ensures the file is closed before returning.
9609  *
9610  * If the last argument is a hash, it specifies option for internal
9611  * open(). The key would be the following. open_args: is exclusive
9612  * to others.
9613  *
9614  * encoding::
9615  * string or encoding
9616  *
9617  * specifies encoding of the read string. +encoding+ will be ignored
9618  * if length is specified.
9619  *
9620  * mode::
9621  * string
9622  *
9623  * specifies mode argument for open(). It should start with "r"
9624  * otherwise it will cause an error.
9625  *
9626  * open_args:: array of strings
9627  *
9628  * specifies arguments for open() as an array.
9629  *
9630  * Examples:
9631  *
9632  * IO.read("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
9633  * IO.read("testfile", 20) #=> "This is line one\nThi"
9634  * IO.read("testfile", 20, 10) #=> "ne one\nThis is line "
9635  */
9636 
9637 static VALUE
9639 {
9640  VALUE opt, offset;
9641  struct foreach_arg arg;
9642 
9643  argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
9644  open_key_args(argc, argv, opt, &arg);
9645  if (NIL_P(arg.io)) return Qnil;
9646  if (!NIL_P(offset)) {
9647  struct seek_arg sarg;
9648  int state = 0;
9649  sarg.io = arg.io;
9650  sarg.offset = offset;
9651  sarg.mode = SEEK_SET;
9652  rb_protect(seek_before_access, (VALUE)&sarg, &state);
9653  if (state) {
9654  rb_io_close(arg.io);
9655  rb_jump_tag(state);
9656  }
9657  if (arg.argc == 2) arg.argc = 1;
9658  }
9659  return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
9660 }
9661 
9662 /*
9663  * call-seq:
9664  * IO.binread(name, [length [, offset]] ) -> string
9665  *
9666  * Opens the file, optionally seeks to the given <i>offset</i>, then returns
9667  * <i>length</i> bytes (defaulting to the rest of the file).
9668  * <code>binread</code> ensures the file is closed before returning.
9669  * The open mode would be "rb:ASCII-8BIT".
9670  *
9671  * IO.binread("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
9672  * IO.binread("testfile", 20) #=> "This is line one\nThi"
9673  * IO.binread("testfile", 20, 10) #=> "ne one\nThis is line "
9674  */
9675 
9676 static VALUE
9678 {
9679  VALUE offset;
9680  struct foreach_arg arg;
9681 
9682  rb_scan_args(argc, argv, "12", NULL, NULL, &offset);
9683  FilePathValue(argv[0]);
9684  arg.io = rb_io_open(argv[0], rb_str_new_cstr("rb:ASCII-8BIT"), Qnil, Qnil);
9685  if (NIL_P(arg.io)) return Qnil;
9686  arg.argv = argv+1;
9687  arg.argc = (argc > 1) ? 1 : 0;
9688  if (!NIL_P(offset)) {
9689  rb_io_seek(arg.io, offset, SEEK_SET);
9690  }
9691  return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
9692 }
9693 
9694 static VALUE
9696 {
9697  return io_write(arg->io,arg->str,arg->nosync);
9698 }
9699 
9700 static VALUE
9701 io_s_write(int argc, VALUE *argv, int binary)
9702 {
9703  VALUE string, offset, opt;
9704  struct foreach_arg arg;
9705  struct write_arg warg;
9706 
9707  rb_scan_args(argc, argv, "21:", NULL, &string, &offset, &opt);
9708 
9709  if (NIL_P(opt)) opt = rb_hash_new();
9710  else opt = rb_hash_dup(opt);
9711 
9712 
9713  if (NIL_P(rb_hash_aref(opt,sym_mode))) {
9714  int mode = O_WRONLY|O_CREAT;
9715 #ifdef O_BINARY
9716  if (binary) mode |= O_BINARY;
9717 #endif
9718  if (NIL_P(offset)) mode |= O_TRUNC;
9719  rb_hash_aset(opt,sym_mode,INT2NUM(mode));
9720  }
9721  open_key_args(argc,argv,opt,&arg);
9722 
9723 #ifndef O_BINARY
9724  if (binary) rb_io_binmode_m(arg.io);
9725 #endif
9726 
9727  if (NIL_P(arg.io)) return Qnil;
9728  if (!NIL_P(offset)) {
9729  struct seek_arg sarg;
9730  int state = 0;
9731  sarg.io = arg.io;
9732  sarg.offset = offset;
9733  sarg.mode = SEEK_SET;
9734  rb_protect(seek_before_access, (VALUE)&sarg, &state);
9735  if (state) {
9736  rb_io_close(arg.io);
9737  rb_jump_tag(state);
9738  }
9739  }
9740 
9741  warg.io = arg.io;
9742  warg.str = string;
9743  warg.nosync = 0;
9744 
9745  return rb_ensure(io_s_write0, (VALUE)&warg, rb_io_close, arg.io);
9746 }
9747 
9748 /*
9749  * call-seq:
9750  * IO.write(name, string, [offset] ) => fixnum
9751  * IO.write(name, string, [offset], open_args ) => fixnum
9752  *
9753  * Opens the file, optionally seeks to the given <i>offset</i>, writes
9754  * <i>string</i>, then returns the length written.
9755  * <code>write</code> ensures the file is closed before returning.
9756  * If <i>offset</i> is not given, the file is truncated. Otherwise,
9757  * it is not truncated.
9758  *
9759  * If the last argument is a hash, it specifies option for internal
9760  * open(). The key would be the following. open_args: is exclusive
9761  * to others.
9762  *
9763  * encoding: string or encoding
9764  *
9765  * specifies encoding of the read string. encoding will be ignored
9766  * if length is specified.
9767  *
9768  * mode: string
9769  *
9770  * specifies mode argument for open(). it should start with "w" or "a" or "r+"
9771  * otherwise it would cause error.
9772  *
9773  * perm: fixnum
9774  *
9775  * specifies perm argument for open().
9776  *
9777  * open_args: array
9778  *
9779  * specifies arguments for open() as an array.
9780  *
9781  * IO.write("testfile", "0123456789", 20) # => 10
9782  * # File could contain: "This is line one\nThi0123456789two\nThis is line three\nAnd so on...\n"
9783  * IO.write("testfile", "0123456789") #=> 10
9784  * # File would now read: "0123456789"
9785  */
9786 
9787 static VALUE
9789 {
9790  return io_s_write(argc, argv, 0);
9791 }
9792 
9793 /*
9794  * call-seq:
9795  * IO.binwrite(name, string, [offset] ) => fixnum
9796  * IO.binwrite(name, string, [offset], open_args ) => fixnum
9797  *
9798  * Same as <code>IO.write</code> except opening the file in binary mode
9799  * and ASCII-8BIT encoding ("wb:ASCII-8BIT").
9800  *
9801  */
9802 
9803 static VALUE
9805 {
9806  return io_s_write(argc, argv, 1);
9807 }
9808 
9812  off_t copy_length; /* (off_t)-1 if not specified */
9813  off_t src_offset; /* (off_t)-1 if not specified */
9814 
9815  int src_fd;
9816  int dst_fd;
9820  const char *syserr;
9822  const char *notimp;
9825 };
9826 
9827 static void *
9829 {
9830  VALUE th = (VALUE)arg;
9832  return NULL;
9833 }
9834 
9835 /*
9836  * returns TRUE if the preceding system call was interrupted
9837  * so we can continue. If the thread was interrupted, we
9838  * reacquire the GVL to execute interrupts before continuing.
9839  */
9840 static int
9842 {
9843  switch (errno) {
9844  case EINTR:
9845 #if defined(ERESTART)
9846  case ERESTART:
9847 #endif
9848  if (rb_thread_interrupted(stp->th)) {
9849  if (has_gvl)
9851  else
9853  }
9854  return TRUE;
9855  }
9856  return FALSE;
9857 }
9858 
9859 static int
9860 maygvl_select(int has_gvl, int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout)
9861 {
9862  if (has_gvl)
9863  return rb_thread_fd_select(n, rfds, wfds, efds, timeout);
9864  else
9865  return rb_fd_select(n, rfds, wfds, efds, timeout);
9866 }
9867 
9868 static int
9870 {
9871  int ret;
9872 
9873  do {
9874  rb_fd_zero(&stp->fds);
9875  rb_fd_set(stp->src_fd, &stp->fds);
9876  ret = maygvl_select(has_gvl, rb_fd_max(&stp->fds), &stp->fds, NULL, NULL, NULL);
9877  } while (ret == -1 && maygvl_copy_stream_continue_p(has_gvl, stp));
9878 
9879  if (ret == -1) {
9880  stp->syserr = "select";
9881  stp->error_no = errno;
9882  return -1;
9883  }
9884  return 0;
9885 }
9886 
9887 static int
9889 {
9890  int ret;
9891 
9892  do {
9893  rb_fd_zero(&stp->fds);
9894  rb_fd_set(stp->dst_fd, &stp->fds);
9895  ret = rb_fd_select(rb_fd_max(&stp->fds), NULL, &stp->fds, NULL, NULL);
9896  } while (ret == -1 && maygvl_copy_stream_continue_p(0, stp));
9897 
9898  if (ret == -1) {
9899  stp->syserr = "select";
9900  stp->error_no = errno;
9901  return -1;
9902  }
9903  return 0;
9904 }
9905 
9906 #ifdef HAVE_SENDFILE
9907 
9908 # ifdef __linux__
9909 # define USE_SENDFILE
9910 
9911 # ifdef HAVE_SYS_SENDFILE_H
9912 # include <sys/sendfile.h>
9913 # endif
9914 
9915 static ssize_t
9916 simple_sendfile(int out_fd, int in_fd, off_t *offset, off_t count)
9917 {
9918  return sendfile(out_fd, in_fd, offset, (size_t)count);
9919 }
9920 
9921 # elif 0 /* defined(__FreeBSD__) || defined(__DragonFly__) */ || defined(__APPLE__)
9922 /* This runs on FreeBSD8.1 r30210, but sendfiles blocks its execution
9923  * without cpuset -l 0.
9924  */
9925 # define USE_SENDFILE
9926 
9927 # ifdef HAVE_SYS_UIO_H
9928 # include <sys/uio.h>
9929 # endif
9930 
9931 static ssize_t
9932 simple_sendfile(int out_fd, int in_fd, off_t *offset, off_t count)
9933 {
9934  int r;
9935  off_t pos = offset ? *offset : lseek(in_fd, 0, SEEK_CUR);
9936  off_t sbytes;
9937 # ifdef __APPLE__
9938  r = sendfile(in_fd, out_fd, pos, &count, NULL, 0);
9939  sbytes = count;
9940 # else
9941  r = sendfile(in_fd, out_fd, pos, (size_t)count, NULL, &sbytes, 0);
9942 # endif
9943  if (r != 0 && sbytes == 0) return -1;
9944  if (offset) {
9945  *offset += sbytes;
9946  }
9947  else {
9948  lseek(in_fd, sbytes, SEEK_CUR);
9949  }
9950  return (ssize_t)sbytes;
9951 }
9952 
9953 # endif
9954 
9955 #endif
9956 
9957 #ifdef USE_SENDFILE
9958 static int
9959 nogvl_copy_stream_sendfile(struct copy_stream_struct *stp)
9960 {
9961  struct stat src_stat, dst_stat;
9962  ssize_t ss;
9963  int ret;
9964 
9965  off_t copy_length;
9966  off_t src_offset;
9967  int use_pread;
9968 
9969  ret = fstat(stp->src_fd, &src_stat);
9970  if (ret == -1) {
9971  stp->syserr = "fstat";
9972  stp->error_no = errno;
9973  return -1;
9974  }
9975  if (!S_ISREG(src_stat.st_mode))
9976  return 0;
9977 
9978  ret = fstat(stp->dst_fd, &dst_stat);
9979  if (ret == -1) {
9980  stp->syserr = "fstat";
9981  stp->error_no = errno;
9982  return -1;
9983  }
9984  if ((dst_stat.st_mode & S_IFMT) != S_IFSOCK)
9985  return 0;
9986 
9987  src_offset = stp->src_offset;
9988  use_pread = src_offset != (off_t)-1;
9989 
9990  copy_length = stp->copy_length;
9991  if (copy_length == (off_t)-1) {
9992  if (use_pread)
9993  copy_length = src_stat.st_size - src_offset;
9994  else {
9995  off_t cur;
9996  errno = 0;
9997  cur = lseek(stp->src_fd, 0, SEEK_CUR);
9998  if (cur == (off_t)-1 && errno) {
9999  stp->syserr = "lseek";
10000  stp->error_no = errno;
10001  return -1;
10002  }
10003  copy_length = src_stat.st_size - cur;
10004  }
10005  }
10006 
10007  retry_sendfile:
10008 # if SIZEOF_OFF_T > SIZEOF_SIZE_T
10009  /* we are limited by the 32-bit ssize_t return value on 32-bit */
10010  ss = (copy_length > (off_t)SSIZE_MAX) ? SSIZE_MAX : (ssize_t)copy_length;
10011 # else
10012  ss = (ssize_t)copy_length;
10013 # endif
10014  if (use_pread) {
10015  ss = simple_sendfile(stp->dst_fd, stp->src_fd, &src_offset, ss);
10016  }
10017  else {
10018  ss = simple_sendfile(stp->dst_fd, stp->src_fd, NULL, ss);
10019  }
10020  if (0 < ss) {
10021  stp->total += ss;
10022  copy_length -= ss;
10023  if (0 < copy_length) {
10024  goto retry_sendfile;
10025  }
10026  }
10027  if (ss == -1) {
10028  if (maygvl_copy_stream_continue_p(0, stp))
10029  goto retry_sendfile;
10030  switch (errno) {
10031  case EINVAL:
10032 #ifdef ENOSYS
10033  case ENOSYS:
10034 #endif
10035  return 0;
10036  case EAGAIN:
10037 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
10038  case EWOULDBLOCK:
10039 #endif
10040 #ifndef __linux__
10041  /*
10042  * Linux requires stp->src_fd to be a mmap-able (regular) file,
10043  * select() reports regular files to always be "ready", so
10044  * there is no need to select() on it.
10045  * Other OSes may have the same limitation for sendfile() which
10046  * allow us to bypass maygvl_copy_stream_wait_read()...
10047  */
10048  if (maygvl_copy_stream_wait_read(0, stp) == -1)
10049  return -1;
10050 #endif
10051  if (nogvl_copy_stream_wait_write(stp) == -1)
10052  return -1;
10053  goto retry_sendfile;
10054  }
10055  stp->syserr = "sendfile";
10056  stp->error_no = errno;
10057  return -1;
10058  }
10059  return 1;
10060 }
10061 #endif
10062 
10063 static ssize_t
10064 maygvl_read(int has_gvl, int fd, void *buf, size_t count)
10065 {
10066  if (has_gvl)
10067  return rb_read_internal(fd, buf, count);
10068  else
10069  return read(fd, buf, count);
10070 }
10071 
10072 static ssize_t
10073 maygvl_copy_stream_read(int has_gvl, struct copy_stream_struct *stp, char *buf, size_t len, off_t offset)
10074 {
10075  ssize_t ss;
10076  retry_read:
10077  if (offset == (off_t)-1) {
10078  ss = maygvl_read(has_gvl, stp->src_fd, buf, len);
10079  }
10080  else {
10081 #ifdef HAVE_PREAD
10082  ss = pread(stp->src_fd, buf, len, offset);
10083 #else
10084  stp->notimp = "pread";
10085  return -1;
10086 #endif
10087  }
10088  if (ss == 0) {
10089  return 0;
10090  }
10091  if (ss == -1) {
10092  if (maygvl_copy_stream_continue_p(has_gvl, stp))
10093  goto retry_read;
10094  switch (errno) {
10095  case EAGAIN:
10096 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
10097  case EWOULDBLOCK:
10098 #endif
10099  if (maygvl_copy_stream_wait_read(has_gvl, stp) == -1)
10100  return -1;
10101  goto retry_read;
10102 #ifdef ENOSYS
10103  case ENOSYS:
10104 #endif
10105  stp->notimp = "pread";
10106  return -1;
10107  }
10108  stp->syserr = offset == (off_t)-1 ? "read" : "pread";
10109  stp->error_no = errno;
10110  return -1;
10111  }
10112  return ss;
10113 }
10114 
10115 static int
10116 nogvl_copy_stream_write(struct copy_stream_struct *stp, char *buf, size_t len)
10117 {
10118  ssize_t ss;
10119  int off = 0;
10120  while (len) {
10121  ss = write(stp->dst_fd, buf+off, len);
10122  if (ss == -1) {
10123  if (maygvl_copy_stream_continue_p(0, stp))
10124  continue;
10125  if (errno == EAGAIN || errno == EWOULDBLOCK) {
10126  if (nogvl_copy_stream_wait_write(stp) == -1)
10127  return -1;
10128  continue;
10129  }
10130  stp->syserr = "write";
10131  stp->error_no = errno;
10132  return -1;
10133  }
10134  off += (int)ss;
10135  len -= (int)ss;
10136  stp->total += ss;
10137  }
10138  return 0;
10139 }
10140 
10141 static void
10143 {
10144  char buf[1024*16];
10145  size_t len;
10146  ssize_t ss;
10147  int ret;
10148  off_t copy_length;
10149  int use_eof;
10150  off_t src_offset;
10151  int use_pread;
10152 
10153  copy_length = stp->copy_length;
10154  use_eof = copy_length == (off_t)-1;
10155  src_offset = stp->src_offset;
10156  use_pread = src_offset != (off_t)-1;
10157 
10158  if (use_pread && stp->close_src) {
10159  off_t r;
10160  errno = 0;
10161  r = lseek(stp->src_fd, src_offset, SEEK_SET);
10162  if (r == (off_t)-1 && errno) {
10163  stp->syserr = "lseek";
10164  stp->error_no = errno;
10165  return;
10166  }
10167  src_offset = (off_t)-1;
10168  use_pread = 0;
10169  }
10170 
10171  while (use_eof || 0 < copy_length) {
10172  if (!use_eof && copy_length < (off_t)sizeof(buf)) {
10173  len = (size_t)copy_length;
10174  }
10175  else {
10176  len = sizeof(buf);
10177  }
10178  if (use_pread) {
10179  ss = maygvl_copy_stream_read(0, stp, buf, len, src_offset);
10180  if (0 < ss)
10181  src_offset += ss;
10182  }
10183  else {
10184  ss = maygvl_copy_stream_read(0, stp, buf, len, (off_t)-1);
10185  }
10186  if (ss <= 0) /* EOF or error */
10187  return;
10188 
10189  ret = nogvl_copy_stream_write(stp, buf, ss);
10190  if (ret < 0)
10191  return;
10192 
10193  if (!use_eof)
10194  copy_length -= ss;
10195  }
10196 }
10197 
10198 static void *
10200 {
10201  struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
10202 #ifdef USE_SENDFILE
10203  int ret;
10204 #endif
10205 
10206 #ifdef USE_SENDFILE
10207  ret = nogvl_copy_stream_sendfile(stp);
10208  if (ret != 0)
10209  goto finish; /* error or success */
10210 #endif
10211 
10213 
10214 #ifdef USE_SENDFILE
10215  finish:
10216 #endif
10217  return 0;
10218 }
10219 
10220 static VALUE
10222 {
10223  struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
10224  const int buflen = 16*1024;
10225  VALUE n;
10226  VALUE buf = rb_str_buf_new(buflen);
10227  off_t rest = stp->copy_length;
10228  off_t off = stp->src_offset;
10229  ID read_method = id_readpartial;
10230 
10231  if (stp->src_fd == -1) {
10232  if (!rb_respond_to(stp->src, read_method)) {
10233  read_method = id_read;
10234  }
10235  }
10236 
10237  while (1) {
10238  long numwrote;
10239  long l;
10240  if (stp->copy_length == (off_t)-1) {
10241  l = buflen;
10242  }
10243  else {
10244  if (rest == 0)
10245  break;
10246  l = buflen < rest ? buflen : (long)rest;
10247  }
10248  if (stp->src_fd == -1) {
10249  VALUE rc = rb_funcall(stp->src, read_method, 2, INT2FIX(l), buf);
10250 
10251  if (read_method == id_read && NIL_P(rc))
10252  break;
10253  }
10254  else {
10255  ssize_t ss;
10256  rb_str_resize(buf, buflen);
10257  ss = maygvl_copy_stream_read(1, stp, RSTRING_PTR(buf), l, off);
10258  if (ss == -1)
10259  return Qnil;
10260  if (ss == 0)
10261  rb_eof_error();
10262  rb_str_resize(buf, ss);
10263  if (off != (off_t)-1)
10264  off += ss;
10265  }
10266  n = rb_io_write(stp->dst, buf);
10267  numwrote = NUM2LONG(n);
10268  stp->total += numwrote;
10269  rest -= numwrote;
10270  if (read_method == id_read && RSTRING_LEN(buf) == 0) {
10271  break;
10272  }
10273  }
10274 
10275  return Qnil;
10276 }
10277 
10278 static VALUE
10280 {
10281  if (stp->src_fd == -1 && stp->src_offset != (off_t)-1) {
10282  rb_raise(rb_eArgError, "cannot specify src_offset for non-IO");
10283  }
10285  (VALUE (*) (ANYARGS))0, (VALUE)0,
10286  rb_eEOFError, (VALUE)0);
10287  return Qnil;
10288 }
10289 
10290 static VALUE
10292 {
10293  struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
10294  VALUE src_io = stp->src, dst_io = stp->dst;
10295  rb_io_t *src_fptr = 0, *dst_fptr = 0;
10296  int src_fd, dst_fd;
10297  const int common_oflags = 0
10298 #ifdef O_NOCTTY
10299  | O_NOCTTY
10300 #endif
10301  ;
10302 
10303  stp->th = rb_thread_current();
10304 
10305  stp->total = 0;
10306 
10307  if (src_io == argf ||
10308  !(RB_TYPE_P(src_io, T_FILE) ||
10309  RB_TYPE_P(src_io, T_STRING) ||
10310  rb_respond_to(src_io, rb_intern("to_path")))) {
10311  src_fd = -1;
10312  }
10313  else {
10314  if (!RB_TYPE_P(src_io, T_FILE)) {
10315  VALUE args[2];
10316  FilePathValue(src_io);
10317  args[0] = src_io;
10318  args[1] = INT2NUM(O_RDONLY|common_oflags);
10319  src_io = rb_class_new_instance(2, args, rb_cFile);
10320  stp->src = src_io;
10321  stp->close_src = 1;
10322  }
10323  GetOpenFile(src_io, src_fptr);
10324  rb_io_check_byte_readable(src_fptr);
10325  src_fd = src_fptr->fd;
10326  }
10327  stp->src_fd = src_fd;
10328 
10329  if (dst_io == argf ||
10330  !(RB_TYPE_P(dst_io, T_FILE) ||
10331  RB_TYPE_P(dst_io, T_STRING) ||
10332  rb_respond_to(dst_io, rb_intern("to_path")))) {
10333  dst_fd = -1;
10334  }
10335  else {
10336  if (!RB_TYPE_P(dst_io, T_FILE)) {
10337  VALUE args[3];
10338  FilePathValue(dst_io);
10339  args[0] = dst_io;
10340  args[1] = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC|common_oflags);
10341  args[2] = INT2FIX(0666);
10342  dst_io = rb_class_new_instance(3, args, rb_cFile);
10343  stp->dst = dst_io;
10344  stp->close_dst = 1;
10345  }
10346  else {
10347  dst_io = GetWriteIO(dst_io);
10348  stp->dst = dst_io;
10349  }
10350  GetOpenFile(dst_io, dst_fptr);
10351  rb_io_check_writable(dst_fptr);
10352  dst_fd = dst_fptr->fd;
10353  }
10354  stp->dst_fd = dst_fd;
10355 
10356 #ifdef O_BINARY
10357  if (src_fptr)
10359 #endif
10360  if (dst_fptr)
10361  io_ascii8bit_binmode(dst_fptr);
10362 
10363  if (stp->src_offset == (off_t)-1 && src_fptr && src_fptr->rbuf.len) {
10364  size_t len = src_fptr->rbuf.len;
10365  VALUE str;
10366  if (stp->copy_length != (off_t)-1 && stp->copy_length < (off_t)len) {
10367  len = (size_t)stp->copy_length;
10368  }
10369  str = rb_str_buf_new(len);
10370  rb_str_resize(str,len);
10371  read_buffered_data(RSTRING_PTR(str), len, src_fptr);
10372  if (dst_fptr) { /* IO or filename */
10373  if (io_binwrite(str, RSTRING_PTR(str), RSTRING_LEN(str), dst_fptr, 0) < 0)
10374  rb_sys_fail(0);
10375  }
10376  else /* others such as StringIO */
10377  rb_io_write(dst_io, str);
10378  stp->total += len;
10379  if (stp->copy_length != (off_t)-1)
10380  stp->copy_length -= len;
10381  }
10382 
10383  if (dst_fptr && io_fflush(dst_fptr) < 0) {
10384  rb_raise(rb_eIOError, "flush failed");
10385  }
10386 
10387  if (stp->copy_length == 0)
10388  return Qnil;
10389 
10390  if (src_fd == -1 || dst_fd == -1) {
10391  return copy_stream_fallback(stp);
10392  }
10393 
10394  rb_fd_set(src_fd, &stp->fds);
10395  rb_fd_set(dst_fd, &stp->fds);
10396 
10398  return Qnil;
10399 }
10400 
10401 static VALUE
10403 {
10404  struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
10405  if (stp->close_src) {
10406  rb_io_close_m(stp->src);
10407  }
10408  if (stp->close_dst) {
10409  rb_io_close_m(stp->dst);
10410  }
10411  rb_fd_term(&stp->fds);
10412  if (stp->syserr) {
10413  errno = stp->error_no;
10414  rb_sys_fail(stp->syserr);
10415  }
10416  if (stp->notimp) {
10417  rb_raise(rb_eNotImpError, "%s() not implemented", stp->notimp);
10418  }
10419  return Qnil;
10420 }
10421 
10422 /*
10423  * call-seq:
10424  * IO.copy_stream(src, dst)
10425  * IO.copy_stream(src, dst, copy_length)
10426  * IO.copy_stream(src, dst, copy_length, src_offset)
10427  *
10428  * IO.copy_stream copies <i>src</i> to <i>dst</i>.
10429  * <i>src</i> and <i>dst</i> is either a filename or an IO.
10430  *
10431  * This method returns the number of bytes copied.
10432  *
10433  * If optional arguments are not given,
10434  * the start position of the copy is
10435  * the beginning of the filename or
10436  * the current file offset of the IO.
10437  * The end position of the copy is the end of file.
10438  *
10439  * If <i>copy_length</i> is given,
10440  * No more than <i>copy_length</i> bytes are copied.
10441  *
10442  * If <i>src_offset</i> is given,
10443  * it specifies the start position of the copy.
10444  *
10445  * When <i>src_offset</i> is specified and
10446  * <i>src</i> is an IO,
10447  * IO.copy_stream doesn't move the current file offset.
10448  *
10449  */
10450 static VALUE
10452 {
10453  VALUE src, dst, length, src_offset;
10454  struct copy_stream_struct st;
10455 
10456  MEMZERO(&st, struct copy_stream_struct, 1);
10457 
10458  rb_scan_args(argc, argv, "22", &src, &dst, &length, &src_offset);
10459 
10460  st.src = src;
10461  st.dst = dst;
10462 
10463  if (NIL_P(length))
10464  st.copy_length = (off_t)-1;
10465  else
10466  st.copy_length = NUM2OFFT(length);
10467 
10468  if (NIL_P(src_offset))
10469  st.src_offset = (off_t)-1;
10470  else
10471  st.src_offset = NUM2OFFT(src_offset);
10472 
10473  rb_fd_init(&st.fds);
10475 
10476  return OFFT2NUM(st.total);
10477 }
10478 
10479 /*
10480  * call-seq:
10481  * io.external_encoding -> encoding
10482  *
10483  * Returns the Encoding object that represents the encoding of the file.
10484  * If io is write mode and no encoding is specified, returns <code>nil</code>.
10485  */
10486 
10487 static VALUE
10489 {
10490  rb_io_t *fptr;
10491 
10492  GetOpenFile(io, fptr);
10493  if (fptr->encs.enc2) {
10494  return rb_enc_from_encoding(fptr->encs.enc2);
10495  }
10496  if (fptr->mode & FMODE_WRITABLE) {
10497  if (fptr->encs.enc)
10498  return rb_enc_from_encoding(fptr->encs.enc);
10499  return Qnil;
10500  }
10501  return rb_enc_from_encoding(io_read_encoding(fptr));
10502 }
10503 
10504 /*
10505  * call-seq:
10506  * io.internal_encoding -> encoding
10507  *
10508  * Returns the Encoding of the internal string if conversion is
10509  * specified. Otherwise returns nil.
10510  */
10511 
10512 static VALUE
10514 {
10515  rb_io_t *fptr;
10516 
10517  GetOpenFile(io, fptr);
10518  if (!fptr->encs.enc2) return Qnil;
10519  return rb_enc_from_encoding(io_read_encoding(fptr));
10520 }
10521 
10522 /*
10523  * call-seq:
10524  * io.set_encoding(ext_enc) -> io
10525  * io.set_encoding("ext_enc:int_enc") -> io
10526  * io.set_encoding(ext_enc, int_enc) -> io
10527  * io.set_encoding("ext_enc:int_enc", opt) -> io
10528  * io.set_encoding(ext_enc, int_enc, opt) -> io
10529  *
10530  * If single argument is specified, read string from io is tagged
10531  * with the encoding specified. If encoding is a colon separated two
10532  * encoding names "A:B", the read string is converted from encoding A
10533  * (external encoding) to encoding B (internal encoding), then tagged
10534  * with B. If two arguments are specified, those must be encoding
10535  * objects or encoding names, and the first one is the external encoding, and the
10536  * second one is the internal encoding.
10537  * If the external encoding and the internal encoding is specified,
10538  * optional hash argument specify the conversion option.
10539  */
10540 
10541 static VALUE
10543 {
10544  rb_io_t *fptr;
10545  VALUE v1, v2, opt;
10546 
10547  if (!RB_TYPE_P(io, T_FILE)) {
10548  return rb_funcall2(io, id_set_encoding, argc, argv);
10549  }
10550 
10551  argc = rb_scan_args(argc, argv, "11:", &v1, &v2, &opt);
10552  GetOpenFile(io, fptr);
10553  io_encoding_set(fptr, v1, v2, opt);
10554  return io;
10555 }
10556 
10557 void
10559 {
10560  extern VALUE rb_stdin, rb_stdout, rb_stderr;
10561  VALUE val = Qnil;
10562 
10563  rb_io_set_encoding(1, &val, rb_stdin);
10564  rb_io_set_encoding(1, &val, rb_stdout);
10565  rb_io_set_encoding(1, &val, rb_stderr);
10566 }
10567 
10568 /*
10569  * call-seq:
10570  * ARGF.external_encoding -> encoding
10571  *
10572  * Returns the external encoding for files read from +ARGF+ as an +Encoding+
10573  * object. The external encoding is the encoding of the text as stored in a
10574  * file. Contrast with +ARGF.internal_encoding+, which is the encoding used
10575  * to represent this text within Ruby.
10576  *
10577  * To set the external encoding use +ARGF.set_encoding+.
10578  *
10579  * For example:
10580  *
10581  * ARGF.external_encoding #=> #<Encoding:UTF-8>
10582  *
10583  */
10584 static VALUE
10586 {
10587  if (!RTEST(ARGF.current_file)) {
10589  }
10590  return rb_io_external_encoding(rb_io_check_io(ARGF.current_file));
10591 }
10592 
10593 /*
10594  * call-seq:
10595  * ARGF.internal_encoding -> encoding
10596  *
10597  * Returns the internal encoding for strings read from +ARGF+ as an
10598  * +Encoding+ object.
10599  *
10600  * If +ARGF.set_encoding+ has been called with two encoding names, the second
10601  * is returned. Otherwise, if +Encoding.default_external+ has been set, that
10602  * value is returned. Failing that, if a default external encoding was
10603  * specified on the command-line, that value is used. If the encoding is
10604  * unknown, nil is returned.
10605  */
10606 static VALUE
10608 {
10609  if (!RTEST(ARGF.current_file)) {
10611  }
10612  return rb_io_internal_encoding(rb_io_check_io(ARGF.current_file));
10613 }
10614 
10615 /*
10616  * call-seq:
10617  * ARGF.set_encoding(ext_enc) -> ARGF
10618  * ARGF.set_encoding("ext_enc:int_enc") -> ARGF
10619  * ARGF.set_encoding(ext_enc, int_enc) -> ARGF
10620  * ARGF.set_encoding("ext_enc:int_enc", opt) -> ARGF
10621  * ARGF.set_encoding(ext_enc, int_enc, opt) -> ARGF
10622  *
10623  * If single argument is specified, strings read from ARGF are tagged with
10624  * the encoding specified.
10625  *
10626  * If two encoding names separated by a colon are given, e.g. "ascii:utf-8",
10627  * the read string is converted from the first encoding (external encoding)
10628  * to the second encoding (internal encoding), then tagged with the second
10629  * encoding.
10630  *
10631  * If two arguments are specified, they must be encoding objects or encoding
10632  * names. Again, the first specifies the external encoding; the second
10633  * specifies the internal encoding.
10634  *
10635  * If the external encoding and the internal encoding are specified, the
10636  * optional +Hash+ argument can be used to adjust the conversion process. The
10637  * structure of this hash is explained in the +String#encode+ documentation.
10638  *
10639  * For example:
10640  *
10641  * ARGF.set_encoding('ascii') # Tag the input as US-ASCII text
10642  * ARGF.set_encoding(Encoding::UTF_8) # Tag the input as UTF-8 text
10643  * ARGF.set_encoding('utf-8','ascii') # Transcode the input from US-ASCII
10644  * # to UTF-8.
10645  */
10646 static VALUE
10648 {
10649  rb_io_t *fptr;
10650 
10651  if (!next_argv()) {
10652  rb_raise(rb_eArgError, "no stream to set encoding");
10653  }
10654  rb_io_set_encoding(argc, argv, ARGF.current_file);
10655  GetOpenFile(ARGF.current_file, fptr);
10656  ARGF.encs = fptr->encs;
10657  return argf;
10658 }
10659 
10660 /*
10661  * call-seq:
10662  * ARGF.tell -> Integer
10663  * ARGF.pos -> Integer
10664  *
10665  * Returns the current offset (in bytes) of the current file in +ARGF+.
10666  *
10667  * ARGF.pos #=> 0
10668  * ARGF.gets #=> "This is line one\n"
10669  * ARGF.pos #=> 17
10670  *
10671  */
10672 static VALUE
10674 {
10675  if (!next_argv()) {
10676  rb_raise(rb_eArgError, "no stream to tell");
10677  }
10678  ARGF_FORWARD(0, 0);
10679  return rb_io_tell(ARGF.current_file);
10680 }
10681 
10682 /*
10683  * call-seq:
10684  * ARGF.seek(amount, whence=IO::SEEK_SET) -> 0
10685  *
10686  * Seeks to offset _amount_ (an +Integer+) in the +ARGF+ stream according to
10687  * the value of _whence_. See +IO#seek+ for further details.
10688  */
10689 static VALUE
10691 {
10692  if (!next_argv()) {
10693  rb_raise(rb_eArgError, "no stream to seek");
10694  }
10695  ARGF_FORWARD(argc, argv);
10696  return rb_io_seek_m(argc, argv, ARGF.current_file);
10697 }
10698 
10699 /*
10700  * call-seq:
10701  * ARGF.pos = position -> Integer
10702  *
10703  * Seeks to the position given by _position_ (in bytes) in +ARGF+.
10704  *
10705  * For example:
10706  *
10707  * ARGF.pos = 17
10708  * ARGF.gets #=> "This is line two\n"
10709  */
10710 static VALUE
10712 {
10713  if (!next_argv()) {
10714  rb_raise(rb_eArgError, "no stream to set position");
10715  }
10716  ARGF_FORWARD(1, &offset);
10717  return rb_io_set_pos(ARGF.current_file, offset);
10718 }
10719 
10720 /*
10721  * call-seq:
10722  * ARGF.rewind -> 0
10723  *
10724  * Positions the current file to the beginning of input, resetting
10725  * +ARGF.lineno+ to zero.
10726  *
10727  * ARGF.readline #=> "This is line one\n"
10728  * ARGF.rewind #=> 0
10729  * ARGF.lineno #=> 0
10730  * ARGF.readline #=> "This is line one\n"
10731  */
10732 static VALUE
10734 {
10735  if (!next_argv()) {
10736  rb_raise(rb_eArgError, "no stream to rewind");
10737  }
10738  ARGF_FORWARD(0, 0);
10739  return rb_io_rewind(ARGF.current_file);
10740 }
10741 
10742 /*
10743  * call-seq:
10744  * ARGF.fileno -> fixnum
10745  * ARGF.to_i -> fixnum
10746  *
10747  * Returns an integer representing the numeric file descriptor for
10748  * the current file. Raises an +ArgumentError+ if there isn't a current file.
10749  *
10750  * ARGF.fileno #=> 3
10751  */
10752 static VALUE
10754 {
10755  if (!next_argv()) {
10756  rb_raise(rb_eArgError, "no stream");
10757  }
10758  ARGF_FORWARD(0, 0);
10759  return rb_io_fileno(ARGF.current_file);
10760 }
10761 
10762 /*
10763  * call-seq:
10764  * ARGF.to_io -> IO
10765  *
10766  * Returns an +IO+ object representing the current file. This will be a
10767  * +File+ object unless the current file is a stream such as STDIN.
10768  *
10769  * For example:
10770  *
10771  * ARGF.to_io #=> #<File:glark.txt>
10772  * ARGF.to_io #=> #<IO:<STDIN>>
10773  */
10774 static VALUE
10776 {
10777  next_argv();
10778  ARGF_FORWARD(0, 0);
10779  return ARGF.current_file;
10780 }
10781 
10782 /*
10783  * call-seq:
10784  * ARGF.eof? -> true or false
10785  * ARGF.eof -> true or false
10786  *
10787  * Returns true if the current file in +ARGF+ is at end of file, i.e. it has
10788  * no data to read. The stream must be opened for reading or an +IOError+
10789  * will be raised.
10790  *
10791  * $ echo "eof" | ruby argf.rb
10792  *
10793  * ARGF.eof? #=> false
10794  * 3.times { ARGF.readchar }
10795  * ARGF.eof? #=> false
10796  * ARGF.readchar #=> "\n"
10797  * ARGF.eof? #=> true
10798  */
10799 
10800 static VALUE
10802 {
10803  next_argv();
10804  if (RTEST(ARGF.current_file)) {
10805  if (ARGF.init_p == 0) return Qtrue;
10806  next_argv();
10807  ARGF_FORWARD(0, 0);
10808  if (rb_io_eof(ARGF.current_file)) {
10809  return Qtrue;
10810  }
10811  }
10812  return Qfalse;
10813 }
10814 
10815 /*
10816  * call-seq:
10817  * ARGF.read([length [, outbuf]]) -> string, outbuf, or nil
10818  *
10819  * Reads _length_ bytes from ARGF. The files named on the command line
10820  * are concatenated and treated as a single file by this method, so when
10821  * called without arguments the contents of this pseudo file are returned in
10822  * their entirety.
10823  *
10824  * _length_ must be a non-negative integer or nil. If it is a positive
10825  * integer, +read+ tries to read at most _length_ bytes. It returns nil
10826  * if an EOF was encountered before anything could be read. Fewer than
10827  * _length_ bytes may be returned if an EOF is encountered during the read.
10828  *
10829  * If _length_ is omitted or is _nil_, it reads until EOF. A String is
10830  * returned even if EOF is encountered before any data is read.
10831  *
10832  * If _length_ is zero, it returns _""_.
10833  *
10834  * If the optional _outbuf_ argument is present, it must reference a String,
10835  * which will receive the data.
10836  * The <i>outbuf</i> will contain only the received data after the method call
10837  * even if it is not empty at the beginning.
10838  *
10839  * For example:
10840  *
10841  * $ echo "small" > small.txt
10842  * $ echo "large" > large.txt
10843  * $ ./glark.rb small.txt large.txt
10844  *
10845  * ARGF.read #=> "small\nlarge"
10846  * ARGF.read(200) #=> "small\nlarge"
10847  * ARGF.read(2) #=> "sm"
10848  * ARGF.read(0) #=> ""
10849  *
10850  * Note that this method behaves like fread() function in C. If you need the
10851  * behavior like read(2) system call, consider +ARGF.readpartial+.
10852  */
10853 
10854 static VALUE
10856 {
10857  VALUE tmp, str, length;
10858  long len = 0;
10859 
10860  rb_scan_args(argc, argv, "02", &length, &str);
10861  if (!NIL_P(length)) {
10862  len = NUM2LONG(argv[0]);
10863  }
10864  if (!NIL_P(str)) {
10865  StringValue(str);
10866  rb_str_resize(str,0);
10867  argv[1] = Qnil;
10868  }
10869 
10870  retry:
10871  if (!next_argv()) {
10872  return str;
10873  }
10874  if (ARGF_GENERIC_INPUT_P()) {
10875  tmp = argf_forward(argc, argv, argf);
10876  }
10877  else {
10878  tmp = io_read(argc, argv, ARGF.current_file);
10879  }
10880  if (NIL_P(str)) str = tmp;
10881  else if (!NIL_P(tmp)) rb_str_append(str, tmp);
10882  if (NIL_P(tmp) || NIL_P(length)) {
10883  if (ARGF.next_p != -1) {
10884  argf_close(argf);
10885  ARGF.next_p = 1;
10886  goto retry;
10887  }
10888  }
10889  else if (argc >= 1) {
10890  if (RSTRING_LEN(str) < len) {
10891  len -= RSTRING_LEN(str);
10892  argv[0] = INT2NUM(len);
10893  goto retry;
10894  }
10895  }
10896  return str;
10897 }
10898 
10900  int argc;
10903 };
10904 
10905 static VALUE
10907 {
10908  struct argf_call_arg *p = (struct argf_call_arg *)arg;
10909  argf_forward(p->argc, p->argv, p->argf);
10910  return Qnil;
10911 }
10912 
10913 static VALUE argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock);
10914 
10915 /*
10916  * call-seq:
10917  * ARGF.readpartial(maxlen) -> string
10918  * ARGF.readpartial(maxlen, outbuf) -> outbuf
10919  *
10920  * Reads at most _maxlen_ bytes from the ARGF stream.
10921  *
10922  * If the optional _outbuf_ argument is present,
10923  * it must reference a String, which will receive the data.
10924  * The <i>outbuf</i> will contain only the received data after the method call
10925  * even if it is not empty at the beginning.
10926  *
10927  * It raises <code>EOFError</code> on end of ARGF stream.
10928  * Since ARGF stream is a concatenation of multiple files,
10929  * internally EOF is occur for each file.
10930  * ARGF.readpartial returns empty strings for EOFs except the last one and
10931  * raises <code>EOFError</code> for the last one.
10932  *
10933  */
10934 
10935 static VALUE
10937 {
10938  return argf_getpartial(argc, argv, argf, 0);
10939 }
10940 
10941 /*
10942  * call-seq:
10943  * ARGF.read_nonblock(maxlen) -> string
10944  * ARGF.read_nonblock(maxlen, outbuf) -> outbuf
10945  *
10946  * Reads at most _maxlen_ bytes from the ARGF stream in non-blocking mode.
10947  */
10948 
10949 static VALUE
10951 {
10952  return argf_getpartial(argc, argv, argf, 1);
10953 }
10954 
10955 static VALUE
10956 argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock)
10957 {
10958  VALUE tmp, str, length;
10959 
10960  rb_scan_args(argc, argv, "11", &length, &str);
10961  if (!NIL_P(str)) {
10962  StringValue(str);
10963  argv[1] = str;
10964  }
10965 
10966  if (!next_argv()) {
10967  rb_str_resize(str, 0);
10968  rb_eof_error();
10969  }
10970  if (ARGF_GENERIC_INPUT_P()) {
10971  struct argf_call_arg arg;
10972  arg.argc = argc;
10973  arg.argv = argv;
10974  arg.argf = argf;
10975  tmp = rb_rescue2(argf_forward_call, (VALUE)&arg,
10977  }
10978  else {
10979  tmp = io_getpartial(argc, argv, ARGF.current_file, nonblock, 0);
10980  }
10981  if (NIL_P(tmp)) {
10982  if (ARGF.next_p == -1) {
10983  rb_eof_error();
10984  }
10985  argf_close(argf);
10986  ARGF.next_p = 1;
10987  if (RARRAY_LEN(ARGF.argv) == 0)
10988  rb_eof_error();
10989  if (NIL_P(str))
10990  str = rb_str_new(NULL, 0);
10991  return str;
10992  }
10993  return tmp;
10994 }
10995 
10996 /*
10997  * call-seq:
10998  * ARGF.getc -> String or nil
10999  *
11000  * Reads the next character from +ARGF+ and returns it as a +String+. Returns
11001  * +nil+ at the end of the stream.
11002  *
11003  * +ARGF+ treats the files named on the command line as a single file created
11004  * by concatenating their contents. After returning the last character of the
11005  * first file, it returns the first character of the second file, and so on.
11006  *
11007  * For example:
11008  *
11009  * $ echo "foo" > file
11010  * $ ruby argf.rb file
11011  *
11012  * ARGF.getc #=> "f"
11013  * ARGF.getc #=> "o"
11014  * ARGF.getc #=> "o"
11015  * ARGF.getc #=> "\n"
11016  * ARGF.getc #=> nil
11017  * ARGF.getc #=> nil
11018  */
11019 static VALUE
11021 {
11022  VALUE ch;
11023 
11024  retry:
11025  if (!next_argv()) return Qnil;
11026  if (ARGF_GENERIC_INPUT_P()) {
11027  ch = rb_funcall3(ARGF.current_file, rb_intern("getc"), 0, 0);
11028  }
11029  else {
11030  ch = rb_io_getc(ARGF.current_file);
11031  }
11032  if (NIL_P(ch) && ARGF.next_p != -1) {
11033  argf_close(argf);
11034  ARGF.next_p = 1;
11035  goto retry;
11036  }
11037 
11038  return ch;
11039 }
11040 
11041 /*
11042  * call-seq:
11043  * ARGF.getbyte -> Fixnum or nil
11044  *
11045  * Gets the next 8-bit byte (0..255) from +ARGF+. Returns +nil+ if called at
11046  * the end of the stream.
11047  *
11048  * For example:
11049  *
11050  * $ echo "foo" > file
11051  * $ ruby argf.rb file
11052  *
11053  * ARGF.getbyte #=> 102
11054  * ARGF.getbyte #=> 111
11055  * ARGF.getbyte #=> 111
11056  * ARGF.getbyte #=> 10
11057  * ARGF.getbyte #=> nil
11058  */
11059 static VALUE
11061 {
11062  VALUE ch;
11063 
11064  retry:
11065  if (!next_argv()) return Qnil;
11066  if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
11067  ch = rb_funcall3(ARGF.current_file, rb_intern("getbyte"), 0, 0);
11068  }
11069  else {
11070  ch = rb_io_getbyte(ARGF.current_file);
11071  }
11072  if (NIL_P(ch) && ARGF.next_p != -1) {
11073  argf_close(argf);
11074  ARGF.next_p = 1;
11075  goto retry;
11076  }
11077 
11078  return ch;
11079 }
11080 
11081 /*
11082  * call-seq:
11083  * ARGF.readchar -> String or nil
11084  *
11085  * Reads the next character from +ARGF+ and returns it as a +String+. Raises
11086  * an +EOFError+ after the last character of the last file has been read.
11087  *
11088  * For example:
11089  *
11090  * $ echo "foo" > file
11091  * $ ruby argf.rb file
11092  *
11093  * ARGF.readchar #=> "f"
11094  * ARGF.readchar #=> "o"
11095  * ARGF.readchar #=> "o"
11096  * ARGF.readchar #=> "\n"
11097  * ARGF.readchar #=> end of file reached (EOFError)
11098  */
11099 static VALUE
11101 {
11102  VALUE ch;
11103 
11104  retry:
11105  if (!next_argv()) rb_eof_error();
11106  if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
11107  ch = rb_funcall3(ARGF.current_file, rb_intern("getc"), 0, 0);
11108  }
11109  else {
11110  ch = rb_io_getc(ARGF.current_file);
11111  }
11112  if (NIL_P(ch) && ARGF.next_p != -1) {
11113  argf_close(argf);
11114  ARGF.next_p = 1;
11115  goto retry;
11116  }
11117 
11118  return ch;
11119 }
11120 
11121 /*
11122  * call-seq:
11123  * ARGF.readbyte -> Fixnum
11124  *
11125  * Reads the next 8-bit byte from ARGF and returns it as a +Fixnum+. Raises
11126  * an +EOFError+ after the last byte of the last file has been read.
11127  *
11128  * For example:
11129  *
11130  * $ echo "foo" > file
11131  * $ ruby argf.rb file
11132  *
11133  * ARGF.readbyte #=> 102
11134  * ARGF.readbyte #=> 111
11135  * ARGF.readbyte #=> 111
11136  * ARGF.readbyte #=> 10
11137  * ARGF.readbyte #=> end of file reached (EOFError)
11138  */
11139 static VALUE
11141 {
11142  VALUE c;
11143 
11144  NEXT_ARGF_FORWARD(0, 0);
11145  c = argf_getbyte(argf);
11146  if (NIL_P(c)) {
11147  rb_eof_error();
11148  }
11149  return c;
11150 }
11151 
11152 #define FOREACH_ARGF() while (next_argv())
11153 
11154 static VALUE
11156 {
11157  const VALUE current = ARGF.current_file;
11159  if (ARGF.init_p == -1 || current != ARGF.current_file) {
11161  }
11162  return Qnil;
11163 }
11164 
11165 static void
11167 {
11168  VALUE ret = rb_block_call(ARGF.current_file, mid, argc, argv, argf_block_call_i, argf);
11169  if (ret != Qundef) ARGF.next_p = 1;
11170 }
11171 
11172 /*
11173  * call-seq:
11174  * ARGF.each(sep=$/) {|line| block } -> ARGF
11175  * ARGF.each(sep=$/,limit) {|line| block } -> ARGF
11176  * ARGF.each(...) -> an_enumerator
11177  *
11178  * ARGF.each_line(sep=$/) {|line| block } -> ARGF
11179  * ARGF.each_line(sep=$/,limit) {|line| block } -> ARGF
11180  * ARGF.each_line(...) -> an_enumerator
11181  *
11182  * Returns an enumerator which iterates over each line (separated by _sep_,
11183  * which defaults to your platform's newline character) of each file in
11184  * +ARGV+. If a block is supplied, each line in turn will be yielded to the
11185  * block, otherwise an enumerator is returned.
11186  * The optional _limit_ argument is a +Fixnum+ specifying the maximum
11187  * length of each line; longer lines will be split according to this limit.
11188  *
11189  * This method allows you to treat the files supplied on the command line as
11190  * a single file consisting of the concatenation of each named file. After
11191  * the last line of the first file has been returned, the first line of the
11192  * second file is returned. The +ARGF.filename+ and +ARGF.lineno+ methods can
11193  * be used to determine the filename and line number, respectively, of the
11194  * current line.
11195  *
11196  * For example, the following code prints out each line of each named file
11197  * prefixed with its line number, displaying the filename once per file:
11198  *
11199  * ARGF.lines do |line|
11200  * puts ARGF.filename if ARGF.lineno == 1
11201  * puts "#{ARGF.lineno}: #{line}"
11202  * end
11203  */
11204 static VALUE
11206 {
11207  RETURN_ENUMERATOR(argf, argc, argv);
11208  FOREACH_ARGF() {
11209  argf_block_call(rb_intern("each_line"), argc, argv, argf);
11210  }
11211  return argf;
11212 }
11213 
11214 /*
11215  * This is a deprecated alias for <code>each_line</code>.
11216  */
11217 
11218 static VALUE
11220 {
11221  rb_warn("ARGF#lines is deprecated; use #each_line instead");
11222  if (!rb_block_given_p())
11223  return rb_enumeratorize(argf, ID2SYM(rb_intern("each_line")), argc, argv);
11224  return argf_each_line(argc, argv, argf);
11225 }
11226 
11227 /*
11228  * call-seq:
11229  * ARGF.bytes {|byte| block } -> ARGF
11230  * ARGF.bytes -> an_enumerator
11231  *
11232  * ARGF.each_byte {|byte| block } -> ARGF
11233  * ARGF.each_byte -> an_enumerator
11234  *
11235  * Iterates over each byte of each file in +ARGV+.
11236  * A byte is returned as a +Fixnum+ in the range 0..255.
11237  *
11238  * This method allows you to treat the files supplied on the command line as
11239  * a single file consisting of the concatenation of each named file. After
11240  * the last byte of the first file has been returned, the first byte of the
11241  * second file is returned. The +ARGF.filename+ method can be used to
11242  * determine the filename of the current byte.
11243  *
11244  * If no block is given, an enumerator is returned instead.
11245  *
11246  * For example:
11247  *
11248  * ARGF.bytes.to_a #=> [35, 32, ... 95, 10]
11249  *
11250  */
11251 static VALUE
11253 {
11254  RETURN_ENUMERATOR(argf, 0, 0);
11255  FOREACH_ARGF() {
11256  argf_block_call(rb_intern("each_byte"), 0, 0, argf);
11257  }
11258  return argf;
11259 }
11260 
11261 /*
11262  * This is a deprecated alias for <code>each_byte</code>.
11263  */
11264 
11265 static VALUE
11267 {
11268  rb_warn("ARGF#bytes is deprecated; use #each_byte instead");
11269  if (!rb_block_given_p())
11270  return rb_enumeratorize(argf, ID2SYM(rb_intern("each_byte")), 0, 0);
11271  return argf_each_byte(argf);
11272 }
11273 
11274 /*
11275  * call-seq:
11276  * ARGF.each_char {|char| block } -> ARGF
11277  * ARGF.each_char -> an_enumerator
11278  *
11279  * Iterates over each character of each file in +ARGF+.
11280  *
11281  * This method allows you to treat the files supplied on the command line as
11282  * a single file consisting of the concatenation of each named file. After
11283  * the last character of the first file has been returned, the first
11284  * character of the second file is returned. The +ARGF.filename+ method can
11285  * be used to determine the name of the file in which the current character
11286  * appears.
11287  *
11288  * If no block is given, an enumerator is returned instead.
11289  */
11290 static VALUE
11292 {
11293  RETURN_ENUMERATOR(argf, 0, 0);
11294  FOREACH_ARGF() {
11295  argf_block_call(rb_intern("each_char"), 0, 0, argf);
11296  }
11297  return argf;
11298 }
11299 
11300 /*
11301  * This is a deprecated alias for <code>each_char</code>.
11302  */
11303 
11304 static VALUE
11306 {
11307  rb_warn("ARGF#chars is deprecated; use #each_char instead");
11308  if (!rb_block_given_p())
11309  return rb_enumeratorize(argf, ID2SYM(rb_intern("each_char")), 0, 0);
11310  return argf_each_char(argf);
11311 }
11312 
11313 /*
11314  * call-seq:
11315  * ARGF.each_codepoint {|codepoint| block } -> ARGF
11316  * ARGF.each_codepoint -> an_enumerator
11317  *
11318  * Iterates over each codepoint of each file in +ARGF+.
11319  *
11320  * This method allows you to treat the files supplied on the command line as
11321  * a single file consisting of the concatenation of each named file. After
11322  * the last codepoint of the first file has been returned, the first
11323  * codepoint of the second file is returned. The +ARGF.filename+ method can
11324  * be used to determine the name of the file in which the current codepoint
11325  * appears.
11326  *
11327  * If no block is given, an enumerator is returned instead.
11328  */
11329 static VALUE
11331 {
11332  RETURN_ENUMERATOR(argf, 0, 0);
11333  FOREACH_ARGF() {
11334  argf_block_call(rb_intern("each_codepoint"), 0, 0, argf);
11335  }
11336  return argf;
11337 }
11338 
11339 /*
11340  * This is a deprecated alias for <code>each_codepoint</code>.
11341  */
11342 
11343 static VALUE
11345 {
11346  rb_warn("ARGF#codepoints is deprecated; use #each_codepoint instead");
11347  if (!rb_block_given_p())
11348  return rb_enumeratorize(argf, ID2SYM(rb_intern("each_codepoint")), 0, 0);
11349  return argf_each_codepoint(argf);
11350 }
11351 
11352 /*
11353  * call-seq:
11354  * ARGF.filename -> String
11355  * ARGF.path -> String
11356  *
11357  * Returns the current filename. "-" is returned when the current file is
11358  * STDIN.
11359  *
11360  * For example:
11361  *
11362  * $ echo "foo" > foo
11363  * $ echo "bar" > bar
11364  * $ echo "glark" > glark
11365  *
11366  * $ ruby argf.rb foo bar glark
11367  *
11368  * ARGF.filename #=> "foo"
11369  * ARGF.read(5) #=> "foo\nb"
11370  * ARGF.filename #=> "bar"
11371  * ARGF.skip
11372  * ARGF.filename #=> "glark"
11373  */
11374 static VALUE
11376 {
11377  next_argv();
11378  return ARGF.filename;
11379 }
11380 
11381 static VALUE
11383 {
11384  return argf_filename(*var);
11385 }
11386 
11387 /*
11388  * call-seq:
11389  * ARGF.file -> IO or File object
11390  *
11391  * Returns the current file as an +IO+ or +File+ object. #<IO:<STDIN>> is
11392  * returned when the current file is STDIN.
11393  *
11394  * For example:
11395  *
11396  * $ echo "foo" > foo
11397  * $ echo "bar" > bar
11398  *
11399  * $ ruby argf.rb foo bar
11400  *
11401  * ARGF.file #=> #<File:foo>
11402  * ARGF.read(5) #=> "foo\nb"
11403  * ARGF.file #=> #<File:bar>
11404  */
11405 static VALUE
11407 {
11408  next_argv();
11409  return ARGF.current_file;
11410 }
11411 
11412 /*
11413  * call-seq:
11414  * ARGF.binmode -> ARGF
11415  *
11416  * Puts +ARGF+ into binary mode. Once a stream is in binary mode, it cannot
11417  * be reset to non-binary mode. This option has the following effects:
11418  *
11419  * * Newline conversion is disabled.
11420  * * Encoding conversion is disabled.
11421  * * Content is treated as ASCII-8BIT.
11422  */
11423 static VALUE
11425 {
11426  ARGF.binmode = 1;
11427  next_argv();
11428  ARGF_FORWARD(0, 0);
11429  rb_io_ascii8bit_binmode(ARGF.current_file);
11430  return argf;
11431 }
11432 
11433 /*
11434  * call-seq:
11435  * ARGF.binmode? -> true or false
11436  *
11437  * Returns true if +ARGF+ is being read in binary mode; false otherwise. (To
11438  * enable binary mode use +ARGF.binmode+.
11439  *
11440  * For example:
11441  *
11442  * ARGF.binmode? #=> false
11443  * ARGF.binmode
11444  * ARGF.binmode? #=> true
11445  */
11446 static VALUE
11448 {
11449  return ARGF.binmode ? Qtrue : Qfalse;
11450 }
11451 
11452 /*
11453  * call-seq:
11454  * ARGF.skip -> ARGF
11455  *
11456  * Sets the current file to the next file in ARGV. If there aren't any more
11457  * files it has no effect.
11458  *
11459  * For example:
11460  *
11461  * $ ruby argf.rb foo bar
11462  * ARGF.filename #=> "foo"
11463  * ARGF.skip
11464  * ARGF.filename #=> "bar"
11465  */
11466 static VALUE
11468 {
11469  if (ARGF.init_p && ARGF.next_p == 0) {
11470  argf_close(argf);
11471  ARGF.next_p = 1;
11472  }
11473  return argf;
11474 }
11475 
11476 /*
11477  * call-seq:
11478  * ARGF.close -> ARGF
11479  *
11480  * Closes the current file and skips to the next in the stream. Trying to
11481  * close a file that has already been closed causes an +IOError+ to be
11482  * raised.
11483  *
11484  * For example:
11485  *
11486  * $ ruby argf.rb foo bar
11487  *
11488  * ARGF.filename #=> "foo"
11489  * ARGF.close
11490  * ARGF.filename #=> "bar"
11491  * ARGF.close
11492  * ARGF.close #=> closed stream (IOError)
11493  */
11494 static VALUE
11496 {
11497  next_argv();
11498  argf_close(argf);
11499  if (ARGF.next_p != -1) {
11500  ARGF.next_p = 1;
11501  }
11502  ARGF.lineno = 0;
11503  return argf;
11504 }
11505 
11506 /*
11507  * call-seq:
11508  * ARGF.closed? -> true or false
11509  *
11510  * Returns _true_ if the current file has been closed; _false_ otherwise. Use
11511  * +ARGF.close+ to actually close the current file.
11512  */
11513 static VALUE
11515 {
11516  next_argv();
11517  ARGF_FORWARD(0, 0);
11518  return rb_io_closed(ARGF.current_file);
11519 }
11520 
11521 /*
11522  * call-seq:
11523  * ARGF.to_s -> String
11524  *
11525  * Returns "ARGF".
11526  */
11527 static VALUE
11529 {
11530  return rb_str_new2("ARGF");
11531 }
11532 
11533 /*
11534  * call-seq:
11535  * ARGF.inplace_mode -> String
11536  *
11537  * Returns the file extension appended to the names of modified files under
11538  * inplace-edit mode. This value can be set using +ARGF.inplace_mode=+ or
11539  * passing the +-i+ switch to the Ruby binary.
11540  */
11541 static VALUE
11543 {
11544  if (!ARGF.inplace) return Qnil;
11545  return rb_str_new2(ARGF.inplace);
11546 }
11547 
11548 static VALUE
11549 opt_i_get(ID id, VALUE *var)
11550 {
11551  return argf_inplace_mode_get(*var);
11552 }
11553 
11554 /*
11555  * call-seq:
11556  * ARGF.inplace_mode = ext -> ARGF
11557  *
11558  * Sets the filename extension for inplace editing mode to the given String.
11559  * Each file being edited has this value appended to its filename. The
11560  * modified file is saved under this new name.
11561  *
11562  * For example:
11563  *
11564  * $ ruby argf.rb file.txt
11565  *
11566  * ARGF.inplace_mode = '.bak'
11567  * ARGF.lines do |line|
11568  * print line.sub("foo","bar")
11569  * end
11570  *
11571  * Each line of _file.txt_ has the first occurrence of "foo" replaced with
11572  * "bar", then the new line is written out to _file.txt.bak_.
11573  */
11574 static VALUE
11576 {
11577  if (rb_safe_level() >= 1 && OBJ_TAINTED(val))
11579 
11580  if (!RTEST(val)) {
11581  if (ARGF.inplace) free(ARGF.inplace);
11582  ARGF.inplace = 0;
11583  }
11584  else {
11585  StringValue(val);
11586  if (ARGF.inplace) free(ARGF.inplace);
11587  ARGF.inplace = 0;
11588  ARGF.inplace = strdup(RSTRING_PTR(val));
11589  }
11590  return argf;
11591 }
11592 
11593 static void
11595 {
11596  argf_inplace_mode_set(*var, val);
11597 }
11598 
11599 const char *
11601 {
11602  return ARGF.inplace;
11603 }
11604 
11605 void
11606 ruby_set_inplace_mode(const char *suffix)
11607 {
11608  if (ARGF.inplace) free(ARGF.inplace);
11609  ARGF.inplace = 0;
11610  if (suffix) ARGF.inplace = strdup(suffix);
11611 }
11612 
11613 /*
11614  * call-seq:
11615  * ARGF.argv -> ARGV
11616  *
11617  * Returns the +ARGV+ array, which contains the arguments passed to your
11618  * script, one per element.
11619  *
11620  * For example:
11621  *
11622  * $ ruby argf.rb -v glark.txt
11623  *
11624  * ARGF.argv #=> ["-v", "glark.txt"]
11625  *
11626  */
11627 static VALUE
11629 {
11630  return ARGF.argv;
11631 }
11632 
11633 static VALUE
11635 {
11636  return argf_argv(*var);
11637 }
11638 
11639 VALUE
11641 {
11642  return ARGF.argv;
11643 }
11644 
11645 /*
11646  * call-seq:
11647  * ARGF.to_write_io -> io
11648  *
11649  * Returns IO instance tied to _ARGF_ for writing if inplace mode is
11650  * enabled.
11651  */
11652 static VALUE
11654 {
11655  if (!RTEST(ARGF.current_file)) {
11656  rb_raise(rb_eIOError, "not opened for writing");
11657  }
11658  return GetWriteIO(ARGF.current_file);
11659 }
11660 
11661 /*
11662  * call-seq:
11663  * ARGF.write(string) -> integer
11664  *
11665  * Writes _string_ if inplace mode.
11666  */
11667 static VALUE
11669 {
11670  return rb_io_write(argf_write_io(argf), str);
11671 }
11672 
11673 void
11674 rb_readwrite_sys_fail(int writable, const char *mesg)
11675 {
11676  VALUE arg;
11677  int n = errno;
11678  arg = mesg ? rb_str_new2(mesg) : Qnil;
11679  if (writable == RB_IO_WAIT_WRITABLE) {
11680  switch (n) {
11681  case EAGAIN:
11683  break;
11684 #if EAGAIN != EWOULDBLOCK
11685  case EWOULDBLOCK:
11687  break;
11688 #endif
11689  case EINPROGRESS:
11691  break;
11692  default:
11694  }
11695  }
11696  else if (writable == RB_IO_WAIT_READABLE) {
11697  switch (n) {
11698  case EAGAIN:
11700  break;
11701 #if EAGAIN != EWOULDBLOCK
11702  case EWOULDBLOCK:
11704  break;
11705 #endif
11706  case EINPROGRESS:
11708  break;
11709  default:
11711  }
11712  }
11713  else {
11714  rb_bug("invalid read/write type passed to rb_readwrite_sys_fail: %d", writable);
11715  }
11716 }
11717 
11718 /*
11719  * Document-class: IOError
11720  *
11721  * Raised when an IO operation fails.
11722  *
11723  * File.open("/etc/hosts") {|f| f << "example"}
11724  * #=> IOError: not opened for writing
11725  *
11726  * File.open("/etc/hosts") {|f| f.close; f.read }
11727  * #=> IOError: closed stream
11728  *
11729  * Note that some IO failures raise +SystemCallError+s and these are not
11730  * subclasses of IOError:
11731  *
11732  * File.open("does/not/exist")
11733  * #=> Errno::ENOENT: No such file or directory - does/not/exist
11734  */
11735 
11736 /*
11737  * Document-class: EOFError
11738  *
11739  * Raised by some IO operations when reaching the end of file. Many IO
11740  * methods exist in two forms,
11741  *
11742  * one that returns +nil+ when the end of file is reached, the other
11743  * raises EOFError +EOFError+.
11744  *
11745  * +EOFError+ is a subclass of +IOError+.
11746  *
11747  * file = File.open("/etc/hosts")
11748  * file.read
11749  * file.gets #=> nil
11750  * file.readline #=> EOFError: end of file reached
11751  */
11752 
11753 /*
11754  * Document-class: ARGF
11755  *
11756  * +ARGF+ is a stream designed for use in scripts that process files given as
11757  * command-line arguments or passed in via STDIN.
11758  *
11759  * The arguments passed to your script are stored in the +ARGV+ Array, one
11760  * argument per element. +ARGF+ assumes that any arguments that aren't
11761  * filenames have been removed from +ARGV+. For example:
11762  *
11763  * $ ruby argf.rb --verbose file1 file2
11764  *
11765  * ARGV #=> ["--verbose", "file1", "file2"]
11766  * option = ARGV.shift #=> "--verbose"
11767  * ARGV #=> ["file1", "file2"]
11768  *
11769  * You can now use +ARGF+ to work with a concatenation of each of these named
11770  * files. For instance, +ARGF.read+ will return the contents of _file1_
11771  * followed by the contents of _file2_.
11772  *
11773  * After a file in +ARGV+ has been read +ARGF+ removes it from the Array.
11774  * Thus, after all files have been read +ARGV+ will be empty.
11775  *
11776  * You can manipulate +ARGV+ yourself to control what +ARGF+ operates on. If
11777  * you remove a file from +ARGV+, it is ignored by +ARGF+; if you add files to
11778  * +ARGV+, they are treated as if they were named on the command line. For
11779  * example:
11780  *
11781  * ARGV.replace ["file1"]
11782  * ARGF.readlines # Returns the contents of file1 as an Array
11783  * ARGV #=> []
11784  * ARGV.replace ["file2", "file3"]
11785  * ARGF.read # Returns the contents of file2 and file3
11786  *
11787  * If +ARGV+ is empty, +ARGF+ acts as if it contained STDIN, i.e. the data
11788  * piped to your script. For example:
11789  *
11790  * $ echo "glark" | ruby -e 'p ARGF.read'
11791  * "glark\n"
11792  */
11793 
11794 /*
11795  * The IO class is the basis for all input and output in Ruby.
11796  * An I/O stream may be <em>duplexed</em> (that is, bidirectional), and
11797  * so may use more than one native operating system stream.
11798  *
11799  * Many of the examples in this section use the File class, the only standard
11800  * subclass of IO. The two classes are closely associated. Like the File
11801  * class, the Socket library subclasses from IO (such as TCPSocket or
11802  * UDPSocket).
11803  *
11804  * The Kernel#open method can create an IO (or File) object for these types
11805  * of arguments:
11806  *
11807  * * A plain string represents a filename suitable for the underlying
11808  * operating system.
11809  *
11810  * * A string starting with <code>"|"</code> indicates a subprocess.
11811  * The remainder of the string following the <code>"|"</code> is
11812  * invoked as a process with appropriate input/output channels
11813  * connected to it.
11814  *
11815  * * A string equal to <code>"|-"</code> will create another Ruby
11816  * instance as a subprocess.
11817  *
11818  * The IO may be opened with different file modes (read-only, write-only) and
11819  * encodings for proper conversion. See IO.new for these options. See
11820  * Kernel#open for details of the various command formats described above.
11821  *
11822  * IO.popen, the Open3 library, or Process#spawn may also be used to
11823  * communicate with subprocesses through an IO.
11824  *
11825  * Ruby will convert pathnames between different operating system
11826  * conventions if possible. For instance, on a Windows system the
11827  * filename <code>"/gumby/ruby/test.rb"</code> will be opened as
11828  * <code>"\gumby\ruby\test.rb"</code>. When specifying a Windows-style
11829  * filename in a Ruby string, remember to escape the backslashes:
11830  *
11831  * "c:\\gumby\\ruby\\test.rb"
11832  *
11833  * Our examples here will use the Unix-style forward slashes;
11834  * File::ALT_SEPARATOR can be used to get the platform-specific separator
11835  * character.
11836  *
11837  * The global constant ARGF (also accessible as $<) provides an
11838  * IO-like stream which allows access to all files mentioned on the
11839  * command line (or STDIN if no files are mentioned). ARGF#path and its alias
11840  * ARGF#filename are provided to access the name of the file currently being
11841  * read.
11842  *
11843  * == io/console
11844  *
11845  * The io/console extension provides methods for interacting with the
11846  * console. The console can be accessed from IO.console or the standard
11847  * input/output/error IO objects.
11848  *
11849  * Requiring io/console adds the following methods:
11850  *
11851  * * IO::console
11852  * * IO#raw
11853  * * IO#raw!
11854  * * IO#cooked
11855  * * IO#cooked!
11856  * * IO#getch
11857  * * IO#echo=
11858  * * IO#echo?
11859  * * IO#noecho
11860  * * IO#winsize
11861  * * IO#winsize=
11862  * * IO#iflush
11863  * * IO#ioflush
11864  * * IO#oflush
11865  *
11866  * Example:
11867  *
11868  * require 'io/console'
11869  * rows, columns = $stdin.winsize
11870  * puts "Your screen is #{columns} wide and #{rows} tall"
11871  */
11872 
11873 void
11874 Init_IO(void)
11875 {
11876 #undef rb_intern
11877 #define rb_intern(str) rb_intern_const(str)
11878 
11879  VALUE rb_cARGF;
11880 #ifdef __CYGWIN__
11881 #include <sys/cygwin.h>
11882  static struct __cygwin_perfile pf[] =
11883  {
11884  {"", O_RDONLY | O_BINARY},
11885  {"", O_WRONLY | O_BINARY},
11886  {"", O_RDWR | O_BINARY},
11887  {"", O_APPEND | O_BINARY},
11888  {NULL, 0}
11889  };
11890  cygwin_internal(CW_PERFILE, pf);
11891 #endif
11892 
11894  rb_eEOFError = rb_define_class("EOFError", rb_eIOError);
11895 
11896  id_write = rb_intern("write");
11897  id_read = rb_intern("read");
11898  id_getc = rb_intern("getc");
11899  id_flush = rb_intern("flush");
11900  id_readpartial = rb_intern("readpartial");
11901  id_set_encoding = rb_intern("set_encoding");
11902 
11903  rb_define_global_function("syscall", rb_f_syscall, -1);
11904 
11905  rb_define_global_function("open", rb_f_open, -1);
11906  rb_define_global_function("printf", rb_f_printf, -1);
11907  rb_define_global_function("print", rb_f_print, -1);
11909  rb_define_global_function("puts", rb_f_puts, -1);
11910  rb_define_global_function("gets", rb_f_gets, -1);
11911  rb_define_global_function("readline", rb_f_readline, -1);
11912  rb_define_global_function("select", rb_f_select, -1);
11913 
11914  rb_define_global_function("readlines", rb_f_readlines, -1);
11915 
11917 
11919  rb_define_method(rb_mKernel, "display", rb_obj_display, -1);
11920 
11923 
11924  rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
11925  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
11930 #if EAGAIN == EWOULDBLOCK
11932  /* same as IO::EAGAINWaitReadable */
11933  rb_define_const(rb_cIO, "EWOULDBLOCKWaitReadable", rb_eEAGAINWaitReadable);
11935  /* same as IO::EAGAINWaitWritable */
11936  rb_define_const(rb_cIO, "EWOULDBLOCKWaitWritable", rb_eEAGAINWaitWritable);
11937 #else
11942 #endif
11947 
11948 #if 0
11949  /* This is necessary only for forcing rdoc handle File::open */
11951 #endif
11952 
11969 
11970  rb_define_method(rb_cIO, "initialize", rb_io_initialize, -1);
11971 
11972  rb_output_fs = Qnil;
11974 
11977  rb_output_rs = Qnil;
11978  OBJ_FREEZE(rb_default_rs); /* avoid modifying RS_default */
11982 
11984 
11985  rb_define_method(rb_cIO, "initialize_copy", rb_io_init_copy, 1);
11986  rb_define_method(rb_cIO, "reopen", rb_io_reopen, -1);
11987 
11988  rb_define_method(rb_cIO, "print", rb_io_print, -1);
11989  rb_define_method(rb_cIO, "putc", rb_io_putc, 1);
11990  rb_define_method(rb_cIO, "puts", rb_io_puts, -1);
11991  rb_define_method(rb_cIO, "printf", rb_io_printf, -1);
11992 
11993  rb_define_method(rb_cIO, "each", rb_io_each_line, -1);
11994  rb_define_method(rb_cIO, "each_line", rb_io_each_line, -1);
11995  rb_define_method(rb_cIO, "each_byte", rb_io_each_byte, 0);
11996  rb_define_method(rb_cIO, "each_char", rb_io_each_char, 0);
11997  rb_define_method(rb_cIO, "each_codepoint", rb_io_each_codepoint, 0);
11998  rb_define_method(rb_cIO, "lines", rb_io_lines, -1);
11999  rb_define_method(rb_cIO, "bytes", rb_io_bytes, 0);
12000  rb_define_method(rb_cIO, "chars", rb_io_chars, 0);
12001  rb_define_method(rb_cIO, "codepoints", rb_io_codepoints, 0);
12002 
12003  rb_define_method(rb_cIO, "syswrite", rb_io_syswrite, 1);
12004  rb_define_method(rb_cIO, "sysread", rb_io_sysread, -1);
12005 
12006  rb_define_method(rb_cIO, "fileno", rb_io_fileno, 0);
12007  rb_define_alias(rb_cIO, "to_i", "fileno");
12008  rb_define_method(rb_cIO, "to_io", rb_io_to_io, 0);
12009 
12010  rb_define_method(rb_cIO, "fsync", rb_io_fsync, 0);
12011  rb_define_method(rb_cIO, "fdatasync", rb_io_fdatasync, 0);
12012  rb_define_method(rb_cIO, "sync", rb_io_sync, 0);
12013  rb_define_method(rb_cIO, "sync=", rb_io_set_sync, 1);
12014 
12015  rb_define_method(rb_cIO, "lineno", rb_io_lineno, 0);
12016  rb_define_method(rb_cIO, "lineno=", rb_io_set_lineno, 1);
12017 
12018  rb_define_method(rb_cIO, "readlines", rb_io_readlines, -1);
12019 
12020  rb_define_method(rb_cIO, "read_nonblock", io_read_nonblock, -1);
12021  rb_define_method(rb_cIO, "write_nonblock", rb_io_write_nonblock, -1);
12022  rb_define_method(rb_cIO, "readpartial", io_readpartial, -1);
12023  rb_define_method(rb_cIO, "read", io_read, -1);
12024  rb_define_method(rb_cIO, "write", io_write_m, 1);
12025  rb_define_method(rb_cIO, "gets", rb_io_gets_m, -1);
12026  rb_define_method(rb_cIO, "readline", rb_io_readline, -1);
12027  rb_define_method(rb_cIO, "getc", rb_io_getc, 0);
12028  rb_define_method(rb_cIO, "getbyte", rb_io_getbyte, 0);
12029  rb_define_method(rb_cIO, "readchar", rb_io_readchar, 0);
12030  rb_define_method(rb_cIO, "readbyte", rb_io_readbyte, 0);
12031  rb_define_method(rb_cIO, "ungetbyte",rb_io_ungetbyte, 1);
12032  rb_define_method(rb_cIO, "ungetc",rb_io_ungetc, 1);
12034  rb_define_method(rb_cIO, "flush", rb_io_flush, 0);
12035  rb_define_method(rb_cIO, "tell", rb_io_tell, 0);
12036  rb_define_method(rb_cIO, "seek", rb_io_seek_m, -1);
12037  /* Set I/O position from the beginning */
12038  rb_define_const(rb_cIO, "SEEK_SET", INT2FIX(SEEK_SET));
12039  /* Set I/O position from the current position */
12040  rb_define_const(rb_cIO, "SEEK_CUR", INT2FIX(SEEK_CUR));
12041  /* Set I/O position from the end */
12042  rb_define_const(rb_cIO, "SEEK_END", INT2FIX(SEEK_END));
12043 #ifdef SEEK_DATA
12044  /* Set I/O position to the next location containing data */
12045  rb_define_const(rb_cIO, "SEEK_DATA", INT2FIX(SEEK_DATA));
12046 #endif
12047 #ifdef SEEK_HOLE
12048  /* Set I/O position to the next hole */
12049  rb_define_const(rb_cIO, "SEEK_HOLE", INT2FIX(SEEK_HOLE));
12050 #endif
12051  rb_define_method(rb_cIO, "rewind", rb_io_rewind, 0);
12052  rb_define_method(rb_cIO, "pos", rb_io_tell, 0);
12053  rb_define_method(rb_cIO, "pos=", rb_io_set_pos, 1);
12054  rb_define_method(rb_cIO, "eof", rb_io_eof, 0);
12055  rb_define_method(rb_cIO, "eof?", rb_io_eof, 0);
12056 
12057  rb_define_method(rb_cIO, "close_on_exec?", rb_io_close_on_exec_p, 0);
12058  rb_define_method(rb_cIO, "close_on_exec=", rb_io_set_close_on_exec, 1);
12059 
12060  rb_define_method(rb_cIO, "close", rb_io_close_m, 0);
12061  rb_define_method(rb_cIO, "closed?", rb_io_closed, 0);
12062  rb_define_method(rb_cIO, "close_read", rb_io_close_read, 0);
12063  rb_define_method(rb_cIO, "close_write", rb_io_close_write, 0);
12064 
12065  rb_define_method(rb_cIO, "isatty", rb_io_isatty, 0);
12066  rb_define_method(rb_cIO, "tty?", rb_io_isatty, 0);
12067  rb_define_method(rb_cIO, "binmode", rb_io_binmode_m, 0);
12068  rb_define_method(rb_cIO, "binmode?", rb_io_binmode_p, 0);
12069  rb_define_method(rb_cIO, "sysseek", rb_io_sysseek, -1);
12070  rb_define_method(rb_cIO, "advise", rb_io_advise, -1);
12071 
12072  rb_define_method(rb_cIO, "ioctl", rb_io_ioctl, -1);
12073  rb_define_method(rb_cIO, "fcntl", rb_io_fcntl, -1);
12074  rb_define_method(rb_cIO, "pid", rb_io_pid, 0);
12075  rb_define_method(rb_cIO, "inspect", rb_io_inspect, 0);
12076 
12077  rb_define_method(rb_cIO, "external_encoding", rb_io_external_encoding, 0);
12078  rb_define_method(rb_cIO, "internal_encoding", rb_io_internal_encoding, 0);
12079  rb_define_method(rb_cIO, "set_encoding", rb_io_set_encoding, -1);
12080 
12081  rb_define_method(rb_cIO, "autoclose?", rb_io_autoclose_p, 0);
12082  rb_define_method(rb_cIO, "autoclose=", rb_io_set_autoclose, 1);
12083 
12084  rb_define_variable("$stdin", &rb_stdin);
12085  rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO, "<STDIN>");
12087  rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO, "<STDOUT>");
12089  rb_stderr = prep_stdio(stderr, FMODE_WRITABLE|FMODE_SYNC, rb_cIO, "<STDERR>");
12093 
12094  /* Holds the original stdin */
12095  rb_define_global_const("STDIN", rb_stdin);
12096  /* Holds the original stdout */
12097  rb_define_global_const("STDOUT", rb_stdout);
12098  /* Holds the original stderr */
12099  rb_define_global_const("STDERR", rb_stderr);
12100 
12101 #if 0
12102  /* Hack to get rdoc to regard ARGF as a class: */
12103  rb_cARGF = rb_define_class("ARGF", rb_cObject);
12104 #endif
12105 
12106  rb_cARGF = rb_class_new(rb_cObject);
12107  rb_set_class_path(rb_cARGF, rb_cObject, "ARGF.class");
12108  rb_define_alloc_func(rb_cARGF, argf_alloc);
12109 
12110  rb_include_module(rb_cARGF, rb_mEnumerable);
12111 
12112  rb_define_method(rb_cARGF, "initialize", argf_initialize, -2);
12113  rb_define_method(rb_cARGF, "initialize_copy", argf_initialize_copy, 1);
12114  rb_define_method(rb_cARGF, "to_s", argf_to_s, 0);
12115  rb_define_alias(rb_cARGF, "inspect", "to_s");
12116  rb_define_method(rb_cARGF, "argv", argf_argv, 0);
12117 
12118  rb_define_method(rb_cARGF, "fileno", argf_fileno, 0);
12119  rb_define_method(rb_cARGF, "to_i", argf_fileno, 0);
12120  rb_define_method(rb_cARGF, "to_io", argf_to_io, 0);
12121  rb_define_method(rb_cARGF, "to_write_io", argf_write_io, 0);
12122  rb_define_method(rb_cARGF, "each", argf_each_line, -1);
12123  rb_define_method(rb_cARGF, "each_line", argf_each_line, -1);
12124  rb_define_method(rb_cARGF, "each_byte", argf_each_byte, 0);
12125  rb_define_method(rb_cARGF, "each_char", argf_each_char, 0);
12126  rb_define_method(rb_cARGF, "each_codepoint", argf_each_codepoint, 0);
12127  rb_define_method(rb_cARGF, "lines", argf_lines, -1);
12128  rb_define_method(rb_cARGF, "bytes", argf_bytes, 0);
12129  rb_define_method(rb_cARGF, "chars", argf_chars, 0);
12130  rb_define_method(rb_cARGF, "codepoints", argf_codepoints, 0);
12131 
12132  rb_define_method(rb_cARGF, "read", argf_read, -1);
12133  rb_define_method(rb_cARGF, "readpartial", argf_readpartial, -1);
12134  rb_define_method(rb_cARGF, "read_nonblock", argf_read_nonblock, -1);
12135  rb_define_method(rb_cARGF, "readlines", argf_readlines, -1);
12136  rb_define_method(rb_cARGF, "to_a", argf_readlines, -1);
12137  rb_define_method(rb_cARGF, "gets", argf_gets, -1);
12138  rb_define_method(rb_cARGF, "readline", argf_readline, -1);
12139  rb_define_method(rb_cARGF, "getc", argf_getc, 0);
12140  rb_define_method(rb_cARGF, "getbyte", argf_getbyte, 0);
12141  rb_define_method(rb_cARGF, "readchar", argf_readchar, 0);
12142  rb_define_method(rb_cARGF, "readbyte", argf_readbyte, 0);
12143  rb_define_method(rb_cARGF, "tell", argf_tell, 0);
12144  rb_define_method(rb_cARGF, "seek", argf_seek_m, -1);
12145  rb_define_method(rb_cARGF, "rewind", argf_rewind, 0);
12146  rb_define_method(rb_cARGF, "pos", argf_tell, 0);
12147  rb_define_method(rb_cARGF, "pos=", argf_set_pos, 1);
12148  rb_define_method(rb_cARGF, "eof", argf_eof, 0);
12149  rb_define_method(rb_cARGF, "eof?", argf_eof, 0);
12150  rb_define_method(rb_cARGF, "binmode", argf_binmode_m, 0);
12151  rb_define_method(rb_cARGF, "binmode?", argf_binmode_p, 0);
12152 
12153  rb_define_method(rb_cARGF, "write", argf_write, 1);
12154  rb_define_method(rb_cARGF, "print", rb_io_print, -1);
12155  rb_define_method(rb_cARGF, "putc", rb_io_putc, 1);
12156  rb_define_method(rb_cARGF, "puts", rb_io_puts, -1);
12157  rb_define_method(rb_cARGF, "printf", rb_io_printf, -1);
12158 
12159  rb_define_method(rb_cARGF, "filename", argf_filename, 0);
12160  rb_define_method(rb_cARGF, "path", argf_filename, 0);
12161  rb_define_method(rb_cARGF, "file", argf_file, 0);
12162  rb_define_method(rb_cARGF, "skip", argf_skip, 0);
12163  rb_define_method(rb_cARGF, "close", argf_close_m, 0);
12164  rb_define_method(rb_cARGF, "closed?", argf_closed, 0);
12165 
12166  rb_define_method(rb_cARGF, "lineno", argf_lineno, 0);
12167  rb_define_method(rb_cARGF, "lineno=", argf_set_lineno, 1);
12168 
12169  rb_define_method(rb_cARGF, "inplace_mode", argf_inplace_mode_get, 0);
12170  rb_define_method(rb_cARGF, "inplace_mode=", argf_inplace_mode_set, 1);
12171 
12172  rb_define_method(rb_cARGF, "external_encoding", argf_external_encoding, 0);
12173  rb_define_method(rb_cARGF, "internal_encoding", argf_internal_encoding, 0);
12174  rb_define_method(rb_cARGF, "set_encoding", argf_set_encoding, -1);
12175 
12176  argf = rb_class_new_instance(0, 0, rb_cARGF);
12177 
12179  /*
12180  * ARGF is a stream designed for use in scripts that process files given
12181  * as command-line arguments or passed in via STDIN.
12182  *
12183  * See ARGF (the class) for more details.
12184  */
12185  rb_define_global_const("ARGF", argf);
12186 
12189  ARGF.filename = rb_str_new2("-");
12190 
12193 
12194 #if defined (_WIN32) || defined(__CYGWIN__)
12195  atexit(pipe_atexit);
12196 #endif
12197 
12198  Init_File();
12199 
12200  rb_define_method(rb_cFile, "initialize", rb_file_initialize, -1);
12201 
12202  sym_mode = ID2SYM(rb_intern("mode"));
12203  sym_perm = ID2SYM(rb_intern("perm"));
12204  sym_extenc = ID2SYM(rb_intern("external_encoding"));
12205  sym_intenc = ID2SYM(rb_intern("internal_encoding"));
12206  sym_encoding = ID2SYM(rb_intern("encoding"));
12207  sym_open_args = ID2SYM(rb_intern("open_args"));
12208  sym_textmode = ID2SYM(rb_intern("textmode"));
12209  sym_binmode = ID2SYM(rb_intern("binmode"));
12210  sym_autoclose = ID2SYM(rb_intern("autoclose"));
12211  sym_normal = ID2SYM(rb_intern("normal"));
12212  sym_sequential = ID2SYM(rb_intern("sequential"));
12213  sym_random = ID2SYM(rb_intern("random"));
12214  sym_willneed = ID2SYM(rb_intern("willneed"));
12215  sym_dontneed = ID2SYM(rb_intern("dontneed"));
12216  sym_noreuse = ID2SYM(rb_intern("noreuse"));
12217  sym_SET = ID2SYM(rb_intern("SET"));
12218  sym_CUR = ID2SYM(rb_intern("CUR"));
12219  sym_END = ID2SYM(rb_intern("END"));
12220 #ifdef SEEK_DATA
12221  sym_DATA = ID2SYM(rb_intern("DATA"));
12222 #endif
12223 #ifdef SEEK_HOLE
12224  sym_HOLE = ID2SYM(rb_intern("HOLE"));
12225 #endif
12226  sym_exception = ID2SYM(rb_intern("exception"));
12227 }
static VALUE argf_bytes(VALUE argf)
Definition: io.c:11266
#define STRNCASECMP(s1, s2, n)
Definition: ruby.h:1784
void rb_define_global_const(const char *, VALUE)
Definition: variable.c:2236
#define RBASIC_CLEAR_CLASS(obj)
Definition: internal.h:607
struct timeval rb_time_interval(VALUE num)
Definition: time.c:2411
unsigned long ruby_strtoul(const char *str, char **endptr, int base)
Definition: util.c:107
void rb_gc(void)
Definition: gc.c:5190
VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags)
Definition: transcode.c:2036
static void make_readconv(rb_io_t *fptr, int size)
Definition: io.c:2143
VALUE rb_eStandardError
Definition: error.c:546
void rb_execarg_setenv(VALUE execarg_obj, VALUE env)
Definition: process.c:2299
static VALUE rb_io_rewind(VALUE io)
Definition: io.c:1655
const char * rb_econv_asciicompat_encoding(const char *encname)
Definition: transcode.c:1786
static VALUE rb_io_close_read(VALUE io)
Definition: io.c:4434
static void argf_close(VALUE argf)
Definition: io.c:7720
int rb_pipe(int *pipes)
Definition: io.c:5651
static VALUE rb_obj_display(int argc, VALUE *argv, VALUE self)
Definition: io.c:7127
static int nogvl_copy_stream_wait_write(struct copy_stream_struct *stp)
Definition: io.c:9888
VALUE rb_io_getbyte(VALUE io)
Definition: io.c:3772
static long fcntl_narg_len(int cmd)
Definition: io.c:8889
static VALUE rb_io_set_lineno(VALUE io, VALUE lineno)
Definition: io.c:3274
int rb_io_wait_writable(int f)
Definition: io.c:1103
static ID id_set_encoding
Definition: io.c:160
#define MBCLEN_CHARFOUND_P(ret)
Definition: encoding.h:139
void rb_thread_atfork(void)
Definition: thread.c:3931
#define ECONV_NEWLINE_DECORATOR_WRITE_MASK
Definition: encoding.h:330
off_t total
Definition: io.c:9819
static VALUE argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock)
Definition: io.c:10956
VALUE argf
Definition: io.c:10902
#define rb_str_new4
Definition: intern.h:842
rb_econv_result_t
Definition: encoding.h:252
static VALUE rb_io_set_sync(VALUE io, VALUE sync)
Definition: io.c:1856
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1171
#define MBCLEN_CHARFOUND_LEN(ret)
Definition: encoding.h:140
Definition: io.c:8686
#define RARRAY_LEN(a)
Definition: ruby.h:878
void rb_bug(const char *fmt,...)
Definition: error.c:327
#define FALSE
Definition: nkf.h:174
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1015
int ioctl(int, int,...)
Definition: win32.c:2540
static VALUE rb_io_internal_encoding(VALUE)
Definition: io.c:10513
static VALUE rb_io_s_readlines(int argc, VALUE *argv, VALUE io)
Definition: io.c:9570
#define FMODE_READWRITE
Definition: io.h:103
long rb_str_coderange_scan_restartable(const char *, const char *, rb_encoding *, int *)
Definition: string.c:340
#define rb_hash_lookup
Definition: tcltklib.c:269
static VALUE sym_random
Definition: io.c:8340
static VALUE rb_io_closed(VALUE io)
Definition: io.c:4396
union rb_execarg::@123 invoke
#define SSIZE_MAX
Definition: ruby.h:290
size_t strlen(const char *)
static VALUE io_enc_str(VALUE str, rb_io_t *fptr)
Definition: io.c:2135
#define INT2NUM(x)
Definition: ruby.h:1288
VALUE rb_cIO
Definition: io.c:133
void rb_io_check_writable(rb_io_t *fptr)
Definition: io.c:818
#define T_FIXNUM
Definition: ruby.h:489
static VALUE sym_autoclose
Definition: io.c:162
static long setup_narg(ioctl_req_t cmd, VALUE *argp, int io_p)
Definition: io.c:8896
static VALUE sym_encoding
Definition: io.c:161
static VALUE argf_set_pos(VALUE argf, VALUE offset)
Definition: io.c:10711
static const char closed_stream[]
Definition: io.c:593
static ID id_getc
Definition: io.c:160
static VALUE rb_io_codepoints(VALUE io)
Definition: io.c:3701
static VALUE sym_SET
Definition: io.c:163
int rb_io_modestr_fmode(const char *modestr)
Definition: io.c:4812
static VALUE sym_noreuse
Definition: io.c:8340
static VALUE argf_set_lineno(VALUE argf, VALUE val)
Definition: io.c:7675
VALUE rb_stderr
Definition: io.c:149
static VALUE argf_inplace_mode_get(VALUE argf)
Definition: io.c:11542
VALUE rb_file_open_str(VALUE fname, const char *modestr)
Definition: io.c:5554
static VALUE rb_f_putc(VALUE recv, VALUE ch)
Definition: io.c:6918
void rb_define_virtual_variable(const char *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
Definition: variable.c:616
static VALUE argf_readpartial(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10936
VALUE rb_hash_dup(VALUE hash)
Definition: hash.c:320
#define NUM2INT(x)
Definition: ruby.h:630
int count
Definition: encoding.c:48
static VALUE io_call_close(VALUE io)
Definition: io.c:4347
static int max(int a, int b)
Definition: strftime.c:141
#define NUM2UINT(x)
Definition: ruby.h:631
static ID id_read
Definition: io.c:160
static int io_fflush(rb_io_t *)
Definition: io.c:1062
rb_uid_t getuid(void)
Definition: win32.c:2494
VALUE rb_io_eof(VALUE io)
Definition: io.c:1745
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1655
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
Definition: io.c:228
static const char * rb_io_fmode_modestr(int fmode)
Definition: io.c:4776
static void argf_init(struct argf *p, VALUE v)
Definition: io.c:7611
static VALUE rb_io_ioctl(int argc, VALUE *argv, VALUE io)
Definition: io.c:8975
static VALUE argf_inplace_mode_set(VALUE argf, VALUE val)
Definition: io.c:11575
int ioctl_req_t
Definition: io.c:8682
VALUE fname
Definition: io.c:5326
VALUE rb_f_sprintf(int, const VALUE *)
Definition: sprintf.c:415
static VALUE pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convconfig)
Definition: io.c:5803
size_t rb_econv_memsize(rb_econv_t *)
Definition: transcode.c:1720
static void must_respond_to(ID mid, VALUE val, ID id)
Definition: io.c:7180
#define FilePathValue(v)
Definition: ruby.h:560
#define rb_usascii_str_new2
Definition: intern.h:846
VALUE str
Definition: io.c:1195
static VALUE io_s_write(int argc, VALUE *argv, int binary)
Definition: io.c:9701
void rb_io_set_nonblock(rb_io_t *fptr)
Definition: io.c:2378
#define CLASS_OF(v)
Definition: ruby.h:440
static VALUE select_call(VALUE arg)
Definition: io.c:8322
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2140
#define PIDT2NUM(v)
Definition: ruby.h:321
static VALUE argf_readbyte(VALUE argf)
Definition: io.c:11140
#define ARGF_FORWARD(argc, argv)
Definition: io.c:7710
static VALUE argf_gets(int, VALUE *, VALUE)
Definition: io.c:8003
struct rb_io_t rb_io_t
rb_fdset_t fdsets[4]
Definition: io.c:8318
#define Qtrue
Definition: ruby.h:426
rb_io_buffer_t cbuf
Definition: io.h:88
VALUE rb_io_binmode(VALUE io)
Definition: io.c:4679
static void argf_mark(void *ptr)
Definition: io.c:7577
VALUE ecopts
Definition: io.h:84
static VALUE io_puts_ary(VALUE ary, VALUE out, int recur)
Definition: io.c:6943
static VALUE rb_io_binmode_p(VALUE io)
Definition: io.c:4768
int rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char *errmsg, size_t errmsg_buflen)
Definition: process.c:2957
Definition: io.h:61
#define OBJ_INIT_COPY(obj, orig)
Definition: intern.h:287
#define ENC_CODERANGE_SET(obj, cr)
Definition: encoding.h:54
#define READ_DATA_PENDING_COUNT(fptr)
Definition: io.c:387
VALUE rb_ary_shift(VALUE ary)
Definition: array.c:991
char * str_ptr
Definition: io.c:2064
static VALUE rb_eEAGAINWaitWritable
Definition: io.c:143
int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen)
Definition: process.c:3104
#define ECONV_ERROR_HANDLER_MASK
Definition: encoding.h:318
#define IO_WBUF_CAPA_MIN
Definition: io.c:125
#define F_DUPFD
Definition: win32.h:616
void * rb_thread_call_without_gvl2(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
Definition: thread.c:1366
static VALUE orig_stderr
Definition: io.c:151
static VALUE io_s_foreach(struct foreach_arg *arg)
Definition: io.c:9495
#define FMODE_WRITABLE
Definition: io.h:102
rb_encoding * rb_to_encoding(VALUE enc)
Definition: encoding.c:219
void rb_fd_fix_cloexec(int fd)
Definition: io.c:221
static int is_popen_fork(VALUE prog)
Definition: io.c:6027
#define FMODE_READABLE
Definition: io.h:101
void rb_econv_close(rb_econv_t *ec)
Definition: transcode.c:1702
static VALUE io_flush_buffer_async(VALUE arg)
Definition: io.c:1022
static VALUE io_binwrite_string(VALUE arg)
Definition: io.c:1207
VALUE rb_str_unlocktmp(VALUE)
Definition: string.c:1991
long tv_sec
Definition: ossl_asn1.c:17
int argc
Definition: io.c:10900
static void io_encoding_set(rb_io_t *, VALUE, VALUE, VALUE)
Definition: io.c:9255
static VALUE rb_io_syswrite(VALUE io, VALUE str)
Definition: io.c:4580
#define FMODE_WSPLIT_INITIALIZED
Definition: io.h:112
VALUE rb_enc_from_encoding(rb_encoding *encoding)
Definition: encoding.c:102
static rb_encoding * find_encoding(VALUE v)
Definition: io.c:9247
ID rb_frame_this_func(void)
Definition: eval.c:943
static VALUE argf_external_encoding(VALUE argf)
Definition: io.c:10585
SOCKET rb_w32_get_osfhandle(int)
Definition: win32.c:984
VALUE rb_eTypeError
Definition: error.c:548
static ID id_write
Definition: io.c:160
static VALUE sym_mode
Definition: io.c:161
static VALUE argf_each_line(int argc, VALUE *argv, VALUE argf)
Definition: io.c:11205
#define UNREACHABLE
Definition: ruby.h:42
static VALUE rb_io_close_write(VALUE io)
Definition: io.c:4494
VALUE * argv
Definition: io.c:10901
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1436
static VALUE argf_filename(VALUE argf)
Definition: io.c:11375
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:896
static void fptr_finalize(rb_io_t *fptr, int noraise)
Definition: io.c:4153
VALUE rb_cFile
Definition: file.c:139
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
#define rb_io_fcntl
Definition: io.c:9077
static VALUE opt_i_get(ID id, VALUE *var)
Definition: io.c:11549
int fcntl(int, int,...)
Definition: win32.c:4085
int rb_thread_alone(void)
Definition: thread.c:2990
void rb_p(VALUE obj)
Definition: io.c:7032
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:534
static VALUE argf_argv(VALUE argf)
Definition: io.c:11628
static int io_encname_bom_p(const char *name, long len)
Definition: io.c:4800
static VALUE rb_io_seek(VALUE io, VALUE offset, int whence)
Definition: io.c:1542
#define free(x)
Definition: io.c:24
VALUE rb_io_print(int argc, VALUE *argv, VALUE out)
Definition: io.c:6818
#define rb_fd_zero(f)
Definition: intern.h:349
int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *)
Definition: thread.c:3576
static VALUE rb_io_getline_fast(rb_io_t *fptr, rb_encoding *enc, VALUE io)
Definition: io.c:2975
rb_pid_t rb_fork_ruby(int *status)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:775
char * ptr
Definition: io.h:55
int8_t binmode
Definition: io.c:178
VALUE rb_str_locktmp_ensure(VALUE str, VALUE(*func)(VALUE), VALUE arg)
Definition: string.c:2001
void rb_str_set_len(VALUE, long)
Definition: string.c:2008
int writeconv_pre_ecflags
Definition: io.h:92
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:807
rb_io_t * fptr
Definition: io.c:2066
#define RBASIC_SET_CLASS(obj, cls)
Definition: internal.h:609
static VALUE rb_io_readchar(VALUE io)
Definition: io.c:3749
int rb_enc_str_coderange(VALUE)
Definition: string.c:435
static VALUE argf_write(VALUE argf, VALUE str)
Definition: io.c:11668
static int rb_sysopen_internal(struct sysopen_struct *data)
Definition: io.c:5340
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:676
int rb_cloexec_dup2(int oldfd, int newfd)
Definition: io.c:251
#define Check_Type(v, t)
Definition: ruby.h:532
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
static VALUE rb_io_sysseek(int argc, VALUE *argv, VALUE io)
Definition: io.c:4540
#define PIPE_BUF
Definition: io.c:109
#define SET_BINARY_MODE_WITH_SEEK_CUR(fptr)
Definition: io.c:571
int writeconv_initialized
Definition: io.h:94
#define FMODE_CREATE
Definition: io.h:109
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:826
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3381
static void pipe_add_fptr(rb_io_t *fptr)
Definition: io.c:5573
VALUE rb_eEINPROGRESS
Definition: error.c:42
#define rb_utf8_encindex()
Definition: internal.h:403
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2616
static VALUE argf_binmode_p(VALUE argf)
Definition: io.c:11447
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:4982
#define NEED_WRITECONV(fptr)
Definition: io.c:567
long lineno
Definition: io.c:174
#define RB_GC_GUARD(v)
Definition: ruby.h:523
static VALUE rb_file_initialize(int argc, VALUE *argv, VALUE io)
Definition: io.c:7483
static VALUE argf_write_io(VALUE argf)
Definition: io.c:11653
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
#define FMODE_DUPLEX
Definition: io.h:107
int rb_io_modestr_oflags(const char *modestr)
Definition: io.c:4931
static int ruby_dup(int orig)
Definition: io.c:856
#define ENCODING_MAXNAMELEN
Definition: encoding.h:45
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:946
#define FMODE_BINMODE
Definition: io.h:104
#define STDIO_READ_DATA_PENDING(fp)
Definition: io.c:381
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
Definition: thread.c:1380
void rb_mutex_allow_trap(VALUE self, int val)
Definition: thread.c:4642
#define FMODE_APPEND
Definition: io.h:108
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:827
#define MORE_CHAR_FINISHED
Definition: io.c:2170
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
void rb_syswait(rb_pid_t pid)
Definition: process.c:3754
void rb_gc_mark(VALUE ptr)
Definition: gc.c:3604
static VALUE more_char(rb_io_t *fptr)
Definition: io.c:2246
static VALUE rb_io_s_sysopen(int argc, VALUE *argv)
Definition: io.c:6305
#define T_ARRAY
Definition: ruby.h:484
static VALUE argf_lineno(VALUE argf)
Definition: io.c:7696
off_t copy_length
Definition: io.c:9812
#define RFILE(obj)
Definition: ruby.h:1129
Definition: io.c:171
static void prepare_getline_args(int argc, VALUE *argv, VALUE *rsp, long *limit, VALUE io)
Definition: io.c:3026
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1684
static VALUE ignore_closed_stream(VALUE io, VALUE exc)
Definition: io.c:4354
static VALUE rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode, convconfig_t *convconfig, mode_t perm)
Definition: io.c:5501
static VALUE internal_write_func(void *ptr)
Definition: io.c:931
void rb_io_check_initialized(rb_io_t *fptr)
Definition: io.c:609
static VALUE rb_eEINPROGRESSWaitWritable
Definition: io.c:146
unsigned int last
Definition: nkf.c:4310
static VALUE rb_io_each_byte(VALUE io)
Definition: io.c:3415
VALUE writeconv_pre_ecopts
Definition: io.h:93
static void open_key_args(int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg)
Definition: io.c:9458
static VALUE argf_readchar(VALUE argf)
Definition: io.c:11100
#define EINPROGRESS
Definition: win32.h:512
const char * syserr
Definition: io.c:9820
void rb_update_max_fd(int fd)
Definition: io.c:183
#define FIXNUM_P(f)
Definition: ruby.h:347
static VALUE rb_io_external_encoding(VALUE io)
Definition: io.c:10488
static VALUE rb_f_readlines(int argc, VALUE *argv, VALUE recv)
Definition: io.c:8105
static void io_set_read_length(VALUE str, long n)
Definition: io.c:2304
static int argf_next_argv(VALUE argf)
Definition: io.c:7732
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2665
rb_encoding * enc2
Definition: io.h:82
static const rb_data_type_t argf_type
Definition: io.c:7604
static long io_fwrite(VALUE str, rb_io_t *fptr, int nosync)
Definition: io.c:1351
static VALUE rb_f_open(int argc, VALUE *argv)
Definition: io.c:6446
static VALUE argf_each_codepoint(VALUE argf)
Definition: io.c:11330
RUBY_FUNC_EXPORTED size_t rb_io_memsize(const rb_io_t *fptr)
Definition: io.c:4280
VALUE rb_stdin
Definition: io.c:149
#define GetOpenFile(obj, fp)
Definition: io.h:118
VALUE rb_io_printf(int argc, VALUE *argv, VALUE out)
Definition: io.c:6759
static ssize_t rb_write_internal2(int fd, const void *buf, size_t count)
Definition: io.c:967
VALUE envp_str
Definition: internal.h:650
int argc
Definition: io.c:7047
static VALUE nogvl_ioctl(void *ptr)
Definition: io.c:8693
static void validate_enc_binmode(int *fmode_p, int ecflags, rb_encoding *enc, rb_encoding *enc2)
Definition: io.c:5146
static VALUE rb_f_p_internal(VALUE arg)
Definition: io.c:7052
int capa
Definition: io.h:58
VALUE rb_io_ascii8bit_binmode(VALUE io)
Definition: io.c:4725
#define OBJ_TAINTED(x)
Definition: ruby.h:1176
#define io_tell(fptr)
Definition: io.c:757
static VALUE rb_io_tell(VALUE io)
Definition: io.c:1529
const char * ptr
Definition: io.c:1196
VALUE argv
Definition: io.c:175
static VALUE argf
Definition: io.c:158
static void io_check_tty(rb_io_t *fptr)
Definition: io.c:5412
static VALUE io_write_nonblock(VALUE io, VALUE str, int no_exception)
Definition: io.c:2616
VALUE rb_mutex_new(void)
Definition: thread.c:4251
#define ENC_CODERANGE_7BIT
Definition: encoding.h:49
const char * rb_obj_classname(VALUE)
Definition: variable.c:406
#define rb_ary_new2
Definition: intern.h:90
static VALUE argf_seek_m(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10690
static void opt_i_set(VALUE val, ID id, VALUE *var)
Definition: io.c:11594
#define GetWriteIO(io)
Definition: io.c:384
RUBY_EXTERN void * memmove(void *, const void *, size_t)
Definition: memmove.c:7
long last_lineno
Definition: io.c:173
static VALUE read_all(rb_io_t *fptr, long siz, VALUE str)
Definition: io.c:2313
#define rb_fd_set(n, f)
Definition: intern.h:350
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
Definition: io.c:5076
static void * exec_interrupts(void *arg)
Definition: io.c:9828
#define sym(x)
Definition: date_core.c:3695
VALUE rb_io_write(VALUE io, VALUE str)
Definition: io.c:1427
VALUE rb_str_buf_cat(VALUE, const char *, long)
Definition: string.c:2124
int mode
Definition: io.h:64
void rb_thread_fd_close(int)
Definition: thread.c:2131
static VALUE rb_io_set_autoclose(VALUE io, VALUE autoclose)
Definition: io.c:7565
#define NEWOBJ_OF(obj, type, klass, flags)
Definition: ruby.h:694
#define rb_fd_isset(n, f)
Definition: intern.h:352
static ssize_t maygvl_read(int has_gvl, int fd, void *buf, size_t count)
Definition: io.c:10064
static rb_encoding * io_read_encoding(rb_io_t *fptr)
Definition: io.c:800
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1511
static VALUE rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
Definition: io.c:6141
static VALUE rb_io_lines(int argc, VALUE *argv, VALUE io)
Definition: io.c:3389
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv)
Definition: enumerator.c:401
void rb_exc_raise(VALUE mesg)
Definition: eval.c:567
#define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags)
Definition: io.c:570
#define rb_io_set_close_on_exec
Definition: io.c:4032
VALUE rb_io_close(VALUE io)
Definition: io.c:4292
VALUE rb_io_flush_raw(VALUE io, int sync)
Definition: io.c:1466
VALUE rb_obj_dup(VALUE)
Definition: object.c:406
static VALUE rb_io_sysread(int argc, VALUE *argv, VALUE io)
Definition: io.c:4625
long narg
Definition: io.c:8689
static void io_ungetbyte(VALUE str, rb_io_t *fptr)
Definition: io.c:714
static void argf_block_call(ID mid, int argc, VALUE *argv, VALUE argf)
Definition: io.c:11166
ioctl_req_t cmd
Definition: io.c:8688
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1664
static VALUE rb_file_open_internal(VALUE io, VALUE filename, const char *modestr)
Definition: io.c:5527
static int str_end_with_asciichar(VALUE str, int c)
Definition: io.c:6928
static VALUE argf_binmode_m(VALUE argf)
Definition: io.c:11424
#define fmode
VALUE current_file
Definition: io.c:172
int rb_thread_fd_writable(int)
Definition: thread.c:3525
VALUE rb_econv_make_exception(rb_econv_t *ec)
Definition: transcode.c:4207
#define O_CLOEXEC
#define MEMZERO(p, type, n)
Definition: ruby.h:1351
static VALUE sym_CUR
Definition: io.c:163
void rb_econv_check_error(rb_econv_t *ec)
Definition: transcode.c:4213
rb_encoding * enc
Definition: io.h:81
VALUE rb_lastline_get(void)
Definition: vm.c:959
int rb_to_encoding_index(VALUE enc)
Definition: encoding.c:171
rb_encoding * rb_default_external_encoding(void)
Definition: encoding.c:1351
void rb_str_setter(VALUE, ID, VALUE *)
Definition: string.c:7875
void rb_maygvl_fd_fix_cloexec(int fd)
Definition: io.c:198
static VALUE copy_stream_fallback_body(VALUE arg)
Definition: io.c:10221
void rb_thread_sleep(int)
Definition: thread.c:1164
fd_set rb_fdset_t
Definition: intern.h:348
off_t src_offset
Definition: io.c:9813
#define rb_fd_term(f)
Definition: intern.h:359
VALUE rb_class_new_instance(int, VALUE *, VALUE)
Definition: object.c:1855
struct rb_execarg * rb_execarg_get(VALUE execarg_obj)
Definition: process.c:2272
#define ECONV_NEWLINE_DECORATOR_READ_MASK
Definition: encoding.h:329
static VALUE orig_stdout
Definition: io.c:151
long len
Definition: io.c:2065
VALUE rb_class_name(VALUE)
Definition: variable.c:391
static VALUE argf_lines(int argc, VALUE *argv, VALUE argf)
Definition: io.c:11219
static void * nogvl_close(void *ptr)
Definition: io.c:4115
#define ALLOC_N(type, n)
Definition: ruby.h:1333
const void * buf
Definition: io.c:919
int rb_block_given_p(void)
Definition: eval.c:712
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1393
void rb_io_unbuffered(rb_io_t *fptr)
Definition: io.c:5645
void rb_write_error2(const char *mesg, long len)
Definition: io.c:7143
static VALUE argf_internal_encoding(VALUE argf)
Definition: io.c:10607
void Init_File(void)
Definition: file.c:5614
VALUE rb_str_encode_ospath(VALUE path)
Definition: file.c:231
#define F_SETFL
Definition: win32.h:622
VALUE rb_str_substr(VALUE, long, long)
Definition: string.c:1945
int nosync
Definition: io.c:1203
#define val
static VALUE io_readpartial(int argc, VALUE *argv, VALUE io)
Definition: io.c:2531
static VALUE argf_getbyte(VALUE argf)
Definition: io.c:11060
static void stdout_setter(VALUE val, ID id, VALUE *variable)
Definition: io.c:7190
long tv_usec
Definition: ossl_asn1.c:18
VALUE rb_stdout
Definition: io.c:149
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1553
static VALUE rb_f_backquote(VALUE obj, VALUE str)
Definition: io.c:8168
VALUE rb_eRuntimeError
Definition: error.c:547
#define PREP_STDIO_NAME(f)
Definition: io.c:4037
static struct pipe_list * pipe_list
static VALUE argf_block_call_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, argf))
Definition: io.c:11155
static VALUE argf_readlines(int, VALUE *, VALUE)
Definition: io.c:8130
static VALUE argf_getline(int argc, VALUE *argv, VALUE argf)
Definition: io.c:7898
#define FMODE_SETENC_BY_BOM
Definition: io.h:116
static VALUE rb_eEWOULDBLOCKWaitWritable
Definition: io.c:145
VALUE rb_deferr
Definition: io.c:150
#define MBCLEN_NEEDMORE_P(ret)
Definition: encoding.h:142
#define RSTRING_END(str)
Definition: ruby.h:849
static VALUE rb_io_s_binread(int argc, VALUE *argv, VALUE io)
Definition: io.c:9677
char * ruby_strdup(const char *)
Definition: util.c:457
static VALUE io_flush_buffer_sync(void *arg)
Definition: io.c:990
FILE * rb_io_stdio_file(rb_io_t *fptr)
Definition: io.c:7247
int rb_io_oflags_fmode(int oflags)
Definition: io.c:4861
#define RB_IO_WAIT_WRITABLE
Definition: ruby.h:1508
static int io_strip_bom(VALUE io)
Definition: io.c:5422
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:2159
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1011
static VALUE io_s_readlines(struct foreach_arg *arg)
Definition: io.c:9546
#define ECONV_STATEFUL_DECORATOR_MASK
Definition: encoding.h:338
static struct StringIO * writable(VALUE strio)
Definition: stringio.c:136
static ssize_t maygvl_copy_stream_read(int has_gvl, struct copy_stream_struct *stp, char *buf, size_t len, off_t offset)
Definition: io.c:10073
VALUE rb_ary_new(void)
Definition: array.c:495
#define dp(v)
Definition: vm_debug.h:21
rb_econv_t * rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts)
Definition: transcode.c:2578
#define UINT2NUM(x)
Definition: ruby.h:1298
VALUE rb_io_get_write_io(VALUE io)
Definition: io.c:639
VALUE rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash)
Definition: process.c:1959
static int swallow(rb_io_t *fptr, int term)
Definition: io.c:2926
static VALUE argf_set_encoding(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10647
#define ARGF_GENERIC_INPUT_P()
Definition: io.c:7708
#define ECONV_PARTIAL_INPUT
Definition: encoding.h:350
VALUE rb_io_ungetbyte(VALUE io, VALUE b)
Definition: io.c:3833
#define ECONV_AFTER_OUTPUT
Definition: encoding.h:351
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1541
VALUE rb_thread_current(void)
Definition: thread.c:2401
int rb_cloexec_fcntl_dupfd(int fd, int minfd)
Definition: io.c:323
static void pipe_finalize(rb_io_t *fptr, int noraise)
Definition: io.c:5620
#define NIL_P(v)
Definition: ruby.h:438
static VALUE copy_stream_fallback(struct copy_stream_struct *stp)
Definition: io.c:10279
#define ISASCII(c)
Definition: ruby.h:1766
VALUE rb_io_flush(VALUE io)
Definition: io.c:1510
static VALUE sym_textmode
Definition: io.c:162
static VALUE finish_writeconv_sync(VALUE arg)
Definition: io.c:4108
static VALUE io_write(VALUE io, VALUE str, int nosync)
Definition: io.c:1375
static VALUE rb_f_puts(int argc, VALUE *argv, VALUE recv)
Definition: io.c:7023
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:630
static VALUE pipe_pair_close(VALUE rw)
Definition: io.c:9318
const char * ruby_get_inplace_mode(void)
Definition: io.c:11600
static int appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
Definition: io.c:2844
int chown(const char *, int, int)
Definition: win32.c:4425
#define ECONV_DEFAULT_NEWLINE_DECORATOR
Definition: encoding.h:344
int fd
Definition: io.h:62
VALUE rb_mutex_synchronize(VALUE mutex, VALUE(*func)(VALUE arg), VALUE arg)
Definition: thread.c:4619
static VALUE rb_io_each_line(int argc, VALUE *argv, VALUE io)
Definition: io.c:3369
#define MODE_BINARY(a, b)
rb_pid_t rb_fork_async_signal_safe(int *status, int(*chfunc)(void *, char *, size_t), void *charg, VALUE fds, char *errmsg, size_t errmsg_buflen)
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2225
int rb_io_wait_readable(int f)
Definition: io.c:1077
int8_t next_p
Definition: io.c:178
void rb_sys_fail_str(VALUE mesg)
Definition: error.c:1982
static VALUE select_internal(VALUE read, VALUE write, VALUE except, struct timeval *tp, rb_fdset_t *fds)
Definition: io.c:8191
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:496
static VALUE rb_io_each_char(VALUE io)
Definition: io.c:3571
static VALUE rb_io_open_with_args(int argc, const VALUE *argv)
Definition: io.c:6503
VALUE rb_io_check_io(VALUE io)
Definition: io.c:633
void rb_lastline_set(VALUE)
Definition: vm.c:965
static VALUE argf_chars(VALUE argf)
Definition: io.c:11305
static VALUE rb_io_getline(int argc, VALUE *argv, VALUE io)
Definition: io.c:3177
VALUE str
Definition: io.c:1202
#define rb_io_fdatasync
Definition: io.c:1901
struct rb_io_t::rb_io_enc_t encs
void Init_IO(void)
Definition: io.c:11874
static void * nogvl_fclose(void *ptr)
Definition: io.c:4136
#define TYPE(x)
Definition: ruby.h:505
#define NUM2IOCTLREQ(num)
Definition: io.c:8683
int argc
Definition: ruby.c:131
#define READ_DATA_PENDING(fptr)
Definition: io.c:386
VALUE writeconv_asciicompat
Definition: io.h:91
#define FMODE_TRUNC
Definition: io.h:113
static VALUE finish_writeconv(rb_io_t *fptr, int noalloc)
Definition: io.c:4040
#define Qfalse
Definition: ruby.h:425
const char * notimp
Definition: io.c:9822
static VALUE rb_open_file(int argc, const VALUE *argv, VALUE io)
Definition: io.c:6232
rb_pid_t pid
Definition: io.h:65
#define T_BIGNUM
Definition: ruby.h:487
#define LONG_MAX
Definition: ruby.h:191
#define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr)
Definition: io.c:569
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:4920
static VALUE rb_io_gets_m(int argc, VALUE *argv, VALUE io)
Definition: io.c:3214
if((ID)(DISPID) nameid!=nameid)
Definition: win32ole.c:770
VALUE rb_io_get_io(VALUE io)
Definition: io.c:627
#define RUBY_FUNC_EXPORTED
Definition: defines.h:246
static VALUE argf_eof(VALUE argf)
Definition: io.c:10801
int len
Definition: io.h:57
#define ENC_CODERANGE_BROKEN
Definition: encoding.h:51
#define rb_ary_new4
Definition: intern.h:92
static void io_setstrbuf(VALUE *str, long len)
Definition: io.c:2283
#define rb_str_new2
Definition: intern.h:840
VALUE rb_obj_alloc(VALUE)
Definition: object.c:1801
#define ARGF
Definition: io.c:366
int err
Definition: win32.c:114
static int io_flush_buffer(rb_io_t *fptr)
Definition: io.c:1048
#define rb_enc_codepoint(p, e, enc)
Definition: encoding.h:155
#define OBJ_FREEZE(x)
Definition: ruby.h:1186
#define argf_of(obj)
Definition: io.c:365
#define rb_enc_mbminlen(enc)
Definition: encoding.h:128
Definition: io.c:1200
VALUE rb_io_gets(VALUE io)
Definition: io.c:3187
int rb_cloexec_dup(int oldfd)
Definition: io.c:244
static VALUE rb_f_printf(int argc, VALUE *argv)
Definition: io.c:6777
static void rscheck(const char *rsptr, long rslen, VALUE rs)
Definition: io.c:2836
VALUE * argv
Definition: io.c:7048
static int nogvl_copy_stream_write(struct copy_stream_struct *stp, char *buf, size_t len)
Definition: io.c:10116
static VALUE argf_initialize(VALUE argf, VALUE argv)
Definition: io.c:7633
#define rb_f_syscall
Definition: io.c:9237
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
#define ENC_CODERANGE_VALID
Definition: encoding.h:50
#define ATOMIC_CAS(var, oldval, newval)
Definition: ruby_atomic.h:132
static VALUE rb_io_seek_m(int argc, VALUE *argv, VALUE io)
Definition: io.c:1597
#define numberof(array)
Definition: etc.c:595
#define ALLOC(type)
Definition: ruby.h:1334
int fd
Definition: io.c:8687
#define EOF
Definition: vsnprintf.c:207
VALUE read
Definition: io.c:8316
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2025
static void io_set_encoding_by_bom(VALUE io)
Definition: io.c:5485
#define DEFAULT_TEXTMODE
Definition: io.c:565
static void advice_arg_check(VALUE advice)
Definition: io.c:8428
#define NUM2OFFT(x)
Definition: ruby.h:672
#define IO_CBUF_CAPA_MIN
Definition: io.c:123
rb_encoding * rb_find_encoding(VALUE enc)
Definition: encoding.c:226
int rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc)
Definition: encoding.c:970
static VALUE argf_alloc(VALUE klass)
Definition: io.c:7620
static void io_ascii8bit_binmode(rb_io_t *fptr)
Definition: io.c:4703
#define NEXT_ARGF_FORWARD(argc, argv)
Definition: io.c:7714
static VALUE prep_io(int fd, int fmode, VALUE klass, const char *path)
Definition: io.c:7197
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1697
int rb_cloexec_pipe(int fildes[2])
Definition: io.c:286
static VALUE rb_f_gets(int argc, VALUE *argv, VALUE recv)
Definition: io.c:7979
#define RSTRING_LEN(str)
Definition: ruby.h:841
VALUE rb_get_argv(void)
Definition: io.c:11640
VALUE rb_yield(VALUE)
Definition: vm_eval.c:942
void ruby_set_inplace_mode(const char *suffix)
Definition: io.c:11606
rb_io_buffer_t wbuf
Definition: io.h:70
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:886
void rb_define_readonly_variable(const char *, VALUE *)
Definition: variable.c:610
int errno
static VALUE copy_stream_body(VALUE arg)
Definition: io.c:10291
#define TRUE
Definition: nkf.h:175
#define off_t
Definition: io.c:65
static VALUE seek_before_access(VALUE argp)
Definition: io.c:9594
#define S_ISREG(m)
Definition: io.c:885
static VALUE rb_io_set_pos(VALUE io, VALUE offset)
Definition: io.c:1623
void rb_last_status_clear(void)
Definition: process.c:336
static rb_atomic_t max_file_descriptor
Definition: io.c:181
static VALUE rb_io_init_copy(VALUE dest, VALUE io)
Definition: io.c:6704
VALUE rb_mEnumerable
Definition: enum.c:20
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
rb_io_t * fptr
Definition: io.c:1194
static void nogvl_copy_stream_read_write(struct copy_stream_struct *stp)
Definition: io.c:10142
static rb_encoding * io_input_encoding(rb_io_t *fptr)
Definition: io.c:809
static VALUE io_close(VALUE io)
Definition: io.c:4367
Definition: io.c:5567
static int rb_sysopen(VALUE fname, int oflags, mode_t perm)
Definition: io.c:5350
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:958
#define IO_RBUF_CAPA_FOR(fptr)
Definition: io.c:124
void rb_execarg_fixup(VALUE execarg_obj)
Definition: process.c:2325
static VALUE argf_rewind(VALUE argf)
Definition: io.c:10733
#define NEED_READCONV(fptr)
Definition: io.c:566
static VALUE rb_io_pid(VALUE io)
Definition: io.c:1949
static VALUE rb_eEINPROGRESSWaitReadable
Definition: io.c:147
void rb_fatal(const char *fmt,...)
Definition: error.c:1911
static VALUE io_s_read(struct foreach_arg *arg)
Definition: io.c:9582
#define rb_enc_name(enc)
Definition: encoding.h:125
VALUE rb_eSystemCallError
Definition: error.c:566
static void * io_flush_buffer_sync2(void *arg)
Definition: io.c:1010
static int maygvl_copy_stream_continue_p(int has_gvl, struct copy_stream_struct *stp)
Definition: io.c:9841
void rb_last_status_set(int status, rb_pid_t pid)
Definition: process.c:327
static VALUE rb_io_readlines(int argc, VALUE *argv, VALUE io)
Definition: io.c:3324
static VALUE rb_io_s_for_fd(int argc, VALUE *argv, VALUE klass)
Definition: io.c:7524
struct rb_io_enc_t encs
Definition: io.c:177
static VALUE rb_f_select(int argc, VALUE *argv, VALUE obj)
Definition: io.c:8656
static VALUE rb_io_chars(VALUE io)
Definition: io.c:3594
#define MEMMOVE(p1, p2, type, n)
Definition: ruby.h:1353
VALUE rb_hash_new(void)
Definition: hash.c:298
static int wsplit_p(rb_io_t *fptr)
Definition: io.c:889
static VALUE rb_io_s_open(int argc, VALUE *argv, VALUE klass)
Definition: io.c:6283
#define NUM2CHR(x)
Definition: ruby.h:1329
static VALUE rb_f_print(int argc, VALUE *argv)
Definition: io.c:6866
static void argf_lineno_setter(VALUE val, ID id, VALUE *var)
Definition: io.c:7936
#define strdup(s)
Definition: util.h:67
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
static VALUE argf_read_nonblock(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10950
void rb_write_error_str(VALUE mesg)
Definition: io.c:7163
void rb_str_modify_expand(VALUE, long)
Definition: string.c:1492
static VALUE argf_to_io(VALUE argf)
Definition: io.c:10775
void rb_thread_execute_interrupts(VALUE th)
Definition: thread.c:2026
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1133
Definition: ruby.h:934
VALUE rb_check_hash_type(VALUE hash)
Definition: hash.c:588
static void io_unread(rb_io_t *fptr)
Definition: io.c:691
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:616
#define PRIsVALUE
Definition: ruby.h:137
unsigned long ID
Definition: ruby.h:89
#define FMODE_WSPLIT
Definition: io.h:111
void rb_thread_wait_fd(int)
Definition: thread.c:3519
VALUE tied_io_for_writing
Definition: io.h:72
#define RUBY_METHOD_FUNC(func)
Definition: ruby.h:1399
static VALUE rb_io_close_m(VALUE io)
Definition: io.c:4339
static VALUE argf_lineno_getter(ID id, VALUE *var)
Definition: io.c:7929
static ssize_t rb_write_internal(int fd, const void *buf, size_t count)
Definition: io.c:956
#define Qnil
Definition: ruby.h:427
int8_t init_p
Definition: io.c:178
#define FMODE_TEXTMODE
Definition: io.h:114
static void rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, int *oflags_p, int *fmode_p, convconfig_t *convconfig_p)
Definition: io.c:5199
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
Definition: numeric.c:2514
#define EWOULDBLOCK
Definition: io.c:114
#define mode_t
Definition: win32.h:116
#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n)
Definition: oniguruma.h:245
#define OBJ_TAINT(x)
Definition: ruby.h:1177
unsigned long VALUE
Definition: ruby.h:88
static VALUE argf_readline(int, VALUE *, VALUE)
Definition: io.c:8078
#define IS_PREP_STDIO(f)
Definition: io.c:4036
#define rb_funcall2
Definition: ruby.h:1456
static VALUE rb_io_s_binwrite(int argc, VALUE *argv, VALUE io)
Definition: io.c:9804
static VALUE result
Definition: nkf.c:40
VALUE rb_gets(void)
Definition: io.c:8014
void rb_readwrite_sys_fail(int writable, const char *mesg)
Definition: io.c:11674
const char * rb_class2name(VALUE)
Definition: variable.c:397
char * strchr(char *, char)
#define RB_IO_WAIT_READABLE
Definition: ruby.h:1507
int intptr_t
Definition: win32.h:87
static VALUE prep_stdio(FILE *f, int fmode, VALUE klass, const char *path)
Definition: io.c:7228
#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr)
Definition: io.c:427
char * str_ptr
Definition: io.c:2402
#define FIX2INT(x)
Definition: ruby.h:632
static void * internal_write_func2(void *ptr)
Definition: io.c:938
#define ECONV_NEWLINE_DECORATOR_MASK
Definition: encoding.h:328
VALUE rb_rs
Definition: io.c:154
void rb_io_synchronized(rb_io_t *fptr)
Definition: io.c:5638
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
Definition: eval.c:741
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:409
static VALUE rb_io_s_write(int argc, VALUE *argv, VALUE io)
Definition: io.c:9788
static long io_bufread(char *ptr, long len, rb_io_t *fptr)
Definition: io.c:2025
rb_fdset_t fds
Definition: io.c:9823
#define rb_enc_asciicompat(enc)
Definition: encoding.h:188
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:839
VALUE rb_str_new_cstr(const char *)
Definition: string.c:560
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
static VALUE argf_read(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10855
static int maygvl_select(int has_gvl, int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout)
Definition: io.c:9860
static int maygvl_copy_stream_wait_read(int has_gvl, struct copy_stream_struct *stp)
Definition: io.c:9869
static VALUE do_writeconv(VALUE str, rb_io_t *fptr)
Definition: io.c:1296
static VALUE io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
Definition: io.c:2256
VALUE rb_uninterruptible(VALUE(*b_proc)(ANYARGS), VALUE data)
Definition: thread.c:5307
void rb_sys_fail(const char *mesg)
Definition: error.c:1976
static VALUE read_internal_call(VALUE arg)
Definition: io.c:2407
static VALUE sym_willneed
Definition: io.c:8340
static VALUE rb_io_autoclose_p(VALUE io)
Definition: io.c:7540
static VALUE io_write_m(VALUE io, VALUE str)
Definition: io.c:1421
void rb_jump_tag(int tag)
Definition: eval.c:706
static VALUE rb_io_set_encoding(int argc, VALUE *argv, VALUE io)
Definition: io.c:10542
int rb_reserved_fd_p(int fd)
void rb_define_hooked_variable(const char *, VALUE *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
Definition: variable.c:585
#define READ_DATA_BUFFERED(fptr)
Definition: io.c:389
#define rb_io_close_on_exec_p
Definition: io.c:3974
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1639
struct timeval * timeout
Definition: io.c:8317
static VALUE bufread_call(VALUE arg)
Definition: io.c:2070
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:766
#define StringValueCStr(v)
Definition: ruby.h:541
rb_econv_t * readconv
Definition: io.h:87
static VALUE argf_tell(VALUE argf)
Definition: io.c:10673
#define shutdown(a, b)
Definition: io.c:575
#define rb_fd_max(f)
Definition: intern.h:360
static VALUE argf_each_byte(VALUE argf)
Definition: io.c:11252
static size_t argf_memsize(const void *ptr)
Definition: io.c:7595
#define SEEK_END
Definition: io.c:762
void rb_iter_break_value(VALUE val)
Definition: vm.c:1160
static int do_ioctl(int fd, ioctl_req_t cmd, long narg)
Definition: io.c:8701
#define recur(fmt)
int argc
Definition: io.c:9452
int rb_econv_putbackable(rb_econv_t *ec)
Definition: transcode.c:1742
#define RSTRING_PTR(str)
Definition: ruby.h:845
static VALUE argf_codepoints(VALUE argf)
Definition: io.c:11344
static VALUE sym_extenc
Definition: io.c:161
VALUE write_lock
Definition: io.h:96
struct pipe_list * next
Definition: io.c:5569
#define rb_exc_new3
Definition: intern.h:248
static VALUE argf_filename_getter(ID id, VALUE *var)
Definition: io.c:11382
static VALUE rb_io_binmode_m(VALUE io)
Definition: io.c:4749
void rb_str_modify(VALUE)
Definition: string.c:1484
static VALUE sym_perm
Definition: io.c:161
static VALUE rb_io_isatty(VALUE io)
Definition: io.c:3925
#define ENCODING_GET(obj)
Definition: encoding.h:38
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:832
static VALUE io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock, int no_exception)
Definition: io.c:2415
VALUE io
Definition: io.c:1201
static VALUE io_s_write0(struct write_arg *arg)
Definition: io.c:9695
void rb_mod_sys_fail_str(VALUE mod, VALUE mesg)
Definition: error.c:2024
struct rb_execarg::@123::@125 cmd
void rb_insecure_operation(void)
Definition: safe.c:109
static VALUE io_flush_buffer_async2(VALUE arg)
Definition: io.c:1029
static VALUE rb_io_lineno(VALUE io)
Definition: io.c:3247
static long io_writable_length(rb_io_t *fptr, long l)
Definition: io.c:979
static VALUE io_read(int argc, VALUE *argv, VALUE io)
Definition: io.c:2788
int size
Definition: encoding.c:49
VALUE rb_funcallv(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:806
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:975
#define f
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
Definition: hash.c:708
#define INT2FIX(i)
Definition: ruby.h:231
static void pipe_atexit(void)
Definition: io.c:5607
static VALUE io_new_instance(VALUE args)
Definition: io.c:9241
static VALUE rb_io_putc(VALUE io, VALUE ch)
Definition: io.c:6891
static VALUE rb_io_bytes(VALUE io)
Definition: io.c:3440
#define MBCLEN_INVALID_P(ret)
Definition: encoding.h:141
#define RARRAY_AREF(a, i)
Definition: ruby.h:901
rb_econv_result_t rb_econv_convert(rb_econv_t *ec, const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end, unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end, int flags)
Definition: transcode.c:1446
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2631
static long io_fread(VALUE str, long offset, long size, rb_io_t *fptr)
Definition: io.c:2078
static int rb_io_fmode_oflags(int fmode)
Definition: io.c:4896
static VALUE check_pipe_command(VALUE filename_or_command)
Definition: io.c:6332
int rb_io_fptr_finalize(rb_io_t *fptr)
Definition: io.c:4257
VALUE rb_mWaitReadable
Definition: io.c:136
VALUE io
Definition: io.c:9454
static VALUE rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
Definition: io.c:9385
VALUE rb_io_fdopen(int fd, int oflags, const char *path)
Definition: io.c:7219
VALUE rb_str_buf_cat_ascii(VALUE, const char *)
Definition: string.c:2258
VALUE rb_eEAGAIN
Definition: error.c:40
static VALUE rb_io_to_io(VALUE io)
Definition: io.c:2004
VALUE rb_eIOError
Definition: io.c:135
struct rb_execarg::@123::@124 sh
static VALUE rb_io_inspect(VALUE obj)
Definition: io.c:1968
int off
Definition: io.h:56
static void rb_scan_open_args(int argc, const VALUE *argv, VALUE *fname_p, int *oflags_p, int *fmode_p, convconfig_t *convconfig_p, mode_t *perm_p)
Definition: io.c:6210
static VALUE sym_intenc
Definition: io.c:161
#define rb_intern(str)
#define ANYARGS
Definition: defines.h:98
static VALUE rb_io_s_try_convert(VALUE dummy, VALUE io)
Definition: io.c:684
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:628
RUBY_SYMBOL_EXPORT_BEGIN void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
Definition: thread.c:1450
static void clear_codeconv(rb_io_t *fptr)
Definition: io.c:4250
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:697
static void rb_io_fptr_cleanup(rb_io_t *fptr, int noraise)
Definition: io.c:4216
void rb_error_arity(int argc, int min, int max)
#define RARRAY_PTR(a)
Definition: ruby.h:907
#define rb_fd_select(n, rfds, wfds, efds, timeout)
Definition: intern.h:361
static void parse_mode_enc(const char *estr, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
Definition: io.c:5005
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1290
void rb_syserr_fail_str(int e, VALUE mesg)
Definition: error.c:1970
long rb_w32_write_console(uintptr_t, int)
Definition: win32.c:6525
static VALUE rb_eEAGAINWaitReadable
Definition: io.c:142
VALUE rb_check_string_type(VALUE)
Definition: string.c:1679
#define is_socket(fd, path)
Definition: io.c:581
#define rb_funcall3
Definition: ruby.h:1457
VALUE rb_any_to_s(VALUE)
Definition: object.c:452
void rb_gvar_readonly_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar)
RUBY_EXTERN char * strerror(int)
Definition: strerror.c:11
static VALUE argf_each_char(VALUE argf)
Definition: io.c:11291
#define LONG2FIX(i)
Definition: ruby.h:232
VALUE pathv
Definition: io.h:67
static VALUE rb_io_advise(int argc, VALUE *argv, VALUE io)
Definition: io.c:8488
#define O_NONBLOCK
Definition: win32.h:626
#define ARGVSTR2ARGV(argv_str)
Definition: internal.h:683
#define RTEST(v)
Definition: ruby.h:437
static VALUE rb_io_getc(VALUE io)
Definition: io.c:3723
void rb_thread_check_ints(void)
Definition: thread.c:1139
#define T_STRING
Definition: ruby.h:482
VALUE rb_eEOFError
Definition: io.c:134
VALUE rb_str_locktmp(VALUE)
static long io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
Definition: io.c:1215
void(* finalize)(struct rb_io_t *, int)
Definition: io.h:68
VALUE offset
Definition: io.c:9589
#define OBJ_INFECT(x, s)
Definition: ruby.h:1180
int use_shell
Definition: internal.h:637
static VALUE argf_closed(VALUE argf)
Definition: io.c:11514
struct rb_encoding_entry * list
Definition: encoding.c:47
int rb_method_basic_definition_p(VALUE, ID)
Definition: vm_method.c:1573
void rb_define_variable(const char *, VALUE *)
Definition: variable.c:604
#define READ_CHECK(fptr)
Definition: io.c:402
#define T_FILE
Definition: ruby.h:488
static VALUE rb_io_s_read(int argc, VALUE *argv, VALUE io)
Definition: io.c:9638
#define fsync
Definition: win32.h:222
void rb_io_check_readable(rb_io_t *fptr)
Definition: io.c:794
FILE * rb_fdopen(int fd, const char *modestr)
Definition: io.c:5373
static rb_io_t * flush_before_seek(rb_io_t *fptr)
Definition: io.c:747
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1030
#define rb_enc_left_char_head(s, p, e, enc)
Definition: encoding.h:170
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:1888
void rb_notimplement(void)
Definition: error.c:1903
static VALUE sym_binmode
Definition: io.c:162
VALUE rb_ary_concat(VALUE x, VALUE y)
Definition: array.c:3542
static long remain_size(rb_io_t *fptr)
Definition: io.c:2106
long length
Definition: io.c:1197
static VALUE argf_argv_getter(ID id, VALUE *var)
Definition: io.c:11634
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:242
rb_io_t * fptr
Definition: io.c:4103
#define SafeStringValue(v)
Definition: ruby.h:545
VALUE rb_ary_join(VALUE ary, VALUE sep)
Definition: array.c:1995
VALUE rb_eNotImpError
Definition: error.c:558
int rb_atomic_t
Definition: ruby_atomic.h:120
#define FOREACH_ARGF()
Definition: io.c:11152
static VALUE io_reopen(VALUE io, VALUE nfile)
Definition: io.c:6513
static void * sysopen_func(void *ptr)
Definition: io.c:5332
static VALUE rb_io_readline(int argc, VALUE *argv, VALUE io)
Definition: io.c:3295
#define FMODE_PREP
Definition: io.c:4035
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:548
static VALUE rb_eEWOULDBLOCKWaitReadable
Definition: io.c:144
#define rb_safe_level()
Definition: tcltklib.c:95
#define rb_sys_fail_path(path)
Definition: internal.h:450
#define OFFT2NUM(v)
Definition: ruby.h:252
VALUE rb_io_addstr(VALUE io, VALUE str)
Definition: io.c:1449
static long ioctl_narg_len(ioctl_req_t cmd)
Definition: io.c:8739
static VALUE internal_read_func(void *ptr)
Definition: io.c:924
int oflags
Definition: io.c:5327
void rb_set_class_path(VALUE, VALUE, const char *)
Definition: variable.c:316
int rb_thread_interrupted(VALUE thval)
Definition: thread.c:1156
static VALUE rb_io_initialize(int argc, VALUE *argv, VALUE io)
Definition: io.c:7403
static void make_writeconv(rb_io_t *fptr)
Definition: io.c:1138
VALUE rb_io_taint_check(VALUE io)
Definition: io.c:602
const char * name
Definition: nkf.c:208
int rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
Definition: process.c:1670
#define ID2SYM(x)
Definition: ruby.h:355
#define NUM2MODET(v)
Definition: ruby.h:339
VALUE rb_io_puts(int argc, VALUE *argv, VALUE out)
Definition: io.c:6983
static VALUE rb_io_readbyte(VALUE io)
Definition: io.c:3805
const char * rb_id2name(ID id)
Definition: ripper.c:17230
#define READ_CHAR_PENDING_PTR(fptr)
Definition: io.c:393
#define FMODE_SYNC
Definition: io.h:105
#define FMODE_TTY
Definition: io.h:106
#define MakeOpenFile(obj, fp)
Definition: io.h:127
#define StringValuePtr(v)
Definition: ruby.h:540
#define SHUT_WR
#define SHUT_RD
VALUE rb_default_rs
Definition: io.c:156
#define MORE_CHAR_SUSPENDED
Definition: io.c:2169
RUBY_EXTERN int dup2(int, int)
Definition: dup2.c:27
static VALUE sym_sequential
Definition: io.c:8340
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:833
rb_io_buffer_t rbuf
Definition: io.h:70
char * inplace
Definition: io.c:176
static VALUE rb_io_s_copy_stream(int argc, VALUE *argv, VALUE io)
Definition: io.c:10451
#define rb_fd_init(f)
Definition: intern.h:357
VALUE rb_inspect(VALUE)
Definition: object.c:470
static void clear_writeconv(rb_io_t *fptr)
Definition: io.c:4240
struct rb_io_enc_t convconfig_t
Definition: io.c:5143
static VALUE fill_cbuf(rb_io_t *fptr, int ec_flags)
Definition: io.c:2172
static VALUE rb_io_reopen(int argc, VALUE *argv, VALUE file)
Definition: io.c:6615
rb_encoding * rb_ascii8bit_encoding(void)
Definition: encoding.c:1227
static long read_buffered_data(char *ptr, long len, rb_io_t *fptr)
Definition: io.c:2011
static VALUE sym_dontneed
Definition: io.c:8340
#define FIX2UINT(x)
Definition: ruby.h:633
static int interpret_seek_whence(VALUE vwhence)
Definition: io.c:1556
void rb_warning(const char *fmt,...)
Definition: error.c:236
int rb_enc_find_index(const char *name)
Definition: encoding.c:684
#define rb_syserr_fail_path(err, path)
Definition: internal.h:451
#define rb_io_fsync
Definition: io.c:1853
static VALUE sym_END
Definition: io.c:163
void rb_secure(int)
Definition: safe.c:88
#define fileno(p)
Definition: vsnprintf.c:223
static VALUE sym_open_args
Definition: io.c:161
static VALUE sym_exception
Definition: io.c:162
VALUE rb_execarg_new(int argc, VALUE *argv, int accept_shell)
Definition: process.c:2261
int rb_io_read_pending(rb_io_t *fptr)
Definition: io.c:830
#define rb_check_frozen(obj)
Definition: intern.h:277
#define NEED_NEWLINE_DECORATOR_ON_READ(fptr)
Definition: io.c:426
#define CONST_ID(var, str)
Definition: ruby.h:1428
FILE * stdio_file
Definition: io.h:63
VALUE rb_eEWOULDBLOCK
Definition: error.c:41
static VALUE rb_io_fileno(VALUE io)
Definition: io.c:1917
ssize_t rb_io_bufread(VALUE io, void *buf, size_t size)
Definition: io.c:2094
static VALUE sym_normal
Definition: io.c:8340
#define MODE_BTMODE(a, b, c)
Definition: io.c:1293
VALUE rb_obj_freeze(VALUE)
Definition: object.c:1076
VALUE filename
Definition: io.c:172
static ID id_readpartial
Definition: io.c:160
static VALUE rb_f_p(int argc, VALUE *argv, VALUE self)
Definition: io.c:7094
static VALUE argf_forward(int argc, VALUE *argv, VALUE argf)
Definition: io.c:7702
static VALUE pipe_open_s(VALUE prog, const char *modestr, int fmode, convconfig_t *convconfig)
Definition: io.c:6041
static VALUE rb_f_readline(int argc, VALUE *argv, VALUE recv)
Definition: io.c:8052
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts)
Definition: transcode.c:2885
void void xfree(void *)
char rb_w32_fd_is_text(int)
Definition: win32.c:6980
#define io_seek(fptr, ofs, whence)
Definition: io.c:756
static VALUE rb_io_write_nonblock(int argc, VALUE *argv, VALUE io)
Definition: io.c:2707
static VALUE argf_fileno(VALUE argf)
Definition: io.c:10753
VALUE write
Definition: io.c:8316
static ssize_t rb_read_internal(int fd, void *buf, size_t count)
Definition: io.c:945
static VALUE argf_to_s(VALUE argf)
Definition: io.c:11528
VALUE rb_output_rs
Definition: io.c:155
static VALUE io_alloc(VALUE klass)
Definition: io.c:875
VALUE * argv
Definition: io.c:9453
#define READ_CHAR_PENDING_COUNT(fptr)
Definition: io.c:392
static VALUE rb_io_getline_1(VALUE rs, long limit, VALUE io)
Definition: io.c:3071
void rb_stdio_set_default_encoding(void)
Definition: io.c:10558
int lineno
Definition: io.h:66
VALUE rb_str_buf_new(long)
Definition: string.c:891
VALUE rb_usascii_str_new(const char *, long)
Definition: string.c:540
VALUE rb_mWaitWritable
Definition: io.c:137
void rb_io_read_check(rb_io_t *fptr)
Definition: io.c:847
#define fstat(fd, st)
Definition: win32.h:214
#define SYMBOL_P(x)
Definition: ruby.h:354
static VALUE rb_ioctl(VALUE io, VALUE req, VALUE arg)
Definition: io.c:8940
#define stat(path, st)
Definition: win32.h:213
static VALUE io_read_nonblock(int argc, VALUE *argv, VALUE io)
Definition: io.c:2593
static void * nogvl_copy_stream_func(void *arg)
Definition: io.c:10199
VALUE except
Definition: io.c:8316
static const char * rb_io_oflags_modestr(int oflags)
Definition: io.c:4937
#define rb_io_sync
Definition: io.c:1854
#define DEFULT_IOCTL_NARG_LEN
Definition: io.c:8715
#define env
mode_t perm
Definition: io.c:5328
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size)
Definition: io.c:1365
#define NULL
Definition: _sdbm.c:103
#define FIX2LONG(x)
Definition: ruby.h:345
static VALUE argf_file(VALUE argf)
Definition: io.c:11406
static VALUE copy_stream_finalize(VALUE arg)
Definition: io.c:10402
#define Qundef
Definition: ruby.h:428
static VALUE io_getc(rb_io_t *fptr, rb_encoding *enc)
Definition: io.c:3449
#define READ_CHAR_PENDING(fptr)
Definition: io.c:391
static void argf_free(void *ptr)
Definition: io.c:7587
#define READ_DATA_PENDING_PTR(fptr)
Definition: io.c:388
static void extract_binmode(VALUE opthash, int *fmode)
Definition: io.c:5170
static VALUE argf_close_m(VALUE argf)
Definition: io.c:11495
static ID id_flush
Definition: io.c:160
static VALUE select_end(VALUE arg)
Definition: io.c:8330
static void rb_io_ext_int_to_encs(rb_encoding *ext, rb_encoding *intern, rb_encoding **enc, rb_encoding **enc2, int fmode)
Definition: io.c:4971
VALUE rb_class_new(VALUE super)
Creates a new class.
Definition: class.c:228
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
#define ruby_verbose
Definition: ruby.h:1475
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2298
VALUE rb_file_open(const char *fname, const char *modestr)
Definition: io.c:5561
#define NOFILE
Definition: io.c:76
void rb_io_check_byte_readable(rb_io_t *fptr)
Definition: io.c:785
static VALUE rb_io_each_codepoint(VALUE io)
Definition: io.c:3619
static void pipe_del_fptr(rb_io_t *fptr)
Definition: io.c:5584
void rb_io_check_char_readable(rb_io_t *fptr)
Definition: io.c:766
#define next_argv()
Definition: io.c:7707
int rb_econv_prepare_options(VALUE opthash, VALUE *ecopts, int ecflags)
Definition: transcode.c:2527
void rb_econv_binmode(rb_econv_t *ec)
Definition: transcode.c:1942
void rb_warn(const char *fmt,...)
Definition: error.c:223
static VALUE rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
Definition: io.c:9532
rb_io_t * fptr
Definition: io.c:5568
#define SEEK_SET
Definition: io.c:760
VALUE rb_eArgError
Definition: error.c:549
static VALUE rb_io_open(VALUE filename, VALUE vmode, VALUE vperm, VALUE opt)
Definition: io.c:6483
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR
Definition: encoding.h:332
#define O_BINARY
Definition: _sdbm.c:89
int mode
Definition: io.c:9590
#define NUM2LONG(x)
Definition: ruby.h:600
VALUE rb_io_set_write_io(VALUE io, VALUE w)
Definition: io.c:651
static VALUE argf_initialize_copy(VALUE argf, VALUE orig)
Definition: io.c:7643
VALUE rb_io_ungetc(VALUE io, VALUE c)
Definition: io.c:3868
VALUE rb_output_fs
Definition: io.c:153
static VALUE argf_getc(VALUE argf)
Definition: io.c:11020
VALUE rb_mutex_owned_p(VALUE self)
Definition: thread.c:4449
static int maygvl_close(int fd, int keepgvl)
Definition: io.c:4123
void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n)
Definition: transcode.c:1753
static VALUE argf_skip(VALUE argf)
Definition: io.c:11467
void rb_io_check_closed(rb_io_t *fptr)
Definition: io.c:617
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1127
#define SEEK_CUR
Definition: io.c:761
#define SET_BINARY_MODE(fptr)
Definition: io.c:568
char * strrchr(const char *, const char)
char ** argv
Definition: ruby.c:132
VALUE rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags)
Definition: transcode.c:1877
VALUE io
Definition: io.c:9588
static int maygvl_fclose(FILE *file, int keepgvl)
Definition: io.c:4144
#define StringValue(v)
Definition: ruby.h:539
rb_econv_t * writeconv
Definition: io.h:90
static VALUE argf_forward_call(VALUE arg)
Definition: io.c:10906
void rb_read_check(FILE *fp)
Definition: io.c:839
Definition: ioctl.h:6
void rb_write_error(const char *mesg)
Definition: io.c:7157
static int io_fillbuf(rb_io_t *fptr)
Definition: io.c:1673
Definition: io.c:9587
#define RUBY_UBF_IO
Definition: intern.h:872
rb_encoding * rb_enc_from_index(int index)
Definition: encoding.c:590
static void unsupported_encoding(const char *name)
Definition: io.c:4999
VALUE rb_obj_class(VALUE)
Definition: object.c:226
VALUE rb_str_new(const char *, long)
Definition: string.c:534
#define SIGNED_VALUE
Definition: ruby.h:90
static VALUE rb_io_s_new(int argc, VALUE *argv, VALUE klass)
Definition: io.c:7503
static void clear_readconv(rb_io_t *fptr)
Definition: io.c:4227
void rb_eof_error(void)
Definition: io.c:596