Ruby  2.1.10p492(2016-04-01revision54464)
io.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  io.c -
4 
5  $Author: usa $
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 */
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
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
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;
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;
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
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
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);
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  argc--;
2604  }
2605 
2606  ret = io_getpartial(argc, argv, io, 1, no_exception);
2607 
2608  if (NIL_P(ret)) {
2609  if (no_exception)
2610  return Qnil;
2611  else
2612  rb_eof_error();
2613  }
2614  return ret;
2615 }
2616 
2617 static VALUE
2618 io_write_nonblock(VALUE io, VALUE str, int no_exception)
2619 {
2620  rb_io_t *fptr;
2621  long n;
2622 
2623  if (!RB_TYPE_P(str, T_STRING))
2624  str = rb_obj_as_string(str);
2625 
2626  io = GetWriteIO(io);
2627  GetOpenFile(io, fptr);
2628  rb_io_check_writable(fptr);
2629 
2630  if (io_fflush(fptr) < 0)
2631  rb_sys_fail(0);
2632 
2633  rb_io_set_nonblock(fptr);
2634  n = write(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
2635 
2636  if (n == -1) {
2637  if (errno == EWOULDBLOCK || errno == EAGAIN) {
2638  if (no_exception) {
2639  return ID2SYM(rb_intern("wait_writable"));
2640  } else {
2641  rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "write would block");
2642  }
2643  }
2644  rb_sys_fail_path(fptr->pathv);
2645  }
2646 
2647  return LONG2FIX(n);
2648 }
2649 
2650 /*
2651  * call-seq:
2652  * ios.write_nonblock(string) -> integer
2653  * ios.write_nonblock(string [, options]) -> integer
2654  *
2655  * Writes the given string to <em>ios</em> using
2656  * the write(2) system call after O_NONBLOCK is set for
2657  * the underlying file descriptor.
2658  *
2659  * It returns the number of bytes written.
2660  *
2661  * write_nonblock just calls the write(2) system call.
2662  * It causes all errors the write(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc.
2663  * The result may also be smaller than string.length (partial write).
2664  * The caller should care such errors and partial write.
2665  *
2666  * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN,
2667  * it is extended by IO::WaitWritable.
2668  * So IO::WaitWritable can be used to rescue the exceptions for retrying write_nonblock.
2669  *
2670  * # Creates a pipe.
2671  * r, w = IO.pipe
2672  *
2673  * # write_nonblock writes only 65536 bytes and return 65536.
2674  * # (The pipe size is 65536 bytes on this environment.)
2675  * s = "a" * 100000
2676  * p w.write_nonblock(s) #=> 65536
2677  *
2678  * # write_nonblock cannot write a byte and raise EWOULDBLOCK (EAGAIN).
2679  * p w.write_nonblock("b") # Resource temporarily unavailable (Errno::EAGAIN)
2680  *
2681  * If the write buffer is not empty, it is flushed at first.
2682  *
2683  * When write_nonblock raises an exception kind of IO::WaitWritable,
2684  * write_nonblock should not be called
2685  * until io is writable for avoiding busy loop.
2686  * This can be done as follows.
2687  *
2688  * begin
2689  * result = io.write_nonblock(string)
2690  * rescue IO::WaitWritable, Errno::EINTR
2691  * IO.select(nil, [io])
2692  * retry
2693  * end
2694  *
2695  * Note that this doesn't guarantee to write all data in string.
2696  * The length written is reported as result and it should be checked later.
2697  *
2698  * On some platforms such as Windows, write_nonblock is not supported
2699  * according to the kind of the IO object.
2700  * In such cases, write_nonblock raises <code>Errno::EBADF</code>.
2701  *
2702  * By specifying `exception: false`, the options hash allows you to indicate
2703  * that write_nonblock should not raise an IO::WaitWritable exception, but
2704  * return the symbol :wait_writable instead.
2705  *
2706  */
2707 
2708 static VALUE
2710 {
2711  VALUE str;
2712  VALUE opts = Qnil;
2713  int no_exceptions = 0;
2714 
2715  rb_scan_args(argc, argv, "10:", &str, &opts);
2716 
2717  if (!NIL_P(opts) && Qfalse == rb_hash_aref(opts, sym_exception))
2718  no_exceptions = 1;
2719 
2720  return io_write_nonblock(io, str, no_exceptions);
2721 }
2722 
2723 /*
2724  * call-seq:
2725  * ios.read([length [, outbuf]]) -> string, outbuf, or nil
2726  *
2727  * Reads <i>length</i> bytes from the I/O stream.
2728  *
2729  * <i>length</i> must be a non-negative integer or <code>nil</code>.
2730  *
2731  * If <i>length</i> is a positive integer,
2732  * it try to read <i>length</i> bytes without any conversion (binary mode).
2733  * It returns <code>nil</code> or a string whose length is 1 to <i>length</i> bytes.
2734  * <code>nil</code> means it met EOF at beginning.
2735  * The 1 to <i>length</i>-1 bytes string means it met EOF after reading the result.
2736  * The <i>length</i> bytes string means it doesn't meet EOF.
2737  * The resulted string is always ASCII-8BIT encoding.
2738  *
2739  * If <i>length</i> is omitted or is <code>nil</code>,
2740  * it reads until EOF and the encoding conversion is applied.
2741  * It returns a string even if EOF is met at beginning.
2742  *
2743  * If <i>length</i> is zero, it returns <code>""</code>.
2744  *
2745  * If the optional <i>outbuf</i> argument is present, it must reference
2746  * a String, which will receive the data.
2747  * The <i>outbuf</i> will contain only the received data after the method call
2748  * even if it is not empty at the beginning.
2749  *
2750  * At end of file, it returns <code>nil</code> or <code>""</code>
2751  * depend on <i>length</i>.
2752  * <code><i>ios</i>.read()</code> and
2753  * <code><i>ios</i>.read(nil)</code> returns <code>""</code>.
2754  * <code><i>ios</i>.read(<i>positive-integer</i>)</code> returns <code>nil</code>.
2755  *
2756  * f = File.new("testfile")
2757  * f.read(16) #=> "This is line one"
2758  *
2759  * # reads whole file
2760  * open("file") {|f|
2761  * data = f.read # This returns a string even if the file is empty.
2762  * ...
2763  * }
2764  *
2765  * # iterate over fixed length records.
2766  * open("fixed-record-file") {|f|
2767  * while record = f.read(256)
2768  * ...
2769  * end
2770  * }
2771  *
2772  * # iterate over variable length records.
2773  * # record is prefixed by 32-bit length.
2774  * open("variable-record-file") {|f|
2775  * while len = f.read(4)
2776  * len = len.unpack("N")[0] # 32-bit length
2777  * record = f.read(len) # This returns a string even if len is 0.
2778  * end
2779  * }
2780  *
2781  * Note that this method behaves like fread() function in C.
2782  * This means it retry to invoke read(2) system call to read data with the specified length (or until EOF).
2783  * This behavior is preserved even if <i>ios</i> is non-blocking mode.
2784  * (This method is non-blocking flag insensitive as other methods.)
2785  * If you need the behavior like single read(2) system call,
2786  * consider readpartial, read_nonblock and sysread.
2787  */
2788 
2789 static VALUE
2791 {
2792  rb_io_t *fptr;
2793  long n, len;
2794  VALUE length, str;
2795 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
2796  int previous_mode;
2797 #endif
2798 
2799  rb_scan_args(argc, argv, "02", &length, &str);
2800 
2801  if (NIL_P(length)) {
2802  GetOpenFile(io, fptr);
2804  return read_all(fptr, remain_size(fptr), str);
2805  }
2806  len = NUM2LONG(length);
2807  if (len < 0) {
2808  rb_raise(rb_eArgError, "negative length %ld given", len);
2809  }
2810 
2811  io_setstrbuf(&str,len);
2812 
2813  GetOpenFile(io, fptr);
2815  if (len == 0) {
2816  io_set_read_length(str, 0);
2817  return str;
2818  }
2819 
2820  READ_CHECK(fptr);
2821 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
2822  previous_mode = set_binary_mode_with_seek_cur(fptr);
2823 #endif
2824  n = io_fread(str, 0, len, fptr);
2825  io_set_read_length(str, n);
2826 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
2827  if (previous_mode == O_TEXT) {
2828  setmode(fptr->fd, O_TEXT);
2829  }
2830 #endif
2831  if (n == 0) return Qnil;
2832  OBJ_TAINT(str);
2833 
2834  return str;
2835 }
2836 
2837 static void
2838 rscheck(const char *rsptr, long rslen, VALUE rs)
2839 {
2840  if (!rs) return;
2841  if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
2842  rb_raise(rb_eRuntimeError, "rs modified");
2843 }
2844 
2845 static int
2846 appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
2847 {
2848  VALUE str = *strp;
2849  long limit = *lp;
2850 
2851  if (NEED_READCONV(fptr)) {
2852  SET_BINARY_MODE(fptr);
2853  make_readconv(fptr, 0);
2854  do {
2855  const char *p, *e;
2856  int searchlen = READ_CHAR_PENDING_COUNT(fptr);
2857  if (searchlen) {
2858  p = READ_CHAR_PENDING_PTR(fptr);
2859  if (0 < limit && limit < searchlen)
2860  searchlen = (int)limit;
2861  e = memchr(p, delim, searchlen);
2862  if (e) {
2863  int len = (int)(e-p+1);
2864  if (NIL_P(str))
2865  *strp = str = rb_str_new(p, len);
2866  else
2867  rb_str_buf_cat(str, p, len);
2868  fptr->cbuf.off += len;
2869  fptr->cbuf.len -= len;
2870  limit -= len;
2871  *lp = limit;
2872  return delim;
2873  }
2874 
2875  if (NIL_P(str))
2876  *strp = str = rb_str_new(p, searchlen);
2877  else
2878  rb_str_buf_cat(str, p, searchlen);
2879  fptr->cbuf.off += searchlen;
2880  fptr->cbuf.len -= searchlen;
2881  limit -= searchlen;
2882 
2883  if (limit == 0) {
2884  *lp = limit;
2885  return (unsigned char)RSTRING_PTR(str)[RSTRING_LEN(str)-1];
2886  }
2887  }
2888  } while (more_char(fptr) != MORE_CHAR_FINISHED);
2889  clear_readconv(fptr);
2890  *lp = limit;
2891  return EOF;
2892  }
2893 
2895  do {
2896  long pending = READ_DATA_PENDING_COUNT(fptr);
2897  if (pending > 0) {
2898  const char *p = READ_DATA_PENDING_PTR(fptr);
2899  const char *e;
2900  long last;
2901 
2902  if (limit > 0 && pending > limit) pending = limit;
2903  e = memchr(p, delim, pending);
2904  if (e) pending = e - p + 1;
2905  if (!NIL_P(str)) {
2906  last = RSTRING_LEN(str);
2907  rb_str_resize(str, last + pending);
2908  }
2909  else {
2910  last = 0;
2911  *strp = str = rb_str_buf_new(pending);
2912  rb_str_set_len(str, pending);
2913  }
2914  read_buffered_data(RSTRING_PTR(str) + last, pending, fptr); /* must not fail */
2915  limit -= pending;
2916  *lp = limit;
2917  if (e) return delim;
2918  if (limit == 0)
2919  return (unsigned char)RSTRING_PTR(str)[RSTRING_LEN(str)-1];
2920  }
2921  READ_CHECK(fptr);
2922  } while (io_fillbuf(fptr) >= 0);
2923  *lp = limit;
2924  return EOF;
2925 }
2926 
2927 static inline int
2928 swallow(rb_io_t *fptr, int term)
2929 {
2930  if (NEED_READCONV(fptr)) {
2931  rb_encoding *enc = io_read_encoding(fptr);
2932  int needconv = rb_enc_mbminlen(enc) != 1;
2933  SET_BINARY_MODE(fptr);
2934  make_readconv(fptr, 0);
2935  do {
2936  size_t cnt;
2937  while ((cnt = READ_CHAR_PENDING_COUNT(fptr)) > 0) {
2938  const char *p = READ_CHAR_PENDING_PTR(fptr);
2939  int i;
2940  if (!needconv) {
2941  if (*p != term) return TRUE;
2942  i = (int)cnt;
2943  while (--i && *++p == term);
2944  }
2945  else {
2946  const char *e = p + cnt;
2947  if (rb_enc_ascget(p, e, &i, enc) != term) return TRUE;
2948  while ((p += i) < e && rb_enc_ascget(p, e, &i, enc) == term);
2949  i = (int)(e - p);
2950  }
2951  io_shift_cbuf(fptr, (int)cnt - i, NULL);
2952  }
2953  } while (more_char(fptr) != MORE_CHAR_FINISHED);
2954  return FALSE;
2955  }
2956 
2958  do {
2959  size_t cnt;
2960  while ((cnt = READ_DATA_PENDING_COUNT(fptr)) > 0) {
2961  char buf[1024];
2962  const char *p = READ_DATA_PENDING_PTR(fptr);
2963  int i;
2964  if (cnt > sizeof buf) cnt = sizeof buf;
2965  if (*p != term) return TRUE;
2966  i = (int)cnt;
2967  while (--i && *++p == term);
2968  if (!read_buffered_data(buf, cnt - i, fptr)) /* must not fail */
2969  rb_sys_fail_path(fptr->pathv);
2970  }
2971  READ_CHECK(fptr);
2972  } while (io_fillbuf(fptr) == 0);
2973  return FALSE;
2974 }
2975 
2976 static VALUE
2978 {
2979  VALUE str = Qnil;
2980  int len = 0;
2981  long pos = 0;
2982  int cr = 0;
2983 
2984  do {
2985  int pending = READ_DATA_PENDING_COUNT(fptr);
2986 
2987  if (pending > 0) {
2988  const char *p = READ_DATA_PENDING_PTR(fptr);
2989  const char *e;
2990 
2991  e = memchr(p, '\n', pending);
2992  if (e) {
2993  pending = (int)(e - p + 1);
2994  }
2995  if (NIL_P(str)) {
2996  str = rb_str_new(p, pending);
2997  fptr->rbuf.off += pending;
2998  fptr->rbuf.len -= pending;
2999  }
3000  else {
3001  rb_str_resize(str, len + pending);
3002  read_buffered_data(RSTRING_PTR(str)+len, pending, fptr);
3003  }
3004  len += pending;
3005  if (cr != ENC_CODERANGE_BROKEN)
3006  pos += rb_str_coderange_scan_restartable(RSTRING_PTR(str) + pos, RSTRING_PTR(str) + len, enc, &cr);
3007  if (e) break;
3008  }
3009  READ_CHECK(fptr);
3010  } while (io_fillbuf(fptr) >= 0);
3011  if (NIL_P(str)) return Qnil;
3012 
3013  str = io_enc_str(str, fptr);
3014  ENC_CODERANGE_SET(str, cr);
3015  fptr->lineno++;
3016  if (io == ARGF.current_file) {
3017  ARGF.lineno++;
3018  ARGF.last_lineno = ARGF.lineno;
3019  }
3020  else {
3021  ARGF.last_lineno = fptr->lineno;
3022  }
3023 
3024  return str;
3025 }
3026 
3027 static void
3028 prepare_getline_args(int argc, VALUE *argv, VALUE *rsp, long *limit, VALUE io)
3029 {
3030  VALUE rs = rb_rs, lim = Qnil;
3031  rb_io_t *fptr;
3032 
3033  if (argc == 1) {
3034  VALUE tmp = Qnil;
3035 
3036  if (NIL_P(argv[0]) || !NIL_P(tmp = rb_check_string_type(argv[0]))) {
3037  rs = tmp;
3038  }
3039  else {
3040  lim = argv[0];
3041  }
3042  }
3043  else if (2 <= argc) {
3044  rb_scan_args(argc, argv, "2", &rs, &lim);
3045  if (!NIL_P(rs))
3046  StringValue(rs);
3047  }
3048  if (!NIL_P(rs)) {
3049  rb_encoding *enc_rs, *enc_io;
3050 
3051  GetOpenFile(io, fptr);
3052  enc_rs = rb_enc_get(rs);
3053  enc_io = io_read_encoding(fptr);
3054  if (enc_io != enc_rs &&
3056  (RSTRING_LEN(rs) > 0 && !rb_enc_asciicompat(enc_io)))) {
3057  if (rs == rb_default_rs) {
3058  rs = rb_enc_str_new(0, 0, enc_io);
3059  rb_str_buf_cat_ascii(rs, "\n");
3060  }
3061  else {
3062  rb_raise(rb_eArgError, "encoding mismatch: %s IO with %s RS",
3063  rb_enc_name(enc_io),
3064  rb_enc_name(enc_rs));
3065  }
3066  }
3067  }
3068  *rsp = rs;
3069  *limit = NIL_P(lim) ? -1L : NUM2LONG(lim);
3070 }
3071 
3072 static VALUE
3073 rb_io_getline_1(VALUE rs, long limit, VALUE io)
3074 {
3075  VALUE str = Qnil;
3076  rb_io_t *fptr;
3077  int nolimit = 0;
3078  rb_encoding *enc;
3079 
3080  GetOpenFile(io, fptr);
3082  if (NIL_P(rs) && limit < 0) {
3083  str = read_all(fptr, 0, Qnil);
3084  if (RSTRING_LEN(str) == 0) return Qnil;
3085  }
3086  else if (limit == 0) {
3087  return rb_enc_str_new(0, 0, io_read_encoding(fptr));
3088  }
3089  else if (rs == rb_default_rs && limit < 0 && !NEED_READCONV(fptr) &&
3090  rb_enc_asciicompat(enc = io_read_encoding(fptr))) {
3092  return rb_io_getline_fast(fptr, enc, io);
3093  }
3094  else {
3095  int c, newline = -1;
3096  const char *rsptr = 0;
3097  long rslen = 0;
3098  int rspara = 0;
3099  int extra_limit = 16;
3100 
3101  SET_BINARY_MODE(fptr);
3102  enc = io_read_encoding(fptr);
3103 
3104  if (!NIL_P(rs)) {
3105  rslen = RSTRING_LEN(rs);
3106  if (rslen == 0) {
3107  rsptr = "\n\n";
3108  rslen = 2;
3109  rspara = 1;
3110  swallow(fptr, '\n');
3111  rs = 0;
3112  if (!rb_enc_asciicompat(enc)) {
3113  rs = rb_usascii_str_new(rsptr, rslen);
3114  rs = rb_str_encode(rs, rb_enc_from_encoding(enc), 0, Qnil);
3115  OBJ_FREEZE(rs);
3116  rsptr = RSTRING_PTR(rs);
3117  rslen = RSTRING_LEN(rs);
3118  }
3119  }
3120  else {
3121  rsptr = RSTRING_PTR(rs);
3122  }
3123  newline = (unsigned char)rsptr[rslen - 1];
3124  }
3125 
3126  /* MS - Optimisation */
3127  while ((c = appendline(fptr, newline, &str, &limit)) != EOF) {
3128  const char *s, *p, *pp, *e;
3129 
3130  if (c == newline) {
3131  if (RSTRING_LEN(str) < rslen) continue;
3132  s = RSTRING_PTR(str);
3133  e = RSTRING_END(str);
3134  p = e - rslen;
3135  pp = rb_enc_left_char_head(s, p, e, enc);
3136  if (pp != p) continue;
3137  if (!rspara) rscheck(rsptr, rslen, rs);
3138  if (memcmp(p, rsptr, rslen) == 0) break;
3139  }
3140  if (limit == 0) {
3141  s = RSTRING_PTR(str);
3142  p = RSTRING_END(str);
3143  pp = rb_enc_left_char_head(s, p-1, p, enc);
3144  if (extra_limit &&
3146  /* relax the limit while incomplete character.
3147  * extra_limit limits the relax length */
3148  limit = 1;
3149  extra_limit--;
3150  }
3151  else {
3152  nolimit = 1;
3153  break;
3154  }
3155  }
3156  }
3157 
3158  if (rspara && c != EOF)
3159  swallow(fptr, '\n');
3160  if (!NIL_P(str))
3161  str = io_enc_str(str, fptr);
3162  }
3163 
3164  if (!NIL_P(str) && !nolimit) {
3165  fptr->lineno++;
3166  if (io == ARGF.current_file) {
3167  ARGF.lineno++;
3168  ARGF.last_lineno = ARGF.lineno;
3169  }
3170  else {
3171  ARGF.last_lineno = fptr->lineno;
3172  }
3173  }
3174 
3175  return str;
3176 }
3177 
3178 static VALUE
3180 {
3181  VALUE rs;
3182  long limit;
3183 
3184  prepare_getline_args(argc, argv, &rs, &limit, io);
3185  return rb_io_getline_1(rs, limit, io);
3186 }
3187 
3188 VALUE
3190 {
3191  return rb_io_getline_1(rb_default_rs, -1, io);
3192 }
3193 
3194 /*
3195  * call-seq:
3196  * ios.gets(sep=$/) -> string or nil
3197  * ios.gets(limit) -> string or nil
3198  * ios.gets(sep, limit) -> string or nil
3199  *
3200  * Reads the next ``line'' from the I/O stream; lines are separated by
3201  * <i>sep</i>. A separator of <code>nil</code> reads the entire
3202  * contents, and a zero-length separator reads the input a paragraph at
3203  * a time (two successive newlines in the input separate paragraphs).
3204  * The stream must be opened for reading or an <code>IOError</code>
3205  * will be raised. The line read in will be returned and also assigned
3206  * to <code>$_</code>. Returns <code>nil</code> if called at end of
3207  * file. If the first argument is an integer, or optional second
3208  * argument is given, the returning string would not be longer than the
3209  * given value in bytes.
3210  *
3211  * File.new("testfile").gets #=> "This is line one\n"
3212  * $_ #=> "This is line one\n"
3213  */
3214 
3215 static VALUE
3217 {
3218  VALUE str;
3219 
3220  str = rb_io_getline(argc, argv, io);
3221  rb_lastline_set(str);
3222 
3223  return str;
3224 }
3225 
3226 /*
3227  * call-seq:
3228  * ios.lineno -> integer
3229  *
3230  * Returns the current line number in <em>ios</em>. The stream must be
3231  * opened for reading. <code>lineno</code> counts the number of times
3232  * #gets is called rather than the number of newlines encountered. The two
3233  * values will differ if #gets is called with a separator other than newline.
3234  *
3235  * Methods that use <code>$/</code> like #each, #lines and #readline will
3236  * also increment <code>lineno</code>.
3237  *
3238  * See also the <code>$.</code> variable.
3239  *
3240  * f = File.new("testfile")
3241  * f.lineno #=> 0
3242  * f.gets #=> "This is line one\n"
3243  * f.lineno #=> 1
3244  * f.gets #=> "This is line two\n"
3245  * f.lineno #=> 2
3246  */
3247 
3248 static VALUE
3250 {
3251  rb_io_t *fptr;
3252 
3253  GetOpenFile(io, fptr);
3255  return INT2NUM(fptr->lineno);
3256 }
3257 
3258 /*
3259  * call-seq:
3260  * ios.lineno = integer -> integer
3261  *
3262  * Manually sets the current line number to the given value.
3263  * <code>$.</code> is updated only on the next read.
3264  *
3265  * f = File.new("testfile")
3266  * f.gets #=> "This is line one\n"
3267  * $. #=> 1
3268  * f.lineno = 1000
3269  * f.lineno #=> 1000
3270  * $. #=> 1 # lineno of last read
3271  * f.gets #=> "This is line two\n"
3272  * $. #=> 1001 # lineno of last read
3273  */
3274 
3275 static VALUE
3277 {
3278  rb_io_t *fptr;
3279 
3280  GetOpenFile(io, fptr);
3282  fptr->lineno = NUM2INT(lineno);
3283  return lineno;
3284 }
3285 
3286 /*
3287  * call-seq:
3288  * ios.readline(sep=$/) -> string
3289  * ios.readline(limit) -> string
3290  * ios.readline(sep, limit) -> string
3291  *
3292  * Reads a line as with <code>IO#gets</code>, but raises an
3293  * <code>EOFError</code> on end of file.
3294  */
3295 
3296 static VALUE
3298 {
3299  VALUE line = rb_io_gets_m(argc, argv, io);
3300 
3301  if (NIL_P(line)) {
3302  rb_eof_error();
3303  }
3304  return line;
3305 }
3306 
3307 /*
3308  * call-seq:
3309  * ios.readlines(sep=$/) -> array
3310  * ios.readlines(limit) -> array
3311  * ios.readlines(sep, limit) -> array
3312  *
3313  * Reads all of the lines in <em>ios</em>, and returns them in
3314  * <i>anArray</i>. Lines are separated by the optional <i>sep</i>. If
3315  * <i>sep</i> is <code>nil</code>, the rest of the stream is returned
3316  * as a single record. If the first argument is an integer, or
3317  * optional second argument is given, the returning string would not be
3318  * longer than the given value in bytes. The stream must be opened for
3319  * reading or an <code>IOError</code> will be raised.
3320  *
3321  * f = File.new("testfile")
3322  * f.readlines[0] #=> "This is line one\n"
3323  */
3324 
3325 static VALUE
3327 {
3328  VALUE line, ary, rs;
3329  long limit;
3330 
3331  prepare_getline_args(argc, argv, &rs, &limit, io);
3332  if (limit == 0)
3333  rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
3334  ary = rb_ary_new();
3335  while (!NIL_P(line = rb_io_getline_1(rs, limit, io))) {
3336  rb_ary_push(ary, line);
3337  }
3338  return ary;
3339 }
3340 
3341 /*
3342  * call-seq:
3343  * ios.each(sep=$/) {|line| block } -> ios
3344  * ios.each(limit) {|line| block } -> ios
3345  * ios.each(sep,limit) {|line| block } -> ios
3346  * ios.each(...) -> an_enumerator
3347  *
3348  * ios.each_line(sep=$/) {|line| block } -> ios
3349  * ios.each_line(limit) {|line| block } -> ios
3350  * ios.each_line(sep,limit) {|line| block } -> ios
3351  * ios.each_line(...) -> an_enumerator
3352  *
3353  * Executes the block for every line in <em>ios</em>, where lines are
3354  * separated by <i>sep</i>. <em>ios</em> must be opened for
3355  * reading or an <code>IOError</code> will be raised.
3356  *
3357  * If no block is given, an enumerator is returned instead.
3358  *
3359  * f = File.new("testfile")
3360  * f.each {|line| puts "#{f.lineno}: #{line}" }
3361  *
3362  * <em>produces:</em>
3363  *
3364  * 1: This is line one
3365  * 2: This is line two
3366  * 3: This is line three
3367  * 4: And so on...
3368  */
3369 
3370 static VALUE
3372 {
3373  VALUE str, rs;
3374  long limit;
3375 
3376  RETURN_ENUMERATOR(io, argc, argv);
3377  prepare_getline_args(argc, argv, &rs, &limit, io);
3378  if (limit == 0)
3379  rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
3380  while (!NIL_P(str = rb_io_getline_1(rs, limit, io))) {
3381  rb_yield(str);
3382  }
3383  return io;
3384 }
3385 
3386 /*
3387  * This is a deprecated alias for <code>each_line</code>.
3388  */
3389 
3390 static VALUE
3392 {
3393  rb_warn("IO#lines is deprecated; use #each_line instead");
3394  if (!rb_block_given_p())
3395  return rb_enumeratorize(io, ID2SYM(rb_intern("each_line")), argc, argv);
3396  return rb_io_each_line(argc, argv, io);
3397 }
3398 
3399 /*
3400  * call-seq:
3401  * ios.each_byte {|byte| block } -> ios
3402  * ios.each_byte -> an_enumerator
3403  *
3404  * Calls the given block once for each byte (0..255) in <em>ios</em>,
3405  * passing the byte as an argument. The stream must be opened for
3406  * reading or an <code>IOError</code> will be raised.
3407  *
3408  * If no block is given, an enumerator is returned instead.
3409  *
3410  * f = File.new("testfile")
3411  * checksum = 0
3412  * f.each_byte {|x| checksum ^= x } #=> #<File:testfile>
3413  * checksum #=> 12
3414  */
3415 
3416 static VALUE
3418 {
3419  rb_io_t *fptr;
3420 
3421  RETURN_ENUMERATOR(io, 0, 0);
3422  GetOpenFile(io, fptr);
3423 
3424  do {
3425  while (fptr->rbuf.len > 0) {
3426  char *p = fptr->rbuf.ptr + fptr->rbuf.off++;
3427  fptr->rbuf.len--;
3428  rb_yield(INT2FIX(*p & 0xff));
3429  errno = 0;
3430  }
3432  READ_CHECK(fptr);
3433  } while (io_fillbuf(fptr) >= 0);
3434  return io;
3435 }
3436 
3437 /*
3438  * This is a deprecated alias for <code>each_byte</code>.
3439  */
3440 
3441 static VALUE
3443 {
3444  rb_warn("IO#bytes is deprecated; use #each_byte instead");
3445  if (!rb_block_given_p())
3446  return rb_enumeratorize(io, ID2SYM(rb_intern("each_byte")), 0, 0);
3447  return rb_io_each_byte(io);
3448 }
3449 
3450 static VALUE
3452 {
3453  int r, n, cr = 0;
3454  VALUE str;
3455 
3456  if (NEED_READCONV(fptr)) {
3457  VALUE str = Qnil;
3458  rb_encoding *read_enc = io_read_encoding(fptr);
3459 
3460  SET_BINARY_MODE(fptr);
3461  make_readconv(fptr, 0);
3462 
3463  while (1) {
3464  if (fptr->cbuf.len) {
3465  r = rb_enc_precise_mbclen(fptr->cbuf.ptr+fptr->cbuf.off,
3466  fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
3467  read_enc);
3468  if (!MBCLEN_NEEDMORE_P(r))
3469  break;
3470  if (fptr->cbuf.len == fptr->cbuf.capa) {
3471  rb_raise(rb_eIOError, "too long character");
3472  }
3473  }
3474 
3475  if (more_char(fptr) == MORE_CHAR_FINISHED) {
3476  if (fptr->cbuf.len == 0) {
3477  clear_readconv(fptr);
3478  return Qnil;
3479  }
3480  /* return an unit of an incomplete character just before EOF */
3481  str = rb_enc_str_new(fptr->cbuf.ptr+fptr->cbuf.off, 1, read_enc);
3482  fptr->cbuf.off += 1;
3483  fptr->cbuf.len -= 1;
3484  if (fptr->cbuf.len == 0) clear_readconv(fptr);
3486  return str;
3487  }
3488  }
3489  if (MBCLEN_INVALID_P(r)) {
3490  r = rb_enc_mbclen(fptr->cbuf.ptr+fptr->cbuf.off,
3491  fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
3492  read_enc);
3493  io_shift_cbuf(fptr, r, &str);
3494  cr = ENC_CODERANGE_BROKEN;
3495  }
3496  else {
3497  io_shift_cbuf(fptr, MBCLEN_CHARFOUND_LEN(r), &str);
3498  cr = ENC_CODERANGE_VALID;
3499  if (MBCLEN_CHARFOUND_LEN(r) == 1 && rb_enc_asciicompat(read_enc) &&
3500  ISASCII(RSTRING_PTR(str)[0])) {
3501  cr = ENC_CODERANGE_7BIT;
3502  }
3503  }
3504  str = io_enc_str(str, fptr);
3505  ENC_CODERANGE_SET(str, cr);
3506  return str;
3507  }
3508 
3510  if (io_fillbuf(fptr) < 0) {
3511  return Qnil;
3512  }
3513  if (rb_enc_asciicompat(enc) && ISASCII(fptr->rbuf.ptr[fptr->rbuf.off])) {
3514  str = rb_str_new(fptr->rbuf.ptr+fptr->rbuf.off, 1);
3515  fptr->rbuf.off += 1;
3516  fptr->rbuf.len -= 1;
3517  cr = ENC_CODERANGE_7BIT;
3518  }
3519  else {
3520  r = rb_enc_precise_mbclen(fptr->rbuf.ptr+fptr->rbuf.off, fptr->rbuf.ptr+fptr->rbuf.off+fptr->rbuf.len, enc);
3521  if (MBCLEN_CHARFOUND_P(r) &&
3522  (n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf.len) {
3523  str = rb_str_new(fptr->rbuf.ptr+fptr->rbuf.off, n);
3524  fptr->rbuf.off += n;
3525  fptr->rbuf.len -= n;
3526  cr = ENC_CODERANGE_VALID;
3527  }
3528  else if (MBCLEN_NEEDMORE_P(r)) {
3529  str = rb_str_new(fptr->rbuf.ptr+fptr->rbuf.off, fptr->rbuf.len);
3530  fptr->rbuf.len = 0;
3531  getc_needmore:
3532  if (io_fillbuf(fptr) != -1) {
3533  rb_str_cat(str, fptr->rbuf.ptr+fptr->rbuf.off, 1);
3534  fptr->rbuf.off++;
3535  fptr->rbuf.len--;
3536  r = rb_enc_precise_mbclen(RSTRING_PTR(str), RSTRING_PTR(str)+RSTRING_LEN(str), enc);
3537  if (MBCLEN_NEEDMORE_P(r)) {
3538  goto getc_needmore;
3539  }
3540  else if (MBCLEN_CHARFOUND_P(r)) {
3541  cr = ENC_CODERANGE_VALID;
3542  }
3543  }
3544  }
3545  else {
3546  str = rb_str_new(fptr->rbuf.ptr+fptr->rbuf.off, 1);
3547  fptr->rbuf.off++;
3548  fptr->rbuf.len--;
3549  }
3550  }
3551  if (!cr) cr = ENC_CODERANGE_BROKEN;
3552  str = io_enc_str(str, fptr);
3553  ENC_CODERANGE_SET(str, cr);
3554  return str;
3555 }
3556 
3557 /*
3558  * call-seq:
3559  * ios.each_char {|c| block } -> ios
3560  * ios.each_char -> an_enumerator
3561  *
3562  * Calls the given block once for each character in <em>ios</em>,
3563  * passing the character as an argument. The stream must be opened for
3564  * reading or an <code>IOError</code> will be raised.
3565  *
3566  * If no block is given, an enumerator is returned instead.
3567  *
3568  * f = File.new("testfile")
3569  * f.each_char {|c| print c, ' ' } #=> #<File:testfile>
3570  */
3571 
3572 static VALUE
3574 {
3575  rb_io_t *fptr;
3576  rb_encoding *enc;
3577  VALUE c;
3578 
3579  RETURN_ENUMERATOR(io, 0, 0);
3580  GetOpenFile(io, fptr);
3582 
3583  enc = io_input_encoding(fptr);
3584  READ_CHECK(fptr);
3585  while (!NIL_P(c = io_getc(fptr, enc))) {
3586  rb_yield(c);
3587  }
3588  return io;
3589 }
3590 
3591 /*
3592  * This is a deprecated alias for <code>each_char</code>.
3593  */
3594 
3595 static VALUE
3597 {
3598  rb_warn("IO#chars is deprecated; use #each_char instead");
3599  if (!rb_block_given_p())
3600  return rb_enumeratorize(io, ID2SYM(rb_intern("each_char")), 0, 0);
3601  return rb_io_each_char(io);
3602 }
3603 
3604 
3605 /*
3606  * call-seq:
3607  * ios.each_codepoint {|c| block } -> ios
3608  * ios.codepoints {|c| block } -> ios
3609  * ios.each_codepoint -> an_enumerator
3610  * ios.codepoints -> an_enumerator
3611  *
3612  * Passes the <code>Integer</code> ordinal of each character in <i>ios</i>,
3613  * passing the codepoint as an argument. The stream must be opened for
3614  * reading or an <code>IOError</code> will be raised.
3615  *
3616  * If no block is given, an enumerator is returned instead.
3617  *
3618  */
3619 
3620 static VALUE
3622 {
3623  rb_io_t *fptr;
3624  rb_encoding *enc;
3625  unsigned int c;
3626  int r, n;
3627 
3628  RETURN_ENUMERATOR(io, 0, 0);
3629  GetOpenFile(io, fptr);
3631 
3632  READ_CHECK(fptr);
3633  if (NEED_READCONV(fptr)) {
3634  SET_BINARY_MODE(fptr);
3635  r = 1; /* no invalid char yet */
3636  for (;;) {
3637  make_readconv(fptr, 0);
3638  for (;;) {
3639  if (fptr->cbuf.len) {
3640  if (fptr->encs.enc)
3641  r = rb_enc_precise_mbclen(fptr->cbuf.ptr+fptr->cbuf.off,
3642  fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
3643  fptr->encs.enc);
3644  else
3646  if (!MBCLEN_NEEDMORE_P(r))
3647  break;
3648  if (fptr->cbuf.len == fptr->cbuf.capa) {
3649  rb_raise(rb_eIOError, "too long character");
3650  }
3651  }
3652  if (more_char(fptr) == MORE_CHAR_FINISHED) {
3653  clear_readconv(fptr);
3654  if (!MBCLEN_CHARFOUND_P(r)) {
3655  enc = fptr->encs.enc;
3656  goto invalid;
3657  }
3658  return io;
3659  }
3660  }
3661  if (MBCLEN_INVALID_P(r)) {
3662  enc = fptr->encs.enc;
3663  goto invalid;
3664  }
3665  n = MBCLEN_CHARFOUND_LEN(r);
3666  if (fptr->encs.enc) {
3667  c = rb_enc_codepoint(fptr->cbuf.ptr+fptr->cbuf.off,
3668  fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
3669  fptr->encs.enc);
3670  }
3671  else {
3672  c = (unsigned char)fptr->cbuf.ptr[fptr->cbuf.off];
3673  }
3674  fptr->cbuf.off += n;
3675  fptr->cbuf.len -= n;
3676  rb_yield(UINT2NUM(c));
3677  }
3678  }
3680  enc = io_input_encoding(fptr);
3681  while (io_fillbuf(fptr) >= 0) {
3682  r = rb_enc_precise_mbclen(fptr->rbuf.ptr+fptr->rbuf.off,
3683  fptr->rbuf.ptr+fptr->rbuf.off+fptr->rbuf.len, enc);
3684  if (MBCLEN_CHARFOUND_P(r) &&
3685  (n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf.len) {
3686  c = rb_enc_codepoint(fptr->rbuf.ptr+fptr->rbuf.off,
3687  fptr->rbuf.ptr+fptr->rbuf.off+fptr->rbuf.len, enc);
3688  fptr->rbuf.off += n;
3689  fptr->rbuf.len -= n;
3690  rb_yield(UINT2NUM(c));
3691  }
3692  else if (MBCLEN_INVALID_P(r)) {
3693  invalid:
3694  rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc));
3695  }
3696  else if (MBCLEN_NEEDMORE_P(r)) {
3697  char cbuf[8], *p = cbuf;
3698  int more = MBCLEN_NEEDMORE_LEN(r);
3699  if (more > numberof(cbuf)) goto invalid;
3700  more += n = fptr->rbuf.len;
3701  if (more > numberof(cbuf)) goto invalid;
3702  while ((n = (int)read_buffered_data(p, more, fptr)) > 0 &&
3703  (p += n, (more -= n) > 0)) {
3704  if (io_fillbuf(fptr) < 0) goto invalid;
3705  if ((n = fptr->rbuf.len) > more) n = more;
3706  }
3707  r = rb_enc_precise_mbclen(cbuf, p, enc);
3708  if (!MBCLEN_CHARFOUND_P(r)) goto invalid;
3709  c = rb_enc_codepoint(cbuf, p, enc);
3710  rb_yield(UINT2NUM(c));
3711  }
3712  else {
3713  continue;
3714  }
3715  }
3716  return io;
3717 }
3718 
3719 /*
3720  * This is a deprecated alias for <code>each_codepoint</code>.
3721  */
3722 
3723 static VALUE
3725 {
3726  rb_warn("IO#codepoints is deprecated; use #each_codepoint instead");
3727  if (!rb_block_given_p())
3728  return rb_enumeratorize(io, ID2SYM(rb_intern("each_codepoint")), 0, 0);
3729  return rb_io_each_codepoint(io);
3730 }
3731 
3732 
3733 /*
3734  * call-seq:
3735  * ios.getc -> string or nil
3736  *
3737  * Reads a one-character string from <em>ios</em>. Returns
3738  * <code>nil</code> if called at end of file.
3739  *
3740  * f = File.new("testfile")
3741  * f.getc #=> "h"
3742  * f.getc #=> "e"
3743  */
3744 
3745 static VALUE
3747 {
3748  rb_io_t *fptr;
3749  rb_encoding *enc;
3750 
3751  GetOpenFile(io, fptr);
3753 
3754  enc = io_input_encoding(fptr);
3755  READ_CHECK(fptr);
3756  return io_getc(fptr, enc);
3757 }
3758 
3759 /*
3760  * call-seq:
3761  * ios.readchar -> string
3762  *
3763  * Reads a one-character string from <em>ios</em>. Raises an
3764  * <code>EOFError</code> on end of file.
3765  *
3766  * f = File.new("testfile")
3767  * f.readchar #=> "h"
3768  * f.readchar #=> "e"
3769  */
3770 
3771 static VALUE
3773 {
3774  VALUE c = rb_io_getc(io);
3775 
3776  if (NIL_P(c)) {
3777  rb_eof_error();
3778  }
3779  return c;
3780 }
3781 
3782 /*
3783  * call-seq:
3784  * ios.getbyte -> fixnum or nil
3785  *
3786  * Gets the next 8-bit byte (0..255) from <em>ios</em>. Returns
3787  * <code>nil</code> if called at end of file.
3788  *
3789  * f = File.new("testfile")
3790  * f.getbyte #=> 84
3791  * f.getbyte #=> 104
3792  */
3793 
3794 VALUE
3796 {
3797  rb_io_t *fptr;
3798  int c;
3799 
3800  GetOpenFile(io, fptr);
3802  READ_CHECK(fptr);
3803  if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && RB_TYPE_P(rb_stdout, T_FILE)) {
3804  rb_io_t *ofp;
3805  GetOpenFile(rb_stdout, ofp);
3806  if (ofp->mode & FMODE_TTY) {
3808  }
3809  }
3810  if (io_fillbuf(fptr) < 0) {
3811  return Qnil;
3812  }
3813  fptr->rbuf.off++;
3814  fptr->rbuf.len--;
3815  c = (unsigned char)fptr->rbuf.ptr[fptr->rbuf.off-1];
3816  return INT2FIX(c & 0xff);
3817 }
3818 
3819 /*
3820  * call-seq:
3821  * ios.readbyte -> fixnum
3822  *
3823  * Reads a byte as with <code>IO#getbyte</code>, but raises an
3824  * <code>EOFError</code> on end of file.
3825  */
3826 
3827 static VALUE
3829 {
3830  VALUE c = rb_io_getbyte(io);
3831 
3832  if (NIL_P(c)) {
3833  rb_eof_error();
3834  }
3835  return c;
3836 }
3837 
3838 /*
3839  * call-seq:
3840  * ios.ungetbyte(string) -> nil
3841  * ios.ungetbyte(integer) -> nil
3842  *
3843  * Pushes back bytes (passed as a parameter) onto <em>ios</em>,
3844  * such that a subsequent buffered read will return it. Only one byte
3845  * may be pushed back before a subsequent read operation (that is,
3846  * you will be able to read only the last of several bytes that have been pushed
3847  * back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).
3848  *
3849  * f = File.new("testfile") #=> #<File:testfile>
3850  * b = f.getbyte #=> 0x38
3851  * f.ungetbyte(b) #=> nil
3852  * f.getbyte #=> 0x38
3853  */
3854 
3855 VALUE
3857 {
3858  rb_io_t *fptr;
3859 
3860  GetOpenFile(io, fptr);
3862  if (NIL_P(b)) return Qnil;
3863  if (FIXNUM_P(b)) {
3864  char cc = FIX2INT(b);
3865  b = rb_str_new(&cc, 1);
3866  }
3867  else {
3868  SafeStringValue(b);
3869  }
3870  io_ungetbyte(b, fptr);
3871  return Qnil;
3872 }
3873 
3874 /*
3875  * call-seq:
3876  * ios.ungetc(string) -> nil
3877  *
3878  * Pushes back one character (passed as a parameter) onto <em>ios</em>,
3879  * such that a subsequent buffered character read will return it. Only one character
3880  * may be pushed back before a subsequent read operation (that is,
3881  * you will be able to read only the last of several characters that have been pushed
3882  * back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).
3883  *
3884  * f = File.new("testfile") #=> #<File:testfile>
3885  * c = f.getc #=> "8"
3886  * f.ungetc(c) #=> nil
3887  * f.getc #=> "8"
3888  */
3889 
3890 VALUE
3892 {
3893  rb_io_t *fptr;
3894  long len;
3895 
3896  GetOpenFile(io, fptr);
3898  if (NIL_P(c)) return Qnil;
3899  if (FIXNUM_P(c)) {
3900  c = rb_enc_uint_chr(FIX2UINT(c), io_read_encoding(fptr));
3901  }
3902  else if (RB_TYPE_P(c, T_BIGNUM)) {
3903  c = rb_enc_uint_chr(NUM2UINT(c), io_read_encoding(fptr));
3904  }
3905  else {
3906  SafeStringValue(c);
3907  }
3908  if (NEED_READCONV(fptr)) {
3909  SET_BINARY_MODE(fptr);
3910  len = RSTRING_LEN(c);
3911 #if SIZEOF_LONG > SIZEOF_INT
3912  if (len > INT_MAX)
3913  rb_raise(rb_eIOError, "ungetc failed");
3914 #endif
3915  make_readconv(fptr, (int)len);
3916  if (fptr->cbuf.capa - fptr->cbuf.len < len)
3917  rb_raise(rb_eIOError, "ungetc failed");
3918  if (fptr->cbuf.off < len) {
3919  MEMMOVE(fptr->cbuf.ptr+fptr->cbuf.capa-fptr->cbuf.len,
3920  fptr->cbuf.ptr+fptr->cbuf.off,
3921  char, fptr->cbuf.len);
3922  fptr->cbuf.off = fptr->cbuf.capa-fptr->cbuf.len;
3923  }
3924  fptr->cbuf.off -= (int)len;
3925  fptr->cbuf.len += (int)len;
3926  MEMMOVE(fptr->cbuf.ptr+fptr->cbuf.off, RSTRING_PTR(c), char, len);
3927  }
3928  else {
3930  io_ungetbyte(c, fptr);
3931  }
3932  return Qnil;
3933 }
3934 
3935 /*
3936  * call-seq:
3937  * ios.isatty -> true or false
3938  * ios.tty? -> true or false
3939  *
3940  * Returns <code>true</code> if <em>ios</em> is associated with a
3941  * terminal device (tty), <code>false</code> otherwise.
3942  *
3943  * File.new("testfile").isatty #=> false
3944  * File.new("/dev/tty").isatty #=> true
3945  */
3946 
3947 static VALUE
3949 {
3950  rb_io_t *fptr;
3951 
3952  GetOpenFile(io, fptr);
3953  if (isatty(fptr->fd) == 0)
3954  return Qfalse;
3955  return Qtrue;
3956 }
3957 
3958 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
3959 /*
3960  * call-seq:
3961  * ios.close_on_exec? -> true or false
3962  *
3963  * Returns <code>true</code> if <em>ios</em> will be closed on exec.
3964  *
3965  * f = open("/dev/null")
3966  * f.close_on_exec? #=> false
3967  * f.close_on_exec = true
3968  * f.close_on_exec? #=> true
3969  * f.close_on_exec = false
3970  * f.close_on_exec? #=> false
3971  */
3972 
3973 static VALUE
3975 {
3976  rb_io_t *fptr;
3977  VALUE write_io;
3978  int fd, ret;
3979 
3980  write_io = GetWriteIO(io);
3981  if (io != write_io) {
3982  GetOpenFile(write_io, fptr);
3983  if (fptr && 0 <= (fd = fptr->fd)) {
3984  if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
3985  if (!(ret & FD_CLOEXEC)) return Qfalse;
3986  }
3987  }
3988 
3989  GetOpenFile(io, fptr);
3990  if (fptr && 0 <= (fd = fptr->fd)) {
3991  if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
3992  if (!(ret & FD_CLOEXEC)) return Qfalse;
3993  }
3994  return Qtrue;
3995 }
3996 #else
3997 #define rb_io_close_on_exec_p rb_f_notimplement
3998 #endif
3999 
4000 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
4001 /*
4002  * call-seq:
4003  * ios.close_on_exec = bool -> true or false
4004  *
4005  * Sets a close-on-exec flag.
4006  *
4007  * f = open("/dev/null")
4008  * f.close_on_exec = true
4009  * system("cat", "/proc/self/fd/#{f.fileno}") # cat: /proc/self/fd/3: No such file or directory
4010  * f.closed? #=> false
4011  *
4012  * Ruby sets close-on-exec flags of all file descriptors by default
4013  * since Ruby 2.0.0.
4014  * So you don't need to set by yourself.
4015  * Also, unsetting a close-on-exec flag can cause file descriptor leak
4016  * if another thread use fork() and exec() (via system() method for example).
4017  * If you really needs file descriptor inheritance to child process,
4018  * use spawn()'s argument such as fd=>fd.
4019  */
4020 
4021 static VALUE
4023 {
4024  int flag = RTEST(arg) ? FD_CLOEXEC : 0;
4025  rb_io_t *fptr;
4026  VALUE write_io;
4027  int fd, ret;
4028 
4029  write_io = GetWriteIO(io);
4030  if (io != write_io) {
4031  GetOpenFile(write_io, fptr);
4032  if (fptr && 0 <= (fd = fptr->fd)) {
4033  if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
4034  if ((ret & FD_CLOEXEC) != flag) {
4035  ret = (ret & ~FD_CLOEXEC) | flag;
4036  ret = fcntl(fd, F_SETFD, ret);
4037  if (ret == -1) rb_sys_fail_path(fptr->pathv);
4038  }
4039  }
4040 
4041  }
4042 
4043  GetOpenFile(io, fptr);
4044  if (fptr && 0 <= (fd = fptr->fd)) {
4045  if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
4046  if ((ret & FD_CLOEXEC) != flag) {
4047  ret = (ret & ~FD_CLOEXEC) | flag;
4048  ret = fcntl(fd, F_SETFD, ret);
4049  if (ret == -1) rb_sys_fail_path(fptr->pathv);
4050  }
4051  }
4052  return Qnil;
4053 }
4054 #else
4055 #define rb_io_set_close_on_exec rb_f_notimplement
4056 #endif
4057 
4058 #define FMODE_PREP (1<<16)
4059 #define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
4060 #define PREP_STDIO_NAME(f) (RSTRING_PTR((f)->pathv))
4061 
4062 static VALUE
4063 finish_writeconv(rb_io_t *fptr, int noalloc)
4064 {
4065  unsigned char *ds, *dp, *de;
4067 
4068  if (!fptr->wbuf.ptr) {
4069  unsigned char buf[1024];
4070  long r;
4071 
4073  while (res == econv_destination_buffer_full) {
4074  ds = dp = buf;
4075  de = buf + sizeof(buf);
4076  res = rb_econv_convert(fptr->writeconv, NULL, NULL, &dp, de, 0);
4077  while (dp-ds) {
4078  retry:
4079  if (fptr->write_lock && rb_mutex_owned_p(fptr->write_lock))
4080  r = rb_write_internal2(fptr->fd, ds, dp-ds);
4081  else
4082  r = rb_write_internal(fptr->fd, ds, dp-ds);
4083  if (r == dp-ds)
4084  break;
4085  if (0 <= r) {
4086  ds += r;
4087  }
4088  if (rb_io_wait_writable(fptr->fd)) {
4089  if (fptr->fd < 0)
4090  return noalloc ? Qtrue : rb_exc_new3(rb_eIOError, rb_str_new_cstr(closed_stream));
4091  goto retry;
4092  }
4093  return noalloc ? Qtrue : INT2NUM(errno);
4094  }
4095  if (res == econv_invalid_byte_sequence ||
4096  res == econv_incomplete_input ||
4097  res == econv_undefined_conversion) {
4098  return noalloc ? Qtrue : rb_econv_make_exception(fptr->writeconv);
4099  }
4100  }
4101 
4102  return Qnil;
4103  }
4104 
4106  while (res == econv_destination_buffer_full) {
4107  if (fptr->wbuf.len == fptr->wbuf.capa) {
4108  if (io_fflush(fptr) < 0)
4109  return noalloc ? Qtrue : INT2NUM(errno);
4110  }
4111 
4112  ds = dp = (unsigned char *)fptr->wbuf.ptr + fptr->wbuf.off + fptr->wbuf.len;
4113  de = (unsigned char *)fptr->wbuf.ptr + fptr->wbuf.capa;
4114  res = rb_econv_convert(fptr->writeconv, NULL, NULL, &dp, de, 0);
4115  fptr->wbuf.len += (int)(dp - ds);
4116  if (res == econv_invalid_byte_sequence ||
4117  res == econv_incomplete_input ||
4118  res == econv_undefined_conversion) {
4119  return noalloc ? Qtrue : rb_econv_make_exception(fptr->writeconv);
4120  }
4121  }
4122  return Qnil;
4123 }
4124 
4127  int noalloc;
4128 };
4129 
4130 static VALUE
4132 {
4133  struct finish_writeconv_arg *p = (struct finish_writeconv_arg *)arg;
4134  return finish_writeconv(p->fptr, p->noalloc);
4135 }
4136 
4137 static void*
4138 nogvl_close(void *ptr)
4139 {
4140  int *fd = ptr;
4141 
4142  return (void*)(intptr_t)close(*fd);
4143 }
4144 
4145 static int
4146 maygvl_close(int fd, int keepgvl)
4147 {
4148  if (keepgvl)
4149  return close(fd);
4150 
4151  /*
4152  * close() may block for certain file types (NFS, SO_LINGER sockets,
4153  * inotify), so let other threads run.
4154  */
4156 }
4157 
4158 static void*
4159 nogvl_fclose(void *ptr)
4160 {
4161  FILE *file = ptr;
4162 
4163  return (void*)(intptr_t)fclose(file);
4164 }
4165 
4166 static int
4167 maygvl_fclose(FILE *file, int keepgvl)
4168 {
4169  if (keepgvl)
4170  return fclose(file);
4171 
4173 }
4174 
4175 static void
4176 fptr_finalize(rb_io_t *fptr, int noraise)
4177 {
4178  VALUE err = Qnil;
4179  int fd = fptr->fd;
4180  FILE *stdio_file = fptr->stdio_file;
4181 
4182  if (fptr->writeconv) {
4183  if (fptr->write_lock && !noraise) {
4184  struct finish_writeconv_arg arg;
4185  arg.fptr = fptr;
4186  arg.noalloc = noraise;
4188  }
4189  else {
4190  err = finish_writeconv(fptr, noraise);
4191  }
4192  }
4193  if (fptr->wbuf.len) {
4194  if (noraise) {
4195  if ((int)io_flush_buffer_sync(fptr) < 0 && NIL_P(err))
4196  err = Qtrue;
4197  }
4198  else {
4199  if (io_fflush(fptr) < 0 && NIL_P(err))
4200  err = INT2NUM(errno);
4201  }
4202  }
4203 
4204  fptr->fd = -1;
4205  fptr->stdio_file = 0;
4206  fptr->mode &= ~(FMODE_READABLE|FMODE_WRITABLE);
4207 
4208  if (IS_PREP_STDIO(fptr) || fd <= 2) {
4209  /* need to keep FILE objects of stdin, stdout and stderr */
4210  }
4211  else if (stdio_file) {
4212  /* stdio_file is deallocated anyway
4213  * even if fclose failed. */
4214  if ((maygvl_fclose(stdio_file, noraise) < 0) && NIL_P(err))
4215  err = noraise ? Qtrue : INT2NUM(errno);
4216  }
4217  else if (0 <= fd) {
4218  /* fptr->fd may be closed even if close fails.
4219  * POSIX doesn't specify it.
4220  * We assumes it is closed. */
4221  if ((maygvl_close(fd, noraise) < 0) && NIL_P(err))
4222  err = noraise ? Qtrue : INT2NUM(errno);
4223  }
4224 
4225  if (!NIL_P(err) && !noraise) {
4226  switch (TYPE(err)) {
4227  case T_FIXNUM:
4228  case T_BIGNUM:
4229  errno = NUM2INT(err);
4230  rb_sys_fail_path(fptr->pathv);
4231 
4232  default:
4233  rb_exc_raise(err);
4234  }
4235  }
4236 }
4237 
4238 static void
4239 rb_io_fptr_cleanup(rb_io_t *fptr, int noraise)
4240 {
4241  if (fptr->finalize) {
4242  (*fptr->finalize)(fptr, noraise);
4243  }
4244  else {
4245  fptr_finalize(fptr, noraise);
4246  }
4247 }
4248 
4249 static void
4251 {
4252  if (fptr->readconv) {
4253  rb_econv_close(fptr->readconv);
4254  fptr->readconv = NULL;
4255  }
4256  if (fptr->cbuf.ptr) {
4257  free(fptr->cbuf.ptr);
4258  fptr->cbuf.ptr = NULL;
4259  }
4260 }
4261 
4262 static void
4264 {
4265  if (fptr->writeconv) {
4266  rb_econv_close(fptr->writeconv);
4267  fptr->writeconv = NULL;
4268  }
4269  fptr->writeconv_initialized = 0;
4270 }
4271 
4272 static void
4274 {
4275  clear_readconv(fptr);
4276  clear_writeconv(fptr);
4277 }
4278 
4279 int
4281 {
4282  if (!fptr) return 0;
4283  fptr->pathv = Qnil;
4284  if (0 <= fptr->fd)
4285  rb_io_fptr_cleanup(fptr, TRUE);
4286  fptr->write_lock = 0;
4287  if (fptr->rbuf.ptr) {
4288  free(fptr->rbuf.ptr);
4289  fptr->rbuf.ptr = 0;
4290  }
4291  if (fptr->wbuf.ptr) {
4292  free(fptr->wbuf.ptr);
4293  fptr->wbuf.ptr = 0;
4294  }
4295  clear_codeconv(fptr);
4296  free(fptr);
4297  return 1;
4298 }
4299 
4300 size_t rb_econv_memsize(rb_econv_t *);
4301 
4302 RUBY_FUNC_EXPORTED size_t
4304 {
4305  size_t size = sizeof(rb_io_t);
4306  size += fptr->rbuf.capa;
4307  size += fptr->wbuf.capa;
4308  size += fptr->cbuf.capa;
4309  if (fptr->readconv) size += rb_econv_memsize(fptr->readconv);
4310  if (fptr->writeconv) size += rb_econv_memsize(fptr->writeconv);
4311  return size;
4312 }
4313 
4314 VALUE
4316 {
4317  rb_io_t *fptr;
4318  int fd;
4319  VALUE write_io;
4320  rb_io_t *write_fptr;
4321 
4322  write_io = GetWriteIO(io);
4323  if (io != write_io) {
4324  write_fptr = RFILE(write_io)->fptr;
4325  if (write_fptr && 0 <= write_fptr->fd) {
4326  rb_io_fptr_cleanup(write_fptr, TRUE);
4327  }
4328  }
4329 
4330  fptr = RFILE(io)->fptr;
4331  if (!fptr) return Qnil;
4332  if (fptr->fd < 0) return Qnil;
4333 
4334  fd = fptr->fd;
4335  rb_thread_fd_close(fd);
4336  rb_io_fptr_cleanup(fptr, FALSE);
4337 
4338  if (fptr->pid) {
4340  rb_syswait(fptr->pid);
4341  fptr->pid = 0;
4342  }
4343 
4344  return Qnil;
4345 }
4346 
4347 /*
4348  * call-seq:
4349  * ios.close -> nil
4350  *
4351  * Closes <em>ios</em> and flushes any pending writes to the operating
4352  * system. The stream is unavailable for any further data operations;
4353  * an <code>IOError</code> is raised if such an attempt is made. I/O
4354  * streams are automatically closed when they are claimed by the
4355  * garbage collector.
4356  *
4357  * If <em>ios</em> is opened by <code>IO.popen</code>,
4358  * <code>close</code> sets <code>$?</code>.
4359  */
4360 
4361 static VALUE
4363 {
4364  rb_io_check_closed(RFILE(io)->fptr);
4365  rb_io_close(io);
4366  return Qnil;
4367 }
4368 
4369 static VALUE
4371 {
4372  rb_check_funcall(io, rb_intern("close"), 0, 0);
4373  return io;
4374 }
4375 
4376 static VALUE
4378 {
4379  enum {mesg_len = sizeof(closed_stream)-1};
4380  VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
4381  if (!RB_TYPE_P(mesg, T_STRING) ||
4382  RSTRING_LEN(mesg) != mesg_len ||
4383  memcmp(RSTRING_PTR(mesg), closed_stream, mesg_len)) {
4384  rb_exc_raise(exc);
4385  }
4386  return io;
4387 }
4388 
4389 static VALUE
4391 {
4392  VALUE closed = rb_check_funcall(io, rb_intern("closed?"), 0, 0);
4393  if (closed != Qundef && RTEST(closed)) return io;
4395  rb_eIOError, (VALUE)0);
4396  return io;
4397 }
4398 
4399 /*
4400  * call-seq:
4401  * ios.closed? -> true or false
4402  *
4403  * Returns <code>true</code> if <em>ios</em> is completely closed (for
4404  * duplex streams, both reader and writer), <code>false</code>
4405  * otherwise.
4406  *
4407  * f = File.new("testfile")
4408  * f.close #=> nil
4409  * f.closed? #=> true
4410  * f = IO.popen("/bin/sh","r+")
4411  * f.close_write #=> nil
4412  * f.closed? #=> false
4413  * f.close_read #=> nil
4414  * f.closed? #=> true
4415  */
4416 
4417 
4418 static VALUE
4420 {
4421  rb_io_t *fptr;
4422  VALUE write_io;
4423  rb_io_t *write_fptr;
4424 
4425  write_io = GetWriteIO(io);
4426  if (io != write_io) {
4427  write_fptr = RFILE(write_io)->fptr;
4428  if (write_fptr && 0 <= write_fptr->fd) {
4429  return Qfalse;
4430  }
4431  }
4432 
4433  fptr = RFILE(io)->fptr;
4435  return 0 <= fptr->fd ? Qfalse : Qtrue;
4436 }
4437 
4438 /*
4439  * call-seq:
4440  * ios.close_read -> nil
4441  *
4442  * Closes the read end of a duplex I/O stream (i.e., one that contains
4443  * both a read and a write stream, such as a pipe). Will raise an
4444  * <code>IOError</code> if the stream is not duplexed.
4445  *
4446  * f = IO.popen("/bin/sh","r+")
4447  * f.close_read
4448  * f.readlines
4449  *
4450  * <em>produces:</em>
4451  *
4452  * prog.rb:3:in `readlines': not opened for reading (IOError)
4453  * from prog.rb:3
4454  */
4455 
4456 static VALUE
4458 {
4459  rb_io_t *fptr;
4460  VALUE write_io;
4461 
4462  GetOpenFile(io, fptr);
4463  if (is_socket(fptr->fd, fptr->pathv)) {
4464 #ifndef SHUT_RD
4465 # define SHUT_RD 0
4466 #endif
4467  if (shutdown(fptr->fd, SHUT_RD) < 0)
4468  rb_sys_fail_path(fptr->pathv);
4469  fptr->mode &= ~FMODE_READABLE;
4470  if (!(fptr->mode & FMODE_WRITABLE))
4471  return rb_io_close(io);
4472  return Qnil;
4473  }
4474 
4475  write_io = GetWriteIO(io);
4476  if (io != write_io) {
4477  rb_io_t *wfptr;
4478  GetOpenFile(write_io, wfptr);
4479  wfptr->pid = fptr->pid;
4480  fptr->pid = 0;
4481  RFILE(io)->fptr = wfptr;
4482  /* bind to write_io temporarily to get rid of memory/fd leak */
4483  fptr->tied_io_for_writing = 0;
4484  fptr->mode &= ~FMODE_DUPLEX;
4485  RFILE(write_io)->fptr = fptr;
4486  rb_io_fptr_cleanup(fptr, FALSE);
4487  /* should not finalize fptr because another thread may be reading it */
4488  return Qnil;
4489  }
4490 
4491  if (fptr->mode & FMODE_WRITABLE) {
4492  rb_raise(rb_eIOError, "closing non-duplex IO for reading");
4493  }
4494  return rb_io_close(io);
4495 }
4496 
4497 /*
4498  * call-seq:
4499  * ios.close_write -> nil
4500  *
4501  * Closes the write end of a duplex I/O stream (i.e., one that contains
4502  * both a read and a write stream, such as a pipe). Will raise an
4503  * <code>IOError</code> if the stream is not duplexed.
4504  *
4505  * f = IO.popen("/bin/sh","r+")
4506  * f.close_write
4507  * f.print "nowhere"
4508  *
4509  * <em>produces:</em>
4510  *
4511  * prog.rb:3:in `write': not opened for writing (IOError)
4512  * from prog.rb:3:in `print'
4513  * from prog.rb:3
4514  */
4515 
4516 static VALUE
4518 {
4519  rb_io_t *fptr;
4520  VALUE write_io;
4521 
4522  write_io = GetWriteIO(io);
4523  GetOpenFile(write_io, fptr);
4524  if (is_socket(fptr->fd, fptr->pathv)) {
4525 #ifndef SHUT_WR
4526 # define SHUT_WR 1
4527 #endif
4528  if (shutdown(fptr->fd, SHUT_WR) < 0)
4529  rb_sys_fail_path(fptr->pathv);
4530  fptr->mode &= ~FMODE_WRITABLE;
4531  if (!(fptr->mode & FMODE_READABLE))
4532  return rb_io_close(write_io);
4533  return Qnil;
4534  }
4535 
4536  if (fptr->mode & FMODE_READABLE) {
4537  rb_raise(rb_eIOError, "closing non-duplex IO for writing");
4538  }
4539 
4540  if (io != write_io) {
4541  GetOpenFile(io, fptr);
4542  fptr->tied_io_for_writing = 0;
4543  fptr->mode &= ~FMODE_DUPLEX;
4544  }
4545  rb_io_close(write_io);
4546  return Qnil;
4547 }
4548 
4549 /*
4550  * call-seq:
4551  * ios.sysseek(offset, whence=IO::SEEK_SET) -> integer
4552  *
4553  * Seeks to a given <i>offset</i> in the stream according to the value
4554  * of <i>whence</i> (see <code>IO#seek</code> for values of
4555  * <i>whence</i>). Returns the new offset into the file.
4556  *
4557  * f = File.new("testfile")
4558  * f.sysseek(-13, IO::SEEK_END) #=> 53
4559  * f.sysread(10) #=> "And so on."
4560  */
4561 
4562 static VALUE
4564 {
4565  VALUE offset, ptrname;
4566  int whence = SEEK_SET;
4567  rb_io_t *fptr;
4568  off_t pos;
4569 
4570  if (rb_scan_args(argc, argv, "11", &offset, &ptrname) == 2) {
4571  whence = interpret_seek_whence(ptrname);
4572  }
4573  pos = NUM2OFFT(offset);
4574  GetOpenFile(io, fptr);
4575  if ((fptr->mode & FMODE_READABLE) &&
4576  (READ_DATA_BUFFERED(fptr) || READ_CHAR_PENDING(fptr))) {
4577  rb_raise(rb_eIOError, "sysseek for buffered IO");
4578  }
4579  if ((fptr->mode & FMODE_WRITABLE) && fptr->wbuf.len) {
4580  rb_warn("sysseek for buffered IO");
4581  }
4582  errno = 0;
4583  pos = lseek(fptr->fd, pos, whence);
4584  if (pos == -1 && errno) rb_sys_fail_path(fptr->pathv);
4585 
4586  return OFFT2NUM(pos);
4587 }
4588 
4589 /*
4590  * call-seq:
4591  * ios.syswrite(string) -> integer
4592  *
4593  * Writes the given string to <em>ios</em> using a low-level write.
4594  * Returns the number of bytes written. Do not mix with other methods
4595  * that write to <em>ios</em> or you may get unpredictable results.
4596  * Raises <code>SystemCallError</code> on error.
4597  *
4598  * f = File.new("out", "w")
4599  * f.syswrite("ABCDEF") #=> 6
4600  */
4601 
4602 static VALUE
4604 {
4605  rb_io_t *fptr;
4606  long n;
4607 
4608  if (!RB_TYPE_P(str, T_STRING))
4609  str = rb_obj_as_string(str);
4610 
4611  io = GetWriteIO(io);
4612  GetOpenFile(io, fptr);
4613  rb_io_check_writable(fptr);
4614 
4615  str = rb_str_new_frozen(str);
4616 
4617  if (fptr->wbuf.len) {
4618  rb_warn("syswrite for buffered IO");
4619  }
4620 
4621  n = rb_write_internal(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
4622  RB_GC_GUARD(str);
4623 
4624  if (n == -1) rb_sys_fail_path(fptr->pathv);
4625 
4626  return LONG2FIX(n);
4627 }
4628 
4629 /*
4630  * call-seq:
4631  * ios.sysread(maxlen[, outbuf]) -> string
4632  *
4633  * Reads <i>maxlen</i> bytes from <em>ios</em> using a low-level
4634  * read and returns them as a string. Do not mix with other methods
4635  * that read from <em>ios</em> or you may get unpredictable results.
4636  * If the optional <i>outbuf</i> argument is present, it must reference
4637  * a String, which will receive the data.
4638  * The <i>outbuf</i> will contain only the received data after the method call
4639  * even if it is not empty at the beginning.
4640  * Raises <code>SystemCallError</code> on error and
4641  * <code>EOFError</code> at end of file.
4642  *
4643  * f = File.new("testfile")
4644  * f.sysread(16) #=> "This is line one"
4645  */
4646 
4647 static VALUE
4649 {
4650  VALUE len, str;
4651  rb_io_t *fptr;
4652  long n, ilen;
4653  struct read_internal_arg arg;
4654 
4655  rb_scan_args(argc, argv, "11", &len, &str);
4656  ilen = NUM2LONG(len);
4657 
4658  io_setstrbuf(&str,ilen);
4659  if (ilen == 0) return str;
4660 
4661  GetOpenFile(io, fptr);
4663 
4664  if (READ_DATA_BUFFERED(fptr)) {
4665  rb_raise(rb_eIOError, "sysread for buffered IO");
4666  }
4667 
4668  n = fptr->fd;
4669 
4670  /*
4671  * FIXME: removing rb_thread_wait_fd() here changes sysread semantics
4672  * on non-blocking IOs. However, it's still currently possible
4673  * for sysread to raise Errno::EAGAIN if another thread read()s
4674  * the IO after we return from rb_thread_wait_fd() but before
4675  * we call read()
4676  */
4677  rb_thread_wait_fd(fptr->fd);
4678 
4679  rb_io_check_closed(fptr);
4680 
4681  io_setstrbuf(&str, ilen);
4682  rb_str_locktmp(str);
4683  arg.fd = fptr->fd;
4684  arg.str_ptr = RSTRING_PTR(str);
4685  arg.len = ilen;
4687  n = arg.len;
4688 
4689  if (n == -1) {
4690  rb_sys_fail_path(fptr->pathv);
4691  }
4692  io_set_read_length(str, n);
4693  if (n == 0 && ilen > 0) {
4694  rb_eof_error();
4695  }
4696  OBJ_TAINT(str);
4697 
4698  return str;
4699 }
4700 
4701 VALUE
4703 {
4704  rb_io_t *fptr;
4705 
4706  GetOpenFile(io, fptr);
4707  if (fptr->readconv)
4708  rb_econv_binmode(fptr->readconv);
4709  if (fptr->writeconv)
4710  rb_econv_binmode(fptr->writeconv);
4711  fptr->mode |= FMODE_BINMODE;
4712  fptr->mode &= ~FMODE_TEXTMODE;
4714 #ifdef O_BINARY
4715  if (!fptr->readconv) {
4717  }
4718  else {
4719  setmode(fptr->fd, O_BINARY);
4720  }
4721 #endif
4722  return io;
4723 }
4724 
4725 static void
4727 {
4728  if (fptr->readconv) {
4729  rb_econv_close(fptr->readconv);
4730  fptr->readconv = NULL;
4731  }
4732  if (fptr->writeconv) {
4733  rb_econv_close(fptr->writeconv);
4734  fptr->writeconv = NULL;
4735  }
4736  fptr->mode |= FMODE_BINMODE;
4737  fptr->mode &= ~FMODE_TEXTMODE;
4739 
4740  fptr->encs.enc = rb_ascii8bit_encoding();
4741  fptr->encs.enc2 = NULL;
4742  fptr->encs.ecflags = 0;
4743  fptr->encs.ecopts = Qnil;
4744  clear_codeconv(fptr);
4745 }
4746 
4747 VALUE
4749 {
4750  rb_io_t *fptr;
4751 
4752  GetOpenFile(io, fptr);
4753  io_ascii8bit_binmode(fptr);
4754 
4755  return io;
4756 }
4757 
4758 /*
4759  * call-seq:
4760  * ios.binmode -> ios
4761  *
4762  * Puts <em>ios</em> into binary mode.
4763  * Once a stream is in binary mode, it cannot be reset to nonbinary mode.
4764  *
4765  * - newline conversion disabled
4766  * - encoding conversion disabled
4767  * - content is treated as ASCII-8BIT
4768  *
4769  */
4770 
4771 static VALUE
4773 {
4774  VALUE write_io;
4775 
4777 
4778  write_io = GetWriteIO(io);
4779  if (write_io != io)
4780  rb_io_ascii8bit_binmode(write_io);
4781  return io;
4782 }
4783 
4784 /*
4785  * call-seq:
4786  * ios.binmode? -> true or false
4787  *
4788  * Returns <code>true</code> if <em>ios</em> is binmode.
4789  */
4790 static VALUE
4792 {
4793  rb_io_t *fptr;
4794  GetOpenFile(io, fptr);
4795  return fptr->mode & FMODE_BINMODE ? Qtrue : Qfalse;
4796 }
4797 
4798 static const char*
4800 {
4801  if (fmode & FMODE_APPEND) {
4802  if ((fmode & FMODE_READWRITE) == FMODE_READWRITE) {
4803  return MODE_BTMODE("a+", "ab+", "at+");
4804  }
4805  return MODE_BTMODE("a", "ab", "at");
4806  }
4807  switch (fmode & FMODE_READWRITE) {
4808  default:
4809  rb_raise(rb_eArgError, "invalid access fmode 0x%x", fmode);
4810  case FMODE_READABLE:
4811  return MODE_BTMODE("r", "rb", "rt");
4812  case FMODE_WRITABLE:
4813  return MODE_BTMODE("w", "wb", "wt");
4814  case FMODE_READWRITE:
4815  if (fmode & FMODE_CREATE) {
4816  return MODE_BTMODE("w+", "wb+", "wt+");
4817  }
4818  return MODE_BTMODE("r+", "rb+", "rt+");
4819  }
4820 }
4821 
4822 static int
4823 io_encname_bom_p(const char *name, long len)
4824 {
4825  static const char bom_prefix[] = "bom|utf-";
4826  enum {bom_prefix_len = (int)sizeof(bom_prefix) - 1};
4827  if (!len) {
4828  const char *p = strchr(name, ':');
4829  len = p ? (long)(p - name) : (long)strlen(name);
4830  }
4831  return len > bom_prefix_len && STRNCASECMP(name, bom_prefix, bom_prefix_len) == 0;
4832 }
4833 
4834 int
4835 rb_io_modestr_fmode(const char *modestr)
4836 {
4837  int fmode = 0;
4838  const char *m = modestr, *p = NULL;
4839 
4840  switch (*m++) {
4841  case 'r':
4842  fmode |= FMODE_READABLE;
4843  break;
4844  case 'w':
4846  break;
4847  case 'a':
4849  break;
4850  default:
4851  error:
4852  rb_raise(rb_eArgError, "invalid access mode %s", modestr);
4853  }
4854 
4855  while (*m) {
4856  switch (*m++) {
4857  case 'b':
4858  fmode |= FMODE_BINMODE;
4859  break;
4860  case 't':
4861  fmode |= FMODE_TEXTMODE;
4862  break;
4863  case '+':
4864  fmode |= FMODE_READWRITE;
4865  break;
4866  default:
4867  goto error;
4868  case ':':
4869  p = m;
4870  goto finished;
4871  }
4872  }
4873 
4874  finished:
4875  if ((fmode & FMODE_BINMODE) && (fmode & FMODE_TEXTMODE))
4876  goto error;
4877  if (p && io_encname_bom_p(p, 0))
4878  fmode |= FMODE_SETENC_BY_BOM;
4879 
4880  return fmode;
4881 }
4882 
4883 int
4885 {
4886  int fmode = 0;
4887 
4888  switch (oflags & (O_RDONLY|O_WRONLY|O_RDWR)) {
4889  case O_RDONLY:
4890  fmode = FMODE_READABLE;
4891  break;
4892  case O_WRONLY:
4893  fmode = FMODE_WRITABLE;
4894  break;
4895  case O_RDWR:
4896  fmode = FMODE_READWRITE;
4897  break;
4898  }
4899 
4900  if (oflags & O_APPEND) {
4901  fmode |= FMODE_APPEND;
4902  }
4903  if (oflags & O_TRUNC) {
4904  fmode |= FMODE_TRUNC;
4905  }
4906  if (oflags & O_CREAT) {
4907  fmode |= FMODE_CREATE;
4908  }
4909 #ifdef O_BINARY
4910  if (oflags & O_BINARY) {
4911  fmode |= FMODE_BINMODE;
4912  }
4913 #endif
4914 
4915  return fmode;
4916 }
4917 
4918 static int
4920 {
4921  int oflags = 0;
4922 
4923  switch (fmode & FMODE_READWRITE) {
4924  case FMODE_READABLE:
4925  oflags |= O_RDONLY;
4926  break;
4927  case FMODE_WRITABLE:
4928  oflags |= O_WRONLY;
4929  break;
4930  case FMODE_READWRITE:
4931  oflags |= O_RDWR;
4932  break;
4933  }
4934 
4935  if (fmode & FMODE_APPEND) {
4936  oflags |= O_APPEND;
4937  }
4938  if (fmode & FMODE_TRUNC) {
4939  oflags |= O_TRUNC;
4940  }
4941  if (fmode & FMODE_CREATE) {
4942  oflags |= O_CREAT;
4943  }
4944 #ifdef O_BINARY
4945  if (fmode & FMODE_BINMODE) {
4946  oflags |= O_BINARY;
4947  }
4948 #endif
4949 
4950  return oflags;
4951 }
4952 
4953 int
4954 rb_io_modestr_oflags(const char *modestr)
4955 {
4956  return rb_io_fmode_oflags(rb_io_modestr_fmode(modestr));
4957 }
4958 
4959 static const char*
4961 {
4962 #ifdef O_BINARY
4963 # define MODE_BINARY(a,b) ((oflags & O_BINARY) ? (b) : (a))
4964 #else
4965 # define MODE_BINARY(a,b) (a)
4966 #endif
4967  int accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR);
4968  if (oflags & O_APPEND) {
4969  if (accmode == O_WRONLY) {
4970  return MODE_BINARY("a", "ab");
4971  }
4972  if (accmode == O_RDWR) {
4973  return MODE_BINARY("a+", "ab+");
4974  }
4975  }
4976  switch (oflags & (O_RDONLY|O_WRONLY|O_RDWR)) {
4977  default:
4978  rb_raise(rb_eArgError, "invalid access oflags 0x%x", oflags);
4979  case O_RDONLY:
4980  return MODE_BINARY("r", "rb");
4981  case O_WRONLY:
4982  return MODE_BINARY("w", "wb");
4983  case O_RDWR:
4984  if (oflags & O_TRUNC) {
4985  return MODE_BINARY("w+", "wb+");
4986  }
4987  return MODE_BINARY("r+", "rb+");
4988  }
4989 }
4990 
4991 /*
4992  * Convert external/internal encodings to enc/enc2
4993  * NULL => use default encoding
4994  * Qnil => no encoding specified (internal only)
4995  */
4996 static void
4998 {
4999  int default_ext = 0;
5000 
5001  if (ext == NULL) {
5003  default_ext = 1;
5004  }
5005  if (ext == rb_ascii8bit_encoding()) {
5006  /* If external is ASCII-8BIT, no transcoding */
5007  intern = NULL;
5008  }
5009  else if (intern == NULL) {
5010  intern = rb_default_internal_encoding();
5011  }
5012  if (intern == NULL || intern == (rb_encoding *)Qnil ||
5013  (!(fmode & FMODE_SETENC_BY_BOM) && (intern == ext))) {
5014  /* No internal encoding => use external + no transcoding */
5015  *enc = (default_ext && intern != ext) ? NULL : ext;
5016  *enc2 = NULL;
5017  }
5018  else {
5019  *enc = intern;
5020  *enc2 = ext;
5021  }
5022 }
5023 
5024 static void
5026 {
5027  rb_warn("Unsupported encoding %s ignored", name);
5028 }
5029 
5030 static void
5031 parse_mode_enc(const char *estr, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
5032 {
5033  const char *p;
5034  char encname[ENCODING_MAXNAMELEN+1];
5035  int idx, idx2;
5036  int fmode = fmode_p ? *fmode_p : 0;
5037  rb_encoding *ext_enc, *int_enc;
5038 
5039  /* parse estr as "enc" or "enc2:enc" or "enc:-" */
5040 
5041  p = strrchr(estr, ':');
5042  if (p) {
5043  long len = (p++) - estr;
5044  if (len == 0 || len > ENCODING_MAXNAMELEN)
5045  idx = -1;
5046  else {
5047  if (io_encname_bom_p(estr, len)) {
5048  fmode |= FMODE_SETENC_BY_BOM;
5049  estr += 4;
5050  len -= 4;
5051  }
5052  memcpy(encname, estr, len);
5053  encname[len] = '\0';
5054  estr = encname;
5055  idx = rb_enc_find_index(encname);
5056  }
5057  }
5058  else {
5059  long len = strlen(estr);
5060  if (io_encname_bom_p(estr, len)) {
5061  fmode |= FMODE_SETENC_BY_BOM;
5062  estr += 4;
5063  len -= 4;
5064  if (len > 0 && len <= ENCODING_MAXNAMELEN) {
5065  memcpy(encname, estr, len);
5066  encname[len] = '\0';
5067  estr = encname;
5068  }
5069  }
5070  idx = rb_enc_find_index(estr);
5071  }
5072  if (fmode_p) *fmode_p = fmode;
5073 
5074  if (idx >= 0)
5075  ext_enc = rb_enc_from_index(idx);
5076  else {
5077  if (idx != -2)
5078  unsupported_encoding(estr);
5079  ext_enc = NULL;
5080  }
5081 
5082  int_enc = NULL;
5083  if (p) {
5084  if (*p == '-' && *(p+1) == '\0') {
5085  /* Special case - "-" => no transcoding */
5086  int_enc = (rb_encoding *)Qnil;
5087  }
5088  else {
5089  idx2 = rb_enc_find_index(p);
5090  if (idx2 < 0)
5092  else if (!(fmode & FMODE_SETENC_BY_BOM) && (idx2 == idx)) {
5093  int_enc = (rb_encoding *)Qnil;
5094  }
5095  else
5096  int_enc = rb_enc_from_index(idx2);
5097  }
5098  }
5099 
5100  rb_io_ext_int_to_encs(ext_enc, int_enc, enc_p, enc2_p, fmode);
5101 }
5102 
5103 int
5104 rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
5105 {
5106  VALUE encoding=Qnil, extenc=Qundef, intenc=Qundef, tmp;
5107  int extracted = 0;
5108  rb_encoding *extencoding = NULL;
5109  rb_encoding *intencoding = NULL;
5110 
5111  if (!NIL_P(opt)) {
5112  VALUE v;
5113  v = rb_hash_lookup2(opt, sym_encoding, Qnil);
5114  if (v != Qnil) encoding = v;
5115  v = rb_hash_lookup2(opt, sym_extenc, Qundef);
5116  if (v != Qnil) extenc = v;
5117  v = rb_hash_lookup2(opt, sym_intenc, Qundef);
5118  if (v != Qundef) intenc = v;
5119  }
5120  if ((extenc != Qundef || intenc != Qundef) && !NIL_P(encoding)) {
5121  if (!NIL_P(ruby_verbose)) {
5122  int idx = rb_to_encoding_index(encoding);
5123  rb_warn("Ignoring encoding parameter '%s': %s_encoding is used",
5124  idx < 0 ? StringValueCStr(encoding) : rb_enc_name(rb_enc_from_index(idx)),
5125  extenc == Qundef ? "internal" : "external");
5126  }
5127  encoding = Qnil;
5128  }
5129  if (extenc != Qundef && !NIL_P(extenc)) {
5130  extencoding = rb_to_encoding(extenc);
5131  }
5132  if (intenc != Qundef) {
5133  if (NIL_P(intenc)) {
5134  /* internal_encoding: nil => no transcoding */
5135  intencoding = (rb_encoding *)Qnil;
5136  }
5137  else if (!NIL_P(tmp = rb_check_string_type(intenc))) {
5138  char *p = StringValueCStr(tmp);
5139 
5140  if (*p == '-' && *(p+1) == '\0') {
5141  /* Special case - "-" => no transcoding */
5142  intencoding = (rb_encoding *)Qnil;
5143  }
5144  else {
5145  intencoding = rb_to_encoding(intenc);
5146  }
5147  }
5148  else {
5149  intencoding = rb_to_encoding(intenc);
5150  }
5151  if (extencoding == intencoding) {
5152  intencoding = (rb_encoding *)Qnil;
5153  }
5154  }
5155  if (!NIL_P(encoding)) {
5156  extracted = 1;
5157  if (!NIL_P(tmp = rb_check_string_type(encoding))) {
5158  parse_mode_enc(StringValueCStr(tmp), enc_p, enc2_p, fmode_p);
5159  }
5160  else {
5161  rb_io_ext_int_to_encs(rb_to_encoding(encoding), NULL, enc_p, enc2_p, 0);
5162  }
5163  }
5164  else if (extenc != Qundef || intenc != Qundef) {
5165  extracted = 1;
5166  rb_io_ext_int_to_encs(extencoding, intencoding, enc_p, enc2_p, 0);
5167  }
5168  return extracted;
5169 }
5170 
5171 typedef struct rb_io_enc_t convconfig_t;
5172 
5173 static void
5175 {
5176  int fmode = *fmode_p;
5177 
5178  if ((fmode & FMODE_READABLE) &&
5179  !enc2 &&
5180  !(fmode & FMODE_BINMODE) &&
5182  rb_raise(rb_eArgError, "ASCII incompatible encoding needs binmode");
5183 
5184  if (!(fmode & FMODE_BINMODE) &&
5186  fmode |= DEFAULT_TEXTMODE;
5187  *fmode_p = fmode;
5188  }
5189 #if !DEFAULT_TEXTMODE
5190  else if (!(ecflags & ECONV_NEWLINE_DECORATOR_MASK)) {
5191  fmode &= ~FMODE_TEXTMODE;
5192  *fmode_p = fmode;
5193  }
5194 #endif
5195 }
5196 
5197 static void
5199 {
5200  if (!NIL_P(opthash)) {
5201  VALUE v;
5202  v = rb_hash_aref(opthash, sym_textmode);
5203  if (!NIL_P(v)) {
5204  if (*fmode & FMODE_TEXTMODE)
5205  rb_raise(rb_eArgError, "textmode specified twice");
5206  if (*fmode & FMODE_BINMODE)
5207  rb_raise(rb_eArgError, "both textmode and binmode specified");
5208  if (RTEST(v))
5209  *fmode |= FMODE_TEXTMODE;
5210  }
5211  v = rb_hash_aref(opthash, sym_binmode);
5212  if (!NIL_P(v)) {
5213  if (*fmode & FMODE_BINMODE)
5214  rb_raise(rb_eArgError, "binmode specified twice");
5215  if (*fmode & FMODE_TEXTMODE)
5216  rb_raise(rb_eArgError, "both textmode and binmode specified");
5217  if (RTEST(v))
5218  *fmode |= FMODE_BINMODE;
5219  }
5220 
5221  if ((*fmode & FMODE_BINMODE) && (*fmode & FMODE_TEXTMODE))
5222  rb_raise(rb_eArgError, "both textmode and binmode specified");
5223  }
5224 }
5225 
5226 static void
5227 rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
5228  int *oflags_p, int *fmode_p, convconfig_t *convconfig_p)
5229 {
5230  VALUE vmode;
5231  int oflags, fmode;
5232  rb_encoding *enc, *enc2;
5233  int ecflags;
5234  VALUE ecopts;
5235  int has_enc = 0, has_vmode = 0;
5236  VALUE intmode;
5237 
5238  vmode = *vmode_p;
5239 
5240  /* Set to defaults */
5241  rb_io_ext_int_to_encs(NULL, NULL, &enc, &enc2, 0);
5242 
5243  vmode_handle:
5244  if (NIL_P(vmode)) {
5245  fmode = FMODE_READABLE;
5246  oflags = O_RDONLY;
5247  }
5248  else if (!NIL_P(intmode = rb_check_to_integer(vmode, "to_int"))) {
5249  vmode = intmode;
5250  oflags = NUM2INT(intmode);
5251  fmode = rb_io_oflags_fmode(oflags);
5252  }
5253  else {
5254  const char *p;
5255 
5256  SafeStringValue(vmode);
5257  p = StringValueCStr(vmode);
5258  fmode = rb_io_modestr_fmode(p);
5259  oflags = rb_io_fmode_oflags(fmode);
5260  p = strchr(p, ':');
5261  if (p) {
5262  has_enc = 1;
5263  parse_mode_enc(p+1, &enc, &enc2, &fmode);
5264  }
5265  else {
5266  rb_encoding *e;
5267 
5268  e = (fmode & FMODE_BINMODE) ? rb_ascii8bit_encoding() : NULL;
5269  rb_io_ext_int_to_encs(e, NULL, &enc, &enc2, fmode);
5270  }
5271  }
5272 
5273  if (NIL_P(opthash)) {
5274  ecflags = (fmode & FMODE_READABLE) ?
5277 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
5278  ecflags |= (fmode & FMODE_WRITABLE) ?
5279  MODE_BTMODE(TEXTMODE_NEWLINE_DECORATOR_ON_WRITE,
5280  0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
5281 #endif
5283  ecopts = Qnil;
5284  }
5285  else {
5286  VALUE v;
5287  extract_binmode(opthash, &fmode);
5288  if (fmode & FMODE_BINMODE) {
5289 #ifdef O_BINARY
5290  oflags |= O_BINARY;
5291 #endif
5292  if (!has_enc)
5293  rb_io_ext_int_to_encs(rb_ascii8bit_encoding(), NULL, &enc, &enc2, fmode);
5294  }
5295 #if DEFAULT_TEXTMODE
5296  else if (NIL_P(vmode)) {
5297  fmode |= DEFAULT_TEXTMODE;
5298  }
5299 #endif
5300  if (!has_vmode) {
5301  v = rb_hash_aref(opthash, sym_mode);
5302  if (!NIL_P(v)) {
5303  if (!NIL_P(vmode)) {
5304  rb_raise(rb_eArgError, "mode specified twice");
5305  }
5306  has_vmode = 1;
5307  vmode = v;
5308  goto vmode_handle;
5309  }
5310  }
5311  v = rb_hash_aref(opthash, sym_perm);
5312  if (!NIL_P(v)) {
5313  if (vperm_p) {
5314  if (!NIL_P(*vperm_p)) {
5315  rb_raise(rb_eArgError, "perm specified twice");
5316  }
5317  *vperm_p = v;
5318  }
5319  else {
5320  /* perm no use, just ignore */
5321  }
5322  }
5323  ecflags = (fmode & FMODE_READABLE) ?
5326 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
5327  ecflags |= (fmode & FMODE_WRITABLE) ?
5328  MODE_BTMODE(TEXTMODE_NEWLINE_DECORATOR_ON_WRITE,
5329  0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
5330 #endif
5331 
5332  if (rb_io_extract_encoding_option(opthash, &enc, &enc2, &fmode)) {
5333  if (has_enc) {
5334  rb_raise(rb_eArgError, "encoding specified twice");
5335  }
5336  }
5338  ecflags = rb_econv_prepare_options(opthash, &ecopts, ecflags);
5339  }
5340 
5341  validate_enc_binmode(&fmode, ecflags, enc, enc2);
5342 
5343  *vmode_p = vmode;
5344 
5345  *oflags_p = oflags;
5346  *fmode_p = fmode;
5347  convconfig_p->enc = enc;
5348  convconfig_p->enc2 = enc2;
5349  convconfig_p->ecflags = ecflags;
5350  convconfig_p->ecopts = ecopts;
5351 }
5352 
5355  int oflags;
5357 };
5358 
5359 static void *
5360 sysopen_func(void *ptr)
5361 {
5362  const struct sysopen_struct *data = ptr;
5363  const char *fname = RSTRING_PTR(data->fname);
5364  return (void *)(VALUE)rb_cloexec_open(fname, data->oflags, data->perm);
5365 }
5366 
5367 static inline int
5369 {
5370  int fd;
5372  if (0 <= fd)
5373  rb_update_max_fd(fd);
5374  return fd;
5375 }
5376 
5377 static int
5379 {
5380  int fd;
5381  struct sysopen_struct data;
5382 
5383  data.fname = rb_str_encode_ospath(fname);
5384  data.oflags = oflags;
5385  data.perm = perm;
5386 
5387  fd = rb_sysopen_internal(&data);
5388  if (fd < 0) {
5389  if (errno == EMFILE || errno == ENFILE) {
5390  rb_gc();
5391  fd = rb_sysopen_internal(&data);
5392  }
5393  if (fd < 0) {
5394  rb_sys_fail_path(fname);
5395  }
5396  }
5397  return fd;
5398 }
5399 
5400 FILE *
5401 rb_fdopen(int fd, const char *modestr)
5402 {
5403  FILE *file;
5404 
5405 #if defined(__sun)
5406  errno = 0;
5407 #endif
5408  file = fdopen(fd, modestr);
5409  if (!file) {
5410  if (
5411 #if defined(__sun)
5412  errno == 0 ||
5413 #endif
5414  errno == EMFILE || errno == ENFILE) {
5415  rb_gc();
5416 #if defined(__sun)
5417  errno = 0;
5418 #endif
5419  file = fdopen(fd, modestr);
5420  }
5421  if (!file) {
5422 #ifdef _WIN32
5423  if (errno == 0) errno = EINVAL;
5424 #elif defined(__sun)
5425  if (errno == 0) errno = EMFILE;
5426 #endif
5427  rb_sys_fail(0);
5428  }
5429  }
5430 
5431  /* xxx: should be _IONBF? A buffer in FILE may have trouble. */
5432 #ifdef USE_SETVBUF
5433  if (setvbuf(file, NULL, _IOFBF, 0) != 0)
5434  rb_warn("setvbuf() can't be honoured (fd=%d)", fd);
5435 #endif
5436  return file;
5437 }
5438 
5439 static void
5441 {
5442  if (isatty(fptr->fd))
5443  fptr->mode |= FMODE_TTY|FMODE_DUPLEX;
5444 }
5445 
5447 static void io_encoding_set(rb_io_t *, VALUE, VALUE, VALUE);
5448 
5449 static int
5451 {
5452  VALUE b1, b2, b3, b4;
5453 
5454  if (NIL_P(b1 = rb_io_getbyte(io))) return 0;
5455  switch (b1) {
5456  case INT2FIX(0xEF):
5457  if (NIL_P(b2 = rb_io_getbyte(io))) break;
5458  if (b2 == INT2FIX(0xBB) && !NIL_P(b3 = rb_io_getbyte(io))) {
5459  if (b3 == INT2FIX(0xBF)) {
5460  return rb_utf8_encindex();
5461  }
5462  rb_io_ungetbyte(io, b3);
5463  }
5464  rb_io_ungetbyte(io, b2);
5465  break;
5466 
5467  case INT2FIX(0xFE):
5468  if (NIL_P(b2 = rb_io_getbyte(io))) break;
5469  if (b2 == INT2FIX(0xFF)) {
5470  return ENCINDEX_UTF_16BE;
5471  }
5472  rb_io_ungetbyte(io, b2);
5473  break;
5474 
5475  case INT2FIX(0xFF):
5476  if (NIL_P(b2 = rb_io_getbyte(io))) break;
5477  if (b2 == INT2FIX(0xFE)) {
5478  b3 = rb_io_getbyte(io);
5479  if (b3 == INT2FIX(0) && !NIL_P(b4 = rb_io_getbyte(io))) {
5480  if (b4 == INT2FIX(0)) {
5481  return ENCINDEX_UTF_32LE;
5482  }
5483  rb_io_ungetbyte(io, b4);
5484  rb_io_ungetbyte(io, b3);
5485  }
5486  else {
5487  rb_io_ungetbyte(io, b3);
5488  return ENCINDEX_UTF_16LE;
5489  }
5490  }
5491  rb_io_ungetbyte(io, b2);
5492  break;
5493 
5494  case INT2FIX(0):
5495  if (NIL_P(b2 = rb_io_getbyte(io))) break;
5496  if (b2 == INT2FIX(0) && !NIL_P(b3 = rb_io_getbyte(io))) {
5497  if (b3 == INT2FIX(0xFE) && !NIL_P(b4 = rb_io_getbyte(io))) {
5498  if (b4 == INT2FIX(0xFF)) {
5499  return ENCINDEX_UTF_32BE;
5500  }
5501  rb_io_ungetbyte(io, b4);
5502  }
5503  rb_io_ungetbyte(io, b3);
5504  }
5505  rb_io_ungetbyte(io, b2);
5506  break;
5507  }
5508  rb_io_ungetbyte(io, b1);
5509  return 0;
5510 }
5511 
5512 static void
5514 {
5515  int idx = io_strip_bom(io);
5516  rb_io_t *fptr;
5517 
5518  GetOpenFile(io, fptr);
5519  if (idx) {
5522  }
5523  else {
5524  fptr->encs.enc2 = NULL;
5525  }
5526 }
5527 
5528 static VALUE
5529 rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode, convconfig_t *convconfig, mode_t perm)
5530 {
5531  rb_io_t *fptr;
5532  convconfig_t cc;
5533  if (!convconfig) {
5534  /* Set to default encodings */
5535  rb_io_ext_int_to_encs(NULL, NULL, &cc.enc, &cc.enc2, fmode);
5536  cc.ecflags = 0;
5537  cc.ecopts = Qnil;
5538  convconfig = &cc;
5539  }
5540  validate_enc_binmode(&fmode, convconfig->ecflags,
5541  convconfig->enc, convconfig->enc2);
5542 
5543  MakeOpenFile(io, fptr);
5544  fptr->mode = fmode;
5545  fptr->encs = *convconfig;
5546  fptr->pathv = rb_str_new_frozen(filename);
5547  fptr->fd = rb_sysopen(fptr->pathv, oflags, perm);
5548  io_check_tty(fptr);
5550 
5551  return io;
5552 }
5553 
5554 static VALUE
5555 rb_file_open_internal(VALUE io, VALUE filename, const char *modestr)
5556 {
5557  int fmode = rb_io_modestr_fmode(modestr);
5558  const char *p = strchr(modestr, ':');
5559  convconfig_t convconfig;
5560 
5561  if (p) {
5562  parse_mode_enc(p+1, &convconfig.enc, &convconfig.enc2, &fmode);
5563  }
5564  else {
5565  rb_encoding *e;
5566  /* Set to default encodings */
5567 
5568  e = (fmode & FMODE_BINMODE) ? rb_ascii8bit_encoding() : NULL;
5569  rb_io_ext_int_to_encs(e, NULL, &convconfig.enc, &convconfig.enc2, fmode);
5570  convconfig.ecflags = 0;
5571  convconfig.ecopts = Qnil;
5572  }
5573 
5574  return rb_file_open_generic(io, filename,
5575  rb_io_fmode_oflags(fmode),
5576  fmode,
5577  &convconfig,
5578  0666);
5579 }
5580 
5581 VALUE
5582 rb_file_open_str(VALUE fname, const char *modestr)
5583 {
5584  FilePathValue(fname);
5585  return rb_file_open_internal(io_alloc(rb_cFile), fname, modestr);
5586 }
5587 
5588 VALUE
5589 rb_file_open(const char *fname, const char *modestr)
5590 {
5591  return rb_file_open_internal(io_alloc(rb_cFile), rb_str_new_cstr(fname), modestr);
5592 }
5593 
5594 #if defined(__CYGWIN__) || !defined(HAVE_FORK)
5595 static struct pipe_list {
5597  struct pipe_list *next;
5598 } *pipe_list;
5599 
5600 static void
5602 {
5603  struct pipe_list *list;
5604 
5605  list = ALLOC(struct pipe_list);
5606  list->fptr = fptr;
5607  list->next = pipe_list;
5608  pipe_list = list;
5609 }
5610 
5611 static void
5613 {
5614  struct pipe_list *list = pipe_list;
5615  struct pipe_list *tmp;
5616 
5617  if (list->fptr == fptr) {
5618  pipe_list = list->next;
5619  free(list);
5620  return;
5621  }
5622 
5623  while (list->next) {
5624  if (list->next->fptr == fptr) {
5625  tmp = list->next;
5626  list->next = list->next->next;
5627  free(tmp);
5628  return;
5629  }
5630  list = list->next;
5631  }
5632 }
5633 
5634 static void
5636 {
5637  struct pipe_list *list = pipe_list;
5638  struct pipe_list *tmp;
5639 
5640  while (list) {
5641  tmp = list->next;
5642  rb_io_fptr_finalize(list->fptr);
5643  list = tmp;
5644  }
5645 }
5646 
5647 static void
5648 pipe_finalize(rb_io_t *fptr, int noraise)
5649 {
5650 #if !defined(HAVE_FORK) && !defined(_WIN32)
5651  int status = 0;
5652  if (fptr->stdio_file) {
5653  status = pclose(fptr->stdio_file);
5654  }
5655  fptr->fd = -1;
5656  fptr->stdio_file = 0;
5657  rb_last_status_set(status, fptr->pid);
5658 #else
5659  fptr_finalize(fptr, noraise);
5660 #endif
5661  pipe_del_fptr(fptr);
5662 }
5663 #endif
5664 
5665 void
5667 {
5669  fptr->mode |= FMODE_SYNC;
5670 }
5671 
5672 void
5674 {
5675  rb_io_synchronized(fptr);
5676 }
5677 
5678 int
5679 rb_pipe(int *pipes)
5680 {
5681  int ret;
5682  ret = rb_cloexec_pipe(pipes);
5683  if (ret == -1) {
5684  if (errno == EMFILE || errno == ENFILE) {
5685  rb_gc();
5686  ret = rb_cloexec_pipe(pipes);
5687  }
5688  }
5689  if (ret == 0) {
5690  rb_update_max_fd(pipes[0]);
5691  rb_update_max_fd(pipes[1]);
5692  }
5693  return ret;
5694 }
5695 
5696 #ifdef _WIN32
5697 #define HAVE_SPAWNV 1
5698 #define spawnv(mode, cmd, args) rb_w32_uaspawn((mode), (cmd), (args))
5699 #define spawn(mode, cmd) rb_w32_uspawn((mode), (cmd), 0)
5700 #endif
5701 
5702 #if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
5703 struct popen_arg {
5704  VALUE execarg_obj;
5705  struct rb_execarg *eargp;
5706  int modef;
5707  int pair[2];
5708  int write_pair[2];
5709 };
5710 #endif
5711 
5712 #ifdef HAVE_FORK
5713 static void
5714 popen_redirect(struct popen_arg *p)
5715 {
5716  if ((p->modef & FMODE_READABLE) && (p->modef & FMODE_WRITABLE)) {
5717  close(p->write_pair[1]);
5718  if (p->write_pair[0] != 0) {
5719  dup2(p->write_pair[0], 0);
5720  close(p->write_pair[0]);
5721  }
5722  close(p->pair[0]);
5723  if (p->pair[1] != 1) {
5724  dup2(p->pair[1], 1);
5725  close(p->pair[1]);
5726  }
5727  }
5728  else if (p->modef & FMODE_READABLE) {
5729  close(p->pair[0]);
5730  if (p->pair[1] != 1) {
5731  dup2(p->pair[1], 1);
5732  close(p->pair[1]);
5733  }
5734  }
5735  else {
5736  close(p->pair[1]);
5737  if (p->pair[0] != 0) {
5738  dup2(p->pair[0], 0);
5739  close(p->pair[0]);
5740  }
5741  }
5742 }
5743 
5744 #if defined(__linux__)
5745 /* Linux /proc/self/status contains a line: "FDSize:\t<nnn>\n"
5746  * Since /proc may not be available, linux_get_maxfd is just a hint.
5747  * This function, linux_get_maxfd, must be async-signal-safe.
5748  * I.e. opendir() is not usable.
5749  *
5750  * Note that memchr() and memcmp is *not* async-signal-safe in POSIX.
5751  * However they are easy to re-implement in async-signal-safe manner.
5752  * (Also note that there is missing/memcmp.c.)
5753  */
5754 static int
5755 linux_get_maxfd(void)
5756 {
5757  int fd;
5758  char buf[4096], *p, *np, *e;
5759  ssize_t ss;
5760  fd = rb_cloexec_open("/proc/self/status", O_RDONLY|O_NOCTTY, 0);
5761  if (fd == -1) return -1;
5762  ss = read(fd, buf, sizeof(buf));
5763  if (ss == -1) goto err;
5764  p = buf;
5765  e = buf + ss;
5766  while ((int)sizeof("FDSize:\t0\n")-1 <= e-p &&
5767  (np = memchr(p, '\n', e-p)) != NULL) {
5768  if (memcmp(p, "FDSize:", sizeof("FDSize:")-1) == 0) {
5769  int fdsize;
5770  p += sizeof("FDSize:")-1;
5771  *np = '\0';
5772  fdsize = (int)ruby_strtoul(p, (char **)NULL, 10);
5773  close(fd);
5774  return fdsize;
5775  }
5776  p = np+1;
5777  }
5778  /* fall through */
5779 
5780  err:
5781  close(fd);
5782  return -1;
5783 }
5784 #endif
5785 
5786 /* This function should be async-signal-safe. */
5787 void
5788 rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
5789 {
5790  int fd, ret;
5791  int max = (int)max_file_descriptor;
5792 #ifdef F_MAXFD
5793  /* F_MAXFD is available since NetBSD 2.0. */
5794  ret = fcntl(0, F_MAXFD); /* async-signal-safe */
5795  if (ret != -1)
5796  maxhint = max = ret;
5797 #elif defined(__linux__)
5798  ret = linux_get_maxfd();
5799  if (maxhint < ret)
5800  maxhint = ret;
5801  /* maxhint = max = ret; if (ret == -1) abort(); // test */
5802 #endif
5803  if (max < maxhint)
5804  max = maxhint;
5805  for (fd = lowfd; fd <= max; fd++) {
5806  if (!NIL_P(noclose_fds) &&
5807  RTEST(rb_hash_lookup(noclose_fds, INT2FIX(fd)))) /* async-signal-safe */
5808  continue;
5809  ret = fcntl(fd, F_GETFD); /* async-signal-safe */
5810  if (ret != -1 && !(ret & FD_CLOEXEC)) {
5811  fcntl(fd, F_SETFD, ret|FD_CLOEXEC); /* async-signal-safe */
5812  }
5813 #define CONTIGUOUS_CLOSED_FDS 20
5814  if (ret != -1) {
5815  if (max < fd + CONTIGUOUS_CLOSED_FDS)
5816  max = fd + CONTIGUOUS_CLOSED_FDS;
5817  }
5818  }
5819 }
5820 
5821 static int
5822 popen_exec(void *pp, char *errmsg, size_t errmsg_len)
5823 {
5824  struct popen_arg *p = (struct popen_arg*)pp;
5825 
5826  return rb_exec_async_signal_safe(p->eargp, errmsg, errmsg_len);
5827 }
5828 #endif
5829 
5830 static VALUE
5831 pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convconfig)
5832 {
5833  struct rb_execarg *eargp = NIL_P(execarg_obj) ? NULL : rb_execarg_get(execarg_obj);
5834  VALUE prog = eargp ? (eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name) : Qfalse ;
5835  rb_pid_t pid = 0;
5836  rb_io_t *fptr;
5837  VALUE port;
5838  rb_io_t *write_fptr;
5839  VALUE write_port;
5840 #if defined(HAVE_FORK)
5841  int status;
5842  char errmsg[80] = { '\0' };
5843 #endif
5844 #if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
5845  struct popen_arg arg;
5846  int e = 0;
5847 #endif
5848 #if defined(HAVE_SPAWNV)
5849 # if defined(HAVE_SPAWNVE)
5850 # define DO_SPAWN(cmd, args, envp) ((args) ? \
5851  spawnve(P_NOWAIT, (cmd), (args), (envp)) : \
5852  spawne(P_NOWAIT, (cmd), (envp)))
5853 # else
5854 # define DO_SPAWN(cmd, args, envp) ((args) ? \
5855  spawnv(P_NOWAIT, (cmd), (args)) : \
5856  spawn(P_NOWAIT, (cmd)))
5857 # endif
5858 # if !defined(HAVE_FORK)
5859  char **args = NULL;
5860 # if defined(HAVE_SPAWNVE)
5861  char **envp = NULL;
5862 # endif
5863 # endif
5864 #endif
5865 #if !defined(HAVE_FORK)
5866  struct rb_execarg sarg, *sargp = &sarg;
5867 #endif
5868  FILE *fp = 0;
5869  int fd = -1;
5870  int write_fd = -1;
5871 #if !defined(HAVE_FORK)
5872  const char *cmd = 0;
5873 #if !defined(HAVE_SPAWNV)
5874  int argc;
5875  VALUE *argv;
5876 #endif
5877 
5878  if (prog)
5879  cmd = StringValueCStr(prog);
5880 #endif
5881 
5882 #if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
5883  arg.execarg_obj = execarg_obj;
5884  arg.eargp = eargp;
5885  arg.modef = fmode;
5886  arg.pair[0] = arg.pair[1] = -1;
5887  arg.write_pair[0] = arg.write_pair[1] = -1;
5888 # if !defined(HAVE_FORK)
5889  if (eargp && !eargp->use_shell) {
5890  args = ARGVSTR2ARGV(eargp->invoke.cmd.argv_str);
5891  }
5892 # endif
5893  switch (fmode & (FMODE_READABLE|FMODE_WRITABLE)) {
5895  if (rb_pipe(arg.write_pair) < 0)
5896  rb_sys_fail_str(prog);
5897  if (rb_pipe(arg.pair) < 0) {
5898  int e = errno;
5899  close(arg.write_pair[0]);
5900  close(arg.write_pair[1]);
5901  errno = e;
5902  rb_sys_fail_str(prog);
5903  }
5904  if (eargp) {
5905  rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(arg.write_pair[0]));
5906  rb_execarg_addopt(execarg_obj, INT2FIX(1), INT2FIX(arg.pair[1]));
5907  }
5908  break;
5909  case FMODE_READABLE:
5910  if (rb_pipe(arg.pair) < 0)
5911  rb_sys_fail_str(prog);
5912  if (eargp)
5913  rb_execarg_addopt(execarg_obj, INT2FIX(1), INT2FIX(arg.pair[1]));
5914  break;
5915  case FMODE_WRITABLE:
5916  if (rb_pipe(arg.pair) < 0)
5917  rb_sys_fail_str(prog);
5918  if (eargp)
5919  rb_execarg_addopt(execarg_obj, INT2FIX(0), INT2FIX(arg.pair[0]));
5920  break;
5921  default:
5922  rb_sys_fail_str(prog);
5923  }
5924  if (!NIL_P(execarg_obj)) {
5925  rb_execarg_fixup(execarg_obj);
5926 # if defined(HAVE_FORK)
5927  pid = rb_fork_async_signal_safe(&status, popen_exec, &arg, arg.eargp->redirect_fds, errmsg, sizeof(errmsg));
5928 # else
5929  rb_execarg_run_options(eargp, sargp, NULL, 0);
5930 # if defined(HAVE_SPAWNVE)
5931  if (eargp->envp_str) envp = (char **)RSTRING_PTR(eargp->envp_str);
5932 # endif
5933  while ((pid = DO_SPAWN(cmd, args, envp)) == -1) {
5934  /* exec failed */
5935  switch (e = errno) {
5936  case EAGAIN:
5937 # if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
5938  case EWOULDBLOCK:
5939 # endif
5940  rb_thread_sleep(1);
5941  continue;
5942  }
5943  break;
5944  }
5945  if (eargp)
5946  rb_execarg_run_options(sargp, NULL, NULL, 0);
5947 # endif
5948  }
5949  else {
5950 # if defined(HAVE_FORK)
5951  pid = rb_fork_ruby(&status);
5952  if (pid == 0) { /* child */
5953  rb_thread_atfork();
5954  popen_redirect(&arg);
5957  return Qnil;
5958  }
5959 # else
5960  rb_notimplement();
5961 # endif
5962  }
5963 
5964  /* parent */
5965  if (pid == -1) {
5966 # if defined(HAVE_FORK)
5967  e = errno;
5968 # endif
5969  close(arg.pair[0]);
5970  close(arg.pair[1]);
5972  close(arg.write_pair[0]);
5973  close(arg.write_pair[1]);
5974  }
5975  errno = e;
5976 # if defined(HAVE_FORK)
5977  if (errmsg[0])
5978  rb_sys_fail(errmsg);
5979 # endif
5980  rb_sys_fail_str(prog);
5981  }
5982  if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) {
5983  close(arg.pair[1]);
5984  fd = arg.pair[0];
5985  close(arg.write_pair[0]);
5986  write_fd = arg.write_pair[1];
5987  }
5988  else if (fmode & FMODE_READABLE) {
5989  close(arg.pair[1]);
5990  fd = arg.pair[0];
5991  }
5992  else {
5993  close(arg.pair[0]);
5994  fd = arg.pair[1];
5995  }
5996 #else
5997  if (argc) {
5998  prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
5999  cmd = StringValueCStr(prog);
6000  }
6001  if (!NIL_P(execarg_obj)) {
6002  rb_execarg_fixup(execarg_obj);
6003  rb_execarg_run_options(eargp, sargp, NULL, 0);
6004  }
6005  fp = popen(cmd, modestr);
6006  if (eargp)
6007  rb_execarg_run_options(sargp, NULL, NULL, 0);
6008  if (!fp) rb_sys_fail_path(prog);
6009  fd = fileno(fp);
6010 #endif
6011 
6012  port = io_alloc(rb_cIO);
6013  MakeOpenFile(port, fptr);
6014  fptr->fd = fd;
6015  fptr->stdio_file = fp;
6016  fptr->mode = fmode | FMODE_SYNC|FMODE_DUPLEX;
6017  if (convconfig) {
6018  fptr->encs = *convconfig;
6019 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
6022  }
6023 #endif
6024  }
6025  else {
6026  if (NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
6028  }
6029 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
6030  if (NEED_NEWLINE_DECORATOR_ON_WRITE(fptr)) {
6031  fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
6032  }
6033 #endif
6034  }
6035  fptr->pid = pid;
6036 
6037  if (0 <= write_fd) {
6038  write_port = io_alloc(rb_cIO);
6039  MakeOpenFile(write_port, write_fptr);
6040  write_fptr->fd = write_fd;
6041  write_fptr->mode = (fmode & ~FMODE_READABLE)| FMODE_SYNC|FMODE_DUPLEX;
6042  fptr->mode &= ~FMODE_WRITABLE;
6043  fptr->tied_io_for_writing = write_port;
6044  rb_ivar_set(port, rb_intern("@tied_io_for_writing"), write_port);
6045  }
6046 
6047 #if defined (__CYGWIN__) || !defined(HAVE_FORK)
6048  fptr->finalize = pipe_finalize;
6049  pipe_add_fptr(fptr);
6050 #endif
6051  return port;
6052 }
6053 
6054 static int
6056 {
6057  if (RSTRING_LEN(prog) == 1 && RSTRING_PTR(prog)[0] == '-') {
6058 #if !defined(HAVE_FORK)
6060  "fork() function is unimplemented on this machine");
6061 #else
6062  return TRUE;
6063 #endif
6064  }
6065  return FALSE;
6066 }
6067 
6068 static VALUE
6069 pipe_open_s(VALUE prog, const char *modestr, int fmode, convconfig_t *convconfig)
6070 {
6071  int argc = 1;
6072  VALUE *argv = &prog;
6073  VALUE execarg_obj = Qnil;
6074 
6075  if (!is_popen_fork(prog))
6076  execarg_obj = rb_execarg_new(argc, argv, TRUE);
6077  return pipe_open(execarg_obj, modestr, fmode, convconfig);
6078 }
6079 
6080 /*
6081  * call-seq:
6082  * IO.popen([env,] cmd, mode="r" [, opt]) -> io
6083  * IO.popen([env,] cmd, mode="r" [, opt]) {|io| block } -> obj
6084  *
6085  * Runs the specified command as a subprocess; the subprocess's
6086  * standard input and output will be connected to the returned
6087  * <code>IO</code> object.
6088  *
6089  * The PID of the started process can be obtained by IO#pid method.
6090  *
6091  * _cmd_ is a string or an array as follows.
6092  *
6093  * cmd:
6094  * "-" : fork
6095  * commandline : command line string which is passed to a shell
6096  * [env, cmdname, arg1, ..., opts] : command name and zero or more arguments (no shell)
6097  * [env, [cmdname, argv0], arg1, ..., opts] : command name, argv[0] and zero or more arguments (no shell)
6098  * (env and opts are optional.)
6099  *
6100  * If _cmd_ is a +String+ ``<code>-</code>'',
6101  * then a new instance of Ruby is started as the subprocess.
6102  *
6103  * If <i>cmd</i> is an +Array+ of +String+,
6104  * then it will be used as the subprocess's +argv+ bypassing a shell.
6105  * The array can contains a hash at first for environments and
6106  * a hash at last for options similar to <code>spawn</code>.
6107  *
6108  * The default mode for the new file object is ``r'',
6109  * but <i>mode</i> may be set to any of the modes listed in the description for class IO.
6110  * The last argument <i>opt</i> qualifies <i>mode</i>.
6111  *
6112  * # set IO encoding
6113  * IO.popen("nkf -e filename", :external_encoding=>"EUC-JP") {|nkf_io|
6114  * euc_jp_string = nkf_io.read
6115  * }
6116  *
6117  * # merge standard output and standard error using
6118  * # spawn option. See the document of Kernel.spawn.
6119  * IO.popen(["ls", "/", :err=>[:child, :out]]) {|ls_io|
6120  * ls_result_with_error = ls_io.read
6121  * }
6122  *
6123  * # spawn options can be mixed with IO options
6124  * IO.popen(["ls", "/"], :err=>[:child, :out]) {|ls_io|
6125  * ls_result_with_error = ls_io.read
6126  * }
6127  *
6128  * Raises exceptions which <code>IO.pipe</code> and
6129  * <code>Kernel.spawn</code> raise.
6130  *
6131  * If a block is given, Ruby will run the command as a child connected
6132  * to Ruby with a pipe. Ruby's end of the pipe will be passed as a
6133  * parameter to the block.
6134  * At the end of block, Ruby close the pipe and sets <code>$?</code>.
6135  * In this case <code>IO.popen</code> returns
6136  * the value of the block.
6137  *
6138  * If a block is given with a _cmd_ of ``<code>-</code>'',
6139  * the block will be run in two separate processes: once in the parent,
6140  * and once in a child. The parent process will be passed the pipe
6141  * object as a parameter to the block, the child version of the block
6142  * will be passed <code>nil</code>, and the child's standard in and
6143  * standard out will be connected to the parent through the pipe. Not
6144  * available on all platforms.
6145  *
6146  * f = IO.popen("uname")
6147  * p f.readlines
6148  * f.close
6149  * puts "Parent is #{Process.pid}"
6150  * IO.popen("date") { |f| puts f.gets }
6151  * IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f.inspect}"}
6152  * p $?
6153  * IO.popen(%w"sed -e s|^|<foo>| -e s&$&;zot;&", "r+") {|f|
6154  * f.puts "bar"; f.close_write; puts f.gets
6155  * }
6156  *
6157  * <em>produces:</em>
6158  *
6159  * ["Linux\n"]
6160  * Parent is 21346
6161  * Thu Jan 15 22:41:19 JST 2009
6162  * 21346 is here, f is #<IO:fd 3>
6163  * 21352 is here, f is nil
6164  * #<Process::Status: pid 21352 exit 0>
6165  * <foo>bar;zot;
6166  */
6167 
6168 static VALUE
6170 {
6171  const char *modestr;
6172  VALUE pname, pmode = Qnil, port, tmp, opt = Qnil, env = Qnil, execarg_obj = Qnil;
6173  int oflags, fmode;
6174  convconfig_t convconfig;
6175 
6176  if (argc > 1 && !NIL_P(opt = rb_check_hash_type(argv[argc-1]))) --argc;
6177  if (argc > 1 && !NIL_P(env = rb_check_hash_type(argv[0]))) --argc, ++argv;
6178  switch (argc) {
6179  case 2:
6180  pmode = argv[1];
6181  case 1:
6182  pname = argv[0];
6183  break;
6184  default:
6185  {
6186  int ex = !NIL_P(opt);
6187  rb_error_arity(argc + ex, 1 + ex, 2 + ex);
6188  }
6189  }
6190 
6191  tmp = rb_check_array_type(pname);
6192  if (!NIL_P(tmp)) {
6193  long len = RARRAY_LEN(tmp);
6194 #if SIZEOF_LONG > SIZEOF_INT
6195  if (len > INT_MAX) {
6196  rb_raise(rb_eArgError, "too many arguments");
6197  }
6198 #endif
6199  tmp = rb_ary_dup(tmp);
6200  RBASIC_CLEAR_CLASS(tmp);
6201  execarg_obj = rb_execarg_new((int)len, RARRAY_PTR(tmp), FALSE);
6202  rb_ary_clear(tmp);
6203  }
6204  else {
6205  SafeStringValue(pname);
6206  execarg_obj = Qnil;
6207  if (!is_popen_fork(pname))
6208  execarg_obj = rb_execarg_new(1, &pname, TRUE);
6209  }
6210  if (!NIL_P(execarg_obj)) {
6211  if (!NIL_P(opt))
6212  opt = rb_execarg_extract_options(execarg_obj, opt);
6213  if (!NIL_P(env))
6214  rb_execarg_setenv(execarg_obj, env);
6215  }
6216  rb_io_extract_modeenc(&pmode, 0, opt, &oflags, &fmode, &convconfig);
6217  modestr = rb_io_oflags_modestr(oflags);
6218 
6219  port = pipe_open(execarg_obj, modestr, fmode, &convconfig);
6220  if (NIL_P(port)) {
6221  /* child */
6222  if (rb_block_given_p()) {
6223  rb_yield(Qnil);
6226  _exit(0);
6227  }
6228  return Qnil;
6229  }
6230  RBASIC_SET_CLASS(port, klass);
6231  if (rb_block_given_p()) {
6232  return rb_ensure(rb_yield, port, io_close, port);
6233  }
6234  return port;
6235 }
6236 
6237 static void
6239  VALUE *fname_p, int *oflags_p, int *fmode_p,
6240  convconfig_t *convconfig_p, mode_t *perm_p)
6241 {
6242  VALUE opt, fname, vmode, vperm;
6243  int oflags, fmode;
6244  mode_t perm;
6245 
6246  argc = rb_scan_args(argc, argv, "12:", &fname, &vmode, &vperm, &opt);
6247  FilePathValue(fname);
6248 
6249  rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, convconfig_p);
6250 
6251  perm = NIL_P(vperm) ? 0666 : NUM2MODET(vperm);
6252 
6253  *fname_p = fname;
6254  *oflags_p = oflags;
6255  *fmode_p = fmode;
6256  *perm_p = perm;
6257 }
6258 
6259 static VALUE
6261 {
6262  VALUE fname;
6263  int oflags, fmode;
6264  convconfig_t convconfig;
6265  mode_t perm;
6266 
6267  rb_scan_open_args(argc, argv, &fname, &oflags, &fmode, &convconfig, &perm);
6268  rb_file_open_generic(io, fname, oflags, fmode, &convconfig, perm);
6269 
6270  return io;
6271 }
6272 
6273 
6274 /*
6275  * Document-method: File::open
6276  *
6277  * call-seq:
6278  * File.open(filename, mode="r" [, opt]) -> file
6279  * File.open(filename [, mode [, perm]] [, opt]) -> file
6280  * File.open(filename, mode="r" [, opt]) {|file| block } -> obj
6281  * File.open(filename [, mode [, perm]] [, opt]) {|file| block } -> obj
6282  *
6283  * With no associated block, <code>File.open</code> is a synonym for
6284  * File.new. If the optional code block is given, it will
6285  * be passed the opened +file+ as an argument and the File object will
6286  * automatically be closed when the block terminates. The value of the block
6287  * will be returned from <code>File.open</code>.
6288  *
6289  * If a file is being created, its initial permissions may be set using the
6290  * +perm+ parameter. See File.new for further discussion.
6291  *
6292  * See IO.new for a description of the +mode+ and +opt+ parameters.
6293  */
6294 
6295 /*
6296  * Document-method: IO::open
6297  *
6298  * call-seq:
6299  * IO.open(fd, mode="r" [, opt]) -> io
6300  * IO.open(fd, mode="r" [, opt]) { |io| block } -> obj
6301  *
6302  * With no associated block, <code>IO.open</code> is a synonym for IO.new. If
6303  * the optional code block is given, it will be passed +io+ as an argument,
6304  * and the IO object will automatically be closed when the block terminates.
6305  * In this instance, IO.open returns the value of the block.
6306  *
6307  * See IO.new for a description of the +fd+, +mode+ and +opt+ parameters.
6308  */
6309 
6310 static VALUE
6312 {
6313  VALUE io = rb_class_new_instance(argc, argv, klass);
6314 
6315  if (rb_block_given_p()) {
6316  return rb_ensure(rb_yield, io, io_close, io);
6317  }
6318 
6319  return io;
6320 }
6321 
6322 /*
6323  * call-seq:
6324  * IO.sysopen(path, [mode, [perm]]) -> fixnum
6325  *
6326  * Opens the given path, returning the underlying file descriptor as a
6327  * <code>Fixnum</code>.
6328  *
6329  * IO.sysopen("testfile") #=> 3
6330  */
6331 
6332 static VALUE
6334 {
6335  VALUE fname, vmode, vperm;
6336  VALUE intmode;
6337  int oflags, fd;
6338  mode_t perm;
6339 
6340  rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm);
6341  FilePathValue(fname);
6342 
6343  if (NIL_P(vmode))
6344  oflags = O_RDONLY;
6345  else if (!NIL_P(intmode = rb_check_to_integer(vmode, "to_int")))
6346  oflags = NUM2INT(intmode);
6347  else {
6348  SafeStringValue(vmode);
6349  oflags = rb_io_modestr_oflags(StringValueCStr(vmode));
6350  }
6351  if (NIL_P(vperm)) perm = 0666;
6352  else perm = NUM2MODET(vperm);
6353 
6354  RB_GC_GUARD(fname) = rb_str_new4(fname);
6355  fd = rb_sysopen(fname, oflags, perm);
6356  return INT2NUM(fd);
6357 }
6358 
6359 static VALUE
6360 check_pipe_command(VALUE filename_or_command)
6361 {
6362  char *s = RSTRING_PTR(filename_or_command);
6363  long l = RSTRING_LEN(filename_or_command);
6364  char *e = s + l;
6365  int chlen;
6366 
6367  if (rb_enc_ascget(s, e, &chlen, rb_enc_get(filename_or_command)) == '|') {
6368  VALUE cmd = rb_str_new(s+chlen, l-chlen);
6369  OBJ_INFECT(cmd, filename_or_command);
6370  return cmd;
6371  }
6372  return Qnil;
6373 }
6374 
6375 /*
6376  * call-seq:
6377  * open(path [, mode [, perm]] [, opt]) -> io or nil
6378  * open(path [, mode [, perm]] [, opt]) {|io| block } -> obj
6379  *
6380  * Creates an IO object connected to the given stream, file, or subprocess.
6381  *
6382  * If +path+ does not start with a pipe character (<code>|</code>), treat it
6383  * as the name of a file to open using the specified mode (defaulting to
6384  * "r").
6385  *
6386  * The +mode+ is either a string or an integer. If it is an integer, it
6387  * must be bitwise-or of open(2) flags, such as File::RDWR or File::EXCL. If
6388  * it is a string, it is either "fmode", "fmode:ext_enc", or
6389  * "fmode:ext_enc:int_enc".
6390  *
6391  * See the documentation of IO.new for full documentation of the +mode+ string
6392  * directives.
6393  *
6394  * If a file is being created, its initial permissions may be set using the
6395  * +perm+ parameter. See File.new and the open(2) and chmod(2) man pages for
6396  * a description of permissions.
6397  *
6398  * If a block is specified, it will be invoked with the IO object as a
6399  * parameter, and the IO will be automatically closed when the block
6400  * terminates. The call returns the value of the block.
6401  *
6402  * If +path+ starts with a pipe character (<code>"|"</code>), a subprocess is
6403  * created, connected to the caller by a pair of pipes. The returned IO
6404  * object may be used to write to the standard input and read from the
6405  * standard output of this subprocess.
6406  *
6407  * If the command following the pipe is a single minus sign
6408  * (<code>"|-"</code>), Ruby forks, and this subprocess is connected to the
6409  * parent. If the command is not <code>"-"</code>, the subprocess runs the
6410  * command.
6411  *
6412  * When the subprocess is ruby (opened via <code>"|-"</code>), the +open+
6413  * call returns +nil+. If a block is associated with the open call, that
6414  * block will run twice --- once in the parent and once in the child.
6415  *
6416  * The block parameter will be an IO object in the parent and +nil+ in the
6417  * child. The parent's +IO+ object will be connected to the child's $stdin
6418  * and $stdout. The subprocess will be terminated at the end of the block.
6419  *
6420  * === Examples
6421  *
6422  * Reading from "testfile":
6423  *
6424  * open("testfile") do |f|
6425  * print f.gets
6426  * end
6427  *
6428  * Produces:
6429  *
6430  * This is line one
6431  *
6432  * Open a subprocess and read its output:
6433  *
6434  * cmd = open("|date")
6435  * print cmd.gets
6436  * cmd.close
6437  *
6438  * Produces:
6439  *
6440  * Wed Apr 9 08:56:31 CDT 2003
6441  *
6442  * Open a subprocess running the same Ruby program:
6443  *
6444  * f = open("|-", "w+")
6445  * if f == nil
6446  * puts "in Child"
6447  * exit
6448  * else
6449  * puts "Got: #{f.gets}"
6450  * end
6451  *
6452  * Produces:
6453  *
6454  * Got: in Child
6455  *
6456  * Open a subprocess using a block to receive the IO object:
6457  *
6458  * open "|-" do |f|
6459  * if f then
6460  * # parent process
6461  * puts "Got: #{f.gets}"
6462  * else
6463  * # child process
6464  * puts "in Child"
6465  * end
6466  * end
6467  *
6468  * Produces:
6469  *
6470  * Got: in Child
6471  */
6472 
6473 static VALUE
6475 {
6476  ID to_open = 0;
6477  int redirect = FALSE;
6478 
6479  if (argc >= 1) {
6480  CONST_ID(to_open, "to_open");
6481  if (rb_respond_to(argv[0], to_open)) {
6482  redirect = TRUE;
6483  }
6484  else {
6485  VALUE tmp = argv[0];
6486  FilePathValue(tmp);
6487  if (NIL_P(tmp)) {
6488  redirect = TRUE;
6489  }
6490  else {
6491  VALUE cmd = check_pipe_command(tmp);
6492  if (!NIL_P(cmd)) {
6493  argv[0] = cmd;
6494  return rb_io_s_popen(argc, argv, rb_cIO);
6495  }
6496  }
6497  }
6498  }
6499  if (redirect) {
6500  VALUE io = rb_funcall2(argv[0], to_open, argc-1, argv+1);
6501 
6502  if (rb_block_given_p()) {
6503  return rb_ensure(rb_yield, io, io_close, io);
6504  }
6505  return io;
6506  }
6507  return rb_io_s_open(argc, argv, rb_cFile);
6508 }
6509 
6510 static VALUE
6511 rb_io_open(VALUE filename, VALUE vmode, VALUE vperm, VALUE opt)
6512 {
6513  VALUE cmd;
6514  int oflags, fmode;
6515  convconfig_t convconfig;
6516  mode_t perm;
6517 
6518  rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, &convconfig);
6519  perm = NIL_P(vperm) ? 0666 : NUM2MODET(vperm);
6520 
6521  if (!NIL_P(cmd = check_pipe_command(filename))) {
6522  return pipe_open_s(cmd, rb_io_oflags_modestr(oflags), fmode, &convconfig);
6523  }
6524  else {
6525  return rb_file_open_generic(io_alloc(rb_cFile), filename,
6526  oflags, fmode, &convconfig, perm);
6527  }
6528 }
6529 
6530 static VALUE
6532 {
6533  VALUE io;
6534 
6535  io = io_alloc(rb_cFile);
6536  rb_open_file(argc, argv, io);
6537  return io;
6538 }
6539 
6540 static VALUE
6542 {
6543  rb_io_t *fptr, *orig;
6544  int fd, fd2;
6545  off_t pos = 0;
6546 
6547  nfile = rb_io_get_io(nfile);
6548  GetOpenFile(io, fptr);
6549  GetOpenFile(nfile, orig);
6550 
6551  if (fptr == orig) return io;
6552  if (IS_PREP_STDIO(fptr)) {
6553  if ((fptr->stdio_file == stdin && !(orig->mode & FMODE_READABLE)) ||
6554  (fptr->stdio_file == stdout && !(orig->mode & FMODE_WRITABLE)) ||
6555  (fptr->stdio_file == stderr && !(orig->mode & FMODE_WRITABLE))) {
6557  "%s can't change access mode from \"%s\" to \"%s\"",
6559  rb_io_fmode_modestr(orig->mode));
6560  }
6561  }
6562  if (fptr->mode & FMODE_WRITABLE) {
6563  if (io_fflush(fptr) < 0)
6564  rb_sys_fail(0);
6565  }
6566  else {
6567  io_tell(fptr);
6568  }
6569  if (orig->mode & FMODE_READABLE) {
6570  pos = io_tell(orig);
6571  }
6572  if (orig->mode & FMODE_WRITABLE) {
6573  if (io_fflush(orig) < 0)
6574  rb_sys_fail(0);
6575  }
6576 
6577  /* copy rb_io_t structure */
6578  fptr->mode = orig->mode | (fptr->mode & FMODE_PREP);
6579  fptr->pid = orig->pid;
6580  fptr->lineno = orig->lineno;
6581  if (RTEST(orig->pathv)) fptr->pathv = orig->pathv;
6582  else if (!IS_PREP_STDIO(fptr)) fptr->pathv = Qnil;
6583  fptr->finalize = orig->finalize;
6584 #if defined (__CYGWIN__) || !defined(HAVE_FORK)
6585  if (fptr->finalize == pipe_finalize)
6586  pipe_add_fptr(fptr);
6587 #endif
6588 
6589  fd = fptr->fd;
6590  fd2 = orig->fd;
6591  if (fd != fd2) {
6592  if (IS_PREP_STDIO(fptr) || fd <= 2 || !fptr->stdio_file) {
6593  /* need to keep FILE objects of stdin, stdout and stderr */
6594  if (rb_cloexec_dup2(fd2, fd) < 0)
6595  rb_sys_fail_path(orig->pathv);
6596  rb_update_max_fd(fd);
6597  }
6598  else {
6599  fclose(fptr->stdio_file);
6600  fptr->stdio_file = 0;
6601  fptr->fd = -1;
6602  if (rb_cloexec_dup2(fd2, fd) < 0)
6603  rb_sys_fail_path(orig->pathv);
6604  rb_update_max_fd(fd);
6605  fptr->fd = fd;
6606  }
6607  rb_thread_fd_close(fd);
6608  if ((orig->mode & FMODE_READABLE) && pos >= 0) {
6609  if (io_seek(fptr, pos, SEEK_SET) < 0 && errno) {
6610  rb_sys_fail_path(fptr->pathv);
6611  }
6612  if (io_seek(orig, pos, SEEK_SET) < 0 && errno) {
6613  rb_sys_fail_path(orig->pathv);
6614  }
6615  }
6616  }
6617 
6618  if (fptr->mode & FMODE_BINMODE) {
6619  rb_io_binmode(io);
6620  }
6621 
6622  RBASIC_SET_CLASS(io, rb_obj_class(nfile));
6623  return io;
6624 }
6625 
6626 /*
6627  * call-seq:
6628  * ios.reopen(other_IO) -> ios
6629  * ios.reopen(path, mode_str) -> ios
6630  *
6631  * Reassociates <em>ios</em> with the I/O stream given in
6632  * <i>other_IO</i> or to a new stream opened on <i>path</i>. This may
6633  * dynamically change the actual class of this stream.
6634  *
6635  * f1 = File.new("testfile")
6636  * f2 = File.new("testfile")
6637  * f2.readlines[0] #=> "This is line one\n"
6638  * f2.reopen(f1) #=> #<File:testfile>
6639  * f2.readlines[0] #=> "This is line one\n"
6640  */
6641 
6642 static VALUE
6644 {
6645  VALUE fname, nmode, opt;
6646  int oflags;
6647  rb_io_t *fptr;
6648 
6649  if (rb_scan_args(argc, argv, "11:", &fname, &nmode, &opt) == 1) {
6650  VALUE tmp = rb_io_check_io(fname);
6651  if (!NIL_P(tmp)) {
6652  return io_reopen(file, tmp);
6653  }
6654  }
6655 
6656  FilePathValue(fname);
6657  rb_io_taint_check(file);
6658  fptr = RFILE(file)->fptr;
6659  if (!fptr) {
6660  fptr = RFILE(file)->fptr = ALLOC(rb_io_t);
6661  MEMZERO(fptr, rb_io_t, 1);
6662  }
6663 
6664  if (!NIL_P(nmode) || !NIL_P(opt)) {
6665  int fmode;
6666  convconfig_t convconfig;
6667 
6668  rb_io_extract_modeenc(&nmode, 0, opt, &oflags, &fmode, &convconfig);
6669  if (IS_PREP_STDIO(fptr) &&
6670  ((fptr->mode & FMODE_READWRITE) & (fmode & FMODE_READWRITE)) !=
6671  (fptr->mode & FMODE_READWRITE)) {
6673  "%s can't change access mode from \"%s\" to \"%s\"",
6675  rb_io_fmode_modestr(fmode));
6676  }
6677  fptr->mode = fmode;
6678  fptr->encs = convconfig;
6679  }
6680  else {
6681  oflags = rb_io_fmode_oflags(fptr->mode);
6682  }
6683 
6684  fptr->pathv = rb_str_new_frozen(fname);
6685  if (fptr->fd < 0) {
6686  fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666);
6687  fptr->stdio_file = 0;
6688  return file;
6689  }
6690 
6691  if (fptr->mode & FMODE_WRITABLE) {
6692  if (io_fflush(fptr) < 0)
6693  rb_sys_fail(0);
6694  }
6695  fptr->rbuf.off = fptr->rbuf.len = 0;
6696 
6697  if (fptr->stdio_file) {
6698  if (freopen(RSTRING_PTR(fptr->pathv), rb_io_oflags_modestr(oflags), fptr->stdio_file) == 0) {
6699  rb_sys_fail_path(fptr->pathv);
6700  }
6701  fptr->fd = fileno(fptr->stdio_file);
6702  rb_fd_fix_cloexec(fptr->fd);
6703 #ifdef USE_SETVBUF
6704  if (setvbuf(fptr->stdio_file, NULL, _IOFBF, 0) != 0)
6705  rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
6706 #endif
6707  if (fptr->stdio_file == stderr) {
6708  if (setvbuf(fptr->stdio_file, NULL, _IONBF, BUFSIZ) != 0)
6709  rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
6710  }
6711  else if (fptr->stdio_file == stdout && isatty(fptr->fd)) {
6712  if (setvbuf(fptr->stdio_file, NULL, _IOLBF, BUFSIZ) != 0)
6713  rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
6714  }
6715  }
6716  else {
6717  int tmpfd = rb_sysopen(fptr->pathv, oflags, 0666);
6718  int err = 0;
6719  if (rb_cloexec_dup2(tmpfd, fptr->fd) < 0)
6720  err = errno;
6721  (void)close(tmpfd);
6722  if (err) {
6723  rb_syserr_fail_path(err, fptr->pathv);
6724  }
6725  }
6726 
6727  return file;
6728 }
6729 
6730 /* :nodoc: */
6731 static VALUE
6733 {
6734  rb_io_t *fptr, *orig;
6735  int fd;
6736  VALUE write_io;
6737  off_t pos;
6738 
6739  io = rb_io_get_io(io);
6740  if (!OBJ_INIT_COPY(dest, io)) return dest;
6741  GetOpenFile(io, orig);
6742  MakeOpenFile(dest, fptr);
6743 
6744  rb_io_flush(io);
6745 
6746  /* copy rb_io_t structure */
6747  fptr->mode = orig->mode & ~FMODE_PREP;
6748  fptr->encs = orig->encs;
6749  fptr->pid = orig->pid;
6750  fptr->lineno = orig->lineno;
6751  if (!NIL_P(orig->pathv)) fptr->pathv = orig->pathv;
6752  fptr->finalize = orig->finalize;
6753 #if defined (__CYGWIN__) || !defined(HAVE_FORK)
6754  if (fptr->finalize == pipe_finalize)
6755  pipe_add_fptr(fptr);
6756 #endif
6757 
6758  fd = ruby_dup(orig->fd);
6759  fptr->fd = fd;
6760  pos = io_tell(orig);
6761  if (0 <= pos)
6762  io_seek(fptr, pos, SEEK_SET);
6763  if (fptr->mode & FMODE_BINMODE) {
6764  rb_io_binmode(dest);
6765  }
6766 
6767  write_io = GetWriteIO(io);
6768  if (io != write_io) {
6769  write_io = rb_obj_dup(write_io);
6770  fptr->tied_io_for_writing = write_io;
6771  rb_ivar_set(dest, rb_intern("@tied_io_for_writing"), write_io);
6772  }
6773 
6774  return dest;
6775 }
6776 
6777 /*
6778  * call-seq:
6779  * ios.printf(format_string [, obj, ...]) -> nil
6780  *
6781  * Formats and writes to <em>ios</em>, converting parameters under
6782  * control of the format string. See <code>Kernel#sprintf</code>
6783  * for details.
6784  */
6785 
6786 VALUE
6788 {
6789  rb_io_write(out, rb_f_sprintf(argc, argv));
6790  return Qnil;
6791 }
6792 
6793 /*
6794  * call-seq:
6795  * printf(io, string [, obj ... ]) -> nil
6796  * printf(string [, obj ... ]) -> nil
6797  *
6798  * Equivalent to:
6799  * io.write(sprintf(string, obj, ...))
6800  * or
6801  * $stdout.write(sprintf(string, obj, ...))
6802  */
6803 
6804 static VALUE
6806 {
6807  VALUE out;
6808 
6809  if (argc == 0) return Qnil;
6810  if (RB_TYPE_P(argv[0], T_STRING)) {
6811  out = rb_stdout;
6812  }
6813  else {
6814  out = argv[0];
6815  argv++;
6816  argc--;
6817  }
6818  rb_io_write(out, rb_f_sprintf(argc, argv));
6819 
6820  return Qnil;
6821 }
6822 
6823 /*
6824  * call-seq:
6825  * ios.print() -> nil
6826  * ios.print(obj, ...) -> nil
6827  *
6828  * Writes the given object(s) to <em>ios</em>. The stream must be
6829  * opened for writing. If the output field separator (<code>$,</code>)
6830  * is not <code>nil</code>, it will be inserted between each object.
6831  * If the output record separator (<code>$\</code>)
6832  * is not <code>nil</code>, it will be appended to the output. If no
6833  * arguments are given, prints <code>$_</code>. Objects that aren't
6834  * strings will be converted by calling their <code>to_s</code> method.
6835  * With no argument, prints the contents of the variable <code>$_</code>.
6836  * Returns <code>nil</code>.
6837  *
6838  * $stdout.print("This is ", 100, " percent.\n")
6839  *
6840  * <em>produces:</em>
6841  *
6842  * This is 100 percent.
6843  */
6844 
6845 VALUE
6847 {
6848  int i;
6849  VALUE line;
6850 
6851  /* if no argument given, print `$_' */
6852  if (argc == 0) {
6853  argc = 1;
6854  line = rb_lastline_get();
6855  argv = &line;
6856  }
6857  for (i=0; i<argc; i++) {
6858  if (!NIL_P(rb_output_fs) && i>0) {
6859  rb_io_write(out, rb_output_fs);
6860  }
6861  rb_io_write(out, argv[i]);
6862  }
6863  if (argc > 0 && !NIL_P(rb_output_rs)) {
6864  rb_io_write(out, rb_output_rs);
6865  }
6866 
6867  return Qnil;
6868 }
6869 
6870 /*
6871  * call-seq:
6872  * print(obj, ...) -> nil
6873  *
6874  * Prints each object in turn to <code>$stdout</code>. If the output
6875  * field separator (<code>$,</code>) is not +nil+, its
6876  * contents will appear between each field. If the output record
6877  * separator (<code>$\</code>) is not +nil+, it will be
6878  * appended to the output. If no arguments are given, prints
6879  * <code>$_</code>. Objects that aren't strings will be converted by
6880  * calling their <code>to_s</code> method.
6881  *
6882  * print "cat", [1,2,3], 99, "\n"
6883  * $, = ", "
6884  * $\ = "\n"
6885  * print "cat", [1,2,3], 99
6886  *
6887  * <em>produces:</em>
6888  *
6889  * cat12399
6890  * cat, 1, 2, 3, 99
6891  */
6892 
6893 static VALUE
6895 {
6896  rb_io_print(argc, argv, rb_stdout);
6897  return Qnil;
6898 }
6899 
6900 /*
6901  * call-seq:
6902  * ios.putc(obj) -> obj
6903  *
6904  * If <i>obj</i> is <code>Numeric</code>, write the character whose code is
6905  * the least-significant byte of <i>obj</i>, otherwise write the first byte
6906  * of the string representation of <i>obj</i> to <em>ios</em>. Note: This
6907  * method is not safe for use with multi-byte characters as it will truncate
6908  * them.
6909  *
6910  * $stdout.putc "A"
6911  * $stdout.putc 65
6912  *
6913  * <em>produces:</em>
6914  *
6915  * AA
6916  */
6917 
6918 static VALUE
6920 {
6921  VALUE str;
6922  if (RB_TYPE_P(ch, T_STRING)) {
6923  str = rb_str_substr(ch, 0, 1);
6924  }
6925  else {
6926  char c = NUM2CHR(ch);
6927  str = rb_str_new(&c, 1);
6928  }
6929  rb_io_write(io, str);
6930  return ch;
6931 }
6932 
6933 /*
6934  * call-seq:
6935  * putc(int) -> int
6936  *
6937  * Equivalent to:
6938  *
6939  * $stdout.putc(int)
6940  *
6941  * Refer to the documentation for IO#putc for important information regarding
6942  * multi-byte characters.
6943  */
6944 
6945 static VALUE
6947 {
6948  if (recv == rb_stdout) {
6949  return rb_io_putc(recv, ch);
6950  }
6951  return rb_funcall2(rb_stdout, rb_intern("putc"), 1, &ch);
6952 }
6953 
6954 
6955 static int
6957 {
6958  long len = RSTRING_LEN(str);
6959  const char *ptr = RSTRING_PTR(str);
6961  int n;
6962 
6963  if (len == 0) return 0;
6964  if ((n = rb_enc_mbminlen(enc)) == 1) {
6965  return ptr[len - 1] == c;
6966  }
6967  return rb_enc_ascget(ptr + ((len - 1) / n) * n, ptr + len, &n, enc) == c;
6968 }
6969 
6970 static VALUE
6972 {
6973  VALUE tmp;
6974  long i;
6975 
6976  if (recur) {
6977  tmp = rb_str_new2("[...]");
6978  rb_io_puts(1, &tmp, out);
6979  return Qtrue;
6980  }
6981  ary = rb_check_array_type(ary);
6982  if (NIL_P(ary)) return Qfalse;
6983  for (i=0; i<RARRAY_LEN(ary); i++) {
6984  tmp = RARRAY_AREF(ary, i);
6985  rb_io_puts(1, &tmp, out);
6986  }
6987  return Qtrue;
6988 }
6989 
6990 /*
6991  * call-seq:
6992  * ios.puts(obj, ...) -> nil
6993  *
6994  * Writes the given objects to <em>ios</em> as with
6995  * <code>IO#print</code>. Writes a record separator (typically a
6996  * newline) after any that do not already end with a newline sequence.
6997  * If called with an array argument, writes each element on a new line.
6998  * If called without arguments, outputs a single record separator.
6999  *
7000  * $stdout.puts("this", "is", "a", "test")
7001  *
7002  * <em>produces:</em>
7003  *
7004  * this
7005  * is
7006  * a
7007  * test
7008  */
7009 
7010 VALUE
7012 {
7013  int i;
7014  VALUE line;
7015 
7016  /* if no argument given, print newline. */
7017  if (argc == 0) {
7018  rb_io_write(out, rb_default_rs);
7019  return Qnil;
7020  }
7021  for (i=0; i<argc; i++) {
7022  if (RB_TYPE_P(argv[i], T_STRING)) {
7023  line = argv[i];
7024  goto string;
7025  }
7026  if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
7027  continue;
7028  }
7029  line = rb_obj_as_string(argv[i]);
7030  string:
7031  rb_io_write(out, line);
7032  if (RSTRING_LEN(line) == 0 ||
7033  !str_end_with_asciichar(line, '\n')) {
7034  rb_io_write(out, rb_default_rs);
7035  }
7036  }
7037 
7038  return Qnil;
7039 }
7040 
7041 /*
7042  * call-seq:
7043  * puts(obj, ...) -> nil
7044  *
7045  * Equivalent to
7046  *
7047  * $stdout.puts(obj, ...)
7048  */
7049 
7050 static VALUE
7052 {
7053  if (recv == rb_stdout) {
7054  return rb_io_puts(argc, argv, recv);
7055  }
7056  return rb_funcall2(rb_stdout, rb_intern("puts"), argc, argv);
7057 }
7058 
7059 void
7060 rb_p(VALUE obj) /* for debug print within C code */
7061 {
7063  if (RB_TYPE_P(rb_stdout, T_FILE) &&
7065  io_write(rb_stdout, str, 1);
7067  }
7068  else {
7069  rb_io_write(rb_stdout, str);
7071  }
7072 }
7073 
7074 struct rb_f_p_arg {
7075  int argc;
7077 };
7078 
7079 static VALUE
7081 {
7082  struct rb_f_p_arg *arg1 = (struct rb_f_p_arg*)arg;
7083  int argc = arg1->argc;
7084  VALUE *argv = arg1->argv;
7085  int i;
7086  VALUE ret = Qnil;
7087 
7088  for (i=0; i<argc; i++) {
7089  rb_p(argv[i]);
7090  }
7091  if (argc == 1) {
7092  ret = argv[0];
7093  }
7094  else if (argc > 1) {
7095  ret = rb_ary_new4(argc, argv);
7096  }
7097  if (RB_TYPE_P(rb_stdout, T_FILE)) {
7099  }
7100  return ret;
7101 }
7102 
7103 /*
7104  * call-seq:
7105  * p(obj) -> obj
7106  * p(obj1, obj2, ...) -> [obj, ...]
7107  * p() -> nil
7108  *
7109  * For each object, directly writes _obj_.+inspect+ followed by a
7110  * newline to the program's standard output.
7111  *
7112  * S = Struct.new(:name, :state)
7113  * s = S['dave', 'TX']
7114  * p s
7115  *
7116  * <em>produces:</em>
7117  *
7118  * #<S name="dave", state="TX">
7119  */
7120 
7121 static VALUE
7123 {
7124  struct rb_f_p_arg arg;
7125  arg.argc = argc;
7126  arg.argv = argv;
7127 
7128  return rb_uninterruptible(rb_f_p_internal, (VALUE)&arg);
7129 }
7130 
7131 /*
7132  * call-seq:
7133  * obj.display(port=$>) -> nil
7134  *
7135  * Prints <i>obj</i> on the given port (default <code>$></code>).
7136  * Equivalent to:
7137  *
7138  * def display(port=$>)
7139  * port.write self
7140  * end
7141  *
7142  * For example:
7143  *
7144  * 1.display
7145  * "cat".display
7146  * [ 4, 5, 6 ].display
7147  * puts
7148  *
7149  * <em>produces:</em>
7150  *
7151  * 1cat456
7152  */
7153 
7154 static VALUE
7156 {
7157  VALUE out;
7158 
7159  if (argc == 0) {
7160  out = rb_stdout;
7161  }
7162  else {
7163  rb_scan_args(argc, argv, "01", &out);
7164  }
7165  rb_io_write(out, self);
7166 
7167  return Qnil;
7168 }
7169 
7170 void
7171 rb_write_error2(const char *mesg, long len)
7172 {
7173  if (rb_stderr == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0) {
7174  if (fwrite(mesg, sizeof(char), (size_t)len, stderr) < (size_t)len) {
7175  /* failed to write to stderr, what can we do? */
7176  return;
7177  }
7178  }
7179  else {
7180  rb_io_write(rb_stderr, rb_str_new(mesg, len));
7181  }
7182 }
7183 
7184 void
7185 rb_write_error(const char *mesg)
7186 {
7187  rb_write_error2(mesg, strlen(mesg));
7188 }
7189 
7190 void
7192 {
7193  /* a stopgap measure for the time being */
7194  if (rb_stderr == orig_stderr || RFILE(orig_stderr)->fptr->fd < 0) {
7195  size_t len = (size_t)RSTRING_LEN(mesg);
7196  if (fwrite(RSTRING_PTR(mesg), sizeof(char), len, stderr) < len) {
7197  RB_GC_GUARD(mesg);
7198  return;
7199  }
7200  }
7201  else {
7202  /* may unlock GVL, and */
7203  rb_io_write(rb_stderr, mesg);
7204  }
7205 }
7206 
7207 static void
7209 {
7210  if (!rb_respond_to(val, mid)) {
7211  rb_raise(rb_eTypeError, "%s must have %s method, %s given",
7212  rb_id2name(id), rb_id2name(mid),
7213  rb_obj_classname(val));
7214  }
7215 }
7216 
7217 static void
7218 stdout_setter(VALUE val, ID id, VALUE *variable)
7219 {
7220  must_respond_to(id_write, val, id);
7221  *variable = val;
7222 }
7223 
7224 static VALUE
7225 prep_io(int fd, int fmode, VALUE klass, const char *path)
7226 {
7227  rb_io_t *fp;
7228  VALUE io = io_alloc(klass);
7229 
7230  MakeOpenFile(io, fp);
7231  fp->fd = fd;
7232 #ifdef __CYGWIN__
7233  if (!isatty(fd)) {
7234  fmode |= FMODE_BINMODE;
7235  setmode(fd, O_BINARY);
7236  }
7237 #endif
7238  fp->mode = fmode;
7239  io_check_tty(fp);
7240  if (path) fp->pathv = rb_obj_freeze(rb_str_new_cstr(path));
7241  rb_update_max_fd(fd);
7242 
7243  return io;
7244 }
7245 
7246 VALUE
7247 rb_io_fdopen(int fd, int oflags, const char *path)
7248 {
7249  VALUE klass = rb_cIO;
7250 
7251  if (path && strcmp(path, "-")) klass = rb_cFile;
7252  return prep_io(fd, rb_io_oflags_fmode(oflags), klass, path);
7253 }
7254 
7255 static VALUE
7256 prep_stdio(FILE *f, int fmode, VALUE klass, const char *path)
7257 {
7258  rb_io_t *fptr;
7259  VALUE io = prep_io(fileno(f), fmode|FMODE_PREP|DEFAULT_TEXTMODE, klass, path);
7260 
7261  GetOpenFile(io, fptr);
7263 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
7264  fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
7265  if (fmode & FMODE_READABLE) {
7267  }
7268 #endif
7269  fptr->stdio_file = f;
7270 
7271  return io;
7272 }
7273 
7274 FILE *
7276 {
7277  if (!fptr->stdio_file) {
7278  int oflags = rb_io_fmode_oflags(fptr->mode);
7279  fptr->stdio_file = rb_fdopen(fptr->fd, rb_io_oflags_modestr(oflags));
7280  }
7281  return fptr->stdio_file;
7282 }
7283 
7284 /*
7285  * call-seq:
7286  * IO.new(fd [, mode] [, opt]) -> io
7287  *
7288  * Returns a new IO object (a stream) for the given integer file descriptor
7289  * +fd+ and +mode+ string. +opt+ may be used to specify parts of +mode+ in a
7290  * more readable fashion. See also IO.sysopen and IO.for_fd.
7291  *
7292  * IO.new is called by various File and IO opening methods such as IO::open,
7293  * Kernel#open, and File::open.
7294  *
7295  * === Open Mode
7296  *
7297  * When +mode+ is an integer it must be combination of the modes defined in
7298  * File::Constants (+File::RDONLY+, +File::WRONLY | File::CREAT+). See the
7299  * open(2) man page for more information.
7300  *
7301  * When +mode+ is a string it must be in one of the following forms:
7302  *
7303  * fmode
7304  * fmode ":" ext_enc
7305  * fmode ":" ext_enc ":" int_enc
7306  * fmode ":" "BOM|UTF-*"
7307  *
7308  * +fmode+ is an IO open mode string, +ext_enc+ is the external encoding for
7309  * the IO and +int_enc+ is the internal encoding.
7310  *
7311  * ==== IO Open Mode
7312  *
7313  * Ruby allows the following open modes:
7314  *
7315  * "r" Read-only, starts at beginning of file (default mode).
7316  *
7317  * "r+" Read-write, starts at beginning of file.
7318  *
7319  * "w" Write-only, truncates existing file
7320  * to zero length or creates a new file for writing.
7321  *
7322  * "w+" Read-write, truncates existing file to zero length
7323  * or creates a new file for reading and writing.
7324  *
7325  * "a" Write-only, each write call appends data at end of file.
7326  * Creates a new file for writing if file does not exist.
7327  *
7328  * "a+" Read-write, each write call appends data at end of file.
7329  * Creates a new file for reading and writing if file does
7330  * not exist.
7331  *
7332  * The following modes must be used separately, and along with one or more of
7333  * the modes seen above.
7334  *
7335  * "b" Binary file mode
7336  * Suppresses EOL <-> CRLF conversion on Windows. And
7337  * sets external encoding to ASCII-8BIT unless explicitly
7338  * specified.
7339  *
7340  * "t" Text file mode
7341  *
7342  * When the open mode of original IO is read only, the mode cannot be
7343  * changed to be writable. Similarly, the open mode cannot be changed from
7344  * write only to readable.
7345  *
7346  * When such a change is attempted the error is raised in different locations
7347  * according to the platform.
7348  *
7349  * === IO Encoding
7350  *
7351  * When +ext_enc+ is specified, strings read will be tagged by the encoding
7352  * when reading, and strings output will be converted to the specified
7353  * encoding when writing.
7354  *
7355  * When +ext_enc+ and +int_enc+ are specified read strings will be converted
7356  * from +ext_enc+ to +int_enc+ upon input, and written strings will be
7357  * converted from +int_enc+ to +ext_enc+ upon output. See Encoding for
7358  * further details of transcoding on input and output.
7359  *
7360  * If "BOM|UTF-8", "BOM|UTF-16LE" or "BOM|UTF16-BE" are used, ruby checks for
7361  * a Unicode BOM in the input document to help determine the encoding. For
7362  * UTF-16 encodings the file open mode must be binary. When present, the BOM
7363  * is stripped and the external encoding from the BOM is used. When the BOM
7364  * is missing the given Unicode encoding is used as +ext_enc+. (The BOM-set
7365  * encoding option is case insensitive, so "bom|utf-8" is also valid.)
7366  *
7367  * === Options
7368  *
7369  * +opt+ can be used instead of +mode+ for improved readability. The
7370  * following keys are supported:
7371  *
7372  * :mode ::
7373  * Same as +mode+ parameter
7374  *
7375  * :\external_encoding ::
7376  * External encoding for the IO. "-" is a synonym for the default external
7377  * encoding.
7378  *
7379  * :\internal_encoding ::
7380  * Internal encoding for the IO. "-" is a synonym for the default internal
7381  * encoding.
7382  *
7383  * If the value is nil no conversion occurs.
7384  *
7385  * :encoding ::
7386  * Specifies external and internal encodings as "extern:intern".
7387  *
7388  * :textmode ::
7389  * If the value is truth value, same as "t" in argument +mode+.
7390  *
7391  * :binmode ::
7392  * If the value is truth value, same as "b" in argument +mode+.
7393  *
7394  * :autoclose ::
7395  * If the value is +false+, the +fd+ will be kept open after this IO
7396  * instance gets finalized.
7397  *
7398  * Also, +opt+ can have same keys in String#encode for controlling conversion
7399  * between the external encoding and the internal encoding.
7400  *
7401  * === Example 1
7402  *
7403  * fd = IO.sysopen("/dev/tty", "w")
7404  * a = IO.new(fd,"w")
7405  * $stderr.puts "Hello"
7406  * a.puts "World"
7407  *
7408  * Produces:
7409  *
7410  * Hello
7411  * World
7412  *
7413  * === Example 2
7414  *
7415  * require 'fcntl'
7416  *
7417  * fd = STDERR.fcntl(Fcntl::F_DUPFD)
7418  * io = IO.new(fd, mode: 'w:UTF-16LE', cr_newline: true)
7419  * io.puts "Hello, World!"
7420  *
7421  * fd = STDERR.fcntl(Fcntl::F_DUPFD)
7422  * io = IO.new(fd, mode: 'w', cr_newline: true,
7423  * external_encoding: Encoding::UTF_16LE)
7424  * io.puts "Hello, World!"
7425  *
7426  * Both of above print "Hello, World!" in UTF-16LE to standard error output
7427  * with converting EOL generated by <code>puts</code> to CR.
7428  */
7429 
7430 static VALUE
7432 {
7433  VALUE fnum, vmode;
7434  rb_io_t *fp;
7435  int fd, fmode, oflags = O_RDONLY;
7436  convconfig_t convconfig;
7437  VALUE opt;
7438 #if defined(HAVE_FCNTL) && defined(F_GETFL)
7439  int ofmode;
7440 #else
7441  struct stat st;
7442 #endif
7443 
7444 
7445  argc = rb_scan_args(argc, argv, "11:", &fnum, &vmode, &opt);
7446  rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &fmode, &convconfig);
7447 
7448  fd = NUM2INT(fnum);
7449  if (rb_reserved_fd_p(fd)) {
7450  rb_raise(rb_eArgError, "The given fd is not accessible because RubyVM reserves it");
7451  }
7452 #if defined(HAVE_FCNTL) && defined(F_GETFL)
7453  oflags = fcntl(fd, F_GETFL);
7454  if (oflags == -1) rb_sys_fail(0);
7455 #else
7456  if (fstat(fd, &st) == -1) rb_sys_fail(0);
7457 #endif
7458  rb_update_max_fd(fd);
7459 #if defined(HAVE_FCNTL) && defined(F_GETFL)
7460  ofmode = rb_io_oflags_fmode(oflags);
7461  if (NIL_P(vmode)) {
7462  fmode = ofmode;
7463  }
7464  else if ((~ofmode & fmode) & FMODE_READWRITE) {
7465  VALUE error = INT2FIX(EINVAL);
7467  }
7468 #endif
7469  if (!NIL_P(opt) && rb_hash_aref(opt, sym_autoclose) == Qfalse) {
7470  fmode |= FMODE_PREP;
7471  }
7472  MakeOpenFile(io, fp);
7473  fp->fd = fd;
7474  fp->mode = fmode;
7475  fp->encs = convconfig;
7476  clear_codeconv(fp);
7477  io_check_tty(fp);
7478  if (fileno(stdin) == fd)
7479  fp->stdio_file = stdin;
7480  else if (fileno(stdout) == fd)
7481  fp->stdio_file = stdout;
7482  else if (fileno(stderr) == fd)
7483  fp->stdio_file = stderr;
7484 
7486  return io;
7487 }
7488 
7489 /*
7490  * call-seq:
7491  * File.new(filename, mode="r" [, opt]) -> file
7492  * File.new(filename [, mode [, perm]] [, opt]) -> file
7493  *
7494  * Opens the file named by +filename+ according to the given +mode+ and
7495  * returns a new File object.
7496  *
7497  * See IO.new for a description of +mode+ and +opt+.
7498  *
7499  * If a file is being created, permission bits may be given in +perm+. These
7500  * mode and permission bits are platform dependent; on Unix systems, see
7501  * open(2) and chmod(2) man pages for details.
7502  *
7503  * === Examples
7504  *
7505  * f = File.new("testfile", "r")
7506  * f = File.new("newfile", "w+")
7507  * f = File.new("newfile", File::CREAT|File::TRUNC|File::RDWR, 0644)
7508  */
7509 
7510 static VALUE
7512 {
7513  if (RFILE(io)->fptr) {
7514  rb_raise(rb_eRuntimeError, "reinitializing File");
7515  }
7516  if (0 < argc && argc < 3) {
7517  VALUE fd = rb_check_convert_type(argv[0], T_FIXNUM, "Fixnum", "to_int");
7518 
7519  if (!NIL_P(fd)) {
7520  argv[0] = fd;
7521  return rb_io_initialize(argc, argv, io);
7522  }
7523  }
7524  rb_open_file(argc, argv, io);
7525 
7526  return io;
7527 }
7528 
7529 /* :nodoc: */
7530 static VALUE
7532 {
7533  if (rb_block_given_p()) {
7534  const char *cname = rb_class2name(klass);
7535 
7536  rb_warn("%s::new() does not take block; use %s::open() instead",
7537  cname, cname);
7538  }
7539  return rb_class_new_instance(argc, argv, klass);
7540 }
7541 
7542 
7543 /*
7544  * call-seq:
7545  * IO.for_fd(fd, mode [, opt]) -> io
7546  *
7547  * Synonym for <code>IO.new</code>.
7548  *
7549  */
7550 
7551 static VALUE
7553 {
7554  VALUE io = rb_obj_alloc(klass);
7555  rb_io_initialize(argc, argv, io);
7556  return io;
7557 }
7558 
7559 /*
7560  * call-seq:
7561  * ios.autoclose? -> true or false
7562  *
7563  * Returns +true+ if the underlying file descriptor of _ios_ will be
7564  * closed automatically at its finalization, otherwise +false+.
7565  */
7566 
7567 static VALUE
7569 {
7570  rb_io_t *fptr = RFILE(io)->fptr;
7571  rb_io_check_closed(fptr);
7572  return (fptr->mode & FMODE_PREP) ? Qfalse : Qtrue;
7573 }
7574 
7575 /*
7576  * call-seq:
7577  * io.autoclose = bool -> true or false
7578  *
7579  * Sets auto-close flag.
7580  *
7581  * f = open("/dev/null")
7582  * IO.for_fd(f.fileno)
7583  * # ...
7584  * f.gets # may cause IOError
7585  *
7586  * f = open("/dev/null")
7587  * IO.for_fd(f.fileno).autoclose = true
7588  * # ...
7589  * f.gets # won't cause IOError
7590  */
7591 
7592 static VALUE
7594 {
7595  rb_io_t *fptr;
7596  GetOpenFile(io, fptr);
7597  if (!RTEST(autoclose))
7598  fptr->mode |= FMODE_PREP;
7599  else
7600  fptr->mode &= ~FMODE_PREP;
7601  return io;
7602 }
7603 
7604 static void
7605 argf_mark(void *ptr)
7606 {
7607  struct argf *p = ptr;
7608  rb_gc_mark(p->filename);
7610  rb_gc_mark(p->argv);
7611  rb_gc_mark(p->encs.ecopts);
7612 }
7613 
7614 static void
7615 argf_free(void *ptr)
7616 {
7617  struct argf *p = ptr;
7618  xfree(p->inplace);
7619  xfree(p);
7620 }
7621 
7622 static size_t
7623 argf_memsize(const void *ptr)
7624 {
7625  const struct argf *p = ptr;
7626  size_t size = sizeof(*p);
7627  if (!ptr) return 0;
7628  if (p->inplace) size += strlen(p->inplace) + 1;
7629  return size;
7630 }
7631 
7632 static const rb_data_type_t argf_type = {
7633  "ARGF",
7636 };
7637 
7638 static inline void
7639 argf_init(struct argf *p, VALUE v)
7640 {
7641  p->filename = Qnil;
7642  p->current_file = Qnil;
7643  p->lineno = 0;
7644  p->argv = v;
7645 }
7646 
7647 static VALUE
7649 {
7650  struct argf *p;
7651  VALUE argf = TypedData_Make_Struct(klass, struct argf, &argf_type, p);
7652 
7653  argf_init(p, Qnil);
7654  return argf;
7655 }
7656 
7657 #undef rb_argv
7658 
7659 /* :nodoc: */
7660 static VALUE
7662 {
7663  memset(&ARGF, 0, sizeof(ARGF));
7664  argf_init(&ARGF, argv);
7665 
7666  return argf;
7667 }
7668 
7669 /* :nodoc: */
7670 static VALUE
7672 {
7673  if (!OBJ_INIT_COPY(argf, orig)) return argf;
7674  ARGF = argf_of(orig);
7675  ARGF.argv = rb_obj_dup(ARGF.argv);
7676  if (ARGF.inplace) {
7677  const char *inplace = ARGF.inplace;
7678  ARGF.inplace = 0;
7679  ARGF.inplace = ruby_strdup(inplace);
7680  }
7681  return argf;
7682 }
7683 
7684 /*
7685  * call-seq:
7686  * ARGF.lineno = integer -> integer
7687  *
7688  * Sets the line number of +ARGF+ as a whole to the given +Integer+.
7689  *
7690  * +ARGF+ sets the line number automatically as you read data, so normally
7691  * you will not need to set it explicitly. To access the current line number
7692  * use +ARGF.lineno+.
7693  *
7694  * For example:
7695  *
7696  * ARGF.lineno #=> 0
7697  * ARGF.readline #=> "This is line 1\n"
7698  * ARGF.lineno #=> 1
7699  * ARGF.lineno = 0 #=> 0
7700  * ARGF.lineno #=> 0
7701  */
7702 static VALUE
7704 {
7705  ARGF.lineno = NUM2INT(val);
7706  ARGF.last_lineno = ARGF.lineno;
7707  return Qnil;
7708 }
7709 
7710 /*
7711  * call-seq:
7712  * ARGF.lineno -> integer
7713  *
7714  * Returns the current line number of ARGF as a whole. This value
7715  * can be set manually with +ARGF.lineno=+.
7716  *
7717  * For example:
7718  *
7719  * ARGF.lineno #=> 0
7720  * ARGF.readline #=> "This is line 1\n"
7721  * ARGF.lineno #=> 1
7722  */
7723 static VALUE
7725 {
7726  return INT2FIX(ARGF.lineno);
7727 }
7728 
7729 static VALUE
7731 {
7732  return rb_funcall3(ARGF.current_file, rb_frame_this_func(), argc, argv);
7733 }
7734 
7735 #define next_argv() argf_next_argv(argf)
7736 #define ARGF_GENERIC_INPUT_P() \
7737  (ARGF.current_file == rb_stdin && !RB_TYPE_P(ARGF.current_file, T_FILE))
7738 #define ARGF_FORWARD(argc, argv) do {\
7739  if (ARGF_GENERIC_INPUT_P())\
7740  return argf_forward((argc), (argv), argf);\
7741 } while (0)
7742 #define NEXT_ARGF_FORWARD(argc, argv) do {\
7743  if (!next_argv()) return Qnil;\
7744  ARGF_FORWARD((argc), (argv));\
7745 } while (0)
7746 
7747 static void
7749 {
7750  VALUE file = ARGF.current_file;
7751  if (file == rb_stdin) return;
7752  if (RB_TYPE_P(file, T_FILE)) {
7753  rb_io_set_write_io(file, Qnil);
7754  }
7755  rb_funcall3(file, rb_intern("close"), 0, 0);
7756  ARGF.init_p = -1;
7757 }
7758 
7759 static int
7761 {
7762  char *fn;
7763  rb_io_t *fptr;
7764  int stdout_binmode = 0;
7765  int fmode;
7766 
7767  if (RB_TYPE_P(rb_stdout, T_FILE)) {
7768  GetOpenFile(rb_stdout, fptr);
7769  if (fptr->mode & FMODE_BINMODE)
7770  stdout_binmode = 1;
7771  }
7772 
7773  if (ARGF.init_p == 0) {
7774  if (!NIL_P(ARGF.argv) && RARRAY_LEN(ARGF.argv) > 0) {
7775  ARGF.next_p = 1;
7776  }
7777  else {
7778  ARGF.next_p = -1;
7779  }
7780  ARGF.init_p = 1;
7781  }
7782  else {
7783  if (NIL_P(ARGF.argv)) {
7784  ARGF.next_p = -1;
7785  }
7786  else if (ARGF.next_p == -1 && RARRAY_LEN(ARGF.argv) > 0) {
7787  ARGF.next_p = 1;
7788  }
7789  }
7790 
7791  if (ARGF.next_p == 1) {
7792  retry:
7793  if (RARRAY_LEN(ARGF.argv) > 0) {
7794  ARGF.filename = rb_ary_shift(ARGF.argv);
7795  fn = StringValueCStr(ARGF.filename);
7796  if (strlen(fn) == 1 && fn[0] == '-') {
7797  ARGF.current_file = rb_stdin;
7798  if (ARGF.inplace) {
7799  rb_warn("Can't do inplace edit for stdio; skipping");
7800  goto retry;
7801  }
7802  }
7803  else {
7804  VALUE write_io = Qnil;
7805  int fr = rb_sysopen(ARGF.filename, O_RDONLY, 0);
7806 
7807  if (ARGF.inplace) {
7808  struct stat st;
7809 #ifndef NO_SAFE_RENAME
7810  struct stat st2;
7811 #endif
7812  VALUE str;
7813  int fw;
7814 
7817  }
7818  fstat(fr, &st);
7819  if (*ARGF.inplace) {
7820  str = rb_str_new2(fn);
7821  rb_str_cat2(str, ARGF.inplace);
7822 #ifdef NO_SAFE_RENAME
7823  (void)close(fr);
7824  (void)unlink(RSTRING_PTR(str));
7825  if (rename(fn, RSTRING_PTR(str)) < 0) {
7826  rb_warn("Can't rename %s to %s: %s, skipping file",
7827  fn, RSTRING_PTR(str), strerror(errno));
7828  goto retry;
7829  }
7830  fr = rb_sysopen(str, O_RDONLY, 0);
7831 #else
7832  if (rename(fn, RSTRING_PTR(str)) < 0) {
7833  rb_warn("Can't rename %s to %s: %s, skipping file",
7834  fn, RSTRING_PTR(str), strerror(errno));
7835  close(fr);
7836  goto retry;
7837  }
7838 #endif
7839  }
7840  else {
7841 #ifdef NO_SAFE_RENAME
7842  rb_fatal("Can't do inplace edit without backup");
7843 #else
7844  if (unlink(fn) < 0) {
7845  rb_warn("Can't remove %s: %s, skipping file",
7846  fn, strerror(errno));
7847  close(fr);
7848  goto retry;
7849  }
7850 #endif
7851  }
7852  fw = rb_sysopen(ARGF.filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
7853 #ifndef NO_SAFE_RENAME
7854  fstat(fw, &st2);
7855 #ifdef HAVE_FCHMOD
7856  fchmod(fw, st.st_mode);
7857 #else
7858  chmod(fn, st.st_mode);
7859 #endif
7860  if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) {
7861  int err;
7862 #ifdef HAVE_FCHOWN
7863  err = fchown(fw, st.st_uid, st.st_gid);
7864 #else
7865  err = chown(fn, st.st_uid, st.st_gid);
7866 #endif
7867  if (err && getuid() == 0 && st2.st_uid == 0) {
7868  const char *wkfn = RSTRING_PTR(ARGF.filename);
7869  rb_warn("Can't set owner/group of %s to same as %s: %s, skipping file",
7870  wkfn, fn, strerror(errno));
7871  (void)close(fr);
7872  (void)close(fw);
7873  (void)unlink(wkfn);
7874  goto retry;
7875  }
7876  }
7877 #endif
7878  write_io = prep_io(fw, FMODE_WRITABLE, rb_cFile, fn);
7879  rb_stdout = write_io;
7880  if (stdout_binmode) rb_io_binmode(rb_stdout);
7881  }
7882  fmode = FMODE_READABLE;
7883  if (!ARGF.binmode) {
7884  fmode |= DEFAULT_TEXTMODE;
7885  }
7886  ARGF.current_file = prep_io(fr, fmode, rb_cFile, fn);
7887  if (!NIL_P(write_io)) {
7888  rb_io_set_write_io(ARGF.current_file, write_io);
7889  }
7890  }
7891  if (ARGF.binmode) rb_io_ascii8bit_binmode(ARGF.current_file);
7892  GetOpenFile(ARGF.current_file, fptr);
7893  if (ARGF.encs.enc) {
7894  fptr->encs = ARGF.encs;
7895  clear_codeconv(fptr);
7896  }
7897  else {
7899  if (!ARGF.binmode) {
7901 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
7902  fptr->encs.ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
7903 #endif
7904  }
7905  }
7906  ARGF.next_p = 0;
7907  }
7908  else {
7909  ARGF.next_p = 1;
7910  return FALSE;
7911  }
7912  }
7913  else if (ARGF.next_p == -1) {
7914  ARGF.current_file = rb_stdin;
7915  ARGF.filename = rb_str_new2("-");
7916  if (ARGF.inplace) {
7917  rb_warn("Can't do inplace edit for stdio");
7919  }
7920  }
7921  if (ARGF.init_p == -1) ARGF.init_p = 1;
7922  return TRUE;
7923 }
7924 
7925 static VALUE
7927 {
7928  VALUE line;
7929  long lineno = ARGF.lineno;
7930 
7931  retry:
7932  if (!next_argv()) return Qnil;
7933  if (ARGF_GENERIC_INPUT_P()) {
7934  line = rb_funcall3(ARGF.current_file, idGets, argc, argv);
7935  }
7936  else {
7937  if (argc == 0 && rb_rs == rb_default_rs) {
7938  line = rb_io_gets(ARGF.current_file);
7939  }
7940  else {
7941  line = rb_io_getline(argc, argv, ARGF.current_file);
7942  }
7943  if (NIL_P(line) && ARGF.next_p != -1) {
7944  argf_close(argf);
7945  ARGF.next_p = 1;
7946  goto retry;
7947  }
7948  }
7949  if (!NIL_P(line)) {
7950  ARGF.lineno = ++lineno;
7951  ARGF.last_lineno = ARGF.lineno;
7952  }
7953  return line;
7954 }
7955 
7956 static VALUE
7958 {
7959  VALUE argf = *var;
7960  return INT2FIX(ARGF.last_lineno);
7961 }
7962 
7963 static void
7965 {
7966  VALUE argf = *var;
7967  int n = NUM2INT(val);
7968  ARGF.last_lineno = ARGF.lineno = n;
7969 }
7970 
7971 static VALUE argf_gets(int, VALUE *, VALUE);
7972 
7973 /*
7974  * call-seq:
7975  * gets(sep=$/) -> string or nil
7976  * gets(limit) -> string or nil
7977  * gets(sep,limit) -> string or nil
7978  *
7979  * Returns (and assigns to <code>$_</code>) the next line from the list
7980  * of files in +ARGV+ (or <code>$*</code>), or from standard input if
7981  * no files are present on the command line. Returns +nil+ at end of
7982  * file. The optional argument specifies the record separator. The
7983  * separator is included with the contents of each record. A separator
7984  * of +nil+ reads the entire contents, and a zero-length separator
7985  * reads the input one paragraph at a time, where paragraphs are
7986  * divided by two consecutive newlines. If the first argument is an
7987  * integer, or optional second argument is given, the returning string
7988  * would not be longer than the given value in bytes. If multiple
7989  * filenames are present in +ARGV+, +gets(nil)+ will read the contents
7990  * one file at a time.
7991  *
7992  * ARGV << "testfile"
7993  * print while gets
7994  *
7995  * <em>produces:</em>
7996  *
7997  * This is line one
7998  * This is line two
7999  * This is line three
8000  * And so on...
8001  *
8002  * The style of programming using <code>$_</code> as an implicit
8003  * parameter is gradually losing favor in the Ruby community.
8004  */
8005 
8006 static VALUE
8008 {
8009  if (recv == argf) {
8010  return argf_gets(argc, argv, argf);
8011  }
8012  return rb_funcall2(argf, idGets, argc, argv);
8013 }
8014 
8015 /*
8016  * call-seq:
8017  * ARGF.gets(sep=$/) -> string or nil
8018  * ARGF.gets(limit) -> string or nil
8019  * ARGF.gets(sep, limit) -> string or nil
8020  *
8021  * Returns the next line from the current file in +ARGF+.
8022  *
8023  * By default lines are assumed to be separated by +$/+; to use a different
8024  * character as a separator, supply it as a +String+ for the _sep_ argument.
8025  *
8026  * The optional _limit_ argument specifies how many characters of each line
8027  * to return. By default all characters are returned.
8028  *
8029  */
8030 static VALUE
8032 {
8033  VALUE line;
8034 
8035  line = argf_getline(argc, argv, argf);
8036  rb_lastline_set(line);
8037 
8038  return line;
8039 }
8040 
8041 VALUE
8042 rb_gets(void)
8043 {
8044  VALUE line;
8045 
8046  if (rb_rs != rb_default_rs) {
8047  return rb_f_gets(0, 0, argf);
8048  }
8049 
8050  retry:
8051  if (!next_argv()) return Qnil;
8052  line = rb_io_gets(ARGF.current_file);
8053  if (NIL_P(line) && ARGF.next_p != -1) {
8054  rb_io_close(ARGF.current_file);
8055  ARGF.next_p = 1;
8056  goto retry;
8057  }
8058  rb_lastline_set(line);
8059  if (!NIL_P(line)) {
8060  ARGF.lineno++;
8061  ARGF.last_lineno = ARGF.lineno;
8062  }
8063 
8064  return line;
8065 }
8066 
8067 static VALUE argf_readline(int, VALUE *, VALUE);
8068 
8069 /*
8070  * call-seq:
8071  * readline(sep=$/) -> string
8072  * readline(limit) -> string
8073  * readline(sep, limit) -> string
8074  *
8075  * Equivalent to <code>Kernel::gets</code>, except
8076  * +readline+ raises +EOFError+ at end of file.
8077  */
8078 
8079 static VALUE
8081 {
8082  if (recv == argf) {
8083  return argf_readline(argc, argv, argf);
8084  }
8085  return rb_funcall2(argf, rb_intern("readline"), argc, argv);
8086 }
8087 
8088 
8089 /*
8090  * call-seq:
8091  * ARGF.readline(sep=$/) -> string
8092  * ARGF.readline(limit) -> string
8093  * ARGF.readline(sep, limit) -> string
8094  *
8095  * Returns the next line from the current file in +ARGF+.
8096  *
8097  * By default lines are assumed to be separated by +$/+; to use a different
8098  * character as a separator, supply it as a +String+ for the _sep_ argument.
8099  *
8100  * The optional _limit_ argument specifies how many characters of each line
8101  * to return. By default all characters are returned.
8102  *
8103  * An +EOFError+ is raised at the end of the file.
8104  */
8105 static VALUE
8107 {
8108  VALUE line;
8109 
8110  if (!next_argv()) rb_eof_error();
8111  ARGF_FORWARD(argc, argv);
8112  line = argf_gets(argc, argv, argf);
8113  if (NIL_P(line)) {
8114  rb_eof_error();
8115  }
8116 
8117  return line;
8118 }
8119 
8120 static VALUE argf_readlines(int, VALUE *, VALUE);
8121 
8122 /*
8123  * call-seq:
8124  * readlines(sep=$/) -> array
8125  * readlines(limit) -> array
8126  * readlines(sep,limit) -> array
8127  *
8128  * Returns an array containing the lines returned by calling
8129  * <code>Kernel.gets(<i>sep</i>)</code> until the end of file.
8130  */
8131 
8132 static VALUE
8134 {
8135  if (recv == argf) {
8136  return argf_readlines(argc, argv, argf);
8137  }
8138  return rb_funcall2(argf, rb_intern("readlines"), argc, argv);
8139 }
8140 
8141 /*
8142  * call-seq:
8143  * ARGF.readlines(sep=$/) -> array
8144  * ARGF.readlines(limit) -> array
8145  * ARGF.readlines(sep, limit) -> array
8146  *
8147  * ARGF.to_a(sep=$/) -> array
8148  * ARGF.to_a(limit) -> array
8149  * ARGF.to_a(sep, limit) -> array
8150  *
8151  * Reads +ARGF+'s current file in its entirety, returning an +Array+ of its
8152  * lines, one line per element. Lines are assumed to be separated by _sep_.
8153  *
8154  * lines = ARGF.readlines
8155  * lines[0] #=> "This is line one\n"
8156  */
8157 static VALUE
8159 {
8160  long lineno = ARGF.lineno;
8161  VALUE lines, ary;
8162 
8163  ary = rb_ary_new();
8164  while (next_argv()) {
8165  if (ARGF_GENERIC_INPUT_P()) {
8166  lines = rb_funcall3(ARGF.current_file, rb_intern("readlines"), argc, argv);
8167  }
8168  else {
8169  lines = rb_io_readlines(argc, argv, ARGF.current_file);
8170  argf_close(argf);
8171  }
8172  ARGF.next_p = 1;
8173  rb_ary_concat(ary, lines);
8174  ARGF.lineno = lineno + RARRAY_LEN(ary);
8175  ARGF.last_lineno = ARGF.lineno;
8176  }
8177  ARGF.init_p = 0;
8178  return ary;
8179 }
8180 
8181 /*
8182  * call-seq:
8183  * `cmd` -> string
8184  *
8185  * Returns the standard output of running _cmd_ in a subshell.
8186  * The built-in syntax <code>%x{...}</code> uses
8187  * this method. Sets <code>$?</code> to the process status.
8188  *
8189  * `date` #=> "Wed Apr 9 08:56:30 CDT 2003\n"
8190  * `ls testdir`.split[1] #=> "main.rb"
8191  * `echo oops && exit 99` #=> "oops\n"
8192  * $?.exitstatus #=> 99
8193  */
8194 
8195 static VALUE
8197 {
8198  volatile VALUE port;
8199  VALUE result;
8200  rb_io_t *fptr;
8201 
8202  SafeStringValue(str);
8204  port = pipe_open_s(str, "r", FMODE_READABLE|DEFAULT_TEXTMODE, NULL);
8205  if (NIL_P(port)) return rb_str_new(0,0);
8206 
8207  GetOpenFile(port, fptr);
8208  result = read_all(fptr, remain_size(fptr), Qnil);
8209  rb_io_close(port);
8210 
8211  return result;
8212 }
8213 
8214 #ifdef HAVE_SYS_SELECT_H
8215 #include <sys/select.h>
8216 #endif
8217 
8218 static VALUE
8219 select_internal(VALUE read, VALUE write, VALUE except, struct timeval *tp, rb_fdset_t *fds)
8220 {
8221  VALUE res, list;
8222  rb_fdset_t *rp, *wp, *ep;
8223  rb_io_t *fptr;
8224  long i;
8225  int max = 0, n;
8226  int pending = 0;
8227  struct timeval timerec;
8228 
8229  if (!NIL_P(read)) {
8230  Check_Type(read, T_ARRAY);
8231  for (i=0; i<RARRAY_LEN(read); i++) {
8232  GetOpenFile(rb_io_get_io(RARRAY_AREF(read, i)), fptr);
8233  rb_fd_set(fptr->fd, &fds[0]);
8234  if (READ_DATA_PENDING(fptr) || READ_CHAR_PENDING(fptr)) { /* check for buffered data */
8235  pending++;
8236  rb_fd_set(fptr->fd, &fds[3]);
8237  }
8238  if (max < fptr->fd) max = fptr->fd;
8239  }
8240  if (pending) { /* no blocking if there's buffered data */
8241  timerec.tv_sec = timerec.tv_usec = 0;
8242  tp = &timerec;
8243  }
8244  rp = &fds[0];
8245  }
8246  else
8247  rp = 0;
8248 
8249  if (!NIL_P(write)) {
8250  Check_Type(write, T_ARRAY);
8251  for (i=0; i<RARRAY_LEN(write); i++) {
8252  VALUE write_io = GetWriteIO(rb_io_get_io(RARRAY_AREF(write, i)));
8253  GetOpenFile(write_io, fptr);
8254  rb_fd_set(fptr->fd, &fds[1]);
8255  if (max < fptr->fd) max = fptr->fd;
8256  }
8257  wp = &fds[1];
8258  }
8259  else
8260  wp = 0;
8261 
8262  if (!NIL_P(except)) {
8263  Check_Type(except, T_ARRAY);
8264  for (i=0; i<RARRAY_LEN(except); i++) {
8265  VALUE io = rb_io_get_io(RARRAY_AREF(except, i));
8266  VALUE write_io = GetWriteIO(io);
8267  GetOpenFile(io, fptr);
8268  rb_fd_set(fptr->fd, &fds[2]);
8269  if (max < fptr->fd) max = fptr->fd;
8270  if (io != write_io) {
8271  GetOpenFile(write_io, fptr);
8272  rb_fd_set(fptr->fd, &fds[2]);
8273  if (max < fptr->fd) max = fptr->fd;
8274  }
8275  }
8276  ep = &fds[2];
8277  }
8278  else {
8279  ep = 0;
8280  }
8281 
8282  max++;
8283 
8284  n = rb_thread_fd_select(max, rp, wp, ep, tp);
8285  if (n < 0) {
8286  rb_sys_fail(0);
8287  }
8288  if (!pending && n == 0) return Qnil; /* returns nil on timeout */
8289 
8290  res = rb_ary_new2(3);
8291  rb_ary_push(res, rp?rb_ary_new():rb_ary_new2(0));
8292  rb_ary_push(res, wp?rb_ary_new():rb_ary_new2(0));
8293  rb_ary_push(res, ep?rb_ary_new():rb_ary_new2(0));
8294 
8295  if (rp) {
8296  list = RARRAY_AREF(res, 0);
8297  for (i=0; i< RARRAY_LEN(read); i++) {
8298  VALUE obj = rb_ary_entry(read, i);
8299  VALUE io = rb_io_get_io(obj);
8300  GetOpenFile(io, fptr);
8301  if (rb_fd_isset(fptr->fd, &fds[0]) ||
8302  rb_fd_isset(fptr->fd, &fds[3])) {
8303  rb_ary_push(list, obj);
8304  }
8305  }
8306  }
8307 
8308  if (wp) {
8309  list = RARRAY_AREF(res, 1);
8310  for (i=0; i< RARRAY_LEN(write); i++) {
8311  VALUE obj = rb_ary_entry(write, i);
8312  VALUE io = rb_io_get_io(obj);
8313  VALUE write_io = GetWriteIO(io);
8314  GetOpenFile(write_io, fptr);
8315  if (rb_fd_isset(fptr->fd, &fds[1])) {
8316  rb_ary_push(list, obj);
8317  }
8318  }
8319  }
8320 
8321  if (ep) {
8322  list = RARRAY_AREF(res, 2);
8323  for (i=0; i< RARRAY_LEN(except); i++) {
8324  VALUE obj = rb_ary_entry(except, i);
8325  VALUE io = rb_io_get_io(obj);
8326  VALUE write_io = GetWriteIO(io);
8327  GetOpenFile(io, fptr);
8328  if (rb_fd_isset(fptr->fd, &fds[2])) {
8329  rb_ary_push(list, obj);
8330  }
8331  else if (io != write_io) {
8332  GetOpenFile(write_io, fptr);
8333  if (rb_fd_isset(fptr->fd, &fds[2])) {
8334  rb_ary_push(list, obj);
8335  }
8336  }
8337  }
8338  }
8339 
8340  return res; /* returns an empty array on interrupt */
8341 }
8342 
8343 struct select_args {
8345  struct timeval *timeout;
8347 };
8348 
8349 static VALUE
8351 {
8352  struct select_args *p = (struct select_args *)arg;
8353 
8354  return select_internal(p->read, p->write, p->except, p->timeout, p->fdsets);
8355 }
8356 
8357 static VALUE
8359 {
8360  struct select_args *p = (struct select_args *)arg;
8361  int i;
8362 
8363  for (i = 0; i < numberof(p->fdsets); ++i)
8364  rb_fd_term(&p->fdsets[i]);
8365  return Qnil;
8366 }
8367 
8370 
8371 #ifdef HAVE_POSIX_FADVISE
8372 struct io_advise_struct {
8373  int fd;
8374  off_t offset;
8375  off_t len;
8376  int advice;
8377 };
8378 
8379 static VALUE
8380 io_advise_internal(void *arg)
8381 {
8382  struct io_advise_struct *ptr = arg;
8383  return posix_fadvise(ptr->fd, ptr->offset, ptr->len, ptr->advice);
8384 }
8385 
8386 static VALUE
8387 io_advise_sym_to_const(VALUE sym)
8388 {
8389 #ifdef POSIX_FADV_NORMAL
8390  if (sym == sym_normal)
8391  return INT2NUM(POSIX_FADV_NORMAL);
8392 #endif
8393 
8394 #ifdef POSIX_FADV_RANDOM
8395  if (sym == sym_random)
8396  return INT2NUM(POSIX_FADV_RANDOM);
8397 #endif
8398 
8399 #ifdef POSIX_FADV_SEQUENTIAL
8400  if (sym == sym_sequential)
8401  return INT2NUM(POSIX_FADV_SEQUENTIAL);
8402 #endif
8403 
8404 #ifdef POSIX_FADV_WILLNEED
8405  if (sym == sym_willneed)
8406  return INT2NUM(POSIX_FADV_WILLNEED);
8407 #endif
8408 
8409 #ifdef POSIX_FADV_DONTNEED
8410  if (sym == sym_dontneed)
8411  return INT2NUM(POSIX_FADV_DONTNEED);
8412 #endif
8413 
8414 #ifdef POSIX_FADV_NOREUSE
8415  if (sym == sym_noreuse)
8416  return INT2NUM(POSIX_FADV_NOREUSE);
8417 #endif
8418 
8419  return Qnil;
8420 }
8421 
8422 static VALUE
8423 do_io_advise(rb_io_t *fptr, VALUE advice, off_t offset, off_t len)
8424 {
8425  int rv;
8426  struct io_advise_struct ias;
8427  VALUE num_adv;
8428 
8429  num_adv = io_advise_sym_to_const(advice);
8430 
8431  /*
8432  * The platform doesn't support this hint. We don't raise exception, instead
8433  * silently ignore it. Because IO::advise is only hint.
8434  */
8435  if (NIL_P(num_adv))
8436  return Qnil;
8437 
8438  ias.fd = fptr->fd;
8439  ias.advice = NUM2INT(num_adv);
8440  ias.offset = offset;
8441  ias.len = len;
8442 
8443  rv = (int)rb_thread_io_blocking_region(io_advise_internal, &ias, fptr->fd);
8444  if (rv) {
8445  /* posix_fadvise(2) doesn't set errno. On success it returns 0; otherwise
8446  it returns the error code. */
8447  rb_syserr_fail_str(rv, fptr->pathv);
8448  }
8449 
8450  return Qnil;
8451 }
8452 
8453 #endif /* HAVE_POSIX_FADVISE */
8454 
8455 static void
8457 {
8458  if (!SYMBOL_P(advice))
8459  rb_raise(rb_eTypeError, "advice must be a Symbol");
8460 
8461  if (advice != sym_normal &&
8462  advice != sym_sequential &&
8463  advice != sym_random &&
8464  advice != sym_willneed &&
8465  advice != sym_dontneed &&
8466  advice != sym_noreuse) {
8467  VALUE symname = rb_inspect(advice);
8468  rb_raise(rb_eNotImpError, "Unsupported advice: %s",
8469  StringValuePtr(symname));
8470  }
8471 }
8472 
8473 /*
8474  * call-seq:
8475  * ios.advise(advice, offset=0, len=0) -> nil
8476  *
8477  * Announce an intention to access data from the current file in a
8478  * specific pattern. On platforms that do not support the
8479  * <em>posix_fadvise(2)</em> system call, this method is a no-op.
8480  *
8481  * _advice_ is one of the following symbols:
8482  *
8483  * :normal:: No advice to give; the default assumption for an open file.
8484  * :sequential:: The data will be accessed sequentially
8485  * with lower offsets read before higher ones.
8486  * :random:: The data will be accessed in random order.
8487  * :willneed:: The data will be accessed in the near future.
8488  * :dontneed:: The data will not be accessed in the near future.
8489  * :noreuse:: The data will only be accessed once.
8490  *
8491  * The semantics of a piece of advice are platform-dependent. See
8492  * <em>man 2 posix_fadvise</em> for details.
8493  *
8494  * "data" means the region of the current file that begins at
8495  * _offset_ and extends for _len_ bytes. If _len_ is 0, the region
8496  * ends at the last byte of the file. By default, both _offset_ and
8497  * _len_ are 0, meaning that the advice applies to the entire file.
8498  *
8499  * If an error occurs, one of the following exceptions will be raised:
8500  *
8501  * <code>IOError</code>:: The <code>IO</code> stream is closed.
8502  * <code>Errno::EBADF</code>::
8503  * The file descriptor of the current file is invalid.
8504  * <code>Errno::EINVAL</code>:: An invalid value for _advice_ was given.
8505  * <code>Errno::ESPIPE</code>::
8506  * The file descriptor of the current file refers to a FIFO or
8507  * pipe. (Linux raises <code>Errno::EINVAL</code> in this case).
8508  * <code>TypeError</code>::
8509  * Either _advice_ was not a Symbol, or one of the
8510  * other arguments was not an <code>Integer</code>.
8511  * <code>RangeError</code>:: One of the arguments given was too big/small.
8512  *
8513  * This list is not exhaustive; other Errno:: exceptions are also possible.
8514  */
8515 static VALUE
8517 {
8518  VALUE advice, offset, len;
8519  off_t off, l;
8520  rb_io_t *fptr;
8521 
8522  rb_scan_args(argc, argv, "12", &advice, &offset, &len);
8523  advice_arg_check(advice);
8524 
8525  io = GetWriteIO(io);
8526  GetOpenFile(io, fptr);
8527 
8528  off = NIL_P(offset) ? 0 : NUM2OFFT(offset);
8529  l = NIL_P(len) ? 0 : NUM2OFFT(len);
8530 
8531 #ifdef HAVE_POSIX_FADVISE
8532  return do_io_advise(fptr, advice, off, l);
8533 #else
8534  ((void)off, (void)l); /* Ignore all hint */
8535  return Qnil;
8536 #endif
8537 }
8538 
8539 /*
8540  * call-seq:
8541  * IO.select(read_array
8542  * [, write_array
8543  * [, error_array
8544  * [, timeout]]]) -> array or nil
8545  *
8546  * Calls select(2) system call.
8547  * It monitors given arrays of <code>IO</code> objects, waits one or more
8548  * of <code>IO</code> objects ready for reading, are ready for writing,
8549  * and have pending exceptions respectively, and returns an array that
8550  * contains arrays of those IO objects. It will return <code>nil</code>
8551  * if optional <i>timeout</i> value is given and no <code>IO</code> object
8552  * is ready in <i>timeout</i> seconds.
8553  *
8554  * <code>IO.select</code> peeks the buffer of <code>IO</code> objects for testing readability.
8555  * If the <code>IO</code> buffer is not empty,
8556  * <code>IO.select</code> immediately notify readability.
8557  * This "peek" is only happen for <code>IO</code> objects.
8558  * It is not happen for IO-like objects such as OpenSSL::SSL::SSLSocket.
8559  *
8560  * The best way to use <code>IO.select</code> is invoking it
8561  * after nonblocking methods such as <code>read_nonblock</code>, <code>write_nonblock</code>, etc.
8562  * The methods raises an exception which is extended by
8563  * <code>IO::WaitReadable</code> or <code>IO::WaitWritable</code>.
8564  * The modules notify how the caller should wait with <code>IO.select</code>.
8565  * If <code>IO::WaitReadable</code> is raised, the caller should wait for reading.
8566  * If <code>IO::WaitWritable</code> is raised, the caller should wait for writing.
8567  *
8568  * So, blocking read (<code>readpartial</code>) can be emulated using
8569  * <code>read_nonblock</code> and <code>IO.select</code> as follows:
8570  *
8571  * begin
8572  * result = io_like.read_nonblock(maxlen)
8573  * rescue IO::WaitReadable
8574  * IO.select([io_like])
8575  * retry
8576  * rescue IO::WaitWritable
8577  * IO.select(nil, [io_like])
8578  * retry
8579  * end
8580  *
8581  * Especially, the combination of nonblocking methods and
8582  * <code>IO.select</code> is preferred for <code>IO</code> like
8583  * objects such as <code>OpenSSL::SSL::SSLSocket</code>.
8584  * It has <code>to_io</code> method to return underlying <code>IO</code> object.
8585  * <code>IO.select</code> calls <code>to_io</code> to obtain the file descriptor to wait.
8586  *
8587  * This means that readability notified by <code>IO.select</code> doesn't mean
8588  * readability from <code>OpenSSL::SSL::SSLSocket</code> object.
8589  *
8590  * Most possible situation is <code>OpenSSL::SSL::SSLSocket</code> buffers some data.
8591  * <code>IO.select</code> doesn't see the buffer.
8592  * So <code>IO.select</code> can block when <code>OpenSSL::SSL::SSLSocket#readpartial</code> doesn't block.
8593  *
8594  * However several more complicated situation exists.
8595  *
8596  * SSL is a protocol which is sequence of records.
8597  * The record consists multiple bytes.
8598  * So, the remote side of SSL sends a partial record,
8599  * <code>IO.select</code> notifies readability but
8600  * <code>OpenSSL::SSL::SSLSocket</code> cannot decrypt a byte and
8601  * <code>OpenSSL::SSL::SSLSocket#readpartial</code> will blocks.
8602  *
8603  * Also, the remote side can request SSL renegotiation which forces
8604  * the local SSL engine writes some data.
8605  * This means <code>OpenSSL::SSL::SSLSocket#readpartial</code> may
8606  * invoke <code>write</code> system call and it can block.
8607  * In such situation, <code>OpenSSL::SSL::SSLSocket#read_nonblock</code>
8608  * raises IO::WaitWritable instead of blocking.
8609  * So, the caller should wait for ready for writability as above example.
8610  *
8611  * The combination of nonblocking methods and <code>IO.select</code> is
8612  * also useful for streams such as tty, pipe socket socket when
8613  * multiple process read form a stream.
8614  *
8615  * Finally, Linux kernel developers doesn't guarantee that
8616  * readability of select(2) means readability of following read(2) even
8617  * for single process.
8618  * See select(2) manual on GNU/Linux system.
8619  *
8620  * Invoking <code>IO.select</code> before <code>IO#readpartial</code> works well in usual.
8621  * However it is not the best way to use <code>IO.select</code>.
8622  *
8623  * The writability notified by select(2) doesn't show
8624  * how many bytes writable.
8625  * <code>IO#write</code> method blocks until given whole string is written.
8626  * So, <code>IO#write(two or more bytes)</code> can block after writability is notified by <code>IO.select</code>.
8627  * <code>IO#write_nonblock</code> is required to avoid the blocking.
8628  *
8629  * Blocking write (<code>write</code>) can be emulated using
8630  * <code>write_nonblock</code> and <code>IO.select</code> as follows:
8631  * IO::WaitReadable should also be rescued for SSL renegotiation in <code>OpenSSL::SSL::SSLSocket</code>.
8632  *
8633  * while 0 < string.bytesize
8634  * begin
8635  * written = io_like.write_nonblock(string)
8636  * rescue IO::WaitReadable
8637  * IO.select([io_like])
8638  * retry
8639  * rescue IO::WaitWritable
8640  * IO.select(nil, [io_like])
8641  * retry
8642  * end
8643  * string = string.byteslice(written..-1)
8644  * end
8645  *
8646  * === Parameters
8647  * read_array:: an array of <code>IO</code> objects that wait until ready for read
8648  * write_array:: an array of <code>IO</code> objects that wait until ready for write
8649  * error_array:: an array of <code>IO</code> objects that wait for exceptions
8650  * timeout:: a numeric value in second
8651  *
8652  * === Example
8653  *
8654  * rp, wp = IO.pipe
8655  * mesg = "ping "
8656  * 100.times {
8657  * # IO.select follows IO#read. Not the best way to use IO.select.
8658  * rs, ws, = IO.select([rp], [wp])
8659  * if r = rs[0]
8660  * ret = r.read(5)
8661  * print ret
8662  * case ret
8663  * when /ping/
8664  * mesg = "pong\n"
8665  * when /pong/
8666  * mesg = "ping "
8667  * end
8668  * end
8669  * if w = ws[0]
8670  * w.write(mesg)
8671  * end
8672  * }
8673  *
8674  * <em>produces:</em>
8675  *
8676  * ping pong
8677  * ping pong
8678  * ping pong
8679  * (snipped)
8680  * ping
8681  */
8682 
8683 static VALUE
8685 {
8686  VALUE timeout;
8687  struct select_args args;
8688  struct timeval timerec;
8689  int i;
8690 
8691  rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout);
8692  if (NIL_P(timeout)) {
8693  args.timeout = 0;
8694  }
8695  else {
8696  timerec = rb_time_interval(timeout);
8697  args.timeout = &timerec;
8698  }
8699 
8700  for (i = 0; i < numberof(args.fdsets); ++i)
8701  rb_fd_init(&args.fdsets[i]);
8702 
8703  return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
8704 }
8705 
8706 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
8707  typedef unsigned long ioctl_req_t;
8708 # define NUM2IOCTLREQ(num) NUM2ULONG(num)
8709 #else
8710  typedef int ioctl_req_t;
8711 # define NUM2IOCTLREQ(num) NUM2INT(num)
8712 #endif
8713 
8714 struct ioctl_arg {
8715  int fd;
8716  ioctl_req_t cmd;
8717  long narg;
8718 };
8719 
8720 static VALUE
8721 nogvl_ioctl(void *ptr)
8722 {
8723  struct ioctl_arg *arg = ptr;
8724 
8725  return (VALUE)ioctl(arg->fd, arg->cmd, arg->narg);
8726 }
8727 
8728 static int
8729 do_ioctl(int fd, ioctl_req_t cmd, long narg)
8730 {
8731  int retval;
8732  struct ioctl_arg arg;
8733 
8734  arg.fd = fd;
8735  arg.cmd = cmd;
8736  arg.narg = narg;
8737 
8738  retval = (int)rb_thread_io_blocking_region(nogvl_ioctl, &arg, fd);
8739 
8740  return retval;
8741 }
8742 
8743 #define DEFULT_IOCTL_NARG_LEN (256)
8744 
8745 #if defined(__linux__) && defined(_IOC_SIZE)
8746 static long
8747 linux_iocparm_len(ioctl_req_t cmd)
8748 {
8749  long len;
8750 
8751  if ((cmd & 0xFFFF0000) == 0) {
8752  /* legacy and unstructured ioctl number. */
8753  return DEFULT_IOCTL_NARG_LEN;
8754  }
8755 
8756  len = _IOC_SIZE(cmd);
8757 
8758  /* paranoia check for silly drivers which don't keep ioctl convention */
8759  if (len < DEFULT_IOCTL_NARG_LEN)
8760  len = DEFULT_IOCTL_NARG_LEN;
8761 
8762  return len;
8763 }
8764 #endif
8765 
8766 static long
8767 ioctl_narg_len(ioctl_req_t cmd)
8768 {
8769  long len;
8770 
8771 #ifdef IOCPARM_MASK
8772 #ifndef IOCPARM_LEN
8773 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
8774 #endif
8775 #endif
8776 #ifdef IOCPARM_LEN
8777  len = IOCPARM_LEN(cmd); /* on BSDish systems we're safe */
8778 #elif defined(__linux__) && defined(_IOC_SIZE)
8779  len = linux_iocparm_len(cmd);
8780 #else
8781  /* otherwise guess at what's safe */
8782  len = DEFULT_IOCTL_NARG_LEN;
8783 #endif
8784 
8785  return len;
8786 }
8787 
8788 #ifdef HAVE_FCNTL
8789 #ifdef __linux__
8790 typedef long fcntl_arg_t;
8791 #else
8792 /* posix */
8793 typedef int fcntl_arg_t;
8794 #endif
8795 
8796 static long
8797 fcntl_narg_len(int cmd)
8798 {
8799  long len;
8800 
8801  switch (cmd) {
8802 #ifdef F_DUPFD
8803  case F_DUPFD:
8804  len = sizeof(fcntl_arg_t);
8805  break;
8806 #endif
8807 #ifdef F_DUP2FD /* bsd specific */
8808  case F_DUP2FD:
8809  len = sizeof(int);
8810  break;
8811 #endif
8812 #ifdef F_DUPFD_CLOEXEC /* linux specific */
8813  case F_DUPFD_CLOEXEC:
8814  len = sizeof(fcntl_arg_t);
8815  break;
8816 #endif
8817 #ifdef F_GETFD
8818  case F_GETFD:
8819  len = 1;
8820  break;
8821 #endif
8822 #ifdef F_SETFD
8823  case F_SETFD:
8824  len = sizeof(fcntl_arg_t);
8825  break;
8826 #endif
8827 #ifdef F_GETFL
8828  case F_GETFL:
8829  len = 1;
8830  break;
8831 #endif
8832 #ifdef F_SETFL
8833  case F_SETFL:
8834  len = sizeof(fcntl_arg_t);
8835  break;
8836 #endif
8837 #ifdef F_GETOWN
8838  case F_GETOWN:
8839  len = 1;
8840  break;
8841 #endif
8842 #ifdef F_SETOWN
8843  case F_SETOWN:
8844  len = sizeof(fcntl_arg_t);
8845  break;
8846 #endif
8847 #ifdef F_GETOWN_EX /* linux specific */
8848  case F_GETOWN_EX:
8849  len = sizeof(struct f_owner_ex);
8850  break;
8851 #endif
8852 #ifdef F_SETOWN_EX /* linux specific */
8853  case F_SETOWN_EX:
8854  len = sizeof(struct f_owner_ex);
8855  break;
8856 #endif
8857 #ifdef F_GETLK
8858  case F_GETLK:
8859  len = sizeof(struct flock);
8860  break;
8861 #endif
8862 #ifdef F_SETLK
8863  case F_SETLK:
8864  len = sizeof(struct flock);
8865  break;
8866 #endif
8867 #ifdef F_SETLKW
8868  case F_SETLKW:
8869  len = sizeof(struct flock);
8870  break;
8871 #endif
8872 #ifdef F_READAHEAD /* bsd specific */
8873  case F_READAHEAD:
8874  len = sizeof(int);
8875  break;
8876 #endif
8877 #ifdef F_RDAHEAD /* Darwin specific */
8878  case F_RDAHEAD:
8879  len = sizeof(int);
8880  break;
8881 #endif
8882 #ifdef F_GETSIG /* linux specific */
8883  case F_GETSIG:
8884  len = 1;
8885  break;
8886 #endif
8887 #ifdef F_SETSIG /* linux specific */
8888  case F_SETSIG:
8889  len = sizeof(fcntl_arg_t);
8890  break;
8891 #endif
8892 #ifdef F_GETLEASE /* linux specific */
8893  case F_GETLEASE:
8894  len = 1;
8895  break;
8896 #endif
8897 #ifdef F_SETLEASE /* linux specific */
8898  case F_SETLEASE:
8899  len = sizeof(fcntl_arg_t);
8900  break;
8901 #endif
8902 #ifdef F_NOTIFY /* linux specific */
8903  case F_NOTIFY:
8904  len = sizeof(fcntl_arg_t);
8905  break;
8906 #endif
8907 
8908  default:
8909  len = 256;
8910  break;
8911  }
8912 
8913  return len;
8914 }
8915 #else /* HAVE_FCNTL */
8916 static long
8918 {
8919  return 0;
8920 }
8921 #endif /* HAVE_FCNTL */
8922 
8923 static long
8924 setup_narg(ioctl_req_t cmd, VALUE *argp, int io_p)
8925 {
8926  long narg = 0;
8927  VALUE arg = *argp;
8928 
8929  if (NIL_P(arg) || arg == Qfalse) {
8930  narg = 0;
8931  }
8932  else if (FIXNUM_P(arg)) {
8933  narg = FIX2LONG(arg);
8934  }
8935  else if (arg == Qtrue) {
8936  narg = 1;
8937  }
8938  else {
8940 
8941  if (NIL_P(tmp)) {
8942  narg = NUM2LONG(arg);
8943  }
8944  else {
8945  long len;
8946 
8947  *argp = arg = tmp;
8948  if (io_p)
8949  len = ioctl_narg_len(cmd);
8950  else
8951  len = fcntl_narg_len((int)cmd);
8952  rb_str_modify(arg);
8953 
8954  /* expand for data + sentinel. */
8955  if (RSTRING_LEN(arg) < len+1) {
8956  rb_str_resize(arg, len+1);
8957  }
8958  /* a little sanity check here */
8959  RSTRING_PTR(arg)[RSTRING_LEN(arg) - 1] = 17;
8960  narg = (long)(SIGNED_VALUE)RSTRING_PTR(arg);
8961  }
8962  }
8963 
8964  return narg;
8965 }
8966 
8967 static VALUE
8969 {
8970  ioctl_req_t cmd = NUM2IOCTLREQ(req);
8971  rb_io_t *fptr;
8972  long narg;
8973  int retval;
8974 
8975  rb_secure(2);
8976 
8977  narg = setup_narg(cmd, &arg, 1);
8978  GetOpenFile(io, fptr);
8979  retval = do_ioctl(fptr->fd, cmd, narg);
8980  if (retval < 0) rb_sys_fail_path(fptr->pathv);
8981  if (RB_TYPE_P(arg, T_STRING)) {
8982  if (RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] != 17)
8983  rb_raise(rb_eArgError, "return value overflowed string");
8984  RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] = '\0';
8985  }
8986 
8987  return INT2NUM(retval);
8988 }
8989 
8990 /*
8991  * call-seq:
8992  * ios.ioctl(integer_cmd, arg) -> integer
8993  *
8994  * Provides a mechanism for issuing low-level commands to control or
8995  * query I/O devices. Arguments and results are platform dependent. If
8996  * <i>arg</i> is a number, its value is passed directly. If it is a
8997  * string, it is interpreted as a binary sequence of bytes. On Unix
8998  * platforms, see <code>ioctl(2)</code> for details. Not implemented on
8999  * all platforms.
9000  */
9001 
9002 static VALUE
9004 {
9005  VALUE req, arg;
9006 
9007  rb_scan_args(argc, argv, "11", &req, &arg);
9008  return rb_ioctl(io, req, arg);
9009 }
9010 
9011 #ifdef HAVE_FCNTL
9012 struct fcntl_arg {
9013  int fd;
9014  int cmd;
9015  long narg;
9016 };
9017 
9018 static VALUE
9019 nogvl_fcntl(void *ptr)
9020 {
9021  struct fcntl_arg *arg = ptr;
9022 
9023 #if defined(F_DUPFD)
9024  if (arg->cmd == F_DUPFD)
9025  return (VALUE)rb_cloexec_fcntl_dupfd(arg->fd, (int)arg->narg);
9026 #endif
9027  return (VALUE)fcntl(arg->fd, arg->cmd, arg->narg);
9028 }
9029 
9030 static int
9031 do_fcntl(int fd, int cmd, long narg)
9032 {
9033  int retval;
9034  struct fcntl_arg arg;
9035 
9036  arg.fd = fd;
9037  arg.cmd = cmd;
9038  arg.narg = narg;
9039 
9040  retval = (int)rb_thread_io_blocking_region(nogvl_fcntl, &arg, fd);
9041 #if defined(F_DUPFD)
9042  if (retval != -1 && cmd == F_DUPFD) {
9043  rb_update_max_fd(retval);
9044  }
9045 #endif
9046 
9047  return retval;
9048 }
9049 
9050 static VALUE
9051 rb_fcntl(VALUE io, VALUE req, VALUE arg)
9052 {
9053  int cmd = NUM2INT(req);
9054  rb_io_t *fptr;
9055  long narg;
9056  int retval;
9057 
9058  rb_secure(2);
9059 
9060  narg = setup_narg(cmd, &arg, 0);
9061  GetOpenFile(io, fptr);
9062  retval = do_fcntl(fptr->fd, cmd, narg);
9063  if (retval < 0) rb_sys_fail_path(fptr->pathv);
9064  if (RB_TYPE_P(arg, T_STRING)) {
9065  if (RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] != 17)
9066  rb_raise(rb_eArgError, "return value overflowed string");
9067  RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] = '\0';
9068  }
9069 
9070  if (cmd == F_SETFL) {
9071  if (narg & O_NONBLOCK) {
9072  fptr->mode |= FMODE_WSPLIT_INITIALIZED;
9073  fptr->mode &= ~FMODE_WSPLIT;
9074  }
9075  else {
9077  }
9078  }
9079 
9080  return INT2NUM(retval);
9081 }
9082 
9083 /*
9084  * call-seq:
9085  * ios.fcntl(integer_cmd, arg) -> integer
9086  *
9087  * Provides a mechanism for issuing low-level commands to control or
9088  * query file-oriented I/O streams. Arguments and results are platform
9089  * dependent. If <i>arg</i> is a number, its value is passed
9090  * directly. If it is a string, it is interpreted as a binary sequence
9091  * of bytes (<code>Array#pack</code> might be a useful way to build this
9092  * string). On Unix platforms, see <code>fcntl(2)</code> for details.
9093  * Not implemented on all platforms.
9094  */
9095 
9096 static VALUE
9097 rb_io_fcntl(int argc, VALUE *argv, VALUE io)
9098 {
9099  VALUE req, arg;
9100 
9101  rb_scan_args(argc, argv, "11", &req, &arg);
9102  return rb_fcntl(io, req, arg);
9103 }
9104 #else
9105 #define rb_io_fcntl rb_f_notimplement
9106 #endif
9107 
9108 #if defined(HAVE_SYSCALL) || defined(HAVE___SYSCALL)
9109 /*
9110  * call-seq:
9111  * syscall(num [, args...]) -> integer
9112  *
9113  * Calls the operating system function identified by _num_ and
9114  * returns the result of the function or raises SystemCallError if
9115  * it failed.
9116  *
9117  * Arguments for the function can follow _num_. They must be either
9118  * +String+ objects or +Integer+ objects. A +String+ object is passed
9119  * as a pointer to the byte sequence. An +Integer+ object is passed
9120  * as an integer whose bit size is same as a pointer.
9121  * Up to nine parameters may be passed (14 on the Atari-ST).
9122  *
9123  * The function identified by _num_ is system
9124  * dependent. On some Unix systems, the numbers may be obtained from a
9125  * header file called <code>syscall.h</code>.
9126  *
9127  * syscall 4, 1, "hello\n", 6 # '4' is write(2) on our box
9128  *
9129  * <em>produces:</em>
9130  *
9131  * hello
9132  *
9133  *
9134  * Calling +syscall+ on a platform which does not have any way to
9135  * an arbitrary system function just fails with NotImplementedError.
9136  *
9137  * Note::
9138  * +syscall+ is essentially unsafe and unportable. Feel free to shoot your foot.
9139  * DL (Fiddle) library is preferred for safer and a bit more portable programming.
9140  */
9141 
9142 static VALUE
9143 rb_f_syscall(int argc, VALUE *argv)
9144 {
9145 #ifdef atarist
9146  VALUE arg[13]; /* yes, we really need that many ! */
9147 #else
9148  VALUE arg[8];
9149 #endif
9150 #if SIZEOF_VOIDP == 8 && defined(HAVE___SYSCALL) && SIZEOF_INT != 8 /* mainly *BSD */
9151 # define SYSCALL __syscall
9152 # define NUM2SYSCALLID(x) NUM2LONG(x)
9153 # define RETVAL2NUM(x) LONG2NUM(x)
9154 # if SIZEOF_LONG == 8
9155  long num, retval = -1;
9156 # elif SIZEOF_LONG_LONG == 8
9157  long long num, retval = -1;
9158 # else
9159 # error ---->> it is asserted that __syscall takes the first argument and returns retval in 64bit signed integer. <<----
9160 # endif
9161 #elif defined(__linux__)
9162 # define SYSCALL syscall
9163 # define NUM2SYSCALLID(x) NUM2LONG(x)
9164 # define RETVAL2NUM(x) LONG2NUM(x)
9165  /*
9166  * Linux man page says, syscall(2) function prototype is below.
9167  *
9168  * int syscall(int number, ...);
9169  *
9170  * But, it's incorrect. Actual one takes and returned long. (see unistd.h)
9171  */
9172  long num, retval = -1;
9173 #else
9174 # define SYSCALL syscall
9175 # define NUM2SYSCALLID(x) NUM2INT(x)
9176 # define RETVAL2NUM(x) INT2NUM(x)
9177  int num, retval = -1;
9178 #endif
9179  int i;
9180 
9181  if (RTEST(ruby_verbose)) {
9182  rb_warning("We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
9183  }
9184 
9185  rb_secure(2);
9186  if (argc == 0)
9187  rb_raise(rb_eArgError, "too few arguments for syscall");
9188  if (argc > numberof(arg))
9189  rb_raise(rb_eArgError, "too many arguments for syscall");
9190  num = NUM2SYSCALLID(argv[0]); ++argv;
9191  for (i = argc - 1; i--; ) {
9192  VALUE v = rb_check_string_type(argv[i]);
9193 
9194  if (!NIL_P(v)) {
9195  SafeStringValue(v);
9196  rb_str_modify(v);
9197  arg[i] = (VALUE)StringValueCStr(v);
9198  }
9199  else {
9200  arg[i] = (VALUE)NUM2LONG(argv[i]);
9201  }
9202  }
9203 
9204  switch (argc) {
9205  case 1:
9206  retval = SYSCALL(num);
9207  break;
9208  case 2:
9209  retval = SYSCALL(num, arg[0]);
9210  break;
9211  case 3:
9212  retval = SYSCALL(num, arg[0],arg[1]);
9213  break;
9214  case 4:
9215  retval = SYSCALL(num, arg[0],arg[1],arg[2]);
9216  break;
9217  case 5:
9218  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3]);
9219  break;
9220  case 6:
9221  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4]);
9222  break;
9223  case 7:
9224  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
9225  break;
9226  case 8:
9227  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
9228  break;
9229 #ifdef atarist
9230  case 9:
9231  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9232  arg[7]);
9233  break;
9234  case 10:
9235  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9236  arg[7], arg[8]);
9237  break;
9238  case 11:
9239  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9240  arg[7], arg[8], arg[9]);
9241  break;
9242  case 12:
9243  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9244  arg[7], arg[8], arg[9], arg[10]);
9245  break;
9246  case 13:
9247  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9248  arg[7], arg[8], arg[9], arg[10], arg[11]);
9249  break;
9250  case 14:
9251  retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
9252  arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]);
9253  break;
9254 #endif
9255  }
9256 
9257  if (retval == -1)
9258  rb_sys_fail(0);
9259  return RETVAL2NUM(retval);
9260 #undef SYSCALL
9261 #undef NUM2SYSCALLID
9262 #undef RETVAL2NUM
9263 }
9264 #else
9265 #define rb_f_syscall rb_f_notimplement
9266 #endif
9267 
9268 static VALUE
9270 {
9271  return rb_class_new_instance(2, (VALUE*)args+1, *(VALUE*)args);
9272 }
9273 
9274 static rb_encoding *
9276 {
9278  if (!enc) unsupported_encoding(StringValueCStr(v));
9279  return enc;
9280 }
9281 
9282 static void
9284 {
9285  rb_encoding *enc, *enc2;
9286  int ecflags = fptr->encs.ecflags;
9287  VALUE ecopts, tmp;
9288 
9289  if (!NIL_P(v2)) {
9290  enc2 = find_encoding(v1);
9291  tmp = rb_check_string_type(v2);
9292  if (!NIL_P(tmp)) {
9293  if (RSTRING_LEN(tmp) == 1 && RSTRING_PTR(tmp)[0] == '-') {
9294  /* Special case - "-" => no transcoding */
9295  enc = enc2;
9296  enc2 = NULL;
9297  }
9298  else
9299  enc = find_encoding(v2);
9300  if (enc == enc2) {
9301  /* Special case - "-" => no transcoding */
9302  enc2 = NULL;
9303  }
9304  }
9305  else {
9306  enc = find_encoding(v2);
9307  if (enc == enc2) {
9308  /* Special case - "-" => no transcoding */
9309  enc2 = NULL;
9310  }
9311  }
9313  ecflags = rb_econv_prepare_options(opt, &ecopts, ecflags);
9314  }
9315  else {
9316  if (NIL_P(v1)) {
9317  /* Set to default encodings */
9318  rb_io_ext_int_to_encs(NULL, NULL, &enc, &enc2, 0);
9320  ecopts = Qnil;
9321  }
9322  else {
9323  tmp = rb_check_string_type(v1);
9324  if (!NIL_P(tmp) && rb_enc_asciicompat(rb_enc_get(tmp))) {
9325  parse_mode_enc(RSTRING_PTR(tmp), &enc, &enc2, NULL);
9327  ecflags = rb_econv_prepare_options(opt, &ecopts, ecflags);
9328  }
9329  else {
9330  rb_io_ext_int_to_encs(find_encoding(v1), NULL, &enc, &enc2, 0);
9332  ecopts = Qnil;
9333  }
9334  }
9335  }
9336  validate_enc_binmode(&fptr->mode, ecflags, enc, enc2);
9337  fptr->encs.enc = enc;
9338  fptr->encs.enc2 = enc2;
9339  fptr->encs.ecflags = ecflags;
9340  fptr->encs.ecopts = ecopts;
9341  clear_codeconv(fptr);
9342 
9343 }
9344 
9345 static VALUE
9347 {
9348  VALUE *rwp = (VALUE *)rw;
9349  return rb_ensure(io_close, rwp[0], io_close, rwp[1]);
9350 }
9351 
9352 /*
9353  * call-seq:
9354  * IO.pipe -> [read_io, write_io]
9355  * IO.pipe(ext_enc) -> [read_io, write_io]
9356  * IO.pipe("ext_enc:int_enc" [, opt]) -> [read_io, write_io]
9357  * IO.pipe(ext_enc, int_enc [, opt]) -> [read_io, write_io]
9358  *
9359  * IO.pipe(...) {|read_io, write_io| ... }
9360  *
9361  * Creates a pair of pipe endpoints (connected to each other) and
9362  * returns them as a two-element array of <code>IO</code> objects:
9363  * <code>[</code> <i>read_io</i>, <i>write_io</i> <code>]</code>.
9364  *
9365  * If a block is given, the block is called and
9366  * returns the value of the block.
9367  * <i>read_io</i> and <i>write_io</i> are sent to the block as arguments.
9368  * If read_io and write_io are not closed when the block exits, they are closed.
9369  * i.e. closing read_io and/or write_io doesn't cause an error.
9370  *
9371  * Not available on all platforms.
9372  *
9373  * If an encoding (encoding name or encoding object) is specified as an optional argument,
9374  * read string from pipe is tagged with the encoding specified.
9375  * If the argument is a colon separated two encoding names "A:B",
9376  * the read string is converted from encoding A (external encoding)
9377  * to encoding B (internal encoding), then tagged with B.
9378  * If two optional arguments are specified, those must be
9379  * encoding objects or encoding names,
9380  * and the first one is the external encoding,
9381  * and the second one is the internal encoding.
9382  * If the external encoding and the internal encoding is specified,
9383  * optional hash argument specify the conversion option.
9384  *
9385  * In the example below, the two processes close the ends of the pipe
9386  * that they are not using. This is not just a cosmetic nicety. The
9387  * read end of a pipe will not generate an end of file condition if
9388  * there are any writers with the pipe still open. In the case of the
9389  * parent process, the <code>rd.read</code> will never return if it
9390  * does not first issue a <code>wr.close</code>.
9391  *
9392  * rd, wr = IO.pipe
9393  *
9394  * if fork
9395  * wr.close
9396  * puts "Parent got: <#{rd.read}>"
9397  * rd.close
9398  * Process.wait
9399  * else
9400  * rd.close
9401  * puts "Sending message to parent"
9402  * wr.write "Hi Dad"
9403  * wr.close
9404  * end
9405  *
9406  * <em>produces:</em>
9407  *
9408  * Sending message to parent
9409  * Parent got: <Hi Dad>
9410  */
9411 
9412 static VALUE
9414 {
9415  int pipes[2], state;
9416  VALUE r, w, args[3], v1, v2;
9417  VALUE opt;
9418  rb_io_t *fptr, *fptr2;
9419  int fmode = 0;
9420  VALUE ret;
9421 
9422  argc = rb_scan_args(argc, argv, "02:", &v1, &v2, &opt);
9423  if (rb_pipe(pipes) == -1)
9424  rb_sys_fail(0);
9425 
9426  args[0] = klass;
9427  args[1] = INT2NUM(pipes[0]);
9428  args[2] = INT2FIX(O_RDONLY);
9429  r = rb_protect(io_new_instance, (VALUE)args, &state);
9430  if (state) {
9431  close(pipes[0]);
9432  close(pipes[1]);
9433  rb_jump_tag(state);
9434  }
9435  GetOpenFile(r, fptr);
9436  io_encoding_set(fptr, v1, v2, opt);
9437  args[1] = INT2NUM(pipes[1]);
9438  args[2] = INT2FIX(O_WRONLY);
9439  w = rb_protect(io_new_instance, (VALUE)args, &state);
9440  if (state) {
9441  close(pipes[1]);
9442  if (!NIL_P(r)) rb_io_close(r);
9443  rb_jump_tag(state);
9444  }
9445  GetOpenFile(w, fptr2);
9446  rb_io_synchronized(fptr2);
9447 
9448  extract_binmode(opt, &fmode);
9449 #if DEFAULT_TEXTMODE
9450  if ((fptr->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
9451  fptr->mode &= ~FMODE_TEXTMODE;
9452  setmode(fptr->fd, O_BINARY);
9453  }
9454 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
9457  }
9458 #endif
9459 #endif
9460  fptr->mode |= fmode;
9461 #if DEFAULT_TEXTMODE
9462  if ((fptr2->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
9463  fptr2->mode &= ~FMODE_TEXTMODE;
9464  setmode(fptr2->fd, O_BINARY);
9465  }
9466 #endif
9467  fptr2->mode |= fmode;
9468 
9469  ret = rb_assoc_new(r, w);
9470  if (rb_block_given_p()) {
9471  VALUE rw[2];
9472  rw[0] = r;
9473  rw[1] = w;
9474  return rb_ensure(rb_yield, ret, pipe_pair_close, (VALUE)rw);
9475  }
9476  return ret;
9477 }
9478 
9479 struct foreach_arg {
9480  int argc;
9483 };
9484 
9485 static void
9486 open_key_args(int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg)
9487 {
9488  VALUE path, v;
9489 
9490  path = *argv++;
9491  argc--;
9492  FilePathValue(path);
9493  arg->io = 0;
9494  arg->argc = argc;
9495  arg->argv = argv;
9496  if (NIL_P(opt)) {
9497  arg->io = rb_io_open(path, INT2NUM(O_RDONLY), INT2FIX(0666), Qnil);
9498  return;
9499  }
9500  v = rb_hash_aref(opt, sym_open_args);
9501  if (!NIL_P(v)) {
9502  VALUE args;
9503  long n;
9504 
9505  v = rb_convert_type(v, T_ARRAY, "Array", "to_ary");
9506  n = RARRAY_LEN(v) + 1;
9507 #if SIZEOF_LONG > SIZEOF_INT
9508  if (n > INT_MAX) {
9509  rb_raise(rb_eArgError, "too many arguments");
9510  }
9511 #endif
9512  args = rb_ary_tmp_new(n);
9513  rb_ary_push(args, path);
9514  rb_ary_concat(args, v);
9515  arg->io = rb_io_open_with_args((int)n, RARRAY_CONST_PTR(args));
9516  rb_ary_clear(args); /* prevent from GC */
9517  return;
9518  }
9519  arg->io = rb_io_open(path, Qnil, Qnil, opt);
9520 }
9521 
9522 static VALUE
9524 {
9525  VALUE str;
9526 
9527  while (!NIL_P(str = rb_io_gets_m(arg->argc, arg->argv, arg->io))) {
9528  rb_yield(str);
9529  }
9530  return Qnil;
9531 }
9532 
9533 /*
9534  * call-seq:
9535  * IO.foreach(name, sep=$/ [, open_args]) {|line| block } -> nil
9536  * IO.foreach(name, limit [, open_args]) {|line| block } -> nil
9537  * IO.foreach(name, sep, limit [, open_args]) {|line| block } -> nil
9538  * IO.foreach(...) -> an_enumerator
9539  *
9540  * Executes the block for every line in the named I/O port, where lines
9541  * are separated by <em>sep</em>.
9542  *
9543  * If no block is given, an enumerator is returned instead.
9544  *
9545  * IO.foreach("testfile") {|x| print "GOT ", x }
9546  *
9547  * <em>produces:</em>
9548  *
9549  * GOT This is line one
9550  * GOT This is line two
9551  * GOT This is line three
9552  * GOT And so on...
9553  *
9554  * If the last argument is a hash, it's the keyword argument to open.
9555  * See <code>IO.read</code> for detail.
9556  *
9557  */
9558 
9559 static VALUE
9561 {
9562  VALUE opt;
9563  int orig_argc = argc;
9564  struct foreach_arg arg;
9565 
9566  argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
9567  RETURN_ENUMERATOR(self, orig_argc, argv);
9568  open_key_args(argc, argv, opt, &arg);
9569  if (NIL_P(arg.io)) return Qnil;
9570  return rb_ensure(io_s_foreach, (VALUE)&arg, rb_io_close, arg.io);
9571 }
9572 
9573 static VALUE
9575 {
9576  return rb_io_readlines(arg->argc, arg->argv, arg->io);
9577 }
9578 
9579 /*
9580  * call-seq:
9581  * IO.readlines(name, sep=$/ [, open_args]) -> array
9582  * IO.readlines(name, limit [, open_args]) -> array
9583  * IO.readlines(name, sep, limit [, open_args]) -> array
9584  *
9585  * Reads the entire file specified by <i>name</i> as individual
9586  * lines, and returns those lines in an array. Lines are separated by
9587  * <i>sep</i>.
9588  *
9589  * a = IO.readlines("testfile")
9590  * a[0] #=> "This is line one\n"
9591  *
9592  * If the last argument is a hash, it's the keyword argument to open.
9593  * See <code>IO.read</code> for detail.
9594  *
9595  */
9596 
9597 static VALUE
9599 {
9600  VALUE opt;
9601  struct foreach_arg arg;
9602 
9603  argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
9604  open_key_args(argc, argv, opt, &arg);
9605  if (NIL_P(arg.io)) return Qnil;
9606  return rb_ensure(io_s_readlines, (VALUE)&arg, rb_io_close, arg.io);
9607 }
9608 
9609 static VALUE
9611 {
9612  return io_read(arg->argc, arg->argv, arg->io);
9613 }
9614 
9615 struct seek_arg {
9618  int mode;
9619 };
9620 
9621 static VALUE
9623 {
9624  struct seek_arg *arg = (struct seek_arg *)argp;
9625  rb_io_binmode(arg->io);
9626  return rb_io_seek(arg->io, arg->offset, arg->mode);
9627 }
9628 
9629 /*
9630  * call-seq:
9631  * IO.read(name, [length [, offset]] ) -> string
9632  * IO.read(name, [length [, offset]], open_args) -> string
9633  *
9634  * Opens the file, optionally seeks to the given +offset+, then returns
9635  * +length+ bytes (defaulting to the rest of the file). <code>read</code>
9636  * ensures the file is closed before returning.
9637  *
9638  * If the last argument is a hash, it specifies option for internal
9639  * open(). The key would be the following. open_args: is exclusive
9640  * to others.
9641  *
9642  * encoding::
9643  * string or encoding
9644  *
9645  * specifies encoding of the read string. +encoding+ will be ignored
9646  * if length is specified.
9647  *
9648  * mode::
9649  * string
9650  *
9651  * specifies mode argument for open(). It should start with "r"
9652  * otherwise it will cause an error.
9653  *
9654  * open_args:: array of strings
9655  *
9656  * specifies arguments for open() as an array.
9657  *
9658  * Examples:
9659  *
9660  * IO.read("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
9661  * IO.read("testfile", 20) #=> "This is line one\nThi"
9662  * IO.read("testfile", 20, 10) #=> "ne one\nThis is line "
9663  */
9664 
9665 static VALUE
9667 {
9668  VALUE opt, offset;
9669  struct foreach_arg arg;
9670 
9671  argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
9672  open_key_args(argc, argv, opt, &arg);
9673  if (NIL_P(arg.io)) return Qnil;
9674  if (!NIL_P(offset)) {
9675  struct seek_arg sarg;
9676  int state = 0;
9677  sarg.io = arg.io;
9678  sarg.offset = offset;
9679  sarg.mode = SEEK_SET;
9680  rb_protect(seek_before_access, (VALUE)&sarg, &state);
9681  if (state) {
9682  rb_io_close(arg.io);
9683  rb_jump_tag(state);
9684  }
9685  if (arg.argc == 2) arg.argc = 1;
9686  }
9687  return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
9688 }
9689 
9690 /*
9691  * call-seq:
9692  * IO.binread(name, [length [, offset]] ) -> string
9693  *
9694  * Opens the file, optionally seeks to the given <i>offset</i>, then returns
9695  * <i>length</i> bytes (defaulting to the rest of the file).
9696  * <code>binread</code> ensures the file is closed before returning.
9697  * The open mode would be "rb:ASCII-8BIT".
9698  *
9699  * IO.binread("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
9700  * IO.binread("testfile", 20) #=> "This is line one\nThi"
9701  * IO.binread("testfile", 20, 10) #=> "ne one\nThis is line "
9702  */
9703 
9704 static VALUE
9706 {
9707  VALUE offset;
9708  struct foreach_arg arg;
9709 
9710  rb_scan_args(argc, argv, "12", NULL, NULL, &offset);
9711  FilePathValue(argv[0]);
9712  arg.io = rb_io_open(argv[0], rb_str_new_cstr("rb:ASCII-8BIT"), Qnil, Qnil);
9713  if (NIL_P(arg.io)) return Qnil;
9714  arg.argv = argv+1;
9715  arg.argc = (argc > 1) ? 1 : 0;
9716  if (!NIL_P(offset)) {
9717  rb_io_seek(arg.io, offset, SEEK_SET);
9718  }
9719  return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
9720 }
9721 
9722 static VALUE
9724 {
9725  return io_write(arg->io,arg->str,arg->nosync);
9726 }
9727 
9728 static VALUE
9729 io_s_write(int argc, VALUE *argv, int binary)
9730 {
9731  VALUE string, offset, opt;
9732  struct foreach_arg arg;
9733  struct write_arg warg;
9734 
9735  rb_scan_args(argc, argv, "21:", NULL, &string, &offset, &opt);
9736 
9737  if (NIL_P(opt)) opt = rb_hash_new();
9738  else opt = rb_hash_dup(opt);
9739 
9740 
9741  if (NIL_P(rb_hash_aref(opt,sym_mode))) {
9742  int mode = O_WRONLY|O_CREAT;
9743 #ifdef O_BINARY
9744  if (binary) mode |= O_BINARY;
9745 #endif
9746  if (NIL_P(offset)) mode |= O_TRUNC;
9747  rb_hash_aset(opt,sym_mode,INT2NUM(mode));
9748  }
9749  open_key_args(argc,argv,opt,&arg);
9750 
9751 #ifndef O_BINARY
9752  if (binary) rb_io_binmode_m(arg.io);
9753 #endif
9754 
9755  if (NIL_P(arg.io)) return Qnil;
9756  if (!NIL_P(offset)) {
9757  struct seek_arg sarg;
9758  int state = 0;
9759  sarg.io = arg.io;
9760  sarg.offset = offset;
9761  sarg.mode = SEEK_SET;
9762  rb_protect(seek_before_access, (VALUE)&sarg, &state);
9763  if (state) {
9764  rb_io_close(arg.io);
9765  rb_jump_tag(state);
9766  }
9767  }
9768 
9769  warg.io = arg.io;
9770  warg.str = string;
9771  warg.nosync = 0;
9772 
9773  return rb_ensure(io_s_write0, (VALUE)&warg, rb_io_close, arg.io);
9774 }
9775 
9776 /*
9777  * call-seq:
9778  * IO.write(name, string, [offset] ) => fixnum
9779  * IO.write(name, string, [offset], open_args ) => fixnum
9780  *
9781  * Opens the file, optionally seeks to the given <i>offset</i>, writes
9782  * <i>string</i>, then returns the length written.
9783  * <code>write</code> ensures the file is closed before returning.
9784  * If <i>offset</i> is not given, the file is truncated. Otherwise,
9785  * it is not truncated.
9786  *
9787  * If the last argument is a hash, it specifies option for internal
9788  * open(). The key would be the following. open_args: is exclusive
9789  * to others.
9790  *
9791  * encoding: string or encoding
9792  *
9793  * specifies encoding of the read string. encoding will be ignored
9794  * if length is specified.
9795  *
9796  * mode: string
9797  *
9798  * specifies mode argument for open(). it should start with "w" or "a" or "r+"
9799  * otherwise it would cause error.
9800  *
9801  * perm: fixnum
9802  *
9803  * specifies perm argument for open().
9804  *
9805  * open_args: array
9806  *
9807  * specifies arguments for open() as an array.
9808  *
9809  * IO.write("testfile", "0123456789", 20) # => 10
9810  * # File could contain: "This is line one\nThi0123456789two\nThis is line three\nAnd so on...\n"
9811  * IO.write("testfile", "0123456789") #=> 10
9812  * # File would now read: "0123456789"
9813  */
9814 
9815 static VALUE
9817 {
9818  return io_s_write(argc, argv, 0);
9819 }
9820 
9821 /*
9822  * call-seq:
9823  * IO.binwrite(name, string, [offset] ) => fixnum
9824  * IO.binwrite(name, string, [offset], open_args ) => fixnum
9825  *
9826  * Same as <code>IO.write</code> except opening the file in binary mode
9827  * and ASCII-8BIT encoding ("wb:ASCII-8BIT").
9828  *
9829  */
9830 
9831 static VALUE
9833 {
9834  return io_s_write(argc, argv, 1);
9835 }
9836 
9840  off_t copy_length; /* (off_t)-1 if not specified */
9841  off_t src_offset; /* (off_t)-1 if not specified */
9842 
9843  int src_fd;
9844  int dst_fd;
9848  const char *syserr;
9850  const char *notimp;
9853 };
9854 
9855 static void *
9857 {
9858  VALUE th = (VALUE)arg;
9860  return NULL;
9861 }
9862 
9863 /*
9864  * returns TRUE if the preceding system call was interrupted
9865  * so we can continue. If the thread was interrupted, we
9866  * reacquire the GVL to execute interrupts before continuing.
9867  */
9868 static int
9870 {
9871  switch (errno) {
9872  case EINTR:
9873 #if defined(ERESTART)
9874  case ERESTART:
9875 #endif
9876  if (rb_thread_interrupted(stp->th)) {
9877  if (has_gvl)
9879  else
9881  }
9882  return TRUE;
9883  }
9884  return FALSE;
9885 }
9886 
9887 static int
9888 maygvl_select(int has_gvl, int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout)
9889 {
9890  if (has_gvl)
9891  return rb_thread_fd_select(n, rfds, wfds, efds, timeout);
9892  else
9893  return rb_fd_select(n, rfds, wfds, efds, timeout);
9894 }
9895 
9896 static int
9898 {
9899  int ret;
9900 
9901  do {
9902  rb_fd_zero(&stp->fds);
9903  rb_fd_set(stp->src_fd, &stp->fds);
9904  ret = maygvl_select(has_gvl, rb_fd_max(&stp->fds), &stp->fds, NULL, NULL, NULL);
9905  } while (ret == -1 && maygvl_copy_stream_continue_p(has_gvl, stp));
9906 
9907  if (ret == -1) {
9908  stp->syserr = "select";
9909  stp->error_no = errno;
9910  return -1;
9911  }
9912  return 0;
9913 }
9914 
9915 static int
9917 {
9918  int ret;
9919 
9920  do {
9921  rb_fd_zero(&stp->fds);
9922  rb_fd_set(stp->dst_fd, &stp->fds);
9923  ret = rb_fd_select(rb_fd_max(&stp->fds), NULL, &stp->fds, NULL, NULL);
9924  } while (ret == -1 && maygvl_copy_stream_continue_p(0, stp));
9925 
9926  if (ret == -1) {
9927  stp->syserr = "select";
9928  stp->error_no = errno;
9929  return -1;
9930  }
9931  return 0;
9932 }
9933 
9934 #ifdef HAVE_SENDFILE
9935 
9936 # ifdef __linux__
9937 # define USE_SENDFILE
9938 
9939 # ifdef HAVE_SYS_SENDFILE_H
9940 # include <sys/sendfile.h>
9941 # endif
9942 
9943 static ssize_t
9944 simple_sendfile(int out_fd, int in_fd, off_t *offset, off_t count)
9945 {
9946  return sendfile(out_fd, in_fd, offset, (size_t)count);
9947 }
9948 
9949 # elif 0 /* defined(__FreeBSD__) || defined(__DragonFly__) */ || defined(__APPLE__)
9950 /* This runs on FreeBSD8.1 r30210, but sendfiles blocks its execution
9951  * without cpuset -l 0.
9952  */
9953 # define USE_SENDFILE
9954 
9955 # ifdef HAVE_SYS_UIO_H
9956 # include <sys/uio.h>
9957 # endif
9958 
9959 static ssize_t
9960 simple_sendfile(int out_fd, int in_fd, off_t *offset, off_t count)
9961 {
9962  int r;
9963  off_t pos = offset ? *offset : lseek(in_fd, 0, SEEK_CUR);
9964  off_t sbytes;
9965 # ifdef __APPLE__
9966  r = sendfile(in_fd, out_fd, pos, &count, NULL, 0);
9967  sbytes = count;
9968 # else
9969  r = sendfile(in_fd, out_fd, pos, (size_t)count, NULL, &sbytes, 0);
9970 # endif
9971  if (r != 0 && sbytes == 0) return -1;
9972  if (offset) {
9973  *offset += sbytes;
9974  }
9975  else {
9976  lseek(in_fd, sbytes, SEEK_CUR);
9977  }
9978  return (ssize_t)sbytes;
9979 }
9980 
9981 # endif
9982 
9983 #endif
9984 
9985 #ifdef USE_SENDFILE
9986 static int
9987 nogvl_copy_stream_sendfile(struct copy_stream_struct *stp)
9988 {
9989  struct stat src_stat, dst_stat;
9990  ssize_t ss;
9991  int ret;
9992 
9993  off_t copy_length;
9994  off_t src_offset;
9995  int use_pread;
9996 
9997  ret = fstat(stp->src_fd, &src_stat);
9998  if (ret == -1) {
9999  stp->syserr = "fstat";
10000  stp->error_no = errno;
10001  return -1;
10002  }
10003  if (!S_ISREG(src_stat.st_mode))
10004  return 0;
10005 
10006  ret = fstat(stp->dst_fd, &dst_stat);
10007  if (ret == -1) {
10008  stp->syserr = "fstat";
10009  stp->error_no = errno;
10010  return -1;
10011  }
10012  if ((dst_stat.st_mode & S_IFMT) != S_IFSOCK)
10013  return 0;
10014 
10015  src_offset = stp->src_offset;
10016  use_pread = src_offset != (off_t)-1;
10017 
10018  copy_length = stp->copy_length;
10019  if (copy_length == (off_t)-1) {
10020  if (use_pread)
10021  copy_length = src_stat.st_size - src_offset;
10022  else {
10023  off_t cur;
10024  errno = 0;
10025  cur = lseek(stp->src_fd, 0, SEEK_CUR);
10026  if (cur == (off_t)-1 && errno) {
10027  stp->syserr = "lseek";
10028  stp->error_no = errno;
10029  return -1;
10030  }
10031  copy_length = src_stat.st_size - cur;
10032  }
10033  }
10034 
10035  retry_sendfile:
10036 # if SIZEOF_OFF_T > SIZEOF_SIZE_T
10037  /* we are limited by the 32-bit ssize_t return value on 32-bit */
10038  ss = (copy_length > (off_t)SSIZE_MAX) ? SSIZE_MAX : (ssize_t)copy_length;
10039 # else
10040  ss = (ssize_t)copy_length;
10041 # endif
10042  if (use_pread) {
10043  ss = simple_sendfile(stp->dst_fd, stp->src_fd, &src_offset, ss);
10044  }
10045  else {
10046  ss = simple_sendfile(stp->dst_fd, stp->src_fd, NULL, ss);
10047  }
10048  if (0 < ss) {
10049  stp->total += ss;
10050  copy_length -= ss;
10051  if (0 < copy_length) {
10052  goto retry_sendfile;
10053  }
10054  }
10055  if (ss == -1) {
10056  if (maygvl_copy_stream_continue_p(0, stp))
10057  goto retry_sendfile;
10058  switch (errno) {
10059  case EINVAL:
10060 #ifdef ENOSYS
10061  case ENOSYS:
10062 #endif
10063  return 0;
10064  case EAGAIN:
10065 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
10066  case EWOULDBLOCK:
10067 #endif
10068 #ifndef __linux__
10069  /*
10070  * Linux requires stp->src_fd to be a mmap-able (regular) file,
10071  * select() reports regular files to always be "ready", so
10072  * there is no need to select() on it.
10073  * Other OSes may have the same limitation for sendfile() which
10074  * allow us to bypass maygvl_copy_stream_wait_read()...
10075  */
10076  if (maygvl_copy_stream_wait_read(0, stp) == -1)
10077  return -1;
10078 #endif
10079  if (nogvl_copy_stream_wait_write(stp) == -1)
10080  return -1;
10081  goto retry_sendfile;
10082  }
10083  stp->syserr = "sendfile";
10084  stp->error_no = errno;
10085  return -1;
10086  }
10087  return 1;
10088 }
10089 #endif
10090 
10091 static ssize_t
10092 maygvl_read(int has_gvl, int fd, void *buf, size_t count)
10093 {
10094  if (has_gvl)
10095  return rb_read_internal(fd, buf, count);
10096  else
10097  return read(fd, buf, count);
10098 }
10099 
10100 static ssize_t
10101 maygvl_copy_stream_read(int has_gvl, struct copy_stream_struct *stp, char *buf, size_t len, off_t offset)
10102 {
10103  ssize_t ss;
10104  retry_read:
10105  if (offset == (off_t)-1) {
10106  ss = maygvl_read(has_gvl, stp->src_fd, buf, len);
10107  }
10108  else {
10109 #ifdef HAVE_PREAD
10110  ss = pread(stp->src_fd, buf, len, offset);
10111 #else
10112  stp->notimp = "pread";
10113  return -1;
10114 #endif
10115  }
10116  if (ss == 0) {
10117  return 0;
10118  }
10119  if (ss == -1) {
10120  if (maygvl_copy_stream_continue_p(has_gvl, stp))
10121  goto retry_read;
10122  switch (errno) {
10123  case EAGAIN:
10124 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
10125  case EWOULDBLOCK:
10126 #endif
10127  if (maygvl_copy_stream_wait_read(has_gvl, stp) == -1)
10128  return -1;
10129  goto retry_read;
10130 #ifdef ENOSYS
10131  case ENOSYS:
10132 #endif
10133  stp->notimp = "pread";
10134  return -1;
10135  }
10136  stp->syserr = offset == (off_t)-1 ? "read" : "pread";
10137  stp->error_no = errno;
10138  return -1;
10139  }
10140  return ss;
10141 }
10142 
10143 static int
10144 nogvl_copy_stream_write(struct copy_stream_struct *stp, char *buf, size_t len)
10145 {
10146  ssize_t ss;
10147  int off = 0;
10148  while (len) {
10149  ss = write(stp->dst_fd, buf+off, len);
10150  if (ss == -1) {
10151  if (maygvl_copy_stream_continue_p(0, stp))
10152  continue;
10153  if (errno == EAGAIN || errno == EWOULDBLOCK) {
10154  if (nogvl_copy_stream_wait_write(stp) == -1)
10155  return -1;
10156  continue;
10157  }
10158  stp->syserr = "write";
10159  stp->error_no = errno;
10160  return -1;
10161  }
10162  off += (int)ss;
10163  len -= (int)ss;
10164  stp->total += ss;
10165  }
10166  return 0;
10167 }
10168 
10169 static void
10171 {
10172  char buf[1024*16];
10173  size_t len;
10174  ssize_t ss;
10175  int ret;
10176  off_t copy_length;
10177  int use_eof;
10178  off_t src_offset;
10179  int use_pread;
10180 
10181  copy_length = stp->copy_length;
10182  use_eof = copy_length == (off_t)-1;
10183  src_offset = stp->src_offset;
10184  use_pread = src_offset != (off_t)-1;
10185 
10186  if (use_pread && stp->close_src) {
10187  off_t r;
10188  errno = 0;
10189  r = lseek(stp->src_fd, src_offset, SEEK_SET);
10190  if (r == (off_t)-1 && errno) {
10191  stp->syserr = "lseek";
10192  stp->error_no = errno;
10193  return;
10194  }
10195  src_offset = (off_t)-1;
10196  use_pread = 0;
10197  }
10198 
10199  while (use_eof || 0 < copy_length) {
10200  if (!use_eof && copy_length < (off_t)sizeof(buf)) {
10201  len = (size_t)copy_length;
10202  }
10203  else {
10204  len = sizeof(buf);
10205  }
10206  if (use_pread) {
10207  ss = maygvl_copy_stream_read(0, stp, buf, len, src_offset);
10208  if (0 < ss)
10209  src_offset += ss;
10210  }
10211  else {
10212  ss = maygvl_copy_stream_read(0, stp, buf, len, (off_t)-1);
10213  }
10214  if (ss <= 0) /* EOF or error */
10215  return;
10216 
10217  ret = nogvl_copy_stream_write(stp, buf, ss);
10218  if (ret < 0)
10219  return;
10220 
10221  if (!use_eof)
10222  copy_length -= ss;
10223  }
10224 }
10225 
10226 static void *
10228 {
10229  struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
10230 #ifdef USE_SENDFILE
10231  int ret;
10232 #endif
10233 
10234 #ifdef USE_SENDFILE
10235  ret = nogvl_copy_stream_sendfile(stp);
10236  if (ret != 0)
10237  goto finish; /* error or success */
10238 #endif
10239 
10241 
10242 #ifdef USE_SENDFILE
10243  finish:
10244 #endif
10245  return 0;
10246 }
10247 
10248 static VALUE
10250 {
10251  struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
10252  const int buflen = 16*1024;
10253  VALUE n;
10254  VALUE buf = rb_str_buf_new(buflen);
10255  off_t rest = stp->copy_length;
10256  off_t off = stp->src_offset;
10257  ID read_method = id_readpartial;
10258 
10259  if (stp->src_fd == -1) {
10260  if (!rb_respond_to(stp->src, read_method)) {
10261  read_method = id_read;
10262  }
10263  }
10264 
10265  while (1) {
10266  long numwrote;
10267  long l;
10268  if (stp->copy_length == (off_t)-1) {
10269  l = buflen;
10270  }
10271  else {
10272  if (rest == 0)
10273  break;
10274  l = buflen < rest ? buflen : (long)rest;
10275  }
10276  if (stp->src_fd == -1) {
10277  VALUE rc = rb_funcall(stp->src, read_method, 2, INT2FIX(l), buf);
10278 
10279  if (read_method == id_read && NIL_P(rc))
10280  break;
10281  }
10282  else {
10283  ssize_t ss;
10284  rb_str_resize(buf, buflen);
10285  ss = maygvl_copy_stream_read(1, stp, RSTRING_PTR(buf), l, off);
10286  if (ss == -1)
10287  return Qnil;
10288  if (ss == 0)
10289  rb_eof_error();
10290  rb_str_resize(buf, ss);
10291  if (off != (off_t)-1)
10292  off += ss;
10293  }
10294  n = rb_io_write(stp->dst, buf);
10295  numwrote = NUM2LONG(n);
10296  stp->total += numwrote;
10297  rest -= numwrote;
10298  if (read_method == id_read && RSTRING_LEN(buf) == 0) {
10299  break;
10300  }
10301  }
10302 
10303  return Qnil;
10304 }
10305 
10306 static VALUE
10308 {
10309  if (stp->src_fd == -1 && stp->src_offset != (off_t)-1) {
10310  rb_raise(rb_eArgError, "cannot specify src_offset for non-IO");
10311  }
10313  (VALUE (*) (ANYARGS))0, (VALUE)0,
10314  rb_eEOFError, (VALUE)0);
10315  return Qnil;
10316 }
10317 
10318 static VALUE
10320 {
10321  struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
10322  VALUE src_io = stp->src, dst_io = stp->dst;
10323  rb_io_t *src_fptr = 0, *dst_fptr = 0;
10324  int src_fd, dst_fd;
10325  const int common_oflags = 0
10326 #ifdef O_NOCTTY
10327  | O_NOCTTY
10328 #endif
10329  ;
10330 
10331  stp->th = rb_thread_current();
10332 
10333  stp->total = 0;
10334 
10335  if (src_io == argf ||
10336  !(RB_TYPE_P(src_io, T_FILE) ||
10337  RB_TYPE_P(src_io, T_STRING) ||
10338  rb_respond_to(src_io, rb_intern("to_path")))) {
10339  src_fd = -1;
10340  }
10341  else {
10342  if (!RB_TYPE_P(src_io, T_FILE)) {
10343  VALUE args[2];
10344  FilePathValue(src_io);
10345  args[0] = src_io;
10346  args[1] = INT2NUM(O_RDONLY|common_oflags);
10347  src_io = rb_class_new_instance(2, args, rb_cFile);
10348  stp->src = src_io;
10349  stp->close_src = 1;
10350  }
10351  GetOpenFile(src_io, src_fptr);
10352  rb_io_check_byte_readable(src_fptr);
10353  src_fd = src_fptr->fd;
10354  }
10355  stp->src_fd = src_fd;
10356 
10357  if (dst_io == argf ||
10358  !(RB_TYPE_P(dst_io, T_FILE) ||
10359  RB_TYPE_P(dst_io, T_STRING) ||
10360  rb_respond_to(dst_io, rb_intern("to_path")))) {
10361  dst_fd = -1;
10362  }
10363  else {
10364  if (!RB_TYPE_P(dst_io, T_FILE)) {
10365  VALUE args[3];
10366  FilePathValue(dst_io);
10367  args[0] = dst_io;
10368  args[1] = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC|common_oflags);
10369  args[2] = INT2FIX(0666);
10370  dst_io = rb_class_new_instance(3, args, rb_cFile);
10371  stp->dst = dst_io;
10372  stp->close_dst = 1;
10373  }
10374  else {
10375  dst_io = GetWriteIO(dst_io);
10376  stp->dst = dst_io;
10377  }
10378  GetOpenFile(dst_io, dst_fptr);
10379  rb_io_check_writable(dst_fptr);
10380  dst_fd = dst_fptr->fd;
10381  }
10382  stp->dst_fd = dst_fd;
10383 
10384 #ifdef O_BINARY
10385  if (src_fptr)
10387 #endif
10388  if (dst_fptr)
10389  io_ascii8bit_binmode(dst_fptr);
10390 
10391  if (stp->src_offset == (off_t)-1 && src_fptr && src_fptr->rbuf.len) {
10392  size_t len = src_fptr->rbuf.len;
10393  VALUE str;
10394  if (stp->copy_length != (off_t)-1 && stp->copy_length < (off_t)len) {
10395  len = (size_t)stp->copy_length;
10396  }
10397  str = rb_str_buf_new(len);
10398  rb_str_resize(str,len);
10399  read_buffered_data(RSTRING_PTR(str), len, src_fptr);
10400  if (dst_fptr) { /* IO or filename */
10401  if (io_binwrite(str, RSTRING_PTR(str), RSTRING_LEN(str), dst_fptr, 0) < 0)
10402  rb_sys_fail(0);
10403  }
10404  else /* others such as StringIO */
10405  rb_io_write(dst_io, str);
10406  stp->total += len;
10407  if (stp->copy_length != (off_t)-1)
10408  stp->copy_length -= len;
10409  }
10410 
10411  if (dst_fptr && io_fflush(dst_fptr) < 0) {
10412  rb_raise(rb_eIOError, "flush failed");
10413  }
10414 
10415  if (stp->copy_length == 0)
10416  return Qnil;
10417 
10418  if (src_fd == -1 || dst_fd == -1) {
10419  return copy_stream_fallback(stp);
10420  }
10421 
10422  rb_fd_set(src_fd, &stp->fds);
10423  rb_fd_set(dst_fd, &stp->fds);
10424 
10426  return Qnil;
10427 }
10428 
10429 static VALUE
10431 {
10432  struct copy_stream_struct *stp = (struct copy_stream_struct *)arg;
10433  if (stp->close_src) {
10434  rb_io_close_m(stp->src);
10435  }
10436  if (stp->close_dst) {
10437  rb_io_close_m(stp->dst);
10438  }
10439  rb_fd_term(&stp->fds);
10440  if (stp->syserr) {
10441  errno = stp->error_no;
10442  rb_sys_fail(stp->syserr);
10443  }
10444  if (stp->notimp) {
10445  rb_raise(rb_eNotImpError, "%s() not implemented", stp->notimp);
10446  }
10447  return Qnil;
10448 }
10449 
10450 /*
10451  * call-seq:
10452  * IO.copy_stream(src, dst)
10453  * IO.copy_stream(src, dst, copy_length)
10454  * IO.copy_stream(src, dst, copy_length, src_offset)
10455  *
10456  * IO.copy_stream copies <i>src</i> to <i>dst</i>.
10457  * <i>src</i> and <i>dst</i> is either a filename or an IO.
10458  *
10459  * This method returns the number of bytes copied.
10460  *
10461  * If optional arguments are not given,
10462  * the start position of the copy is
10463  * the beginning of the filename or
10464  * the current file offset of the IO.
10465  * The end position of the copy is the end of file.
10466  *
10467  * If <i>copy_length</i> is given,
10468  * No more than <i>copy_length</i> bytes are copied.
10469  *
10470  * If <i>src_offset</i> is given,
10471  * it specifies the start position of the copy.
10472  *
10473  * When <i>src_offset</i> is specified and
10474  * <i>src</i> is an IO,
10475  * IO.copy_stream doesn't move the current file offset.
10476  *
10477  */
10478 static VALUE
10480 {
10482  struct copy_stream_struct st;
10483 
10484  MEMZERO(&st, struct copy_stream_struct, 1);
10485 
10486  rb_scan_args(argc, argv, "22", &src, &dst, &length, &src_offset);
10487 
10488  st.src = src;
10489  st.dst = dst;
10490 
10491  if (NIL_P(length))
10492  st.copy_length = (off_t)-1;
10493  else
10494  st.copy_length = NUM2OFFT(length);
10495 
10496  if (NIL_P(src_offset))
10497  st.src_offset = (off_t)-1;
10498  else
10499  st.src_offset = NUM2OFFT(src_offset);
10500 
10501  rb_fd_init(&st.fds);
10503 
10504  return OFFT2NUM(st.total);
10505 }
10506 
10507 /*
10508  * call-seq:
10509  * io.external_encoding -> encoding
10510  *
10511  * Returns the Encoding object that represents the encoding of the file.
10512  * If io is write mode and no encoding is specified, returns <code>nil</code>.
10513  */
10514 
10515 static VALUE
10517 {
10518  rb_io_t *fptr;
10519 
10520  GetOpenFile(io, fptr);
10521  if (fptr->encs.enc2) {
10522  return rb_enc_from_encoding(fptr->encs.enc2);
10523  }
10524  if (fptr->mode & FMODE_WRITABLE) {
10525  if (fptr->encs.enc)
10526  return rb_enc_from_encoding(fptr->encs.enc);
10527  return Qnil;
10528  }
10529  return rb_enc_from_encoding(io_read_encoding(fptr));
10530 }
10531 
10532 /*
10533  * call-seq:
10534  * io.internal_encoding -> encoding
10535  *
10536  * Returns the Encoding of the internal string if conversion is
10537  * specified. Otherwise returns nil.
10538  */
10539 
10540 static VALUE
10542 {
10543  rb_io_t *fptr;
10544 
10545  GetOpenFile(io, fptr);
10546  if (!fptr->encs.enc2) return Qnil;
10547  return rb_enc_from_encoding(io_read_encoding(fptr));
10548 }
10549 
10550 /*
10551  * call-seq:
10552  * io.set_encoding(ext_enc) -> io
10553  * io.set_encoding("ext_enc:int_enc") -> io
10554  * io.set_encoding(ext_enc, int_enc) -> io
10555  * io.set_encoding("ext_enc:int_enc", opt) -> io
10556  * io.set_encoding(ext_enc, int_enc, opt) -> io
10557  *
10558  * If single argument is specified, read string from io is tagged
10559  * with the encoding specified. If encoding is a colon separated two
10560  * encoding names "A:B", the read string is converted from encoding A
10561  * (external encoding) to encoding B (internal encoding), then tagged
10562  * with B. If two arguments are specified, those must be encoding
10563  * objects or encoding names, and the first one is the external encoding, and the
10564  * second one is the internal encoding.
10565  * If the external encoding and the internal encoding is specified,
10566  * optional hash argument specify the conversion option.
10567  */
10568 
10569 static VALUE
10571 {
10572  rb_io_t *fptr;
10573  VALUE v1, v2, opt;
10574 
10575  if (!RB_TYPE_P(io, T_FILE)) {
10576  return rb_funcall2(io, id_set_encoding, argc, argv);
10577  }
10578 
10579  argc = rb_scan_args(argc, argv, "11:", &v1, &v2, &opt);
10580  GetOpenFile(io, fptr);
10581  io_encoding_set(fptr, v1, v2, opt);
10582  return io;
10583 }
10584 
10585 void
10587 {
10588  extern VALUE rb_stdin, rb_stdout, rb_stderr;
10589  VALUE val = Qnil;
10590 
10591  rb_io_set_encoding(1, &val, rb_stdin);
10592  rb_io_set_encoding(1, &val, rb_stdout);
10593  rb_io_set_encoding(1, &val, rb_stderr);
10594 }
10595 
10596 /*
10597  * call-seq:
10598  * ARGF.external_encoding -> encoding
10599  *
10600  * Returns the external encoding for files read from +ARGF+ as an +Encoding+
10601  * object. The external encoding is the encoding of the text as stored in a
10602  * file. Contrast with +ARGF.internal_encoding+, which is the encoding used
10603  * to represent this text within Ruby.
10604  *
10605  * To set the external encoding use +ARGF.set_encoding+.
10606  *
10607  * For example:
10608  *
10609  * ARGF.external_encoding #=> #<Encoding:UTF-8>
10610  *
10611  */
10612 static VALUE
10614 {
10615  if (!RTEST(ARGF.current_file)) {
10617  }
10618  return rb_io_external_encoding(rb_io_check_io(ARGF.current_file));
10619 }
10620 
10621 /*
10622  * call-seq:
10623  * ARGF.internal_encoding -> encoding
10624  *
10625  * Returns the internal encoding for strings read from +ARGF+ as an
10626  * +Encoding+ object.
10627  *
10628  * If +ARGF.set_encoding+ has been called with two encoding names, the second
10629  * is returned. Otherwise, if +Encoding.default_external+ has been set, that
10630  * value is returned. Failing that, if a default external encoding was
10631  * specified on the command-line, that value is used. If the encoding is
10632  * unknown, nil is returned.
10633  */
10634 static VALUE
10636 {
10637  if (!RTEST(ARGF.current_file)) {
10639  }
10640  return rb_io_internal_encoding(rb_io_check_io(ARGF.current_file));
10641 }
10642 
10643 /*
10644  * call-seq:
10645  * ARGF.set_encoding(ext_enc) -> ARGF
10646  * ARGF.set_encoding("ext_enc:int_enc") -> ARGF
10647  * ARGF.set_encoding(ext_enc, int_enc) -> ARGF
10648  * ARGF.set_encoding("ext_enc:int_enc", opt) -> ARGF
10649  * ARGF.set_encoding(ext_enc, int_enc, opt) -> ARGF
10650  *
10651  * If single argument is specified, strings read from ARGF are tagged with
10652  * the encoding specified.
10653  *
10654  * If two encoding names separated by a colon are given, e.g. "ascii:utf-8",
10655  * the read string is converted from the first encoding (external encoding)
10656  * to the second encoding (internal encoding), then tagged with the second
10657  * encoding.
10658  *
10659  * If two arguments are specified, they must be encoding objects or encoding
10660  * names. Again, the first specifies the external encoding; the second
10661  * specifies the internal encoding.
10662  *
10663  * If the external encoding and the internal encoding are specified, the
10664  * optional +Hash+ argument can be used to adjust the conversion process. The
10665  * structure of this hash is explained in the +String#encode+ documentation.
10666  *
10667  * For example:
10668  *
10669  * ARGF.set_encoding('ascii') # Tag the input as US-ASCII text
10670  * ARGF.set_encoding(Encoding::UTF_8) # Tag the input as UTF-8 text
10671  * ARGF.set_encoding('utf-8','ascii') # Transcode the input from US-ASCII
10672  * # to UTF-8.
10673  */
10674 static VALUE
10676 {
10677  rb_io_t *fptr;
10678 
10679  if (!next_argv()) {
10680  rb_raise(rb_eArgError, "no stream to set encoding");
10681  }
10682  rb_io_set_encoding(argc, argv, ARGF.current_file);
10683  GetOpenFile(ARGF.current_file, fptr);
10684  ARGF.encs = fptr->encs;
10685  return argf;
10686 }
10687 
10688 /*
10689  * call-seq:
10690  * ARGF.tell -> Integer
10691  * ARGF.pos -> Integer
10692  *
10693  * Returns the current offset (in bytes) of the current file in +ARGF+.
10694  *
10695  * ARGF.pos #=> 0
10696  * ARGF.gets #=> "This is line one\n"
10697  * ARGF.pos #=> 17
10698  *
10699  */
10700 static VALUE
10702 {
10703  if (!next_argv()) {
10704  rb_raise(rb_eArgError, "no stream to tell");
10705  }
10706  ARGF_FORWARD(0, 0);
10707  return rb_io_tell(ARGF.current_file);
10708 }
10709 
10710 /*
10711  * call-seq:
10712  * ARGF.seek(amount, whence=IO::SEEK_SET) -> 0
10713  *
10714  * Seeks to offset _amount_ (an +Integer+) in the +ARGF+ stream according to
10715  * the value of _whence_. See +IO#seek+ for further details.
10716  */
10717 static VALUE
10719 {
10720  if (!next_argv()) {
10721  rb_raise(rb_eArgError, "no stream to seek");
10722  }
10723  ARGF_FORWARD(argc, argv);
10724  return rb_io_seek_m(argc, argv, ARGF.current_file);
10725 }
10726 
10727 /*
10728  * call-seq:
10729  * ARGF.pos = position -> Integer
10730  *
10731  * Seeks to the position given by _position_ (in bytes) in +ARGF+.
10732  *
10733  * For example:
10734  *
10735  * ARGF.pos = 17
10736  * ARGF.gets #=> "This is line two\n"
10737  */
10738 static VALUE
10740 {
10741  if (!next_argv()) {
10742  rb_raise(rb_eArgError, "no stream to set position");
10743  }
10744  ARGF_FORWARD(1, &offset);
10745  return rb_io_set_pos(ARGF.current_file, offset);
10746 }
10747 
10748 /*
10749  * call-seq:
10750  * ARGF.rewind -> 0
10751  *
10752  * Positions the current file to the beginning of input, resetting
10753  * +ARGF.lineno+ to zero.
10754  *
10755  * ARGF.readline #=> "This is line one\n"
10756  * ARGF.rewind #=> 0
10757  * ARGF.lineno #=> 0
10758  * ARGF.readline #=> "This is line one\n"
10759  */
10760 static VALUE
10762 {
10763  if (!next_argv()) {
10764  rb_raise(rb_eArgError, "no stream to rewind");
10765  }
10766  ARGF_FORWARD(0, 0);
10767  return rb_io_rewind(ARGF.current_file);
10768 }
10769 
10770 /*
10771  * call-seq:
10772  * ARGF.fileno -> fixnum
10773  * ARGF.to_i -> fixnum
10774  *
10775  * Returns an integer representing the numeric file descriptor for
10776  * the current file. Raises an +ArgumentError+ if there isn't a current file.
10777  *
10778  * ARGF.fileno #=> 3
10779  */
10780 static VALUE
10782 {
10783  if (!next_argv()) {
10784  rb_raise(rb_eArgError, "no stream");
10785  }
10786  ARGF_FORWARD(0, 0);
10787  return rb_io_fileno(ARGF.current_file);
10788 }
10789 
10790 /*
10791  * call-seq:
10792  * ARGF.to_io -> IO
10793  *
10794  * Returns an +IO+ object representing the current file. This will be a
10795  * +File+ object unless the current file is a stream such as STDIN.
10796  *
10797  * For example:
10798  *
10799  * ARGF.to_io #=> #<File:glark.txt>
10800  * ARGF.to_io #=> #<IO:<STDIN>>
10801  */
10802 static VALUE
10804 {
10805  next_argv();
10806  ARGF_FORWARD(0, 0);
10807  return ARGF.current_file;
10808 }
10809 
10810 /*
10811  * call-seq:
10812  * ARGF.eof? -> true or false
10813  * ARGF.eof -> true or false
10814  *
10815  * Returns true if the current file in +ARGF+ is at end of file, i.e. it has
10816  * no data to read. The stream must be opened for reading or an +IOError+
10817  * will be raised.
10818  *
10819  * $ echo "eof" | ruby argf.rb
10820  *
10821  * ARGF.eof? #=> false
10822  * 3.times { ARGF.readchar }
10823  * ARGF.eof? #=> false
10824  * ARGF.readchar #=> "\n"
10825  * ARGF.eof? #=> true
10826  */
10827 
10828 static VALUE
10830 {
10831  next_argv();
10832  if (RTEST(ARGF.current_file)) {
10833  if (ARGF.init_p == 0) return Qtrue;
10834  next_argv();
10835  ARGF_FORWARD(0, 0);
10836  if (rb_io_eof(ARGF.current_file)) {
10837  return Qtrue;
10838  }
10839  }
10840  return Qfalse;
10841 }
10842 
10843 /*
10844  * call-seq:
10845  * ARGF.read([length [, outbuf]]) -> string, outbuf, or nil
10846  *
10847  * Reads _length_ bytes from ARGF. The files named on the command line
10848  * are concatenated and treated as a single file by this method, so when
10849  * called without arguments the contents of this pseudo file are returned in
10850  * their entirety.
10851  *
10852  * _length_ must be a non-negative integer or nil. If it is a positive
10853  * integer, +read+ tries to read at most _length_ bytes. It returns nil
10854  * if an EOF was encountered before anything could be read. Fewer than
10855  * _length_ bytes may be returned if an EOF is encountered during the read.
10856  *
10857  * If _length_ is omitted or is _nil_, it reads until EOF. A String is
10858  * returned even if EOF is encountered before any data is read.
10859  *
10860  * If _length_ is zero, it returns _""_.
10861  *
10862  * If the optional _outbuf_ argument is present, it must reference a String,
10863  * which will receive the data.
10864  * The <i>outbuf</i> will contain only the received data after the method call
10865  * even if it is not empty at the beginning.
10866  *
10867  * For example:
10868  *
10869  * $ echo "small" > small.txt
10870  * $ echo "large" > large.txt
10871  * $ ./glark.rb small.txt large.txt
10872  *
10873  * ARGF.read #=> "small\nlarge"
10874  * ARGF.read(200) #=> "small\nlarge"
10875  * ARGF.read(2) #=> "sm"
10876  * ARGF.read(0) #=> ""
10877  *
10878  * Note that this method behaves like fread() function in C. If you need the
10879  * behavior like read(2) system call, consider +ARGF.readpartial+.
10880  */
10881 
10882 static VALUE
10884 {
10885  VALUE tmp, str, length;
10886  long len = 0;
10887 
10888  rb_scan_args(argc, argv, "02", &length, &str);
10889  if (!NIL_P(length)) {
10890  len = NUM2LONG(argv[0]);
10891  }
10892  if (!NIL_P(str)) {
10893  StringValue(str);
10894  rb_str_resize(str,0);
10895  argv[1] = Qnil;
10896  }
10897 
10898  retry:
10899  if (!next_argv()) {
10900  return str;
10901  }
10902  if (ARGF_GENERIC_INPUT_P()) {
10903  tmp = argf_forward(argc, argv, argf);
10904  }
10905  else {
10906  tmp = io_read(argc, argv, ARGF.current_file);
10907  }
10908  if (NIL_P(str)) str = tmp;
10909  else if (!NIL_P(tmp)) rb_str_append(str, tmp);
10910  if (NIL_P(tmp) || NIL_P(length)) {
10911  if (ARGF.next_p != -1) {
10912  argf_close(argf);
10913  ARGF.next_p = 1;
10914  goto retry;
10915  }
10916  }
10917  else if (argc >= 1) {
10918  if (RSTRING_LEN(str) < len) {
10919  len -= RSTRING_LEN(str);
10920  argv[0] = INT2NUM(len);
10921  goto retry;
10922  }
10923  }
10924  return str;
10925 }
10926 
10928  int argc;
10931 };
10932 
10933 static VALUE
10935 {
10936  struct argf_call_arg *p = (struct argf_call_arg *)arg;
10937  argf_forward(p->argc, p->argv, p->argf);
10938  return Qnil;
10939 }
10940 
10941 static VALUE argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock);
10942 
10943 /*
10944  * call-seq:
10945  * ARGF.readpartial(maxlen) -> string
10946  * ARGF.readpartial(maxlen, outbuf) -> outbuf
10947  *
10948  * Reads at most _maxlen_ bytes from the ARGF stream.
10949  *
10950  * If the optional _outbuf_ argument is present,
10951  * it must reference a String, which will receive the data.
10952  * The <i>outbuf</i> will contain only the received data after the method call
10953  * even if it is not empty at the beginning.
10954  *
10955  * It raises <code>EOFError</code> on end of ARGF stream.
10956  * Since ARGF stream is a concatenation of multiple files,
10957  * internally EOF is occur for each file.
10958  * ARGF.readpartial returns empty strings for EOFs except the last one and
10959  * raises <code>EOFError</code> for the last one.
10960  *
10961  */
10962 
10963 static VALUE
10965 {
10966  return argf_getpartial(argc, argv, argf, 0);
10967 }
10968 
10969 /*
10970  * call-seq:
10971  * ARGF.read_nonblock(maxlen) -> string
10972  * ARGF.read_nonblock(maxlen, outbuf) -> outbuf
10973  *
10974  * Reads at most _maxlen_ bytes from the ARGF stream in non-blocking mode.
10975  */
10976 
10977 static VALUE
10979 {
10980  return argf_getpartial(argc, argv, argf, 1);
10981 }
10982 
10983 static VALUE
10984 argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock)
10985 {
10986  VALUE tmp, str, length;
10987 
10988  rb_scan_args(argc, argv, "11", &length, &str);
10989  if (!NIL_P(str)) {
10990  StringValue(str);
10991  argv[1] = str;
10992  }
10993 
10994  if (!next_argv()) {
10995  if (!NIL_P(str)) {
10996  rb_str_resize(str, 0);
10997  }
10998  rb_eof_error();
10999  }
11000  if (ARGF_GENERIC_INPUT_P()) {
11001  struct argf_call_arg arg;
11002  arg.argc = argc;
11003  arg.argv = argv;
11004  arg.argf = argf;
11005  tmp = rb_rescue2(argf_forward_call, (VALUE)&arg,
11007  }
11008  else {
11009  tmp = io_getpartial(argc, argv, ARGF.current_file, nonblock, 0);
11010  }
11011  if (NIL_P(tmp)) {
11012  if (ARGF.next_p == -1) {
11013  rb_eof_error();
11014  }
11015  argf_close(argf);
11016  ARGF.next_p = 1;
11017  if (RARRAY_LEN(ARGF.argv) == 0)
11018  rb_eof_error();
11019  if (NIL_P(str))
11020  str = rb_str_new(NULL, 0);
11021  return str;
11022  }
11023  return tmp;
11024 }
11025 
11026 /*
11027  * call-seq:
11028  * ARGF.getc -> String or nil
11029  *
11030  * Reads the next character from +ARGF+ and returns it as a +String+. Returns
11031  * +nil+ at the end of the stream.
11032  *
11033  * +ARGF+ treats the files named on the command line as a single file created
11034  * by concatenating their contents. After returning the last character of the
11035  * first file, it returns the first character of the second file, and so on.
11036  *
11037  * For example:
11038  *
11039  * $ echo "foo" > file
11040  * $ ruby argf.rb file
11041  *
11042  * ARGF.getc #=> "f"
11043  * ARGF.getc #=> "o"
11044  * ARGF.getc #=> "o"
11045  * ARGF.getc #=> "\n"
11046  * ARGF.getc #=> nil
11047  * ARGF.getc #=> nil
11048  */
11049 static VALUE
11051 {
11052  VALUE ch;
11053 
11054  retry:
11055  if (!next_argv()) return Qnil;
11056  if (ARGF_GENERIC_INPUT_P()) {
11057  ch = rb_funcall3(ARGF.current_file, rb_intern("getc"), 0, 0);
11058  }
11059  else {
11060  ch = rb_io_getc(ARGF.current_file);
11061  }
11062  if (NIL_P(ch) && ARGF.next_p != -1) {
11063  argf_close(argf);
11064  ARGF.next_p = 1;
11065  goto retry;
11066  }
11067 
11068  return ch;
11069 }
11070 
11071 /*
11072  * call-seq:
11073  * ARGF.getbyte -> Fixnum or nil
11074  *
11075  * Gets the next 8-bit byte (0..255) from +ARGF+. Returns +nil+ if called at
11076  * the end of the stream.
11077  *
11078  * For example:
11079  *
11080  * $ echo "foo" > file
11081  * $ ruby argf.rb file
11082  *
11083  * ARGF.getbyte #=> 102
11084  * ARGF.getbyte #=> 111
11085  * ARGF.getbyte #=> 111
11086  * ARGF.getbyte #=> 10
11087  * ARGF.getbyte #=> nil
11088  */
11089 static VALUE
11091 {
11092  VALUE ch;
11093 
11094  retry:
11095  if (!next_argv()) return Qnil;
11096  if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
11097  ch = rb_funcall3(ARGF.current_file, rb_intern("getbyte"), 0, 0);
11098  }
11099  else {
11100  ch = rb_io_getbyte(ARGF.current_file);
11101  }
11102  if (NIL_P(ch) && ARGF.next_p != -1) {
11103  argf_close(argf);
11104  ARGF.next_p = 1;
11105  goto retry;
11106  }
11107 
11108  return ch;
11109 }
11110 
11111 /*
11112  * call-seq:
11113  * ARGF.readchar -> String or nil
11114  *
11115  * Reads the next character from +ARGF+ and returns it as a +String+. Raises
11116  * an +EOFError+ after the last character of the last file has been read.
11117  *
11118  * For example:
11119  *
11120  * $ echo "foo" > file
11121  * $ ruby argf.rb file
11122  *
11123  * ARGF.readchar #=> "f"
11124  * ARGF.readchar #=> "o"
11125  * ARGF.readchar #=> "o"
11126  * ARGF.readchar #=> "\n"
11127  * ARGF.readchar #=> end of file reached (EOFError)
11128  */
11129 static VALUE
11131 {
11132  VALUE ch;
11133 
11134  retry:
11135  if (!next_argv()) rb_eof_error();
11136  if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
11137  ch = rb_funcall3(ARGF.current_file, rb_intern("getc"), 0, 0);
11138  }
11139  else {
11140  ch = rb_io_getc(ARGF.current_file);
11141  }
11142  if (NIL_P(ch) && ARGF.next_p != -1) {
11143  argf_close(argf);
11144  ARGF.next_p = 1;
11145  goto retry;
11146  }
11147 
11148  return ch;
11149 }
11150 
11151 /*
11152  * call-seq:
11153  * ARGF.readbyte -> Fixnum
11154  *
11155  * Reads the next 8-bit byte from ARGF and returns it as a +Fixnum+. Raises
11156  * an +EOFError+ after the last byte of the last file has been read.
11157  *
11158  * For example:
11159  *
11160  * $ echo "foo" > file
11161  * $ ruby argf.rb file
11162  *
11163  * ARGF.readbyte #=> 102
11164  * ARGF.readbyte #=> 111
11165  * ARGF.readbyte #=> 111
11166  * ARGF.readbyte #=> 10
11167  * ARGF.readbyte #=> end of file reached (EOFError)
11168  */
11169 static VALUE
11171 {
11172  VALUE c;
11173 
11174  NEXT_ARGF_FORWARD(0, 0);
11175  c = argf_getbyte(argf);
11176  if (NIL_P(c)) {
11177  rb_eof_error();
11178  }
11179  return c;
11180 }
11181 
11182 #define FOREACH_ARGF() while (next_argv())
11183 
11184 static VALUE
11185 argf_block_call_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, argf))
11187  const VALUE current = ARGF.current_file;
11189  if (ARGF.init_p == -1 || current != ARGF.current_file) {
11191  }
11192  return Qnil;
11193 }
11194 
11195 static void
11197 {
11198  VALUE ret = rb_block_call(ARGF.current_file, mid, argc, argv, argf_block_call_i, argf);
11199  if (ret != Qundef) ARGF.next_p = 1;
11200 }
11201 
11202 /*
11203  * call-seq:
11204  * ARGF.each(sep=$/) {|line| block } -> ARGF
11205  * ARGF.each(sep=$/,limit) {|line| block } -> ARGF
11206  * ARGF.each(...) -> an_enumerator
11207  *
11208  * ARGF.each_line(sep=$/) {|line| block } -> ARGF
11209  * ARGF.each_line(sep=$/,limit) {|line| block } -> ARGF
11210  * ARGF.each_line(...) -> an_enumerator
11211  *
11212  * Returns an enumerator which iterates over each line (separated by _sep_,
11213  * which defaults to your platform's newline character) of each file in
11214  * +ARGV+. If a block is supplied, each line in turn will be yielded to the
11215  * block, otherwise an enumerator is returned.
11216  * The optional _limit_ argument is a +Fixnum+ specifying the maximum
11217  * length of each line; longer lines will be split according to this limit.
11218  *
11219  * This method allows you to treat the files supplied on the command line as
11220  * a single file consisting of the concatenation of each named file. After
11221  * the last line of the first file has been returned, the first line of the
11222  * second file is returned. The +ARGF.filename+ and +ARGF.lineno+ methods can
11223  * be used to determine the filename and line number, respectively, of the
11224  * current line.
11225  *
11226  * For example, the following code prints out each line of each named file
11227  * prefixed with its line number, displaying the filename once per file:
11228  *
11229  * ARGF.lines do |line|
11230  * puts ARGF.filename if ARGF.lineno == 1
11231  * puts "#{ARGF.lineno}: #{line}"
11232  * end
11233  */
11234 static VALUE
11236 {
11237  RETURN_ENUMERATOR(argf, argc, argv);
11238  FOREACH_ARGF() {
11239  argf_block_call(rb_intern("each_line"), argc, argv, argf);
11240  }
11241  return argf;
11242 }
11243 
11244 /*
11245  * This is a deprecated alias for <code>each_line</code>.
11246  */
11247 
11248 static VALUE
11250 {
11251  rb_warn("ARGF#lines is deprecated; use #each_line instead");
11252  if (!rb_block_given_p())
11253  return rb_enumeratorize(argf, ID2SYM(rb_intern("each_line")), argc, argv);
11254  return argf_each_line(argc, argv, argf);
11255 }
11256 
11257 /*
11258  * call-seq:
11259  * ARGF.bytes {|byte| block } -> ARGF
11260  * ARGF.bytes -> an_enumerator
11261  *
11262  * ARGF.each_byte {|byte| block } -> ARGF
11263  * ARGF.each_byte -> an_enumerator
11264  *
11265  * Iterates over each byte of each file in +ARGV+.
11266  * A byte is returned as a +Fixnum+ in the range 0..255.
11267  *
11268  * This method allows you to treat the files supplied on the command line as
11269  * a single file consisting of the concatenation of each named file. After
11270  * the last byte of the first file has been returned, the first byte of the
11271  * second file is returned. The +ARGF.filename+ method can be used to
11272  * determine the filename of the current byte.
11273  *
11274  * If no block is given, an enumerator is returned instead.
11275  *
11276  * For example:
11277  *
11278  * ARGF.bytes.to_a #=> [35, 32, ... 95, 10]
11279  *
11280  */
11281 static VALUE
11283 {
11284  RETURN_ENUMERATOR(argf, 0, 0);
11285  FOREACH_ARGF() {
11286  argf_block_call(rb_intern("each_byte"), 0, 0, argf);
11287  }
11288  return argf;
11289 }
11290 
11291 /*
11292  * This is a deprecated alias for <code>each_byte</code>.
11293  */
11294 
11295 static VALUE
11297 {
11298  rb_warn("ARGF#bytes is deprecated; use #each_byte instead");
11299  if (!rb_block_given_p())
11300  return rb_enumeratorize(argf, ID2SYM(rb_intern("each_byte")), 0, 0);
11301  return argf_each_byte(argf);
11302 }
11303 
11304 /*
11305  * call-seq:
11306  * ARGF.each_char {|char| block } -> ARGF
11307  * ARGF.each_char -> an_enumerator
11308  *
11309  * Iterates over each character of each file in +ARGF+.
11310  *
11311  * This method allows you to treat the files supplied on the command line as
11312  * a single file consisting of the concatenation of each named file. After
11313  * the last character of the first file has been returned, the first
11314  * character of the second file is returned. The +ARGF.filename+ method can
11315  * be used to determine the name of the file in which the current character
11316  * appears.
11317  *
11318  * If no block is given, an enumerator is returned instead.
11319  */
11320 static VALUE
11322 {
11323  RETURN_ENUMERATOR(argf, 0, 0);
11324  FOREACH_ARGF() {
11325  argf_block_call(rb_intern("each_char"), 0, 0, argf);
11326  }
11327  return argf;
11328 }
11329 
11330 /*
11331  * This is a deprecated alias for <code>each_char</code>.
11332  */
11333 
11334 static VALUE
11336 {
11337  rb_warn("ARGF#chars is deprecated; use #each_char instead");
11338  if (!rb_block_given_p())
11339  return rb_enumeratorize(argf, ID2SYM(rb_intern("each_char")), 0, 0);
11340  return argf_each_char(argf);
11341 }
11342 
11343 /*
11344  * call-seq:
11345  * ARGF.each_codepoint {|codepoint| block } -> ARGF
11346  * ARGF.each_codepoint -> an_enumerator
11347  *
11348  * Iterates over each codepoint of each file in +ARGF+.
11349  *
11350  * This method allows you to treat the files supplied on the command line as
11351  * a single file consisting of the concatenation of each named file. After
11352  * the last codepoint of the first file has been returned, the first
11353  * codepoint of the second file is returned. The +ARGF.filename+ method can
11354  * be used to determine the name of the file in which the current codepoint
11355  * appears.
11356  *
11357  * If no block is given, an enumerator is returned instead.
11358  */
11359 static VALUE
11361 {
11362  RETURN_ENUMERATOR(argf, 0, 0);
11363  FOREACH_ARGF() {
11364  argf_block_call(rb_intern("each_codepoint"), 0, 0, argf);
11365  }
11366  return argf;
11367 }
11368 
11369 /*
11370  * This is a deprecated alias for <code>each_codepoint</code>.
11371  */
11372 
11373 static VALUE
11375 {
11376  rb_warn("ARGF#codepoints is deprecated; use #each_codepoint instead");
11377  if (!rb_block_given_p())
11378  return rb_enumeratorize(argf, ID2SYM(rb_intern("each_codepoint")), 0, 0);
11379  return argf_each_codepoint(argf);
11380 }
11381 
11382 /*
11383  * call-seq:
11384  * ARGF.filename -> String
11385  * ARGF.path -> String
11386  *
11387  * Returns the current filename. "-" is returned when the current file is
11388  * STDIN.
11389  *
11390  * For example:
11391  *
11392  * $ echo "foo" > foo
11393  * $ echo "bar" > bar
11394  * $ echo "glark" > glark
11395  *
11396  * $ ruby argf.rb foo bar glark
11397  *
11398  * ARGF.filename #=> "foo"
11399  * ARGF.read(5) #=> "foo\nb"
11400  * ARGF.filename #=> "bar"
11401  * ARGF.skip
11402  * ARGF.filename #=> "glark"
11403  */
11404 static VALUE
11406 {
11407  next_argv();
11408  return ARGF.filename;
11409 }
11410 
11411 static VALUE
11413 {
11414  return argf_filename(*var);
11415 }
11416 
11417 /*
11418  * call-seq:
11419  * ARGF.file -> IO or File object
11420  *
11421  * Returns the current file as an +IO+ or +File+ object. #<IO:<STDIN>> is
11422  * returned when the current file is STDIN.
11423  *
11424  * For example:
11425  *
11426  * $ echo "foo" > foo
11427  * $ echo "bar" > bar
11428  *
11429  * $ ruby argf.rb foo bar
11430  *
11431  * ARGF.file #=> #<File:foo>
11432  * ARGF.read(5) #=> "foo\nb"
11433  * ARGF.file #=> #<File:bar>
11434  */
11435 static VALUE
11437 {
11438  next_argv();
11439  return ARGF.current_file;
11440 }
11441 
11442 /*
11443  * call-seq:
11444  * ARGF.binmode -> ARGF
11445  *
11446  * Puts +ARGF+ into binary mode. Once a stream is in binary mode, it cannot
11447  * be reset to non-binary mode. This option has the following effects:
11448  *
11449  * * Newline conversion is disabled.
11450  * * Encoding conversion is disabled.
11451  * * Content is treated as ASCII-8BIT.
11452  */
11453 static VALUE
11455 {
11456  ARGF.binmode = 1;
11457  next_argv();
11458  ARGF_FORWARD(0, 0);
11459  rb_io_ascii8bit_binmode(ARGF.current_file);
11460  return argf;
11461 }
11462 
11463 /*
11464  * call-seq:
11465  * ARGF.binmode? -> true or false
11466  *
11467  * Returns true if +ARGF+ is being read in binary mode; false otherwise. (To
11468  * enable binary mode use +ARGF.binmode+.
11469  *
11470  * For example:
11471  *
11472  * ARGF.binmode? #=> false
11473  * ARGF.binmode
11474  * ARGF.binmode? #=> true
11475  */
11476 static VALUE
11478 {
11479  return ARGF.binmode ? Qtrue : Qfalse;
11480 }
11481 
11482 /*
11483  * call-seq:
11484  * ARGF.skip -> ARGF
11485  *
11486  * Sets the current file to the next file in ARGV. If there aren't any more
11487  * files it has no effect.
11488  *
11489  * For example:
11490  *
11491  * $ ruby argf.rb foo bar
11492  * ARGF.filename #=> "foo"
11493  * ARGF.skip
11494  * ARGF.filename #=> "bar"
11495  */
11496 static VALUE
11498 {
11499  if (ARGF.init_p && ARGF.next_p == 0) {
11500  argf_close(argf);
11501  ARGF.next_p = 1;
11502  }
11503  return argf;
11504 }
11505 
11506 /*
11507  * call-seq:
11508  * ARGF.close -> ARGF
11509  *
11510  * Closes the current file and skips to the next in the stream. Trying to
11511  * close a file that has already been closed causes an +IOError+ to be
11512  * raised.
11513  *
11514  * For example:
11515  *
11516  * $ ruby argf.rb foo bar
11517  *
11518  * ARGF.filename #=> "foo"
11519  * ARGF.close
11520  * ARGF.filename #=> "bar"
11521  * ARGF.close
11522  * ARGF.close #=> closed stream (IOError)
11523  */
11524 static VALUE
11526 {
11527  next_argv();
11528  argf_close(argf);
11529  if (ARGF.next_p != -1) {
11530  ARGF.next_p = 1;
11531  }
11532  ARGF.lineno = 0;
11533  return argf;
11534 }
11535 
11536 /*
11537  * call-seq:
11538  * ARGF.closed? -> true or false
11539  *
11540  * Returns _true_ if the current file has been closed; _false_ otherwise. Use
11541  * +ARGF.close+ to actually close the current file.
11542  */
11543 static VALUE
11545 {
11546  next_argv();
11547  ARGF_FORWARD(0, 0);
11548  return rb_io_closed(ARGF.current_file);
11549 }
11550 
11551 /*
11552  * call-seq:
11553  * ARGF.to_s -> String
11554  *
11555  * Returns "ARGF".
11556  */
11557 static VALUE
11559 {
11560  return rb_str_new2("ARGF");
11561 }
11562 
11563 /*
11564  * call-seq:
11565  * ARGF.inplace_mode -> String
11566  *
11567  * Returns the file extension appended to the names of modified files under
11568  * inplace-edit mode. This value can be set using +ARGF.inplace_mode=+ or
11569  * passing the +-i+ switch to the Ruby binary.
11570  */
11571 static VALUE
11573 {
11574  if (!ARGF.inplace) return Qnil;
11575  return rb_str_new2(ARGF.inplace);
11576 }
11577 
11578 static VALUE
11580 {
11581  return argf_inplace_mode_get(*var);
11582 }
11583 
11584 /*
11585  * call-seq:
11586  * ARGF.inplace_mode = ext -> ARGF
11587  *
11588  * Sets the filename extension for inplace editing mode to the given String.
11589  * Each file being edited has this value appended to its filename. The
11590  * modified file is saved under this new name.
11591  *
11592  * For example:
11593  *
11594  * $ ruby argf.rb file.txt
11595  *
11596  * ARGF.inplace_mode = '.bak'
11597  * ARGF.lines do |line|
11598  * print line.sub("foo","bar")
11599  * end
11600  *
11601  * Each line of _file.txt_ has the first occurrence of "foo" replaced with
11602  * "bar", then the new line is written out to _file.txt.bak_.
11603  */
11604 static VALUE
11606 {
11607  if (rb_safe_level() >= 1 && OBJ_TAINTED(val))
11609 
11610  if (!RTEST(val)) {
11611  if (ARGF.inplace) free(ARGF.inplace);
11612  ARGF.inplace = 0;
11613  }
11614  else {
11615  StringValue(val);
11616  if (ARGF.inplace) free(ARGF.inplace);
11617  ARGF.inplace = 0;
11618  ARGF.inplace = strdup(RSTRING_PTR(val));
11619  }
11620  return argf;
11621 }
11622 
11623 static void
11625 {
11626  argf_inplace_mode_set(*var, val);
11627 }
11628 
11629 const char *
11631 {
11632  return ARGF.inplace;
11633 }
11634 
11635 void
11636 ruby_set_inplace_mode(const char *suffix)
11637 {
11638  if (ARGF.inplace) free(ARGF.inplace);
11639  ARGF.inplace = 0;
11640  if (suffix) ARGF.inplace = strdup(suffix);
11641 }
11642 
11643 /*
11644  * call-seq:
11645  * ARGF.argv -> ARGV
11646  *
11647  * Returns the +ARGV+ array, which contains the arguments passed to your
11648  * script, one per element.
11649  *
11650  * For example:
11651  *
11652  * $ ruby argf.rb -v glark.txt
11653  *
11654  * ARGF.argv #=> ["-v", "glark.txt"]
11655  *
11656  */
11657 static VALUE
11659 {
11660  return ARGF.argv;
11661 }
11662 
11663 static VALUE
11665 {
11666  return argf_argv(*var);
11667 }
11668 
11669 VALUE
11671 {
11672  return ARGF.argv;
11673 }
11674 
11675 /*
11676  * call-seq:
11677  * ARGF.to_write_io -> io
11678  *
11679  * Returns IO instance tied to _ARGF_ for writing if inplace mode is
11680  * enabled.
11681  */
11682 static VALUE
11684 {
11685  if (!RTEST(ARGF.current_file)) {
11686  rb_raise(rb_eIOError, "not opened for writing");
11687  }
11688  return GetWriteIO(ARGF.current_file);
11689 }
11690 
11691 /*
11692  * call-seq:
11693  * ARGF.write(string) -> integer
11694  *
11695  * Writes _string_ if inplace mode.
11696  */
11697 static VALUE
11699 {
11700  return rb_io_write(argf_write_io(argf), str);
11701 }
11702 
11703 void
11704 rb_readwrite_sys_fail(int writable, const char *mesg)
11705 {
11706  VALUE arg;
11707  int n = errno;
11708  arg = mesg ? rb_str_new2(mesg) : Qnil;
11709  if (writable == RB_IO_WAIT_WRITABLE) {
11710  switch (n) {
11711  case EAGAIN:
11713  break;
11714 #if EAGAIN != EWOULDBLOCK
11715  case EWOULDBLOCK:
11717  break;
11718 #endif
11719  case EINPROGRESS:
11721  break;
11722  default:
11724  }
11725  }
11726  else if (writable == RB_IO_WAIT_READABLE) {
11727  switch (n) {
11728  case EAGAIN:
11730  break;
11731 #if EAGAIN != EWOULDBLOCK
11732  case EWOULDBLOCK:
11734  break;
11735 #endif
11736  case EINPROGRESS:
11738  break;
11739  default:
11741  }
11742  }
11743  else {
11744  rb_bug("invalid read/write type passed to rb_readwrite_sys_fail: %d", writable);
11745  }
11746 }
11747 
11748 /*
11749  * Document-class: IOError
11750  *
11751  * Raised when an IO operation fails.
11752  *
11753  * File.open("/etc/hosts") {|f| f << "example"}
11754  * #=> IOError: not opened for writing
11755  *
11756  * File.open("/etc/hosts") {|f| f.close; f.read }
11757  * #=> IOError: closed stream
11758  *
11759  * Note that some IO failures raise +SystemCallError+s and these are not
11760  * subclasses of IOError:
11761  *
11762  * File.open("does/not/exist")
11763  * #=> Errno::ENOENT: No such file or directory - does/not/exist
11764  */
11765 
11766 /*
11767  * Document-class: EOFError
11768  *
11769  * Raised by some IO operations when reaching the end of file. Many IO
11770  * methods exist in two forms,
11771  *
11772  * one that returns +nil+ when the end of file is reached, the other
11773  * raises EOFError +EOFError+.
11774  *
11775  * +EOFError+ is a subclass of +IOError+.
11776  *
11777  * file = File.open("/etc/hosts")
11778  * file.read
11779  * file.gets #=> nil
11780  * file.readline #=> EOFError: end of file reached
11781  */
11782 
11783 /*
11784  * Document-class: ARGF
11785  *
11786  * +ARGF+ is a stream designed for use in scripts that process files given as
11787  * command-line arguments or passed in via STDIN.
11788  *
11789  * The arguments passed to your script are stored in the +ARGV+ Array, one
11790  * argument per element. +ARGF+ assumes that any arguments that aren't
11791  * filenames have been removed from +ARGV+. For example:
11792  *
11793  * $ ruby argf.rb --verbose file1 file2
11794  *
11795  * ARGV #=> ["--verbose", "file1", "file2"]
11796  * option = ARGV.shift #=> "--verbose"
11797  * ARGV #=> ["file1", "file2"]
11798  *
11799  * You can now use +ARGF+ to work with a concatenation of each of these named
11800  * files. For instance, +ARGF.read+ will return the contents of _file1_
11801  * followed by the contents of _file2_.
11802  *
11803  * After a file in +ARGV+ has been read +ARGF+ removes it from the Array.
11804  * Thus, after all files have been read +ARGV+ will be empty.
11805  *
11806  * You can manipulate +ARGV+ yourself to control what +ARGF+ operates on. If
11807  * you remove a file from +ARGV+, it is ignored by +ARGF+; if you add files to
11808  * +ARGV+, they are treated as if they were named on the command line. For
11809  * example:
11810  *
11811  * ARGV.replace ["file1"]
11812  * ARGF.readlines # Returns the contents of file1 as an Array
11813  * ARGV #=> []
11814  * ARGV.replace ["file2", "file3"]
11815  * ARGF.read # Returns the contents of file2 and file3
11816  *
11817  * If +ARGV+ is empty, +ARGF+ acts as if it contained STDIN, i.e. the data
11818  * piped to your script. For example:
11819  *
11820  * $ echo "glark" | ruby -e 'p ARGF.read'
11821  * "glark\n"
11822  */
11823 
11824 /*
11825  * The IO class is the basis for all input and output in Ruby.
11826  * An I/O stream may be <em>duplexed</em> (that is, bidirectional), and
11827  * so may use more than one native operating system stream.
11828  *
11829  * Many of the examples in this section use the File class, the only standard
11830  * subclass of IO. The two classes are closely associated. Like the File
11831  * class, the Socket library subclasses from IO (such as TCPSocket or
11832  * UDPSocket).
11833  *
11834  * The Kernel#open method can create an IO (or File) object for these types
11835  * of arguments:
11836  *
11837  * * A plain string represents a filename suitable for the underlying
11838  * operating system.
11839  *
11840  * * A string starting with <code>"|"</code> indicates a subprocess.
11841  * The remainder of the string following the <code>"|"</code> is
11842  * invoked as a process with appropriate input/output channels
11843  * connected to it.
11844  *
11845  * * A string equal to <code>"|-"</code> will create another Ruby
11846  * instance as a subprocess.
11847  *
11848  * The IO may be opened with different file modes (read-only, write-only) and
11849  * encodings for proper conversion. See IO.new for these options. See
11850  * Kernel#open for details of the various command formats described above.
11851  *
11852  * IO.popen, the Open3 library, or Process#spawn may also be used to
11853  * communicate with subprocesses through an IO.
11854  *
11855  * Ruby will convert pathnames between different operating system
11856  * conventions if possible. For instance, on a Windows system the
11857  * filename <code>"/gumby/ruby/test.rb"</code> will be opened as
11858  * <code>"\gumby\ruby\test.rb"</code>. When specifying a Windows-style
11859  * filename in a Ruby string, remember to escape the backslashes:
11860  *
11861  * "c:\\gumby\\ruby\\test.rb"
11862  *
11863  * Our examples here will use the Unix-style forward slashes;
11864  * File::ALT_SEPARATOR can be used to get the platform-specific separator
11865  * character.
11866  *
11867  * The global constant ARGF (also accessible as $<) provides an
11868  * IO-like stream which allows access to all files mentioned on the
11869  * command line (or STDIN if no files are mentioned). ARGF#path and its alias
11870  * ARGF#filename are provided to access the name of the file currently being
11871  * read.
11872  *
11873  * == io/console
11874  *
11875  * The io/console extension provides methods for interacting with the
11876  * console. The console can be accessed from IO.console or the standard
11877  * input/output/error IO objects.
11878  *
11879  * Requiring io/console adds the following methods:
11880  *
11881  * * IO::console
11882  * * IO#raw
11883  * * IO#raw!
11884  * * IO#cooked
11885  * * IO#cooked!
11886  * * IO#getch
11887  * * IO#echo=
11888  * * IO#echo?
11889  * * IO#noecho
11890  * * IO#winsize
11891  * * IO#winsize=
11892  * * IO#iflush
11893  * * IO#ioflush
11894  * * IO#oflush
11895  *
11896  * Example:
11897  *
11898  * require 'io/console'
11899  * rows, columns = $stdin.winsize
11900  * puts "Your screen is #{columns} wide and #{rows} tall"
11901  */
11902 
11903 void
11904 Init_IO(void)
11905 {
11906 #undef rb_intern
11907 #define rb_intern(str) rb_intern_const(str)
11908 
11909  VALUE rb_cARGF;
11910 #ifdef __CYGWIN__
11911 #include <sys/cygwin.h>
11912  static struct __cygwin_perfile pf[] =
11913  {
11914  {"", O_RDONLY | O_BINARY},
11915  {"", O_WRONLY | O_BINARY},
11916  {"", O_RDWR | O_BINARY},
11917  {"", O_APPEND | O_BINARY},
11918  {NULL, 0}
11919  };
11920  cygwin_internal(CW_PERFILE, pf);
11921 #endif
11922 
11924  rb_eEOFError = rb_define_class("EOFError", rb_eIOError);
11925 
11926  id_write = rb_intern("write");
11927  id_read = rb_intern("read");
11928  id_getc = rb_intern("getc");
11929  id_flush = rb_intern("flush");
11930  id_readpartial = rb_intern("readpartial");
11931  id_set_encoding = rb_intern("set_encoding");
11932 
11933  rb_define_global_function("syscall", rb_f_syscall, -1);
11934 
11935  rb_define_global_function("open", rb_f_open, -1);
11936  rb_define_global_function("printf", rb_f_printf, -1);
11937  rb_define_global_function("print", rb_f_print, -1);
11939  rb_define_global_function("puts", rb_f_puts, -1);
11940  rb_define_global_function("gets", rb_f_gets, -1);
11941  rb_define_global_function("readline", rb_f_readline, -1);
11942  rb_define_global_function("select", rb_f_select, -1);
11943 
11944  rb_define_global_function("readlines", rb_f_readlines, -1);
11945 
11947 
11949  rb_define_method(rb_mKernel, "display", rb_obj_display, -1);
11950 
11953 
11954  rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
11955  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
11960 #if EAGAIN == EWOULDBLOCK
11962  /* same as IO::EAGAINWaitReadable */
11963  rb_define_const(rb_cIO, "EWOULDBLOCKWaitReadable", rb_eEAGAINWaitReadable);
11965  /* same as IO::EAGAINWaitWritable */
11966  rb_define_const(rb_cIO, "EWOULDBLOCKWaitWritable", rb_eEAGAINWaitWritable);
11967 #else
11972 #endif
11977 
11978 #if 0
11979  /* This is necessary only for forcing rdoc handle File::open */
11981 #endif
11982 
11999 
12000  rb_define_method(rb_cIO, "initialize", rb_io_initialize, -1);
12001 
12002  rb_output_fs = Qnil;
12004 
12007  rb_output_rs = Qnil;
12008  OBJ_FREEZE(rb_default_rs); /* avoid modifying RS_default */
12012 
12014 
12015  rb_define_method(rb_cIO, "initialize_copy", rb_io_init_copy, 1);
12016  rb_define_method(rb_cIO, "reopen", rb_io_reopen, -1);
12017 
12018  rb_define_method(rb_cIO, "print", rb_io_print, -1);
12019  rb_define_method(rb_cIO, "putc", rb_io_putc, 1);
12020  rb_define_method(rb_cIO, "puts", rb_io_puts, -1);
12021  rb_define_method(rb_cIO, "printf", rb_io_printf, -1);
12022 
12023  rb_define_method(rb_cIO, "each", rb_io_each_line, -1);
12024  rb_define_method(rb_cIO, "each_line", rb_io_each_line, -1);
12025  rb_define_method(rb_cIO, "each_byte", rb_io_each_byte, 0);
12026  rb_define_method(rb_cIO, "each_char", rb_io_each_char, 0);
12027  rb_define_method(rb_cIO, "each_codepoint", rb_io_each_codepoint, 0);
12028  rb_define_method(rb_cIO, "lines", rb_io_lines, -1);
12029  rb_define_method(rb_cIO, "bytes", rb_io_bytes, 0);
12030  rb_define_method(rb_cIO, "chars", rb_io_chars, 0);
12031  rb_define_method(rb_cIO, "codepoints", rb_io_codepoints, 0);
12032 
12033  rb_define_method(rb_cIO, "syswrite", rb_io_syswrite, 1);
12034  rb_define_method(rb_cIO, "sysread", rb_io_sysread, -1);
12035 
12036  rb_define_method(rb_cIO, "fileno", rb_io_fileno, 0);
12037  rb_define_alias(rb_cIO, "to_i", "fileno");
12038  rb_define_method(rb_cIO, "to_io", rb_io_to_io, 0);
12039 
12040  rb_define_method(rb_cIO, "fsync", rb_io_fsync, 0);
12041  rb_define_method(rb_cIO, "fdatasync", rb_io_fdatasync, 0);
12042  rb_define_method(rb_cIO, "sync", rb_io_sync, 0);
12043  rb_define_method(rb_cIO, "sync=", rb_io_set_sync, 1);
12044 
12045  rb_define_method(rb_cIO, "lineno", rb_io_lineno, 0);
12046  rb_define_method(rb_cIO, "lineno=", rb_io_set_lineno, 1);
12047 
12048  rb_define_method(rb_cIO, "readlines", rb_io_readlines, -1);
12049 
12050  rb_define_method(rb_cIO, "read_nonblock", io_read_nonblock, -1);
12051  rb_define_method(rb_cIO, "write_nonblock", rb_io_write_nonblock, -1);
12052  rb_define_method(rb_cIO, "readpartial", io_readpartial, -1);
12053  rb_define_method(rb_cIO, "read", io_read, -1);
12054  rb_define_method(rb_cIO, "write", io_write_m, 1);
12055  rb_define_method(rb_cIO, "gets", rb_io_gets_m, -1);
12056  rb_define_method(rb_cIO, "readline", rb_io_readline, -1);
12057  rb_define_method(rb_cIO, "getc", rb_io_getc, 0);
12058  rb_define_method(rb_cIO, "getbyte", rb_io_getbyte, 0);
12059  rb_define_method(rb_cIO, "readchar", rb_io_readchar, 0);
12060  rb_define_method(rb_cIO, "readbyte", rb_io_readbyte, 0);
12061  rb_define_method(rb_cIO, "ungetbyte",rb_io_ungetbyte, 1);
12062  rb_define_method(rb_cIO, "ungetc",rb_io_ungetc, 1);
12064  rb_define_method(rb_cIO, "flush", rb_io_flush, 0);
12065  rb_define_method(rb_cIO, "tell", rb_io_tell, 0);
12066  rb_define_method(rb_cIO, "seek", rb_io_seek_m, -1);
12067  /* Set I/O position from the beginning */
12068  rb_define_const(rb_cIO, "SEEK_SET", INT2FIX(SEEK_SET));
12069  /* Set I/O position from the current position */
12070  rb_define_const(rb_cIO, "SEEK_CUR", INT2FIX(SEEK_CUR));
12071  /* Set I/O position from the end */
12072  rb_define_const(rb_cIO, "SEEK_END", INT2FIX(SEEK_END));
12073 #ifdef SEEK_DATA
12074  /* Set I/O position to the next location containing data */
12075  rb_define_const(rb_cIO, "SEEK_DATA", INT2FIX(SEEK_DATA));
12076 #endif
12077 #ifdef SEEK_HOLE
12078  /* Set I/O position to the next hole */
12079  rb_define_const(rb_cIO, "SEEK_HOLE", INT2FIX(SEEK_HOLE));
12080 #endif
12081  rb_define_method(rb_cIO, "rewind", rb_io_rewind, 0);
12082  rb_define_method(rb_cIO, "pos", rb_io_tell, 0);
12083  rb_define_method(rb_cIO, "pos=", rb_io_set_pos, 1);
12084  rb_define_method(rb_cIO, "eof", rb_io_eof, 0);
12085  rb_define_method(rb_cIO, "eof?", rb_io_eof, 0);
12086 
12087  rb_define_method(rb_cIO, "close_on_exec?", rb_io_close_on_exec_p, 0);
12088  rb_define_method(rb_cIO, "close_on_exec=", rb_io_set_close_on_exec, 1);
12089 
12090  rb_define_method(rb_cIO, "close", rb_io_close_m, 0);
12091  rb_define_method(rb_cIO, "closed?", rb_io_closed, 0);
12092  rb_define_method(rb_cIO, "close_read", rb_io_close_read, 0);
12093  rb_define_method(rb_cIO, "close_write", rb_io_close_write, 0);
12094 
12095  rb_define_method(rb_cIO, "isatty", rb_io_isatty, 0);
12096  rb_define_method(rb_cIO, "tty?", rb_io_isatty, 0);
12097  rb_define_method(rb_cIO, "binmode", rb_io_binmode_m, 0);
12098  rb_define_method(rb_cIO, "binmode?", rb_io_binmode_p, 0);
12099  rb_define_method(rb_cIO, "sysseek", rb_io_sysseek, -1);
12100  rb_define_method(rb_cIO, "advise", rb_io_advise, -1);
12101 
12102  rb_define_method(rb_cIO, "ioctl", rb_io_ioctl, -1);
12103  rb_define_method(rb_cIO, "fcntl", rb_io_fcntl, -1);
12104  rb_define_method(rb_cIO, "pid", rb_io_pid, 0);
12105  rb_define_method(rb_cIO, "inspect", rb_io_inspect, 0);
12106 
12107  rb_define_method(rb_cIO, "external_encoding", rb_io_external_encoding, 0);
12108  rb_define_method(rb_cIO, "internal_encoding", rb_io_internal_encoding, 0);
12109  rb_define_method(rb_cIO, "set_encoding", rb_io_set_encoding, -1);
12110 
12111  rb_define_method(rb_cIO, "autoclose?", rb_io_autoclose_p, 0);
12112  rb_define_method(rb_cIO, "autoclose=", rb_io_set_autoclose, 1);
12113 
12114  rb_define_variable("$stdin", &rb_stdin);
12115  rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO, "<STDIN>");
12117  rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO, "<STDOUT>");
12119  rb_stderr = prep_stdio(stderr, FMODE_WRITABLE|FMODE_SYNC, rb_cIO, "<STDERR>");
12123 
12124  /* Holds the original stdin */
12125  rb_define_global_const("STDIN", rb_stdin);
12126  /* Holds the original stdout */
12127  rb_define_global_const("STDOUT", rb_stdout);
12128  /* Holds the original stderr */
12129  rb_define_global_const("STDERR", rb_stderr);
12130 
12131 #if 0
12132  /* Hack to get rdoc to regard ARGF as a class: */
12133  rb_cARGF = rb_define_class("ARGF", rb_cObject);
12134 #endif
12135 
12136  rb_cARGF = rb_class_new(rb_cObject);
12137  rb_set_class_path(rb_cARGF, rb_cObject, "ARGF.class");
12138  rb_define_alloc_func(rb_cARGF, argf_alloc);
12139 
12140  rb_include_module(rb_cARGF, rb_mEnumerable);
12141 
12142  rb_define_method(rb_cARGF, "initialize", argf_initialize, -2);
12143  rb_define_method(rb_cARGF, "initialize_copy", argf_initialize_copy, 1);
12144  rb_define_method(rb_cARGF, "to_s", argf_to_s, 0);
12145  rb_define_alias(rb_cARGF, "inspect", "to_s");
12146  rb_define_method(rb_cARGF, "argv", argf_argv, 0);
12147 
12148  rb_define_method(rb_cARGF, "fileno", argf_fileno, 0);
12149  rb_define_method(rb_cARGF, "to_i", argf_fileno, 0);
12150  rb_define_method(rb_cARGF, "to_io", argf_to_io, 0);
12151  rb_define_method(rb_cARGF, "to_write_io", argf_write_io, 0);
12152  rb_define_method(rb_cARGF, "each", argf_each_line, -1);
12153  rb_define_method(rb_cARGF, "each_line", argf_each_line, -1);
12154  rb_define_method(rb_cARGF, "each_byte", argf_each_byte, 0);
12155  rb_define_method(rb_cARGF, "each_char", argf_each_char, 0);
12156  rb_define_method(rb_cARGF, "each_codepoint", argf_each_codepoint, 0);
12157  rb_define_method(rb_cARGF, "lines", argf_lines, -1);
12158  rb_define_method(rb_cARGF, "bytes", argf_bytes, 0);
12159  rb_define_method(rb_cARGF, "chars", argf_chars, 0);
12160  rb_define_method(rb_cARGF, "codepoints", argf_codepoints, 0);
12161 
12162  rb_define_method(rb_cARGF, "read", argf_read, -1);
12163  rb_define_method(rb_cARGF, "readpartial", argf_readpartial, -1);
12164  rb_define_method(rb_cARGF, "read_nonblock", argf_read_nonblock, -1);
12165  rb_define_method(rb_cARGF, "readlines", argf_readlines, -1);
12166  rb_define_method(rb_cARGF, "to_a", argf_readlines, -1);
12167  rb_define_method(rb_cARGF, "gets", argf_gets, -1);
12168  rb_define_method(rb_cARGF, "readline", argf_readline, -1);
12169  rb_define_method(rb_cARGF, "getc", argf_getc, 0);
12170  rb_define_method(rb_cARGF, "getbyte", argf_getbyte, 0);
12171  rb_define_method(rb_cARGF, "readchar", argf_readchar, 0);
12172  rb_define_method(rb_cARGF, "readbyte", argf_readbyte, 0);
12173  rb_define_method(rb_cARGF, "tell", argf_tell, 0);
12174  rb_define_method(rb_cARGF, "seek", argf_seek_m, -1);
12175  rb_define_method(rb_cARGF, "rewind", argf_rewind, 0);
12176  rb_define_method(rb_cARGF, "pos", argf_tell, 0);
12177  rb_define_method(rb_cARGF, "pos=", argf_set_pos, 1);
12178  rb_define_method(rb_cARGF, "eof", argf_eof, 0);
12179  rb_define_method(rb_cARGF, "eof?", argf_eof, 0);
12180  rb_define_method(rb_cARGF, "binmode", argf_binmode_m, 0);
12181  rb_define_method(rb_cARGF, "binmode?", argf_binmode_p, 0);
12182 
12183  rb_define_method(rb_cARGF, "write", argf_write, 1);
12184  rb_define_method(rb_cARGF, "print", rb_io_print, -1);
12185  rb_define_method(rb_cARGF, "putc", rb_io_putc, 1);
12186  rb_define_method(rb_cARGF, "puts", rb_io_puts, -1);
12187  rb_define_method(rb_cARGF, "printf", rb_io_printf, -1);
12188 
12189  rb_define_method(rb_cARGF, "filename", argf_filename, 0);
12190  rb_define_method(rb_cARGF, "path", argf_filename, 0);
12191  rb_define_method(rb_cARGF, "file", argf_file, 0);
12192  rb_define_method(rb_cARGF, "skip", argf_skip, 0);
12193  rb_define_method(rb_cARGF, "close", argf_close_m, 0);
12194  rb_define_method(rb_cARGF, "closed?", argf_closed, 0);
12195 
12196  rb_define_method(rb_cARGF, "lineno", argf_lineno, 0);
12197  rb_define_method(rb_cARGF, "lineno=", argf_set_lineno, 1);
12198 
12199  rb_define_method(rb_cARGF, "inplace_mode", argf_inplace_mode_get, 0);
12200  rb_define_method(rb_cARGF, "inplace_mode=", argf_inplace_mode_set, 1);
12201 
12202  rb_define_method(rb_cARGF, "external_encoding", argf_external_encoding, 0);
12203  rb_define_method(rb_cARGF, "internal_encoding", argf_internal_encoding, 0);
12204  rb_define_method(rb_cARGF, "set_encoding", argf_set_encoding, -1);
12205 
12206  argf = rb_class_new_instance(0, 0, rb_cARGF);
12207 
12209  /*
12210  * ARGF is a stream designed for use in scripts that process files given
12211  * as command-line arguments or passed in via STDIN.
12212  *
12213  * See ARGF (the class) for more details.
12214  */
12215  rb_define_global_const("ARGF", argf);
12216 
12219  ARGF.filename = rb_str_new2("-");
12220 
12223 
12224 #if defined (_WIN32) || defined(__CYGWIN__)
12225  atexit(pipe_atexit);
12226 #endif
12227 
12228  Init_File();
12229 
12230  rb_define_method(rb_cFile, "initialize", rb_file_initialize, -1);
12231 
12232  sym_mode = ID2SYM(rb_intern("mode"));
12233  sym_perm = ID2SYM(rb_intern("perm"));
12234  sym_extenc = ID2SYM(rb_intern("external_encoding"));
12235  sym_intenc = ID2SYM(rb_intern("internal_encoding"));
12236  sym_encoding = ID2SYM(rb_intern("encoding"));
12237  sym_open_args = ID2SYM(rb_intern("open_args"));
12238  sym_textmode = ID2SYM(rb_intern("textmode"));
12239  sym_binmode = ID2SYM(rb_intern("binmode"));
12240  sym_autoclose = ID2SYM(rb_intern("autoclose"));
12241  sym_normal = ID2SYM(rb_intern("normal"));
12242  sym_sequential = ID2SYM(rb_intern("sequential"));
12243  sym_random = ID2SYM(rb_intern("random"));
12244  sym_willneed = ID2SYM(rb_intern("willneed"));
12245  sym_dontneed = ID2SYM(rb_intern("dontneed"));
12246  sym_noreuse = ID2SYM(rb_intern("noreuse"));
12247  sym_SET = ID2SYM(rb_intern("SET"));
12248  sym_CUR = ID2SYM(rb_intern("CUR"));
12249  sym_END = ID2SYM(rb_intern("END"));
12250 #ifdef SEEK_DATA
12251  sym_DATA = ID2SYM(rb_intern("DATA"));
12252 #endif
12253 #ifdef SEEK_HOLE
12254  sym_HOLE = ID2SYM(rb_intern("HOLE"));
12255 #endif
12256  sym_exception = ID2SYM(rb_intern("exception"));
12257 }
static VALUE argf_bytes(VALUE argf)
Definition: io.c:11296
VALUE data
Definition: tcltklib.c:3360
#define ARGVSTR2ARGV(argv_str)
#define RB_TYPE_P(obj, type)
RARRAY_PTR(q->result)[0]
static void make_readconv(rb_io_t *fptr, int size)
Definition: io.c:2143
#define ALLOC(type)
VALUE rb_eStandardError
Definition: error.c:546
static VALUE rb_io_rewind(VALUE io)
Definition: io.c:1655
static VALUE rb_io_close_read(VALUE io)
Definition: io.c:4457
static void argf_close(VALUE argf)
Definition: io.c:7748
VALUE rb_str_locktmp_ensure(VALUE str, VALUE(*func)(VALUE), VALUE arg)
Definition: string.c:2000
static VALUE rb_obj_display(int argc, VALUE *argv, VALUE self)
Definition: io.c:7155
static int nogvl_copy_stream_wait_write(struct copy_stream_struct *stp)
Definition: io.c:9916
static long fcntl_narg_len(int cmd)
Definition: io.c:8917
static VALUE rb_io_set_lineno(VALUE io, VALUE lineno)
Definition: io.c:3276
static ID id_set_encoding
Definition: io.c:160
#define FilePathValue(v)
VALUE sym
Definition: tkutil.c:1299
off_t total
Definition: io.c:9847
static VALUE argf_getpartial(int argc, VALUE *argv, VALUE argf, int nonblock)
Definition: io.c:10984
VALUE argf
Definition: io.c:10930
VP_EXPORT int
Definition: bigdecimal.c:5172
static VALUE rb_io_set_sync(VALUE io, VALUE sync)
Definition: io.c:1856
rb_funcall2(argv[0], id_yield, argc-1, argv+1)
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1179
VALUE rb_any_to_s(VALUE)
Definition: object.c:452
Definition: io.c:8714
void rb_set_class_path(VALUE, VALUE, const char *)
Definition: variable.c:316
void rb_bug(const char *fmt,...)
Definition: error.c:327
#define FALSE
Definition: nkf.h:174
int ioctl(int, int,...)
Definition: win32.c:2544
static VALUE rb_io_internal_encoding(VALUE)
Definition: io.c:10541
static VALUE rb_io_s_readlines(int argc, VALUE *argv, VALUE io)
Definition: io.c:9598
#define FMODE_READWRITE
Definition: io.h:103
#define rb_hash_lookup
Definition: tcltklib.c:269
static VALUE sym_random
Definition: io.c:8368
static VALUE VALUE th
Definition: tcltklib.c:2944
static VALUE rb_io_closed(VALUE io)
Definition: io.c:4419
#define MBCLEN_NEEDMORE_LEN(ret)
#define SSIZE_MAX
Definition: ruby.h:290
#define rb_funcall3
void rb_io_check_readable(rb_io_t *)
Definition: io.c:794
size_t strlen(const char *)
gz enc2
Definition: zlib.c:2274
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)
static VALUE io_enc_str(VALUE str, rb_io_t *fptr)
Definition: io.c:2135
#define OBJ_INFECT(x, s)
void rb_io_set_nonblock(rb_io_t *fptr)
Definition: io.c:2378
void rb_thread_wait_fd(int)
Definition: thread.c:3523
VALUE rb_class_new_instance(int, VALUE *, VALUE)
Definition: object.c:1857
#define FIX2UINT(x)
static VALUE sym_autoclose
Definition: io.c:162
void rb_io_synchronized(rb_io_t *)
Definition: io.c:5666
static long setup_narg(ioctl_req_t cmd, VALUE *argp, int io_p)
Definition: io.c:8924
static VALUE sym_encoding
Definition: io.c:161
const char * rb_obj_classname(VALUE)
Definition: variable.c:406
VALUE rb_str_buf_cat_ascii(VALUE, const char *)
Definition: string.c:2257
static VALUE argf_set_pos(VALUE argf, VALUE offset)
Definition: io.c:10739
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:3724
static VALUE sym_SET
Definition: io.c:163
static VALUE sym_noreuse
Definition: io.c:8368
static VALUE argf_set_lineno(VALUE argf, VALUE val)
Definition: io.c:7703
#define RSTRING_END(str)
static VALUE argf_inplace_mode_get(VALUE argf)
Definition: io.c:11572
size_t rb_io_memsize(const rb_io_t *)
Definition: io.c:4303
static VALUE rb_f_putc(VALUE recv, VALUE ch)
Definition: io.c:6946
static VALUE argf_readpartial(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10964
struct rb_execarg::@109::@110 sh
int count
Definition: encoding.c:48
#define ECONV_AFTER_OUTPUT
static VALUE io_call_close(VALUE io)
Definition: io.c:4370
static int max(int a, int b)
Definition: strftime.c:141
static ID id_read
Definition: io.c:160
static int io_fflush(rb_io_t *)
Definition: io.c:1062
#define ENCODING_MAXNAMELEN
volatile VALUE pair
Definition: tkutil.c:554
rb_uid_t getuid(void)
Definition: win32.c:2498
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1646
VALUE rb_eEWOULDBLOCK
Definition: error.c:41
VALUE rb_gets(void)
Definition: io.c:8042
int rb_io_modestr_oflags(const char *modestr)
Definition: io.c:4954
static const char * rb_io_fmode_modestr(int fmode)
Definition: io.c:4799
static void argf_init(struct argf *p, VALUE v)
Definition: io.c:7639
static VALUE rb_io_ioctl(int argc, VALUE *argv, VALUE io)
Definition: io.c:9003
static VALUE argf_inplace_mode_set(VALUE argf, VALUE val)
Definition: io.c:11605
int rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char *errmsg, size_t errmsg_buflen)
Definition: process.c:2966
int ioctl_req_t
Definition: io.c:8710
VALUE fname
Definition: io.c:5354
C_block * out
Definition: crypt.c:308
static VALUE pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convconfig)
Definition: io.c:5831
RUBY_EXTERN VALUE rb_stdout
Definition: ripper.y:1635
VALUE rb_io_puts(int, VALUE *, VALUE)
Definition: io.c:7011
size_t rb_econv_memsize(rb_econv_t *)
Definition: transcode.c:1718
static void must_respond_to(ID mid, VALUE val, ID id)
Definition: io.c:7208
VALUE str
Definition: io.c:1195
static VALUE io_s_write(int argc, VALUE *argv, int binary)
Definition: io.c:9729
static VALUE select_call(VALUE arg)
Definition: io.c:8350
VALUE rb_io_ungetc(VALUE, VALUE)
Definition: io.c:3891
VALUE rb_io_eof(VALUE)
Definition: io.c:1745
#define PIDT2NUM(v)
Definition: ruby.h:321
rb_funcall(memo->yielder, id_lshift, 1, rb_assoc_new(memo->prev_value, memo->prev_elts))
static VALUE argf_readbyte(VALUE argf)
Definition: io.c:11170
#define ARGF_FORWARD(argc, argv)
Definition: io.c:7738
static VALUE argf_gets(int, VALUE *, VALUE)
Definition: io.c:8031
RUBY_EXTERN VALUE rb_mWaitReadable
Definition: ripper.y:1557
#define rb_usascii_str_new2
size_t siz
Definition: strlcat.c:49
struct rb_io_t rb_io_t
void rb_secure(int)
Definition: safe.c:88
#define rb_enc_codepoint(p, e, enc)
rb_fdset_t fdsets[4]
Definition: io.c:8346
rb_io_buffer_t cbuf
Definition: io.h:88
void rb_syswait(rb_pid_t pid)
Definition: process.c:3763
static void argf_mark(void *ptr)
Definition: io.c:7605
VALUE ecopts
Definition: io.h:84
static VALUE io_puts_ary(VALUE ary, VALUE out, int recur)
Definition: io.c:6971
void rb_define_global_const(const char *, VALUE)
Definition: variable.c:2239
static VALUE rb_io_binmode_p(VALUE io)
Definition: io.c:4791
void rb_p(VALUE)
Definition: io.c:7060
int rb_pipe(int *pipes)
Definition: io.c:5679
Definition: io.h:61
VALUE rb_str_locktmp(VALUE)
#define rb_check_frozen(obj)
RUBY_EXTERN void * memmove(void *, const void *, size_t)
Definition: memmove.c:7
void rb_io_check_initialized(rb_io_t *)
Definition: io.c:609
#define READ_DATA_PENDING_COUNT(fptr)
Definition: io.c:387
VALUE rb_ary_shift(VALUE ary)
Definition: array.c:995
#define rb_enc_name(enc)
char * str_ptr
Definition: io.c:2064
static VALUE rb_eEAGAINWaitWritable
Definition: io.c:143
#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:1370
static VALUE orig_stderr
Definition: io.c:151
static VALUE io_s_foreach(struct foreach_arg *arg)
Definition: io.c:9523
#define FMODE_WRITABLE
Definition: io.h:102
VALUE rb_hash_lookup2(VALUE, VALUE, VALUE)
Definition: hash.c:717
rb_encoding * rb_to_encoding(VALUE enc)
Definition: encoding.c:219
VALUE rb_str_new_cstr(const char *)
Definition: string.c:560
static int is_popen_fork(VALUE prog)
Definition: io.c:6055
#define FMODE_READABLE
Definition: io.h:101
int ret
Definition: tcltklib.c:285
static VALUE io_flush_buffer_async(VALUE arg)
Definition: io.c:1022
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size)
Definition: io.c:1365
static VALUE io_binwrite_string(VALUE arg)
Definition: io.c:1207
long tv_sec
Definition: ossl_asn1.c:17
int argc
Definition: io.c:10928
static void io_encoding_set(rb_io_t *, VALUE, VALUE, VALUE)
Definition: io.c:9283
static VALUE rb_io_syswrite(VALUE io, VALUE str)
Definition: io.c:4603
#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:9275
ID rb_frame_this_func(void)
Definition: eval.c:943
int status
Definition: tcltklib.c:2197
static VALUE argf_external_encoding(VALUE argf)
Definition: io.c:10613
SOCKET rb_w32_get_osfhandle(int)
Definition: win32.c:988
VALUE rb_obj_freeze(VALUE)
Definition: object.c:1070
VALUE rb_io_printf(int, VALUE *, VALUE)
Definition: io.c:6787
rb_yield(i)
VALUE rb_eTypeError
Definition: error.c:548
static ID id_write
Definition: io.c:160
static VALUE sym_mode
Definition: io.c:161
void rb_define_hooked_variable(const char *, VALUE *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
Definition: variable.c:585
#define OBJ_FREEZE(x)
static VALUE argf_each_line(int argc, VALUE *argv, VALUE argf)
Definition: io.c:11235
VALUE rb_obj_dup(VALUE)
Definition: object.c:406
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash)
Definition: process.c:1960
#define ECONV_NEWLINE_DECORATOR_MASK
RB_GC_GUARD(args)
#define OBJ_TAINTED(x)
#define UNREACHABLE
Definition: ruby.h:42
unsigned long ruby_strtoul(const char *str, char **endptr, int base)
Definition: util.c:111
static VALUE rb_io_close_write(VALUE io)
Definition: io.c:4517
void rb_update_max_fd(int fd)
Definition: io.c:183
VALUE * argv
Definition: io.c:10929
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1451
VALUE exc
Definition: tcltklib.c:3088
static VALUE argf_filename(VALUE argf)
Definition: io.c:11405
VALUE enc
Definition: tcltklib.c:10318
#define RUBY_UBF_IO
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:900
static void fptr_finalize(rb_io_t *fptr, int noraise)
Definition: io.c:4176
void rb_io_check_byte_readable(rb_io_t *fptr)
Definition: io.c:785
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:981
#define rb_io_fcntl
Definition: io.c:9105
static VALUE opt_i_get(ID id, VALUE *var)
Definition: io.c:11579
int fcntl(int, int,...)
Definition: win32.c:4089
gz path
Definition: zlib.c:2279
#define TYPE(x)
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
Definition: numeric.c:2523
int rb_econv_prepare_options(VALUE opthash, VALUE *ecopts, int ecflags)
Definition: transcode.c:2526
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:538
static VALUE argf_argv(VALUE argf)
Definition: io.c:11658
static int io_encname_bom_p(const char *name, long len)
Definition: io.c:4823
static VALUE rb_io_seek(VALUE io, VALUE offset, int whence)
Definition: io.c:1542
rb_str_append(str, i)
#define RSTRING_PTR(str)
#define CLASS_OF(v)
static VALUE rb_io_getline_fast(rb_io_t *fptr, rb_encoding *enc, VALUE io)
Definition: io.c:2977
NIL_P(eventloop_thread)
Definition: tcltklib.c:4056
void rb_lastline_set(VALUE)
Definition: vm.c:965
#define RFILE(obj)
#define T_ARRAY
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:548
char * ptr
Definition: io.h:55
int8_t binmode
Definition: io.c:178
int writeconv_pre_ecflags
Definition: io.h:92
VALUE var
Definition: tcltklib.c:5495
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:807
rb_io_t * fptr
Definition: io.c:2066
#define xfree
#define MBCLEN_NEEDMORE_P(ret)
static VALUE rb_io_readchar(VALUE io)
Definition: io.c:3772
int rb_io_modestr_fmode(const char *modestr)
Definition: io.c:4835
static VALUE argf_write(VALUE argf, VALUE str)
Definition: io.c:11698
static int rb_sysopen_internal(struct sysopen_struct *data)
Definition: io.c:5368
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:657
#define MEMMOVE(p1, p2, type, n)
register C_block * tp
Definition: crypt.c:311
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
int rb_io_fptr_finalize(rb_io_t *)
Definition: io.c:4280
static VALUE rb_io_sysseek(int argc, VALUE *argv, VALUE io)
Definition: io.c:4563
#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
return Qtrue
Definition: tcltklib.c:9618
#define rb_str_new4
#define FMODE_CREATE
Definition: io.h:109
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:826
VALUE rb_execarg_new(int argc, VALUE *argv, int accept_shell)
Definition: process.c:2262
VALUE rb_obj_class(VALUE)
Definition: object.c:226
#define RETURN_ENUMERATOR(obj, argc, argv)
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3392
static void pipe_add_fptr(rb_io_t *fptr)
Definition: io.c:5601
VALUE rb_io_taint_check(VALUE)
Definition: io.c:602
VALUE rb_str_encode_ospath(VALUE)
Definition: file.c:232
VALUE rb_class_name(VALUE)
Definition: variable.c:391
static VALUE argf_binmode_p(VALUE argf)
Definition: io.c:11477
#define NEED_WRITECONV(fptr)
Definition: io.c:567
#define rb_enc_left_char_head(s, p, e, enc)
#define T_FILE
long lineno
Definition: io.c:174
static VALUE rb_file_initialize(int argc, VALUE *argv, VALUE io)
Definition: io.c:7511
static VALUE argf_write_io(VALUE argf)
Definition: io.c:11683
#define FMODE_DUPLEX
Definition: io.h:107
#define SafeStringValue(v)
static int ruby_dup(int orig)
Definition: io.c:856
RUBY_EXTERN VALUE rb_eIOError
Definition: ripper.y:1611
RUBY_EXTERN VALUE rb_output_rs
Definition: ripper.y:520
rb_thread_check_ints()
Definition: thread.c:1143
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
#define rb_ary_new4
#define FMODE_APPEND
Definition: io.h:108
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:808
#define MORE_CHAR_FINISHED
Definition: io.c:2170
void rb_last_status_clear(void)
Definition: process.c:336
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:6333
r
Definition: bigdecimal.c:1212
static VALUE argf_lineno(VALUE argf)
Definition: io.c:7724
off_t copy_length
Definition: io.c:9840
tmp
Definition: enum.c:447
#define rb_str_new2
Definition: io.c:171
static void prepare_getline_args(int argc, VALUE *argv, VALUE *rsp, long *limit, VALUE io)
Definition: io.c:3028
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1675
int rb_cloexec_dup(int oldfd)
Definition: io.c:244
static VALUE ignore_closed_stream(VALUE io, VALUE exc)
Definition: io.c:4377
static VALUE rb_file_open_generic(VALUE io, VALUE filename, int oflags, int fmode, convconfig_t *convconfig, mode_t perm)
Definition: io.c:5529
VALUE rb_lastline_get(void)
Definition: vm.c:959
static VALUE internal_write_func(void *ptr)
Definition: io.c:931
static VALUE rb_eEINPROGRESSWaitWritable
Definition: io.c:146
int size
Definition: encoding.c:49
VALUE rb_str_unlocktmp(VALUE)
Definition: string.c:1990
static VALUE rb_io_each_byte(VALUE io)
Definition: io.c:3417
VALUE writeconv_pre_ecopts
Definition: io.h:93
VALUE rb_str_substr(VALUE, long, long)
Definition: string.c:1944
static void open_key_args(int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg)
Definition: io.c:9486
static VALUE argf_readchar(VALUE argf)
Definition: io.c:11130
#define EINPROGRESS
Definition: win32.h:512
const char * syserr
Definition: io.c:9848
static VALUE rb_io_external_encoding(VALUE io)
Definition: io.c:10516
#define ID2SYM(x)
static VALUE rb_f_readlines(int argc, VALUE *argv, VALUE recv)
Definition: io.c:8133
if(args--[1]==0)
Definition: array.c:3187
static void io_set_read_length(VALUE str, long n)
Definition: io.c:2304
static int argf_next_argv(VALUE argf)
Definition: io.c:7760
rb_encoding * enc2
Definition: io.h:82
static const rb_data_type_t argf_type
Definition: io.c:7632
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:6474
static VALUE argf_each_codepoint(VALUE argf)
Definition: io.c:11360
memo state
Definition: enum.c:2432
#define ENC_CODERANGE_BROKEN
void rb_io_read_check(rb_io_t *)
Definition: io.c:847
#define rb_ary_new2
#define GetOpenFile(obj, fp)
Definition: io.h:118
static ssize_t rb_write_internal2(int fd, const void *buf, size_t count)
Definition: io.c:967
VALUE envp_str
Definition: ripper.y:654
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:833
int argc
Definition: io.c:7075
static VALUE nogvl_ioctl(void *ptr)
Definition: io.c:8721
static void validate_enc_binmode(int *fmode_p, int ecflags, rb_encoding *enc, rb_encoding *enc2)
Definition: io.c:5174
static VALUE rb_f_p_internal(VALUE arg)
Definition: io.c:7080
int capa
Definition: io.h:58
VALUE rb_f_sprintf(int, const VALUE *)
Definition: sprintf.c:415
#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
flag
Definition: tcltklib.c:2046
VALUE argv
Definition: io.c:175
void rb_str_modify_expand(VALUE, long)
Definition: string.c:1491
#define rb_fd_term(f)
static VALUE argf
Definition: io.c:158
static void io_check_tty(rb_io_t *fptr)
Definition: io.c:5440
static VALUE io_write_nonblock(VALUE io, VALUE str, int no_exception)
Definition: io.c:2618
#define rb_fd_max(f)
void rb_fd_fix_cloexec(int fd)
Definition: io.c:221
RUBY_EXTERN VALUE rb_mWaitWritable
Definition: ripper.y:1558
gz lineno
Definition: zlib.c:2270
i
Definition: enum.c:446
static VALUE argf_seek_m(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10718
VALUE ary
Definition: enum.c:674
static void opt_i_set(VALUE val, ID id, VALUE *var)
Definition: io.c:11624
#define GetWriteIO(io)
Definition: io.c:384
#define ENCODING_GET(obj)
long last_lineno
Definition: io.c:173
static VALUE read_all(rb_io_t *fptr, long siz, VALUE str)
Definition: io.c:2313
static void * exec_interrupts(void *arg)
Definition: io.c:9856
VALUE rb_eEAGAIN
Definition: error.c:40
int mode
Definition: io.h:64
static VALUE rb_io_set_autoclose(VALUE io, VALUE autoclose)
Definition: io.c:7593
static ssize_t maygvl_read(int has_gvl, int fd, void *buf, size_t count)
Definition: io.c:10092
static rb_encoding * io_read_encoding(rb_io_t *fptr)
Definition: io.c:800
static VALUE rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
Definition: io.c:6169
static VALUE rb_io_lines(int argc, VALUE *argv, VALUE io)
Definition: io.c:3391
#define MEMZERO(p, type, n)
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 ECONV_ERROR_HANDLER_MASK
#define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags)
Definition: io.c:570
#define rb_io_set_close_on_exec
Definition: io.c:4055
VALUE rb_usascii_str_new(const char *, long)
Definition: string.c:540
static VALUE rb_io_sysread(int argc, VALUE *argv, VALUE io)
Definition: io.c:4648
long narg
Definition: io.c:8717
static void io_ungetbyte(VALUE str, rb_io_t *fptr)
Definition: io.c:714
#define rb_exc_new3
static void argf_block_call(ID mid, int argc, VALUE *argv, VALUE argf)
Definition: io.c:11196
ioctl_req_t cmd
Definition: io.c:8716
static VALUE rb_file_open_internal(VALUE io, VALUE filename, const char *modestr)
Definition: io.c:5555
void rb_define_readonly_variable(const char *, VALUE *)
Definition: variable.c:610
static int str_end_with_asciichar(VALUE str, int c)
Definition: io.c:6956
gz ecflags
Definition: zlib.c:2276
static VALUE argf_binmode_m(VALUE argf)
Definition: io.c:11454
#define fmode
VALUE current_file
Definition: io.c:172
#define O_CLOEXEC
static VALUE sym_CUR
Definition: io.c:163
rb_encoding * enc
Definition: io.h:81
int rb_to_encoding_index(VALUE enc)
Definition: encoding.c:171
rb_encoding * rb_default_external_encoding(void)
Definition: encoding.c:1366
void rb_gc(void)
Definition: gc.c:5193
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
#define rb_fd_select(n, rfds, wfds, efds, timeout)
BDIGIT m
Definition: bigdecimal.c:5209
static VALUE copy_stream_fallback_body(VALUE arg)
Definition: io.c:10249
off_t src_offset
Definition: io.c:9841
static VALUE orig_stdout
Definition: io.c:151
#define FIXNUM_P(f)
return Qfalse
Definition: tcltklib.c:6790
VALUE rb_io_get_write_io(VALUE io)
Definition: io.c:639
long len
Definition: io.c:2065
static VALUE argf_lines(int argc, VALUE *argv, VALUE argf)
Definition: io.c:11249
static void * nogvl_close(void *ptr)
Definition: io.c:4138
const void * buf
Definition: io.c:919
int rb_block_given_p(void)
Definition: eval.c:712
void rb_io_unbuffered(rb_io_t *fptr)
Definition: io.c:5673
#define RARRAY_LEN(a)
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:1444
static VALUE argf_internal_encoding(VALUE argf)
Definition: io.c:10635
#define F_SETFL
Definition: win32.h:622
#define Qnil
Definition: enum.c:67
#define StringValuePtr(v)
int nosync
Definition: io.c:1203
#define val
Definition: tcltklib.c:1935
static VALUE io_readpartial(int argc, VALUE *argv, VALUE io)
Definition: io.c:2531
static VALUE argf_getbyte(VALUE argf)
Definition: io.c:11090
VALUE rb_funcallv(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:812
static void stdout_setter(VALUE val, ID id, VALUE *variable)
Definition: io.c:7218
long tv_usec
Definition: ossl_asn1.c:18
static VALUE rb_f_backquote(VALUE obj, VALUE str)
Definition: io.c:8196
VALUE rb_eRuntimeError
Definition: error.c:547
#define PREP_STDIO_NAME(f)
Definition: io.c:4060
static struct pipe_list * pipe_list
static VALUE argf_readlines(int, VALUE *, VALUE)
Definition: io.c:8158
static VALUE argf_getline(int argc, VALUE *argv, VALUE argf)
Definition: io.c:7926
#define FMODE_SETENC_BY_BOM
Definition: io.h:116
static VALUE rb_eEWOULDBLOCKWaitWritable
Definition: io.c:145
VALUE rb_deferr
Definition: io.c:150
RUBY_EXTERN VALUE rb_mKernel
Definition: ripper.y:1549
VALUE rb_file_open(const char *, const char *)
Definition: io.c:5589
static VALUE rb_io_s_binread(int argc, VALUE *argv, VALUE io)
Definition: io.c:9705
void ruby_set_inplace_mode(const char *)
Definition: io.c:11636
static VALUE char * str
Definition: tcltklib.c:3539
char * ruby_strdup(const char *)
Definition: util.c:461
static VALUE io_flush_buffer_sync(void *arg)
Definition: io.c:990
fd_set rb_fdset_t
Definition: ripper.y:348
static int io_strip_bom(VALUE io)
Definition: io.c:5450
VALUE rb_io_check_io(VALUE io)
Definition: io.c:633
#define RARRAY_CONST_PTR(a)
static VALUE io_s_readlines(struct foreach_arg *arg)
Definition: io.c:9574
#define RARRAY_AREF(a, i)
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:10101
VALUE rb_ary_new(void)
Definition: array.c:499
struct rb_execarg * rb_execarg_get(VALUE execarg_obj)
Definition: process.c:2273
#define StringValueCStr(v)
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
Definition: thread.c:1384
#define dp(v)
Definition: vm_debug.h:21
int flags
Definition: tcltklib.c:3015
void rb_econv_binmode(rb_econv_t *ec)
Definition: transcode.c:1941
unsigned long ID
Definition: ripper.y:89
static int swallow(rb_io_t *fptr, int term)
Definition: io.c:2928
static VALUE argf_set_encoding(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10675
#define ARGF_GENERIC_INPUT_P()
Definition: io.c:7736
void rb_gc_mark(VALUE)
Definition: gc.c:3607
struct rb_execarg::@109::@111 cmd
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2228
Check_Type(i, T_ARRAY)
static void pipe_finalize(rb_io_t *fptr, int noraise)
Definition: io.c:5648
static VALUE copy_stream_fallback(struct copy_stream_struct *stp)
Definition: io.c:10307
#define ISASCII(c)
Definition: ruby.h:1774
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:2158
static VALUE sym_textmode
Definition: io.c:162
static VALUE finish_writeconv_sync(VALUE arg)
Definition: io.c:4131
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:7051
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:611
int rb_cloexec_pipe(int fildes[2])
Definition: io.c:286
static VALUE pipe_pair_close(VALUE rw)
Definition: io.c:9346
static VALUE VALUE obj
Definition: tcltklib.c:3150
#define RSTRING_LEN(str)
static int appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
Definition: io.c:2846
#define FIX2INT(x)
#define INT2FIX(i)
int chown(const char *, int, int)
Definition: win32.c:4431
int fd
Definition: io.h:62
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2686
static VALUE rb_io_each_line(int argc, VALUE *argv, VALUE io)
Definition: io.c:3371
#define MODE_BINARY(a, b)
int rb_io_wait_writable(int)
Definition: io.c:1103
#define FIX2LONG(x)
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:8219
#define ANYARGS
void rb_last_status_set(int status, rb_pid_t pid)
Definition: process.c:327
static VALUE rb_io_each_char(VALUE io)
Definition: io.c:3573
#define T_STRING
static VALUE rb_io_open_with_args(int argc, const VALUE *argv)
Definition: io.c:6531
int rb_thread_alone(void)
Definition: thread.c:2994
static VALUE argf_chars(VALUE argf)
Definition: io.c:11335
static VALUE rb_io_getline(int argc, VALUE *argv, VALUE io)
Definition: io.c:3179
VALUE str
Definition: io.c:1202
void rb_gvar_readonly_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar)
#define rb_fd_zero(f)
#define MBCLEN_CHARFOUND_P(ret)
#define rb_io_fdatasync
Definition: io.c:1901
struct rb_io_t::rb_io_enc_t encs
void Init_IO(void)
Definition: io.c:11904
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
static void * nogvl_fclose(void *ptr)
Definition: io.c:4159
#define OBJ_INIT_COPY(obj, orig)
#define NUM2IOCTLREQ(num)
Definition: io.c:8711
#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:4063
const char * notimp
Definition: io.c:9850
VALUE rb_io_print(int, VALUE *, VALUE)
Definition: io.c:6846
VALUE rb_mutex_owned_p(VALUE self)
Definition: thread.c:4453
static VALUE rb_open_file(int argc, const VALUE *argv, VALUE io)
Definition: io.c:6260
rb_pid_t pid
Definition: io.h:65
VALUE rb_check_hash_type(VALUE)
Definition: hash.c:597
#define LONG_MAX
Definition: ruby.h:191
#define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr)
Definition: io.c:569
static VALUE rb_io_gets_m(int argc, VALUE *argv, VALUE io)
Definition: io.c:3216
#define RUBY_FUNC_EXPORTED
Definition: defines.h:246
ssize_t rb_io_bufread(VALUE io, void *buf, size_t size)
Definition: io.c:2094
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
static VALUE argf_eof(VALUE argf)
Definition: io.c:10829
int len
Definition: io.h:57
void rb_maygvl_fd_fix_cloexec(int fd)
Definition: io.c:198
static void io_setstrbuf(VALUE *str, long len)
Definition: io.c:2283
#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 argf_of(obj)
Definition: io.c:365
STATIC void C_block perm[64/CHUNKBITS][1<< CHUNKBITS]
Definition: crypt.c:904
void Init_File(void)
Definition: file.c:5623
Definition: io.c:1200
static VALUE rb_f_printf(int argc, VALUE *argv)
Definition: io.c:6805
static void rscheck(const char *rsptr, long rslen, VALUE rs)
Definition: io.c:2838
VALUE * argv
Definition: io.c:7076
void rb_str_setter(VALUE, ID, VALUE *)
Definition: string.c:7875
static int nogvl_copy_stream_write(struct copy_stream_struct *stp, char *buf, size_t len)
Definition: io.c:10144
int len
Definition: enumerator.c:1332
#define ENC_CODERANGE_SET(obj, cr)
static VALUE argf_initialize(VALUE argf, VALUE argv)
Definition: io.c:7661
#define rb_f_syscall
Definition: io.c:9265
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
#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:602
VALUE arg
Definition: enum.c:2427
#define RB_IO_WAIT_WRITABLE
int fd
Definition: io.c:8715
#define EOF
Definition: vsnprintf.c:207
VALUE rb_str_buf_cat(VALUE, const char *, long)
Definition: string.c:2123
VALUE read
Definition: io.c:8344
#define rb_utf8_encindex()
#define rb_fd_set(n, f)
static void io_set_encoding_by_bom(VALUE io)
Definition: io.c:5513
#define DEFAULT_TEXTMODE
Definition: io.c:565
static void advice_arg_check(VALUE advice)
Definition: io.c:8456
#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
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1011
VALUE * argv
Definition: tcltklib.c:1969
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:7648
static void io_ascii8bit_binmode(rb_io_t *fptr)
Definition: io.c:4726
#define NEXT_ARGF_FORWARD(argc, argv)
Definition: io.c:7742
static VALUE prep_io(int fd, int fmode, VALUE klass, const char *path)
Definition: io.c:7225
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1688
static VALUE rb_f_gets(int argc, VALUE *argv, VALUE recv)
Definition: io.c:8007
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2024
memcpy(buf+1, str, len)
#define RTEST(v)
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
Definition: io.c:5104
rb_io_buffer_t wbuf
Definition: io.h:70
#define rb_enc_mbminlen(enc)
int errno
static VALUE copy_stream_body(VALUE arg)
Definition: io.c:10319
#define TRUE
Definition: nkf.h:175
void rb_thread_atfork(void)
Definition: thread.c:3935
VALUE rb_thread_current(void)
Definition: thread.c:2405
#define off_t
Definition: io.c:65
static VALUE seek_before_access(VALUE argp)
Definition: io.c:9622
#define S_ISREG(m)
Definition: io.c:885
static VALUE rb_io_set_pos(VALUE io, VALUE offset)
Definition: io.c:1623
static rb_atomic_t max_file_descriptor
Definition: io.c:181
static VALUE rb_io_init_copy(VALUE dest, VALUE io)
Definition: io.c:6732
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:10170
#define StringValue(v)
rb_block_call(enumerable, id_each, 0, 0, chunk_ii, arg)
void rb_econv_close(rb_econv_t *ec)
Definition: transcode.c:1700
volatile VALUE encname
Definition: tcltklib.c:10162
memo u3 cnt
Definition: enum.c:128
static rb_encoding * io_input_encoding(rb_io_t *fptr)
Definition: io.c:809
static VALUE io_close(VALUE io)
Definition: io.c:4390
Definition: io.c:5595
#define MBCLEN_CHARFOUND_LEN(ret)
static int rb_sysopen(VALUE fname, int oflags, mode_t perm)
Definition: io.c:5378
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
static VALUE argf_rewind(VALUE argf)
Definition: io.c:10761
#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
VALUE v
Definition: enum.c:845
#define RUBY_TYPED_FREE_IMMEDIATELY
void rb_fatal(const char *fmt,...)
Definition: error.c:1911
static VALUE io_s_read(struct foreach_arg *arg)
Definition: io.c:9610
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:9869
static VALUE rb_io_readlines(int argc, VALUE *argv, VALUE io)
Definition: io.c:3326
register char * s
Definition: os2.c:56
VALUE rb_io_get_io(VALUE)
Definition: io.c:627
long rb_str_coderange_scan_restartable(const char *, const char *, rb_encoding *, int *)
Definition: string.c:340
static VALUE rb_io_s_for_fd(int argc, VALUE *argv, VALUE klass)
Definition: io.c:7552
struct rb_io_enc_t encs
Definition: io.c:177
#define CONST_ID(var, str)
static VALUE rb_f_select(int argc, VALUE *argv, VALUE obj)
Definition: io.c:8684
static VALUE rb_io_chars(VALUE io)
Definition: io.c:3596
void rb_gc_register_mark_object(VALUE)
Definition: gc.c:4923
static int wsplit_p(rb_io_t *fptr)
Definition: io.c:889
VP_EXPORT void
Definition: bigdecimal.c:5207
VALUE mode
Definition: tcltklib.c:1668
static VALUE rb_io_s_open(int argc, VALUE *argv, VALUE klass)
Definition: io.c:6311
static VALUE rb_f_print(int argc, VALUE *argv)
Definition: io.c:6894
VALUE rb_io_ungetbyte(VALUE, VALUE)
Definition: io.c:3856
static void argf_lineno_setter(VALUE val, ID id, VALUE *var)
Definition: io.c:7964
#define strdup(s)
Definition: util.h:67
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
static VALUE argf_read_nonblock(int argc, VALUE *argv, VALUE argf)
Definition: io.c:10978
static VALUE argf_to_io(VALUE argf)
Definition: io.c:10803
#define NUM2UINT(x)
Definition: ripper.y:934
size_t length
Definition: tcltklib.c:4549
static void io_unread(rb_io_t *fptr)
Definition: io.c:691
VALUE retval
Definition: tcltklib.c:7823
VALUE rb_io_gets(VALUE)
Definition: io.c:3189
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:620
#define FMODE_WSPLIT
Definition: io.h:111
VALUE tied_io_for_writing
Definition: io.h:72
static VALUE rb_io_close_m(VALUE io)
Definition: io.c:4362
static VALUE argf_lineno_getter(ID id, VALUE *var)
Definition: io.c:7957
static ssize_t rb_write_internal(int fd, const void *buf, size_t count)
Definition: io.c:956
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:5227
int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen)
Definition: process.c:3113
#define EWOULDBLOCK
Definition: io.c:114
VALUE rb_file_open_str(VALUE, const char *)
Definition: io.c:5582
#define mode_t
Definition: win32.h:116
#define RB_IO_WAIT_READABLE
void rb_mutex_allow_trap(VALUE self, int val)
Definition: thread.c:4646
VALUE rb_io_ascii8bit_binmode(VALUE)
Definition: io.c:4748
#define T_FIXNUM
VALUE rb_mutex_synchronize(VALUE mutex, VALUE(*func)(VALUE arg), VALUE arg)
Definition: thread.c:4623
int argc
Definition: tcltklib.c:1968
static VALUE argf_readline(int, VALUE *, VALUE)
Definition: io.c:8106
#define IS_PREP_STDIO(f)
Definition: io.c:4059
VALUE rb_str_buf_new(long)
Definition: string.c:891
static VALUE rb_io_s_binwrite(int argc, VALUE *argv, VALUE io)
Definition: io.c:9832
ssize_t ex
Definition: bigdecimal.c:5211
VALUE rb_eEINPROGRESS
Definition: error.c:42
#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n)
void rb_readwrite_sys_fail(int writable, const char *mesg)
Definition: io.c:11704
char * strchr(char *, char)
int intptr_t
Definition: win32.h:87
static VALUE prep_stdio(FILE *f, int fmode, VALUE klass, const char *path)
Definition: io.c:7256
#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr)
Definition: io.c:427
char * str_ptr
Definition: io.c:2402
rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1))
static void * internal_write_func2(void *ptr)
Definition: io.c:938
#define ECONV_STATEFUL_DECORATOR_MASK
VALUE rb_io_getbyte(VALUE)
Definition: io.c:3795
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
Definition: eval.c:741
int rb_io_oflags_fmode(int oflags)
Definition: io.c:4884
RUBY_EXTERN VALUE rb_stdin
Definition: ripper.y:1635
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1127
static VALUE rb_io_s_write(int argc, VALUE *argv, VALUE io)
Definition: io.c:9816
static long io_bufread(char *ptr, long len, rb_io_t *fptr)
Definition: io.c:2025
rb_fdset_t fds
Definition: io.c:9851
rb_econv_t * rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts)
Definition: transcode.c:2577
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:839
const char * cmd
Definition: tcltklib.c:283
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:10883
VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags)
Definition: transcode.c:2035
#define rb_fd_isset(n, f)
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:9888
static int maygvl_copy_stream_wait_read(int has_gvl, struct copy_stream_struct *stp)
Definition: io.c:9897
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 idx
Definition: enumerator.c:499
int rb_reserved_fd_p(int fd)
void rb_sys_fail(const char *mesg)
Definition: error.c:1976
static VALUE read_internal_call(VALUE arg)
Definition: io.c:2407
int rb_cloexec_fcntl_dupfd(int fd, int minfd)
Definition: io.c:323
static VALUE sym_willneed
Definition: io.c:8368
static VALUE rb_io_autoclose_p(VALUE io)
Definition: io.c:7568
static VALUE io_write_m(VALUE io, VALUE str)
Definition: io.c:1421
ruby_verbose
Definition: tcltklib.c:5796
void rb_jump_tag(int tag)
Definition: eval.c:706
Real * b
Definition: bigdecimal.c:1198
VALUE rb_get_argv(void)
Definition: io.c:11670
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts)
Definition: transcode.c:2884
return ptr
Definition: tcltklib.c:789
#define free(x)
Definition: dln.c:50
VpDivd * c
Definition: bigdecimal.c:1223
static VALUE rb_io_set_encoding(int argc, VALUE *argv, VALUE io)
Definition: io.c:10570
RUBY_EXTERN VALUE rb_cIO
Definition: ripper.y:1577
#define READ_DATA_BUFFERED(fptr)
Definition: io.c:389
#define rb_io_close_on_exec_p
Definition: io.c:3997
#define T_BIGNUM
VALUE rb_io_binmode(VALUE)
Definition: io.c:4702
struct timeval * timeout
Definition: io.c:8345
static VALUE bufread_call(VALUE arg)
Definition: io.c:2070
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:747
RUBY_EXTERN char * strerror(int)
Definition: strerror.c:11
rb_econv_t * readconv
Definition: io.h:87
#define ENC_CODERANGE_VALID
static VALUE argf_tell(VALUE argf)
Definition: io.c:10701
#define shutdown(a, b)
Definition: io.c:575
static VALUE argf_each_byte(VALUE argf)
Definition: io.c:11282
static size_t argf_memsize(const void *ptr)
Definition: io.c:7623
void rb_write_error2(const char *, long)
Definition: io.c:7171
#define SEEK_END
Definition: io.c:762
void rb_iter_break_value(VALUE val)
Definition: vm.c:1160
RUBY_EXTERN VALUE rb_cFile
Definition: ripper.y:1572
static int do_ioctl(int fd, ioctl_req_t cmd, long narg)
Definition: io.c:8729
#define recur(fmt)
int argc
Definition: io.c:9480
const char * rb_class2name(VALUE)
Definition: variable.c:397
static VALUE argf_codepoints(VALUE argf)
Definition: io.c:11374
static VALUE sym_extenc
Definition: io.c:161
VALUE write_lock
Definition: io.h:96
struct pipe_list * next
Definition: io.c:5597
static VALUE argf_filename_getter(ID id, VALUE *var)
Definition: io.c:11412
memo last
Definition: enum.c:1356
void rb_econv_check_error(rb_econv_t *ec)
Definition: transcode.c:4219
RUBY_EXTERN VALUE rb_stderr
Definition: ripper.y:1635
static VALUE rb_io_binmode_m(VALUE io)
Definition: io.c:4772
static VALUE sym_perm
Definition: io.c:161
VALUE src
Definition: tcltklib.c:7943
static VALUE rb_io_isatty(VALUE io)
Definition: io.c:3948
void rb_str_modify(VALUE)
Definition: string.c:1483
#define NEWOBJ_OF(obj, type, klass, flags)
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2139
int rb_io_read_pending(rb_io_t *)
Definition: io.c:830
#define ENC_CODERANGE_7BIT
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
struct timeval rb_time_interval(VALUE num)
Definition: time.c:2411
static VALUE io_s_write0(struct write_arg *arg)
Definition: io.c:9723
void rb_mod_sys_fail_str(VALUE mod, VALUE mesg)
Definition: error.c:2024
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:3249
static long io_writable_length(rb_io_t *fptr, long l)
Definition: io.c:979
void rb_io_check_char_readable(rb_io_t *fptr)
Definition: io.c:766
static VALUE io_read(int argc, VALUE *argv, VALUE io)
Definition: io.c:2790
#define f
#define NUM2LONG(x)
static void pipe_atexit(void)
Definition: io.c:5635
static VALUE io_new_instance(VALUE args)
Definition: io.c:9269
VALUE rb_mutex_new(void)
Definition: thread.c:4255
#define SYMBOL_P(x)
RUBY_EXTERN VALUE rb_default_rs
Definition: ripper.y:519
static VALUE rb_io_putc(VALUE io, VALUE ch)
Definition: io.c:6919
static VALUE rb_io_bytes(VALUE io)
Definition: io.c:3442
#define Qundef
int rb_method_basic_definition_p(VALUE, ID)
Definition: vm_method.c:1585
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:4919
static VALUE check_pipe_command(VALUE filename_or_command)
Definition: io.c:6360
VALUE rb_hash_dup(VALUE)
Definition: hash.c:329
VALUE io
Definition: io.c:9482
static VALUE rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
Definition: io.c:9413
VALUE name
Definition: enum.c:572
static VALUE rb_io_to_io(VALUE io)
Definition: io.c:2004
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:6238
void rb_thread_sleep(int)
Definition: thread.c:1168
static VALUE sym_intenc
Definition: io.c:161
#define MBCLEN_INVALID_P(ret)
static VALUE rb_io_s_try_convert(VALUE dummy, VALUE io)
Definition: io.c:684
void rb_thread_execute_interrupts(VALUE th)
Definition: thread.c:2030
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:632
RUBY_SYMBOL_EXPORT_BEGIN void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
Definition: thread.c:1454
static void clear_codeconv(rb_io_t *fptr)
Definition: io.c:4273
static void rb_io_fptr_cleanup(rb_io_t *fptr, int noraise)
Definition: io.c:4239
void rb_error_arity(int argc, int min, int max)
union rb_execarg::@109 invoke
args[0]
Definition: enum.c:585
static void parse_mode_enc(const char *estr, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
Definition: io.c:5031
#define TypedData_Make_Struct(klass, type, data_type, sval)
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:6566
#define ECONV_PARTIAL_INPUT
rb_pid_t rb_fork_ruby(int *status)
static VALUE rb_eEAGAINWaitReadable
Definition: io.c:142
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1561
#define is_socket(fd, path)
Definition: io.c:581
#define ALLOC_N(type, n)
#define LONG2FIX(i)
int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *)
Definition: thread.c:3580
VALUE rb_io_flush(VALUE)
Definition: io.c:1510
rb_econv_result_t
Definition: ripper.y:252
static VALUE argf_each_char(VALUE argf)
Definition: io.c:11321
VALUE pathv
Definition: io.h:67
static VALUE rb_io_advise(int argc, VALUE *argv, VALUE io)
Definition: io.c:8516
#define O_NONBLOCK
Definition: win32.h:626
VALUE rb_output_fs
Definition: ripper.y:517
static VALUE rb_io_getc(VALUE io)
Definition: io.c:3746
VALUE rb_econv_make_exception(rb_econv_t *ec)
Definition: transcode.c:4213
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
klass
Definition: tcltklib.c:3496
#define UINT2NUM(x)
VALUE offset
Definition: io.c:9617
#define INT2NUM(x)
int use_shell
Definition: ripper.y:641
static VALUE argf_closed(VALUE argf)
Definition: io.c:11544
struct rb_encoding_entry * list
Definition: encoding.c:47
void rb_define_variable(const char *, VALUE *)
Definition: variable.c:604
#define STRNCASECMP(s1, s2, n)
#define READ_CHECK(fptr)
Definition: io.c:402
static VALUE rb_io_s_read(int argc, VALUE *argv, VALUE io)
Definition: io.c:9666
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1651
#define fsync
Definition: win32.h:222
FILE * rb_fdopen(int, const char *)
Definition: io.c:5401
RUBY_EXTERN VALUE rb_rs
Definition: ripper.y:518
static rb_io_t * flush_before_seek(rb_io_t *fptr)
Definition: io.c:747
#define RBASIC_SET_CLASS(obj, cls)
int rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
Definition: process.c:1670
int rb_cloexec_dup2(int oldfd, int newfd)
Definition: io.c:251
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:1899
RUBY_EXTERN int dup2(int, int)
Definition: dup2.c:27
gz io
Definition: zlib.c:2263
void rb_notimplement(void)
Definition: error.c:1903
void rb_define_virtual_variable(const char *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
Definition: variable.c:616
static VALUE sym_binmode
Definition: io.c:162
const char * rb_econv_asciicompat_encoding(const char *encname)
Definition: transcode.c:1784
void rb_thread_fd_close(int)
Definition: thread.c:2135
VALUE rb_ary_concat(VALUE x, VALUE y)
Definition: array.c:3553
static long remain_size(rb_io_t *fptr)
Definition: io.c:2106
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:4992
long length
Definition: io.c:1197
static VALUE argf_argv_getter(ID id, VALUE *var)
Definition: io.c:11664
rb_io_t * fptr
Definition: io.c:4126
register C_block * p
Definition: crypt.c:309
rb_ivar_set(yielder, id_memo, LONG2NUM(++count))
VALUE rb_ary_join(VALUE ary, VALUE sep)
Definition: array.c:2006
VALUE rb_eNotImpError
Definition: error.c:558
FILE * rb_io_stdio_file(rb_io_t *fptr)
Definition: io.c:7275
int rb_atomic_t
Definition: ruby_atomic.h:120
#define FOREACH_ARGF()
Definition: io.c:11182
static VALUE io_reopen(VALUE io, VALUE nfile)
Definition: io.c:6541
static void * sysopen_func(void *ptr)
Definition: io.c:5360
static VALUE rb_io_readline(int argc, VALUE *argv, VALUE io)
Definition: io.c:3297
VALUE rb_str_new(const char *, long)
Definition: string.c:534
#define FMODE_PREP
Definition: io.c:4058
static VALUE rb_eEWOULDBLOCKWaitReadable
Definition: io.c:144
#define rb_safe_level()
Definition: tcltklib.c:95
#define OFFT2NUM(v)
Definition: ruby.h:252
void rb_write_error(const char *)
Definition: io.c:7185
data n
Definition: enum.c:860
static long ioctl_narg_len(ioctl_req_t cmd)
Definition: io.c:8767
static VALUE internal_read_func(void *ptr)
Definition: io.c:924
#define ECONV_NEWLINE_DECORATOR_READ_MASK
void rb_execarg_setenv(VALUE execarg_obj, VALUE env)
Definition: process.c:2300
int oflags
Definition: io.c:5355
void rb_io_check_writable(rb_io_t *)
Definition: io.c:818
Real * res
Definition: bigdecimal.c:1251
static VALUE rb_io_initialize(int argc, VALUE *argv, VALUE io)
Definition: io.c:7431
static void make_writeconv(rb_io_t *fptr)
Definition: io.c:1138
#define ECONV_NEWLINE_DECORATOR_WRITE_MASK
#define rb_enc_asciicompat(enc)
#define NUM2MODET(v)
Definition: ruby.h:339
#define NUM2INT(x)
#define SIGNED_VALUE
VALUE rb_hash_new(void)
Definition: hash.c:307
static VALUE rb_io_readbyte(VALUE io)
Definition: io.c:3828
VALUE rb_obj_alloc(VALUE)
Definition: object.c:1804
const char * rb_id2name(ID id)
Definition: ripper.c:17271
#define READ_CHAR_PENDING_PTR(fptr)
Definition: io.c:393
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
Definition: io.c:228
#define FMODE_SYNC
Definition: io.h:105
#define FMODE_TTY
Definition: io.h:106
#define MakeOpenFile(obj, fp)
Definition: io.h:127
#define SHUT_WR
#define SHUT_RD
#define MORE_CHAR_SUSPENDED
Definition: io.c:2169
VALUE rb_io_close(VALUE)
Definition: io.c:4315
static VALUE sym_sequential
Definition: io.c:8368
#define PRIsVALUE
#define rb_fd_init(f)
rb_io_buffer_t rbuf
Definition: io.h:70
char * inplace
Definition: io.c:176
#define RBASIC_CLEAR_CLASS(obj)
static VALUE rb_io_s_copy_stream(int argc, VALUE *argv, VALUE io)
Definition: io.c:10479
BDIGIT e
Definition: bigdecimal.c:5209
static void clear_writeconv(rb_io_t *fptr)
Definition: io.c:4263
struct rb_io_enc_t convconfig_t
Definition: io.c:5171
static VALUE fill_cbuf(rb_io_t *fptr, int ec_flags)
Definition: io.c:2172
VALUE rb_hash_aref(VALUE, VALUE)
Definition: hash.c:706
VALUE opts
Definition: tcltklib.c:6160
#define NUM2CHR(x)
unsigned long VALUE
Definition: ripper.y:88
static VALUE rb_io_reopen(int argc, VALUE *argv, VALUE file)
Definition: io.c:6643
rb_encoding * rb_ascii8bit_encoding(void)
Definition: encoding.c:1242
static long read_buffered_data(char *ptr, long len, rb_io_t *fptr)
Definition: io.c:2011
static VALUE sym_dontneed
Definition: io.c:8368
static int interpret_seek_whence(VALUE vwhence)
Definition: io.c:1556
RUBY_EXTERN VALUE rb_eEOFError
Definition: ripper.y:1606
void rb_warning(const char *fmt,...)
Definition: error.c:236
int rb_enc_find_index(const char *name)
Definition: encoding.c:684
#define rb_io_fsync
Definition: io.c:1853
static VALUE sym_END
Definition: io.c:163
#define fileno(p)
Definition: vsnprintf.c:223
static VALUE sym_open_args
Definition: io.c:161
#define ECONV_DEFAULT_NEWLINE_DECORATOR
static VALUE sym_exception
Definition: io.c:162
VALUE rb_uninterruptible(VALUE(*b_proc)(ANYARGS), VALUE data)
Definition: thread.c:5317
#define NEED_NEWLINE_DECORATOR_ON_READ(fptr)
Definition: io.c:426
FILE * stdio_file
Definition: io.h:63
static VALUE rb_io_fileno(VALUE io)
Definition: io.c:1917
const char * ruby_get_inplace_mode(void)
Definition: io.c:11630
static VALUE sym_normal
Definition: io.c:8368
void rb_stdio_set_default_encoding(void)
Definition: io.c:10586
#define MODE_BTMODE(a, b, c)
Definition: io.c:1293
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:7122
static VALUE argf_forward(int argc, VALUE *argv, VALUE argf)
Definition: io.c:7730
gz ecopts
Definition: zlib.c:2277
static VALUE pipe_open_s(VALUE prog, const char *modestr, int fmode, convconfig_t *convconfig)
Definition: io.c:6069
static VALUE rb_f_readline(int argc, VALUE *argv, VALUE recv)
Definition: io.c:8080
char rb_w32_fd_is_text(int)
Definition: win32.c:7021
#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:2709
static VALUE argf_fileno(VALUE argf)
Definition: io.c:10781
VALUE write
Definition: io.c:8344
#define OBJ_TAINT(x)
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:11558
static VALUE io_alloc(VALUE klass)
Definition: io.c:875
#define RUBY_METHOD_FUNC(func)
VALUE * argv
Definition: io.c:9481
#define rb_intern(str)
#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:3073
int lineno
Definition: io.h:66
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
#define rb_sys_fail_path(path)
#define fstat(fd, st)
Definition: win32.h:214
static VALUE rb_ioctl(VALUE io, VALUE req, VALUE arg)
Definition: io.c:8968
#define stat(path, st)
Definition: win32.h:213
static VALUE io_read_nonblock(int argc, VALUE *argv, VALUE io)
Definition: io.c:2593
VALUE rb_io_set_write_io(VALUE io, VALUE w)
Definition: io.c:651
static void * nogvl_copy_stream_func(void *arg)
Definition: io.c:10227
VALUE except
Definition: io.c:8344
static const char * rb_io_oflags_modestr(int oflags)
Definition: io.c:4960
#define rb_io_sync
Definition: io.c:1854
#define DEFULT_IOCTL_NARG_LEN
Definition: io.c:8743
#define env
mode_t perm
Definition: io.c:5356
int rb_econv_putbackable(rb_econv_t *ec)
Definition: transcode.c:1740
VALUE rb_io_flush_raw(VALUE, int)
Definition: io.c:1466
#define NULL
Definition: _sdbm.c:102
static VALUE argf_file(VALUE argf)
Definition: io.c:11436
static VALUE copy_stream_finalize(VALUE arg)
Definition: io.c:10430
static VALUE io_getc(rb_io_t *fptr, rb_encoding *enc)
Definition: io.c:3451
int rb_io_wait_readable(int)
Definition: io.c:1077
#define READ_CHAR_PENDING(fptr)
Definition: io.c:391
VALUE rb_check_string_type(VALUE)
Definition: string.c:1678
static void argf_free(void *ptr)
Definition: io.c:7615
#define READ_DATA_PENDING_PTR(fptr)
Definition: io.c:388
#define rb_syserr_fail_path(err, path)
static void extract_binmode(VALUE opthash, int *fmode)
Definition: io.c:5198
static VALUE argf_close_m(VALUE argf)
Definition: io.c:11525
void rb_write_error_str(VALUE mesg)
Definition: io.c:7191
int rb_enc_str_coderange(VALUE)
Definition: string.c:435
static ID id_flush
Definition: io.c:160
static VALUE select_end(VALUE arg)
Definition: io.c:8358
volatile VALUE result
Definition: enum.c:1989
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:4997
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:1479
int retry
Definition: tcltklib.c:10158
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:410
#define NOFILE
Definition: io.c:76
volatile VALUE current
Definition: tcltklib.c:7114
static VALUE rb_io_each_codepoint(VALUE io)
Definition: io.c:3621
static void pipe_del_fptr(rb_io_t *fptr)
Definition: io.c:5612
#define next_argv()
Definition: io.c:7735
int rb_thread_fd_writable(int)
Definition: thread.c:3529
char * dst
Definition: tcltklib.c:9876
void rb_warn(const char *fmt,...)
Definition: error.c:223
void rb_io_check_closed(rb_io_t *)
Definition: io.c:617
static VALUE rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
Definition: io.c:9560
rb_io_t * fptr
Definition: io.c:5596
void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n)
Definition: transcode.c:1751
VALUE rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags)
Definition: transcode.c:1876
#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:6511
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2637
#define O_BINARY
Definition: _sdbm.c:88
int mode
Definition: io.c:9618
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2652
gz cbuf
Definition: zlib.c:2278
static VALUE argf_initialize_copy(VALUE argf, VALUE orig)
Definition: io.c:7671
static VALUE argf_getc(VALUE argf)
Definition: io.c:11050
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR
static int maygvl_close(int fd, int keepgvl)
Definition: io.c:4146
int dummy
Definition: tcltklib.c:4473
static VALUE argf_skip(VALUE argf)
Definition: io.c:11497
VALUE rb_io_fdopen(int, int, const char *)
Definition: io.c:7247
#define SEEK_CUR
Definition: io.c:761
#define SET_BINARY_MODE(fptr)
Definition: io.c:568
char * strrchr(const char *, const char)
VALUE rb_io_addstr(VALUE, VALUE)
Definition: io.c:1449
VALUE io
Definition: io.c:9616
static int maygvl_fclose(FILE *file, int keepgvl)
Definition: io.c:4167
rb_econv_t * writeconv
Definition: io.h:90
static VALUE argf_forward_call(VALUE arg)
Definition: io.c:10934
void rb_read_check(FILE *fp)
Definition: io.c:839
VALUE rb_io_write(VALUE, VALUE)
Definition: io.c:1427
Definition: ioctl.h:6
static int io_fillbuf(rb_io_t *fptr)
Definition: io.c:1673
Definition: io.c:9615
VALUE rb_inspect(VALUE)
Definition: object.c:470
int rb_thread_interrupted(VALUE thval)
Definition: thread.c:1160
rb_encoding * rb_enc_from_index(int index)
Definition: encoding.c:590
static void unsupported_encoding(const char *name)
Definition: io.c:5025
static VALUE rb_io_s_new(int argc, VALUE *argv, VALUE klass)
Definition: io.c:7531
void rb_execarg_fixup(VALUE execarg_obj)
Definition: process.c:2326
static void clear_readconv(rb_io_t *fptr)
Definition: io.c:4250
void rb_eof_error(void)
Definition: io.c:596
void rb_str_set_len(VALUE, long)
Definition: string.c:2007