25 #define free(x) xfree(x) 27 #if defined(DOSISH) || defined(__CYGWIN__) 31 #include <sys/types.h> 32 #if defined HAVE_NET_SOCKET_H 33 # include <net/socket.h> 34 #elif defined HAVE_SYS_SOCKET_H 35 # include <sys/socket.h> 38 #if defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32) 39 # define NO_SAFE_RENAME 42 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__sun) || defined(_nec_ews) 50 #include <sys/types.h> 51 #if defined(HAVE_SYS_IOCTL_H) && !defined(_WIN32) 52 #include <sys/ioctl.h> 54 #if defined(HAVE_FCNTL_H) || defined(_WIN32) 56 #elif defined(HAVE_SYS_FCNTL_H) 57 #include <sys/fcntl.h> 60 #if !HAVE_OFF_T && !defined(off_t) 64 #ifdef HAVE_SYS_TIME_H 65 # include <sys/time.h> 70 #if defined(HAVE_SYS_PARAM_H) || defined(__HIUX_MPP__) 71 # include <sys/param.h> 84 #elif defined HAVE_SYS_SYSCALL_H 85 #include <sys/syscall.h> 92 #ifdef HAVE_SYS_WAIT_H 93 # include <sys/wait.h> 99 #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) 102 #if SIZEOF_OFF_T > SIZEOF_LONG && !defined(HAVE_LONG_LONG) 103 # error off_t is bigger than long, but you have no long long... 107 # ifdef _POSIX_PIPE_BUF 108 # define PIPE_BUF _POSIX_PIPE_BUF 110 # define PIPE_BUF 512 115 # define EWOULDBLOCK EAGAIN 118 #if defined(HAVE___SYSCALL) && (defined(__APPLE__) || defined(__OpenBSD__)) 120 off_t __syscall(quad_t number, ...);
123 #ifdef __native_client__ 130 #define IO_RBUF_CAPA_MIN 8192 131 #define IO_CBUF_CAPA_MIN (128*1024) 132 #define IO_RBUF_CAPA_FOR(fptr) (NEED_READCONV(fptr) ? IO_CBUF_CAPA_MIN : IO_RBUF_CAPA_MIN) 133 #define IO_WBUF_CAPA_MIN 8192 138 #define open rb_w32_uopen 140 #define rename(f, t) rb_w32_urename((f), (t)) 149 static VALUE rb_eEAGAINWaitReadable;
150 static VALUE rb_eEAGAINWaitWritable;
151 static VALUE rb_eEWOULDBLOCKWaitReadable;
152 static VALUE rb_eEWOULDBLOCKWaitWritable;
153 static VALUE rb_eEINPROGRESSWaitWritable;
154 static VALUE rb_eEINPROGRESSWaitReadable;
157 static VALUE orig_stdout, orig_stderr;
166 #define id_exception idException 167 static ID id_write, id_read, id_getc, id_flush, id_readpartial, id_set_encoding;
168 static VALUE sym_mode, sym_perm, sym_flags, sym_extenc, sym_intenc, sym_encoding, sym_open_args;
169 static VALUE sym_textmode, sym_binmode, sym_autoclose;
170 static VALUE sym_SET, sym_CUR, sym_END;
171 static VALUE sym_wait_readable, sym_wait_writable;
173 static VALUE sym_DATA;
176 static VALUE sym_HOLE;
201 rb_bug(
"rb_update_max_fd: invalid fd (%d) given.", fd);
204 while (max_fd < afd) {
205 max_fd =
ATOMIC_CAS(max_file_descriptor, max_fd, afd);
213 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) 214 int flags, flags2, ret;
223 if (flags != flags2) {
226 rb_bug(
"rb_maygvl_fd_fix_cloexec: fcntl(%d, F_SETFD, %d) failed: %s", fd, flags2,
strerror(
errno));
241 rb_fix_detect_o_cloexec(
int fd)
243 #if defined(O_CLOEXEC) && defined(F_GETFD) 260 static int o_cloexec_state = -1;
265 #elif defined O_NOINHERIT 266 flags |= O_NOINHERIT;
268 ret = open(pathname, flags, mode);
269 if (ret == -1)
return -1;
270 if (ret <= 2 || o_cloexec_state == 0) {
273 else if (o_cloexec_state > 0) {
277 o_cloexec_state = rb_fix_detect_o_cloexec(ret);
296 if (oldfd == newfd) {
300 #if defined(HAVE_DUP3) && defined(O_CLOEXEC) 301 static int try_dup3 = 1;
302 if (2 < newfd && try_dup3) {
307 if (
errno == ENOSYS) {
309 ret =
dup2(oldfd, newfd);
313 ret =
dup2(oldfd, newfd);
316 ret =
dup2(oldfd, newfd);
318 if (ret == -1)
return -1;
329 #if defined(HAVE_PIPE2) 330 static int try_pipe2 = 1;
336 if (
errno == ENOSYS) {
347 if (ret == -1)
return -1;
349 if (ret == 0 && fildes[1] == -1) {
366 #if defined(HAVE_FCNTL) && defined(F_DUPFD_CLOEXEC) && defined(F_DUPFD) 367 static int try_dupfd_cloexec = 1;
368 if (try_dupfd_cloexec) {
376 if (
errno == EINVAL) {
379 try_dupfd_cloexec = 0;
386 #elif defined(HAVE_FCNTL) && defined(F_DUPFD) 388 #elif defined(HAVE_DUP) 390 if (ret != -1 && ret < minfd) {
391 const int prev_fd = ret;
397 # error "dup() or fcntl(F_DUPFD) must be supported." 399 if (ret == -1)
return -1;
404 #define argf_of(obj) (*(struct argf *)DATA_PTR(obj)) 405 #define ARGF argf_of(argf) 407 #define GetWriteIO(io) rb_io_get_write_io(io) 409 #define READ_DATA_PENDING(fptr) ((fptr)->rbuf.len) 410 #define READ_DATA_PENDING_COUNT(fptr) ((fptr)->rbuf.len) 411 #define READ_DATA_PENDING_PTR(fptr) ((fptr)->rbuf.ptr+(fptr)->rbuf.off) 412 #define READ_DATA_BUFFERED(fptr) READ_DATA_PENDING(fptr) 414 #define READ_CHAR_PENDING(fptr) ((fptr)->cbuf.len) 415 #define READ_CHAR_PENDING_COUNT(fptr) ((fptr)->cbuf.len) 416 #define READ_CHAR_PENDING_PTR(fptr) ((fptr)->cbuf.ptr+(fptr)->cbuf.off) 419 #define WAIT_FD_IN_WIN32(fptr) \ 420 (rb_w32_io_cancelable_p((fptr)->fd) ? 0 : rb_thread_wait_fd((fptr)->fd)) 422 #define WAIT_FD_IN_WIN32(fptr) 425 #define READ_CHECK(fptr) do {\ 426 if (!READ_DATA_PENDING(fptr)) {\ 427 WAIT_FD_IN_WIN32(fptr);\ 428 rb_io_check_closed(fptr);\ 434 # define S_ISSOCK(m) _S_ISSOCK(m) 437 # define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK) 440 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) 446 static int io_fflush(
rb_io_t *);
449 #define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE) 450 #define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) ((fptr)->mode & FMODE_TEXTMODE) 451 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) 453 # define DEFAULT_TEXTMODE FMODE_TEXTMODE 454 # define TEXTMODE_NEWLINE_DECORATOR_ON_WRITE ECONV_CRLF_NEWLINE_DECORATOR 462 #define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || (fptr)->encs.ecflags & ~ECONV_CRLF_NEWLINE_DECORATOR) 463 #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))) 464 #define SET_BINARY_MODE(fptr) setmode((fptr)->fd, O_BINARY) 466 #define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr) do {\ 467 if (NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {\ 468 if (((fptr)->mode & FMODE_READABLE) &&\ 469 !((fptr)->encs.ecflags & ECONV_NEWLINE_DECORATOR_MASK)) {\ 470 setmode((fptr)->fd, O_BINARY);\ 473 setmode((fptr)->fd, O_TEXT);\ 478 #define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags) do {\ 479 if ((enc2) && ((ecflags) & ECONV_DEFAULT_NEWLINE_DECORATOR)) {\ 480 (ecflags) |= ECONV_UNIVERSAL_NEWLINE_DECORATOR;\ 506 if (r < 0 &&
errno) {
518 if (pos < 0 &&
errno) {
525 extra_max = (long)(pos - fptr->
rbuf.len);
526 p = fptr->
rbuf.ptr + fptr->
rbuf.off;
529 if (*(fptr->
rbuf.ptr + fptr->
rbuf.capa - 1) ==
'\r') {
533 for (i = 0; i < fptr->
rbuf.len; i++) {
534 if (*p ==
'\n') newlines++;
535 if (extra_max == newlines)
break;
540 while (newlines >= 0) {
542 if (newlines == 0)
break;
547 read_size = _read(fptr->
fd, buf, fptr->
rbuf.len + newlines);
553 if (read_size == fptr->
rbuf.len) {
575 set_binary_mode_with_seek_cur(
rb_io_t *fptr)
582 flush_before_seek(fptr);
585 #define SET_BINARY_MODE_WITH_SEEK_CUR(fptr) set_binary_mode_with_seek_cur(fptr) 589 # define DEFAULT_TEXTMODE 0 590 #define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || NEED_NEWLINE_DECORATOR_ON_READ(fptr)) 591 #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))) 592 #define SET_BINARY_MODE(fptr) (void)(fptr) 593 #define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr) (void)(fptr) 594 #define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags) ((void)(enc2), (void)(ecflags)) 595 #define SET_BINARY_MODE_WITH_SEEK_CUR(fptr) (void)(fptr) 598 #if !defined HAVE_SHUTDOWN && !defined shutdown 599 #define shutdown(a,b) 0 603 #define is_socket(fd, path) rb_w32_is_socket(fd) 604 #elif !defined(S_ISSOCK) 605 #define is_socket(fd, path) 0 611 if (
fstat(fd, &sbuf) < 0)
613 return S_ISSOCK(sbuf.st_mode);
617 static const char closed_stream[] =
"closed stream";
650 rb_io_get_fptr(
VALUE io)
684 rb_io_t *fptr = rb_io_get_fptr(io);
693 return write_io ? write_io :
Qnil;
719 #if !(defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)) 730 if (r < 0 &&
errno) {
752 #if SIZEOF_LONG > SIZEOF_INT 757 fptr->
rbuf.capa = (int)len;
759 fptr->
rbuf.capa = min_capa;
762 if (fptr->
rbuf.capa < len + fptr->
rbuf.len) {
765 if (fptr->
rbuf.off < len) {
768 char, fptr->
rbuf.len);
771 fptr->
rbuf.off-=(int)len;
772 fptr->
rbuf.len+=(int)len;
777 flush_before_seek(
rb_io_t *fptr)
779 if (io_fflush(fptr) < 0)
786 #define io_seek(fptr, ofs, whence) (errno = 0, lseek(flush_before_seek(fptr)->fd, (ofs), (whence))) 787 #define io_tell(fptr) lseek(flush_before_seek(fptr)->fd, 0, SEEK_CUR) 802 if (fptr->
wbuf.len) {
803 if (io_fflush(fptr) < 0)
809 if (io_fflush(wfptr) < 0)
830 io_read_encoding(
rb_io_t *fptr)
839 io_input_encoding(
rb_io_t *fptr)
844 return io_read_encoding(fptr);
854 if (fptr->
rbuf.len) {
880 if (err == EMFILE || err == ENFILE || err == ENOMEM) {
907 io_alloc(
VALUE klass)
917 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 933 struct io_internal_writev_struct {
936 const struct iovec *iov;
941 internal_read_func(
void *ptr)
944 return read(iis->
fd, iis->
buf, iis->
capa);
948 internal_write_func(
void *ptr)
951 return write(iis->
fd, iis->
buf, iis->
capa);
955 internal_write_func2(
void *ptr)
963 internal_writev_func(
void *ptr)
965 struct io_internal_writev_struct *iis = ptr;
966 return writev(iis->fd, iis->iov, iis->iovcnt);
971 rb_read_internal(
int fd,
void *
buf,
size_t count)
982 rb_write_internal(
int fd,
const void *
buf,
size_t count)
993 rb_write_internal2(
int fd,
const void *
buf,
size_t count)
1006 rb_writev_internal(
int fd,
const struct iovec *iov,
int iovcnt)
1008 struct io_internal_writev_struct iis;
1011 iis.iovcnt = iovcnt;
1018 io_flush_buffer_sync(
void *arg)
1021 long l = fptr->
wbuf.len;
1022 ssize_t r = write(fptr->
fd, fptr->
wbuf.ptr+fptr->
wbuf.off, (
size_t)l);
1024 if (fptr->
wbuf.len <= r) {
1030 fptr->
wbuf.off += (int)r;
1031 fptr->
wbuf.len -= (int)r;
1038 io_flush_buffer_sync2(
void *arg)
1040 VALUE result = io_flush_buffer_sync(arg);
1046 return !result ? (
void*)1 : (
void*)result;
1050 io_flush_buffer_async(
VALUE arg)
1057 io_flush_buffer_async2(
VALUE arg)
1070 else if (ret == 1) {
1077 io_flush_buffer(
rb_io_t *fptr)
1081 return (
int)io_flush_buffer_async2((
VALUE)fptr);
1086 return (
int)io_flush_buffer_async((
VALUE)fptr);
1094 if (fptr->
wbuf.len == 0)
1097 while (fptr->
wbuf.len > 0 && io_flush_buffer(fptr) != 0) {
1113 #if defined(ERESTART) 1120 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 1139 #if defined(ERESTART) 1155 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 1170 const char *senc, *denc;
1237 io_binwrite_string(
VALUE arg)
1243 if (fptr->
wbuf.len) {
1244 struct iovec iov[2];
1251 r = rb_writev_internal(fptr->
fd, iov, 2);
1256 if (fptr->
wbuf.len <= r) {
1257 r -= fptr->
wbuf.len;
1262 fptr->
wbuf.off += (int)r;
1263 fptr->
wbuf.len -= (int)r;
1268 r = rb_write_internal(fptr->
fd, p->
ptr, p->
length);
1275 io_binwrite_string(
VALUE arg)
1283 if (fptr->
wbuf.len) {
1284 if (fptr->
wbuf.len+len <= fptr->wbuf.capa) {
1285 if (fptr->
wbuf.capa < fptr->
wbuf.off+fptr->
wbuf.len+len) {
1290 fptr->
wbuf.len += (int)len;
1293 if (io_fflush(fptr) < 0)
1309 long n, r, offset = 0;
1314 if ((n =
len) <= 0)
return n;
1336 r = io_binwrite_string((
VALUE)&arg);
1339 if (r == n)
return len;
1355 if (fptr->
wbuf.off) {
1365 # define MODE_BTMODE(a,b,c) ((fmode & FMODE_BINMODE) ? (b) : \ 1366 (fmode & FMODE_TEXTMODE) ? (c) : (a)) 1374 make_writeconv(fptr);
1377 #define fmode (fptr->mode) 1381 rb_raise(
rb_eArgError,
"ASCII incompatible string written for text mode IO without encoding conversion: %s",
1393 if (!
NIL_P(common_encoding)) {
1404 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) 1405 #define fmode (fptr->mode) 1412 setmode(fptr->
fd, O_TEXT);
1415 rb_raise(
rb_eArgError,
"ASCII incompatible string written for text mode IO without encoding conversion: %s",
1434 if (len > 0)
return len;
1437 str = do_writeconv(
str, fptr, &converted);
1443 n = io_binwrite(tmp, ptr, len, fptr, nosync);
1456 return (ssize_t)io_binwrite(0, buf, (
long)size, fptr, 0);
1479 n = io_fwrite(
str, fptr, nosync);
1506 return io_write(io, str, 0);
1540 nogvl_fsync(
void *
ptr)
1565 if (io_fflush(fptr) < 0)
1611 rb_io_tell(
VALUE io)
1619 pos -= fptr->
rbuf.len;
1624 rb_io_seek(
VALUE io,
VALUE offset,
int whence)
1631 pos =
io_seek(fptr, pos, whence);
1638 interpret_seek_whence(
VALUE vwhence)
1640 if (vwhence == sym_SET)
1642 if (vwhence == sym_CUR)
1644 if (vwhence == sym_END)
1647 if (vwhence == sym_DATA)
1651 if (vwhence == sym_HOLE)
1681 VALUE offset, ptrname;
1685 whence = interpret_seek_whence(ptrname);
1688 return rb_io_seek(io, offset, whence);
1718 static void clear_readconv(
rb_io_t *fptr);
1737 rb_io_rewind(
VALUE io)
1743 if (io ==
ARGF.current_file) {
1748 clear_readconv(fptr);
1768 if (fptr->
rbuf.len == 0) {
1771 r = rb_read_internal(fptr->
fd, fptr->
rbuf.ptr, fptr->
rbuf.capa);
1787 fptr->
rbuf.len = (int)r;
1839 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) 1844 if (io_fillbuf(fptr) < 0) {
1926 if (io_fflush(fptr) < 0)
1933 # define rb_io_fsync rb_f_notimplement 1934 # define rb_io_sync rb_f_notimplement 1943 #ifdef HAVE_FDATASYNC 1945 nogvl_fdatasync(
void *
ptr)
1953 return (
VALUE)fdatasync(fptr->
fd);
1975 if (io_fflush(fptr) < 0)
1985 #define rb_io_fdatasync rb_io_fsync 2001 rb_io_fileno(
VALUE io)
2052 rb_io_inspect(
VALUE obj)
2056 static const char closed[] =
" (closed)";
2058 fptr =
RFILE(obj)->fptr;
2088 rb_io_to_io(
VALUE io)
2100 if (n <= 0)
return 0;
2101 if (n >
len) n = (int)
len;
2103 fptr->
rbuf.off += n;
2104 fptr->
rbuf.len -= n;
2118 c = rb_read_internal(fptr->
fd,
ptr+offset, n);
2126 if ((n -= c) <= 0)
break;
2132 c = read_buffered_data(
ptr+offset, n, fptr);
2135 if ((n -= c) <= 0)
break;
2138 if (io_fillbuf(fptr) < 0) {
2154 bufread_call(
VALUE arg)
2167 io_setstrbuf(&str, offset +
size);
2184 return (ssize_t)io_bufread(buf, (
long)size, fptr);
2195 #
if defined(__HAIKU__)
2200 if (io_fflush(fptr) < 0)
2203 if (st.st_size >= pos && pos >= 0) {
2204 siz += st.st_size - pos;
2230 const char *sname, *dname;
2251 #define MORE_CHAR_SUSPENDED Qtrue 2252 #define MORE_CHAR_FINISHED Qnil 2254 fill_cbuf(
rb_io_t *fptr,
int ec_flags)
2256 const unsigned char *ss, *sp, *se;
2257 unsigned char *ds, *
dp, *de;
2265 if (fptr->
cbuf.len == fptr->
cbuf.capa)
2267 if (fptr->
cbuf.len == 0)
2269 else if (fptr->
cbuf.off + fptr->
cbuf.len == fptr->
cbuf.capa) {
2274 cbuf_len0 = fptr->
cbuf.len;
2277 ss = sp = (
const unsigned char *)fptr->
rbuf.ptr + fptr->
rbuf.off;
2278 se = sp + fptr->
rbuf.len;
2279 ds = dp = (
unsigned char *)fptr->
cbuf.ptr + fptr->
cbuf.off + fptr->
cbuf.len;
2280 de = (
unsigned char *)fptr->
cbuf.ptr + fptr->
cbuf.capa;
2282 fptr->
rbuf.off += (int)(sp - ss);
2283 fptr->
rbuf.len -= (int)(sp - ss);
2284 fptr->
cbuf.len += (int)(dp - ds);
2289 fptr->
rbuf.off -= putbackable;
2290 fptr->
rbuf.len += putbackable;
2297 if (cbuf_len0 != fptr->
cbuf.len)
2305 if (fptr->
rbuf.len == 0) {
2307 if (io_fillbuf(fptr) == -1) {
2311 ds = dp = (
unsigned char *)fptr->
cbuf.ptr + fptr->
cbuf.off + fptr->
cbuf.len;
2312 de = (
unsigned char *)fptr->
cbuf.ptr + fptr->
cbuf.capa;
2314 fptr->
cbuf.len += (int)(dp - ds);
2321 if (cbuf_len0 != fptr->
cbuf.len)
2355 if (fptr->
cbuf.len == 0)
2357 else if (fptr->
cbuf.capa/2 < fptr->
cbuf.off) {
2368 len = (len + 1) & ~1L;
2387 #define MAX_REALLOC_GAP 4096 2389 io_shrink_read_string(
VALUE str,
long n)
2397 io_set_read_length(
VALUE str,
long n,
int shrinkable)
2402 if (shrinkable) io_shrink_read_string(str, n);
2417 int first = !
NIL_P(str);
2419 shrinkable = io_setstrbuf(&str,0);
2420 make_readconv(fptr, 0);
2423 if (fptr->
cbuf.len) {
2425 io_shift_cbuf(fptr, fptr->
cbuf.len, &str);
2427 v = fill_cbuf(fptr, 0);
2429 if (fptr->
cbuf.len) {
2431 io_shift_cbuf(fptr, fptr->
cbuf.len, &str);
2436 clear_readconv(fptr);
2438 if (shrinkable) io_shrink_read_string(str,
RSTRING_LEN(str));
2439 return io_enc_str(str, fptr);
2448 enc = io_read_encoding(fptr);
2451 if (siz == 0) siz = BUFSIZ;
2452 shrinkable = io_setstrbuf(&str, siz);
2455 n = io_fread(str, bytes, siz - bytes, fptr);
2456 if (n == 0 && bytes == 0) {
2464 if (bytes < siz)
break;
2468 if (shrinkable) io_shrink_read_string(str,
RSTRING_LEN(str));
2469 str = io_enc_str(str, fptr);
2484 oflags =
fcntl(fptr->
fd, F_GETFL);
2507 read_internal_call(
VALUE arg)
2515 no_exception_p(
VALUE opts)
2535 if ((len =
NUM2LONG(length)) < 0) {
2539 shrinkable = io_setstrbuf(&str, len);
2550 n = read_buffered_data(
RSTRING_PTR(str), len, fptr);
2556 io_setstrbuf(&str, len);
2566 if (nonblock && (e ==
EWOULDBLOCK || e == EAGAIN)) {
2567 if (no_exception_p(opts))
2568 return sym_wait_readable;
2571 e,
"read would block");
2576 io_set_read_length(str, n, shrinkable);
2657 io_nonblock_eof(
VALUE opts)
2659 if (!no_exception_p(opts)) {
2674 if ((len =
NUM2LONG(length)) < 0) {
2678 shrinkable = io_setstrbuf(&str, len);
2686 n = read_buffered_data(
RSTRING_PTR(str), len, fptr);
2689 shrinkable |= io_setstrbuf(&str, len);
2698 if (ex ==
Qfalse)
return sym_wait_readable;
2700 e,
"read would block");
2705 io_set_read_length(str, n, shrinkable);
2729 if (io_fflush(fptr) < 0)
2739 return sym_wait_writable;
2825 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) 2831 if (
NIL_P(length)) {
2834 return read_all(fptr, remain_size(fptr), str);
2841 shrinkable = io_setstrbuf(&str,len);
2846 io_set_read_length(str, 0, shrinkable);
2851 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) 2852 previous_mode = set_binary_mode_with_seek_cur(fptr);
2854 n = io_fread(str, 0, len, fptr);
2855 io_set_read_length(str, n, shrinkable);
2856 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) 2857 if (previous_mode == O_TEXT) {
2858 setmode(fptr->
fd, O_TEXT);
2861 if (n == 0)
return Qnil;
2868 rscheck(
const char *rsptr,
long rslen,
VALUE rs)
2876 appendline(
rb_io_t *fptr,
int delim,
VALUE *strp,
long *lp)
2883 make_readconv(fptr, 0);
2889 if (0 < limit && limit < searchlen)
2890 searchlen = (int)limit;
2891 e = memchr(p, delim, searchlen);
2893 int len = (int)(e-p+1);
2909 fptr->
cbuf.off += searchlen;
2910 fptr->
cbuf.len -= searchlen;
2919 clear_readconv(fptr);
2932 if (limit > 0 && pending > limit) pending = limit;
2933 e = memchr(p, delim, pending);
2934 if (e) pending = e - p + 1;
2944 read_buffered_data(
RSTRING_PTR(str) + last, pending, fptr);
2947 if (e)
return delim;
2952 }
while (io_fillbuf(fptr) >= 0);
2964 make_readconv(fptr, 0);
2971 if (*p != term)
return TRUE;
2973 while (--i && *++p == term);
2976 const char *e = p +
cnt;
2981 io_shift_cbuf(fptr, (
int)cnt - i,
NULL);
2994 if (cnt >
sizeof buf) cnt =
sizeof buf;
2995 if (*p != term)
return TRUE;
2997 while (--i && *++p == term);
2998 if (!read_buffered_data(buf, cnt - i, fptr))
3002 }
while (io_fillbuf(fptr) == 0);
3022 e = memchr(p,
'\n', pending);
3024 pending = (int)(e - p + 1);
3026 chomplen = (pending > 1 && *(e-1) ==
'\r') + 1;
3031 fptr->
rbuf.off += pending;
3032 fptr->
rbuf.len -= pending;
3036 read_buffered_data(
RSTRING_PTR(str)+len, pending - chomplen, fptr);
3037 fptr->
rbuf.off += chomplen;
3038 fptr->
rbuf.len -= chomplen;
3040 len += pending - chomplen;
3046 }
while (io_fillbuf(fptr) >= 0);
3049 str = io_enc_str(str, fptr);
3060 unsigned int chomp: 1;
3076 args->
chomp = chomp;
3094 else if (2 <=
argc) {
3104 check_getline_args(
VALUE *rsp,
long *limit,
VALUE io)
3114 enc_io = io_read_encoding(fptr);
3115 if (enc_io != enc_rs &&
3137 extract_getline_args(
argc,
argv, args);
3138 extract_getline_opts(opts, args);
3139 check_getline_args(&args->
rs, &args->
limit, io);
3143 rb_io_getline_0(
VALUE rs,
long limit,
int chomp,
rb_io_t *fptr)
3150 if (
NIL_P(rs) && limit < 0) {
3151 str = read_all(fptr, 0,
Qnil);
3155 else if (limit == 0) {
3161 return rb_io_getline_fast(fptr, enc, chomp);
3164 int c, newline = -1;
3165 const char *rsptr = 0;
3168 int extra_limit = 16;
3169 int chomp_cr = chomp;
3172 enc = io_read_encoding(fptr);
3180 swallow(fptr,
'\n');
3193 newline = (
unsigned char)rsptr[rslen - 1];
3194 chomp_cr = chomp && rslen == 1 && newline ==
'\n';
3198 while ((c = appendline(fptr, newline, &str, &limit)) !=
EOF) {
3199 const char *s, *p, *pp, *e;
3207 if (pp != p)
continue;
3208 if (!rspara) rscheck(rsptr, rslen, rs);
3209 if (
memcmp(p, rsptr, rslen) == 0) {
3211 if (chomp_cr && p > s && *(p-1) ==
'\r') --p;
3235 if (rspara && c !=
EOF)
3236 swallow(fptr,
'\n');
3238 str = io_enc_str(str, fptr);
3241 if (!
NIL_P(str) && !nolimit) {
3249 rb_io_getline_1(
VALUE rs,
long limit,
int chomp,
VALUE io)
3252 int old_lineno, new_lineno;
3256 old_lineno = fptr->
lineno;
3257 str = rb_io_getline_0(rs, limit, chomp, fptr);
3258 if (!
NIL_P(str) && (new_lineno = fptr->
lineno) != old_lineno) {
3259 if (io ==
ARGF.current_file) {
3260 ARGF.lineno += new_lineno - old_lineno;
3264 ARGF.last_lineno = new_lineno;
3276 prepare_getline_args(
argc,
argv, &args, io);
3277 return rb_io_getline_1(args.
rs, args.
limit, args.
chomp, io);
3332 str = rb_io_getline(
argc,
argv, io);
3447 prepare_getline_args(
argc,
argv, &args, io);
3448 return io_readlines(&args, io);
3456 if (arg->
limit == 0)
3503 prepare_getline_args(
argc,
argv, &args, io);
3504 if (args.
limit == 0)
3519 rb_warn(
"IO#lines is deprecated; use #each_line instead");
3522 return rb_io_each_line(
argc,
argv, io);
3551 while (fptr->
rbuf.len > 0) {
3552 char *p = fptr->
rbuf.ptr + fptr->
rbuf.off++;
3559 }
while (io_fillbuf(fptr) >= 0);
3570 rb_warn(
"IO#bytes is deprecated; use #each_byte instead");
3573 return rb_io_each_byte(io);
3587 make_readconv(fptr, 0);
3590 if (fptr->
cbuf.len) {
3596 if (fptr->
cbuf.len == fptr->
cbuf.capa) {
3602 if (fptr->
cbuf.len == 0) {
3603 clear_readconv(fptr);
3608 fptr->
cbuf.off += 1;
3609 fptr->
cbuf.len -= 1;
3610 if (fptr->
cbuf.len == 0) clear_readconv(fptr);
3619 io_shift_cbuf(fptr, r, &str);
3630 str = io_enc_str(str, fptr);
3636 if (io_fillbuf(fptr) < 0) {
3641 fptr->
rbuf.off += 1;
3642 fptr->
rbuf.len -= 1;
3650 fptr->
rbuf.off += n;
3651 fptr->
rbuf.len -= n;
3658 if (io_fillbuf(fptr) != -1) {
3678 str = io_enc_str(str, fptr);
3709 enc = io_input_encoding(fptr);
3711 while (!
NIL_P(c = io_getc(fptr, enc))) {
3724 rb_warn(
"IO#chars is deprecated; use #each_char instead");
3727 return rb_io_each_char(io);
3747 rb_io_each_codepoint(
VALUE io)
3763 make_readconv(fptr, 0);
3765 if (fptr->
cbuf.len) {
3774 if (fptr->
cbuf.len == fptr->
cbuf.capa) {
3779 clear_readconv(fptr);
3798 c = (
unsigned char)fptr->
cbuf.ptr[fptr->
cbuf.off];
3800 fptr->
cbuf.off += n;
3801 fptr->
cbuf.len -= n;
3806 enc = io_input_encoding(fptr);
3807 while (io_fillbuf(fptr) >= 0) {
3814 fptr->
rbuf.off += n;
3815 fptr->
rbuf.len -= n;
3823 char cbuf[8], *p = cbuf;
3825 if (more >
numberof(cbuf))
goto invalid;
3826 more += n = fptr->
rbuf.len;
3827 if (more >
numberof(cbuf))
goto invalid;
3828 while ((n = (
int)read_buffered_data(p, more, fptr)) > 0 &&
3829 (p += n, (more -= n) > 0)) {
3830 if (io_fillbuf(fptr) < 0)
goto invalid;
3831 if ((n = fptr->
rbuf.len) > more) n = more;
3852 rb_warn(
"IO#codepoints is deprecated; use #each_codepoint instead");
3855 return rb_io_each_codepoint(io);
3880 enc = io_input_encoding(fptr);
3882 return io_getc(fptr, enc);
3900 VALUE c = rb_io_getc(io);
3936 if (io_fillbuf(fptr) < 0) {
3941 c = (
unsigned char)fptr->
rbuf.ptr[fptr->
rbuf.off-1];
3996 io_ungetbyte(b, fptr);
4037 #if SIZEOF_LONG > SIZEOF_INT 4041 make_readconv(fptr, (
int)len);
4042 if (fptr->
cbuf.capa - fptr->
cbuf.len < len)
4044 if (fptr->
cbuf.off < len) {
4047 char, fptr->
cbuf.len);
4050 fptr->
cbuf.off -= (int)len;
4051 fptr->
cbuf.len += (int)len;
4056 io_ungetbyte(c, fptr);
4079 if (isatty(fptr->
fd) == 0)
4084 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) 4107 if (io != write_io) {
4109 if (fptr && 0 <= (fd = fptr->
fd)) {
4116 if (fptr && 0 <= (fd = fptr->
fd)) {
4123 #define rb_io_close_on_exec_p rb_f_notimplement 4126 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) 4156 if (io != write_io) {
4158 if (fptr && 0 <= (fd = fptr->
fd)) {
4161 ret = (ret & ~FD_CLOEXEC) | flag;
4170 if (fptr && 0 <= (fd = fptr->
fd)) {
4173 ret = (ret & ~FD_CLOEXEC) | flag;
4181 #define rb_io_set_close_on_exec rb_f_notimplement 4184 #define FMODE_PREP (1<<16) 4185 #define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP) 4186 #define PREP_STDIO_NAME(f) (RSTRING_PTR((f)->pathv)) 4189 finish_writeconv(
rb_io_t *fptr,
int noalloc)
4191 unsigned char *ds, *
dp, *de;
4194 if (!fptr->
wbuf.ptr) {
4195 unsigned char buf[1024];
4201 de = buf +
sizeof(
buf);
4206 r = rb_write_internal2(fptr->
fd, ds, dp-ds);
4208 r = rb_write_internal(fptr->
fd, ds, dp-ds);
4233 if (fptr->
wbuf.len == fptr->
wbuf.capa) {
4234 if (io_fflush(fptr) < 0)
4238 ds = dp = (
unsigned char *)fptr->
wbuf.ptr + fptr->
wbuf.off + fptr->
wbuf.len;
4239 de = (
unsigned char *)fptr->
wbuf.ptr + fptr->
wbuf.capa;
4241 fptr->
wbuf.len += (int)(dp - ds);
4257 finish_writeconv_sync(
VALUE arg)
4264 nogvl_close(
void *ptr)
4268 return (
void*)(
intptr_t)close(*fd);
4272 maygvl_close(
int fd,
int keepgvl)
4285 nogvl_fclose(
void *ptr)
4289 return (
void*)(
intptr_t)fclose(file);
4293 maygvl_fclose(
FILE *file,
int keepgvl)
4296 return fclose(file);
4302 static void clear_codeconv(
rb_io_t *fptr);
4305 fptr_finalize_flush(
rb_io_t *fptr,
int noraise,
int keepgvl)
4310 int mode = fptr->
mode;
4320 err = finish_writeconv(fptr, noraise);
4323 if (fptr->
wbuf.len) {
4325 if ((
int)io_flush_buffer_sync(fptr) < 0 &&
NIL_P(err))
4329 if (io_fflush(fptr) < 0 &&
NIL_P(err))
4341 else if (stdio_file) {
4344 if ((maygvl_fclose(stdio_file, noraise) < 0) &&
NIL_P(err))
4355 if ((maygvl_close(fd, keepgvl) < 0) &&
NIL_P(err))
4359 if (!
NIL_P(err) && !noraise) {
4368 fptr_finalize(
rb_io_t *fptr,
int noraise)
4370 fptr_finalize_flush(fptr, noraise,
FALSE);
4371 free_io_buffer(&fptr->
rbuf);
4372 free_io_buffer(&fptr->
wbuf);
4373 clear_codeconv(fptr);
4377 rb_io_fptr_cleanup(
rb_io_t *fptr,
int noraise)
4383 fptr_finalize(fptr, noraise);
4403 free_io_buffer(&fptr->
cbuf);
4407 clear_writeconv(
rb_io_t *fptr)
4419 clear_readconv(fptr);
4420 clear_writeconv(fptr);
4426 if (!fptr)
return 0;
4429 rb_io_fptr_cleanup(fptr,
TRUE);
4431 free_io_buffer(&fptr->
rbuf);
4432 free_io_buffer(&fptr->
wbuf);
4433 clear_codeconv(fptr);
4442 size += fptr->
rbuf.capa;
4443 size += fptr->
wbuf.capa;
4444 size += fptr->
cbuf.capa;
4452 # define KEEPGVL TRUE 4454 # define KEEPGVL FALSE 4459 io_close_fptr(
VALUE io)
4468 if (io != write_io) {
4469 write_fptr =
RFILE(write_io)->fptr;
4470 if (write_fptr && 0 <= write_fptr->
fd) {
4471 rb_io_fptr_cleanup(write_fptr,
TRUE);
4475 fptr =
RFILE(io)->fptr;
4476 if (!fptr)
return 0;
4477 if (fptr->
fd < 0)
return 0;
4485 rb_io_fptr_cleanup(fptr,
FALSE);
4490 fptr_waitpid(
rb_io_t *fptr,
int nohang)
4503 rb_io_t *fptr = io_close_fptr(io);
4504 if (fptr) fptr_waitpid(fptr, 0);
4525 rb_io_close_m(
VALUE io)
4527 rb_io_t *fptr = rb_io_get_fptr(io);
4536 io_call_close(
VALUE io)
4545 enum {mesg_len =
sizeof(closed_stream)-1};
4560 rb_rescue2(io_call_close, io, ignore_closed_stream, io,
4585 rb_io_closed(
VALUE io)
4592 if (io != write_io) {
4593 write_fptr =
RFILE(write_io)->fptr;
4594 if (write_fptr && 0 <= write_fptr->
fd) {
4599 fptr = rb_io_get_fptr(io);
4622 rb_io_close_read(
VALUE io)
4628 if (fptr->
fd < 0)
return Qnil;
4642 if (io != write_io) {
4647 RFILE(io)->fptr = wfptr;
4651 rb_io_fptr_cleanup(fptr,
FALSE);
4682 rb_io_close_write(
VALUE io)
4689 if (fptr->
fd < 0)
return Qnil;
4706 if (io != write_io) {
4730 VALUE offset, ptrname;
4735 if (
rb_scan_args(argc, argv,
"11", &offset, &ptrname) == 2) {
4736 whence = interpret_seek_whence(ptrname);
4745 rb_warn(
"sysseek for buffered IO");
4748 pos = lseek(fptr->
fd, pos, whence);
4782 if (fptr->
wbuf.len) {
4783 rb_warn(
"syswrite for buffered IO");
4788 n = rb_write_internal(fptr->
fd, ptr, len);
4816 rb_io_sysread(
int argc,
VALUE *argv,
VALUE io)
4827 shrinkable = io_setstrbuf(&str, ilen);
4828 if (ilen == 0)
return str;
4848 io_setstrbuf(&str, ilen);
4859 io_set_read_length(str, n, shrinkable);
4860 if (n == 0 && ilen > 0) {
4868 #if defined(HAVE_PREAD) || defined(HAVE_PWRITE) 4869 struct prdwr_internal_arg {
4877 #if defined(HAVE_PREAD) 4879 internal_pread_func(
void *arg)
4881 struct prdwr_internal_arg *p = arg;
4882 return (
VALUE)pread(p->fd, p->buf, p->count, p->offset);
4886 pread_internal_call(
VALUE arg)
4888 struct prdwr_internal_arg *p = (
struct prdwr_internal_arg *)arg;
4919 struct prdwr_internal_arg arg;
4926 shrinkable = io_setstrbuf(&str, (
long)arg.count);
4927 if (arg.count == 0)
return str;
4942 io_set_read_length(str, n, shrinkable);
4943 if (n == 0 && arg.count > 0) {
4951 # define rb_io_pread rb_f_notimplement 4954 #if defined(HAVE_PWRITE) 4956 internal_pwrite_func(
void *ptr)
4958 struct prdwr_internal_arg *arg = ptr;
4960 return (
VALUE)pwrite(arg->fd, arg->buf, arg->count, arg->offset);
4986 struct prdwr_internal_arg arg;
5008 # define rb_io_pwrite rb_f_notimplement 5036 io_ascii8bit_binmode(
rb_io_t *fptr)
5054 clear_codeconv(fptr);
5063 io_ascii8bit_binmode(fptr);
5081 rb_io_binmode_m(
VALUE io)
5100 rb_io_binmode_p(
VALUE io)
5108 rb_io_fmode_modestr(
int fmode)
5131 static const char bom_prefix[] =
"bom|";
5132 static const char utf_prefix[] =
"utf-";
5137 io_encname_bom_p(
const char *
name,
long len)
5146 const char *m = modestr, *p =
NULL;
5178 if (io_encname_bom_p(m, p ? (
long)(p - m) : (
long)
strlen(m)))
5208 if (oflags & O_APPEND) {
5211 if (oflags & O_TRUNC) {
5214 if (oflags & O_CREAT) {
5227 rb_io_fmode_oflags(
int fmode)
5268 rb_io_oflags_modestr(
int oflags)
5271 # define MODE_BINARY(a,b) ((oflags & O_BINARY) ? (b) : (a)) 5273 # define MODE_BINARY(a,b) (a) 5275 int accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR);
5276 if (oflags & O_APPEND) {
5277 if (accmode == O_WRONLY) {
5280 if (accmode == O_RDWR) {
5284 switch (oflags & (O_RDONLY|O_WRONLY|O_RDWR)) {
5292 if (oflags & O_TRUNC) {
5307 int default_ext = 0;
5317 else if (intern ==
NULL) {
5323 *enc = (default_ext && intern != ext) ?
NULL : ext;
5333 unsupported_encoding(
const char *name,
rb_encoding *enc)
5335 rb_enc_warn(enc,
"Unsupported encoding %s ignored", name);
5339 parse_mode_enc(
const char *estr,
rb_encoding *estr_enc,
5345 int fmode = fmode_p ? *fmode_p : 0;
5352 len = p ? (p++ - estr) : (
long)
strlen(estr);
5360 rb_enc_warn(estr_enc,
"BOM with non-UTF encoding %s is nonsense", estr);
5361 fmode &= ~FMODE_SETENC_BY_BOM;
5369 memcpy(encname, estr, len);
5370 encname[
len] =
'\0';
5375 if (fmode_p) *fmode_p =
fmode;
5381 unsupported_encoding(estr, estr_enc);
5387 if (*p ==
'-' && *(p+1) ==
'\0') {
5394 unsupported_encoding(p, estr_enc);
5395 else if (!(fmode & FMODE_SETENC_BY_BOM) && (idx2 == idx)) {
5403 rb_io_ext_int_to_encs(ext_enc, int_enc, enc_p, enc2_p, fmode);
5417 if (v !=
Qnil) encoding = v;
5419 if (v !=
Qnil) extenc = v;
5421 if (v !=
Qundef) intenc = v;
5428 encoding, extenc ==
Qundef ?
"internal" :
"external");
5436 if (
NIL_P(intenc)) {
5443 if (*p ==
'-' && *(p+1) ==
'\0') {
5454 if (extencoding == intencoding) {
5458 if (!
NIL_P(encoding)) {
5462 enc_p, enc2_p, fmode_p);
5470 rb_io_ext_int_to_encs(extencoding, intencoding, enc_p, enc2_p, 0);
5480 int fmode = *fmode_p;
5491 if (!(fmode & FMODE_BINMODE) &&
5496 #if !DEFAULT_TEXTMODE 5497 else if (!(ecflags & ECONV_NEWLINE_DECORATOR_MASK)) {
5505 extract_binmode(
VALUE opthash,
int *fmode)
5507 if (!
NIL_P(opthash)) {
5513 if (*fmode & FMODE_BINMODE)
5520 if (*fmode & FMODE_BINMODE)
5522 if (*fmode & FMODE_TEXTMODE)
5528 if ((*fmode & FMODE_BINMODE) && (*fmode & FMODE_TEXTMODE))
5535 int *oflags_p,
int *fmode_p,
convconfig_t *convconfig_p)
5542 int has_enc = 0, has_vmode = 0;
5548 rb_io_ext_int_to_encs(
NULL,
NULL, &enc, &enc2, 0);
5566 oflags = rb_io_fmode_oflags(fmode);
5570 parse_mode_enc(p+1,
rb_enc_get(vmode), &enc, &enc2, &fmode);
5576 rb_io_ext_int_to_encs(e,
NULL, &enc, &enc2, fmode);
5580 if (
NIL_P(opthash)) {
5584 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE 5587 0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
5597 if (!
NIL_P(vmode)) {
5612 extract_binmode(opthash, &fmode);
5613 if (fmode & FMODE_BINMODE) {
5620 #if DEFAULT_TEXTMODE 5621 else if (
NIL_P(vmode)) {
5628 if (!
NIL_P(*vperm_p)) {
5640 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE 5643 0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
5655 validate_enc_binmode(&fmode, ecflags, enc, enc2);
5661 convconfig_p->enc = enc;
5662 convconfig_p->enc2 = enc2;
5663 convconfig_p->ecflags = ecflags;
5664 convconfig_p->ecopts = ecopts;
5674 sysopen_func(
void *ptr)
5702 fd = rb_sysopen_internal(&data);
5706 fd = rb_sysopen_internal(&data);
5723 file = fdopen(fd, modestr);
5730 file = fdopen(fd, modestr);
5735 file = fdopen(fd, modestr);
5739 if (e == 0) e = EINVAL;
5740 #elif defined(__sun) 5741 if (e == 0) e = EMFILE;
5749 if (setvbuf(file,
NULL, _IOFBF, 0) != 0)
5750 rb_warn(
"setvbuf() can't be honoured (fd=%d)", fd);
5758 int t = isatty(fptr->
fd);
5768 io_strip_bom(
VALUE io)
5770 VALUE b1, b2, b3, b4;
5831 io_set_encoding_by_bom(
VALUE io)
5833 int idx = io_strip_bom(io);
5839 rb_io_internal_encoding(io),
Qnil);
5855 rb_io_ext_int_to_encs(
NULL,
NULL, &cc.enc, &cc.enc2, fmode);
5860 validate_enc_binmode(&fmode, convconfig->ecflags,
5861 convconfig->enc, convconfig->enc2);
5865 fptr->
encs = *convconfig;
5868 if (!(oflags & O_TMPFILE)) {
5869 fptr->
pathv = pathv;
5872 fptr->
pathv = pathv;
5874 fptr->
fd = rb_sysopen(pathv, oflags, perm);
5882 rb_file_open_internal(
VALUE io,
VALUE filename,
const char *modestr)
5885 const char *p =
strchr(modestr,
':');
5890 &convconfig.enc, &convconfig.enc2, &fmode);
5897 rb_io_ext_int_to_encs(e,
NULL, &convconfig.enc, &convconfig.enc2, fmode);
5898 convconfig.ecflags = 0;
5899 convconfig.ecopts =
Qnil;
5902 return rb_file_open_generic(io, filename,
5903 rb_io_fmode_oflags(fmode),
5913 return rb_file_open_internal(io_alloc(
rb_cFile), fname, modestr);
5922 #if defined(__CYGWIN__) || !defined(HAVE_WORKING_FORK) 5923 static struct pipe_list {
5925 struct pipe_list *next;
5931 struct pipe_list *
list;
5933 list =
ALLOC(
struct pipe_list);
5935 list->next = pipe_list;
5942 struct pipe_list *
list = pipe_list;
5943 struct pipe_list *tmp;
5945 if (list->fptr == fptr) {
5946 pipe_list = list->next;
5951 while (list->next) {
5952 if (list->next->fptr == fptr) {
5954 list->next = list->next->next;
5962 #if defined (_WIN32) || defined(__CYGWIN__) 5966 struct pipe_list *
list = pipe_list;
5967 struct pipe_list *tmp;
5978 pipe_finalize(
rb_io_t *fptr,
int noraise)
5980 #if !defined(HAVE_WORKING_FORK) && !defined(_WIN32) 5989 fptr_finalize(fptr, noraise);
5991 pipe_del_fptr(fptr);
6026 #define HAVE_SPAWNV 1 6027 #define spawnv(mode, cmd, args) rb_w32_uaspawn((mode), (cmd), (args)) 6028 #define spawn(mode, cmd) rb_w32_uspawn((mode), (cmd), 0) 6031 #if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV) 6041 #ifdef HAVE_WORKING_FORK 6043 popen_redirect(
struct popen_arg *p)
6045 if ((p->modef & FMODE_READABLE) && (p->modef &
FMODE_WRITABLE)) {
6046 close(p->write_pair[1]);
6047 if (p->write_pair[0] != 0) {
6048 dup2(p->write_pair[0], 0);
6049 close(p->write_pair[0]);
6052 if (p->pair[1] != 1) {
6053 dup2(p->pair[1], 1);
6057 else if (p->modef & FMODE_READABLE) {
6059 if (p->pair[1] != 1) {
6060 dup2(p->pair[1], 1);
6066 if (p->pair[0] != 0) {
6067 dup2(p->pair[0], 0);
6073 #if defined(__linux__) 6084 linux_get_maxfd(
void)
6087 char buf[4096], *p, *np, *e;
6090 if (fd == -1)
return -1;
6091 ss = read(fd, buf,
sizeof(buf));
6092 if (ss == -1)
goto err;
6095 while ((
int)
sizeof(
"FDSize:\t0\n")-1 <= e-p &&
6096 (np = memchr(p,
'\n', e-p)) !=
NULL) {
6097 if (
memcmp(p,
"FDSize:",
sizeof(
"FDSize:")-1) == 0) {
6099 p +=
sizeof(
"FDSize:")-1;
6119 #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) 6121 int max = (int)max_file_descriptor;
6124 ret =
fcntl(0, F_MAXFD);
6126 maxhint = max = ret;
6127 # elif defined(__linux__) 6128 ret = linux_get_maxfd();
6135 for (fd = lowfd; fd <= max; fd++) {
6136 if (!
NIL_P(noclose_fds) &&
6143 # define CONTIGUOUS_CLOSED_FDS 20 6145 if (max < fd + CONTIGUOUS_CLOSED_FDS)
6146 max = fd + CONTIGUOUS_CLOSED_FDS;
6153 popen_exec(
void *pp,
char *errmsg,
size_t errmsg_len)
6155 struct popen_arg *p = (
struct popen_arg*)pp;
6161 #if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV) 6163 rb_execarg_fixup_v(
VALUE execarg_obj)
6173 pipe_open(
VALUE execarg_obj,
const char *modestr,
int fmode,
6183 #if defined(HAVE_WORKING_FORK) 6185 char errmsg[80] = {
'\0' };
6187 #if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV) 6189 struct popen_arg arg;
6192 #if defined(HAVE_SPAWNV) 6193 # if defined(HAVE_SPAWNVE) 6194 # define DO_SPAWN(cmd, args, envp) ((args) ? \ 6195 spawnve(P_NOWAIT, (cmd), (args), (envp)) : \ 6196 spawne(P_NOWAIT, (cmd), (envp))) 6198 # define DO_SPAWN(cmd, args, envp) ((args) ? \ 6199 spawnv(P_NOWAIT, (cmd), (args)) : \ 6200 spawn(P_NOWAIT, (cmd))) 6202 # if !defined(HAVE_WORKING_FORK) 6204 # if defined(HAVE_SPAWNVE) 6209 #if !defined(HAVE_WORKING_FORK) 6215 #if !defined(HAVE_WORKING_FORK) 6216 const char *
cmd = 0;
6222 #if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV) 6223 arg.execarg_obj = execarg_obj;
6226 arg.pair[0] = arg.pair[1] = -1;
6227 arg.write_pair[0] = arg.write_pair[1] = -1;
6228 # if !defined(HAVE_WORKING_FORK) 6235 if (
rb_pipe(arg.write_pair) < 0)
6239 close(arg.write_pair[0]);
6240 close(arg.write_pair[1]);
6263 if (!
NIL_P(execarg_obj)) {
6264 rb_protect(rb_execarg_fixup_v, execarg_obj, &state);
6266 if (0 <= arg.write_pair[0]) close(arg.write_pair[0]);
6267 if (0 <= arg.write_pair[1]) close(arg.write_pair[1]);
6268 if (0 <= arg.pair[0]) close(arg.pair[0]);
6269 if (0 <= arg.pair[1]) close(arg.pair[1]);
6274 # if defined(HAVE_WORKING_FORK) 6278 # if defined(HAVE_SPAWNVE) 6281 while ((pid = DO_SPAWN(cmd, args, envp)) == -1) {
6283 switch (e =
errno) {
6285 # if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 6299 # if defined(HAVE_WORKING_FORK) 6303 popen_redirect(&arg);
6315 # if defined(HAVE_WORKING_FORK) 6321 close(arg.write_pair[0]);
6322 close(arg.write_pair[1]);
6324 # if defined(HAVE_WORKING_FORK) 6333 close(arg.write_pair[0]);
6334 write_fd = arg.write_pair[1];
6336 else if (fmode & FMODE_READABLE) {
6346 if (!
NIL_P(execarg_obj)) {
6350 fp = popen(cmd, modestr);
6366 fptr->
encs = *convconfig;
6367 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) 6377 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE 6379 fptr->
encs.
ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
6385 if (0 <= write_fd) {
6386 write_port = io_alloc(
rb_cIO);
6388 write_fptr->
fd = write_fd;
6390 fptr->
mode &= ~FMODE_WRITABLE;
6395 #if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK) 6397 pipe_add_fptr(fptr);
6403 is_popen_fork(
VALUE prog)
6406 #if !defined(HAVE_WORKING_FORK) 6408 "fork() function is unimplemented on this machine");
6417 pipe_open_s(
VALUE prog,
const char *modestr,
int fmode,
6421 VALUE *argv = &prog;
6424 if (!is_popen_fork(prog))
6426 return pipe_open(execarg_obj, modestr, fmode, convconfig);
6430 pipe_close(
VALUE io)
6432 rb_io_t *fptr = io_close_fptr(io);
6528 rb_io_s_popen(
int argc,
VALUE *argv,
VALUE klass)
6530 const char *modestr;
6545 int ex = !
NIL_P(opt);
6553 #if SIZEOF_LONG > SIZEOF_INT 6554 if (len > INT_MAX) {
6564 if (!is_popen_fork(pname))
6567 if (!
NIL_P(execarg_obj)) {
6573 rb_io_extract_modeenc(&pmode, 0, opt, &oflags, &fmode, &convconfig);
6574 modestr = rb_io_oflags_modestr(oflags);
6576 port = pipe_open(execarg_obj, modestr, fmode, &convconfig);
6595 rb_scan_open_args(
int argc,
const VALUE *argv,
6596 VALUE *fname_p,
int *oflags_p,
int *fmode_p,
6599 VALUE opt, fname, vmode, vperm;
6603 argc =
rb_scan_args(argc, argv,
"12:", &fname, &vmode, &vperm, &opt);
6606 rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, convconfig_p);
6617 rb_open_file(
int argc,
const VALUE *argv,
VALUE io)
6624 rb_scan_open_args(argc, argv, &fname, &oflags, &fmode, &convconfig, &perm);
6625 rb_file_open_generic(io, fname, oflags, fmode, &convconfig, perm);
6668 rb_io_s_open(
int argc,
VALUE *argv,
VALUE klass)
6690 rb_io_s_sysopen(
int argc,
VALUE *argv)
6692 VALUE fname, vmode, vperm;
6697 rb_scan_args(argc, argv,
"12", &fname, &vmode, &vperm);
6708 if (
NIL_P(vperm)) perm = 0666;
6712 fd = rb_sysopen(fname, oflags, perm);
6717 check_pipe_command(
VALUE filename_or_command)
6831 rb_f_open(
int argc,
VALUE *argv)
6834 int redirect =
FALSE;
6842 VALUE tmp = argv[0];
6848 VALUE cmd = check_pipe_command(tmp);
6851 return rb_io_s_popen(argc, argv,
rb_cIO);
6864 return rb_io_s_open(argc, argv,
rb_cFile);
6876 rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, &convconfig);
6878 return rb_io_open_generic(filename, oflags, fmode, &convconfig, perm);
6882 rb_io_open_generic(
VALUE filename,
int oflags,
int fmode,
6886 if (!
NIL_P(cmd = check_pipe_command(filename))) {
6887 return pipe_open_s(cmd, rb_io_oflags_modestr(oflags), fmode, convconfig);
6890 return rb_file_open_generic(io_alloc(
rb_cFile), filename,
6891 oflags, fmode, convconfig, perm);
6896 rb_io_open_with_args(
int argc,
const VALUE *argv)
6901 rb_open_file(argc, argv, io);
6916 if (fptr == orig)
return io;
6918 if ((fptr->
stdio_file == stdin && !(orig->
mode & FMODE_READABLE)) ||
6922 "%s can't change access mode from \"%s\" to \"%s\"",
6924 rb_io_fmode_modestr(orig->
mode));
6928 if (io_fflush(fptr) < 0)
6934 if (orig->
mode & FMODE_READABLE) {
6938 if (io_fflush(orig) < 0)
6949 #
if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK)
6950 if (fptr->
finalize == pipe_finalize)
6951 pipe_add_fptr(fptr);
6973 if ((orig->
mode & FMODE_READABLE) && pos >= 0) {
6983 if (fptr->
mode & FMODE_BINMODE) {
7022 rb_io_reopen(
int argc,
VALUE *argv,
VALUE file)
7024 VALUE fname, nmode, opt;
7028 if (
rb_scan_args(argc, argv,
"11:", &fname, &nmode, &opt) == 1) {
7031 return io_reopen(file, tmp);
7037 fptr =
RFILE(file)->fptr;
7046 rb_io_extract_modeenc(&nmode, 0, opt, &oflags, &fmode, &convconfig);
7049 (fptr->
mode & FMODE_READWRITE)) {
7051 "%s can't change access mode from \"%s\" to \"%s\"",
7053 rb_io_fmode_modestr(fmode));
7056 fptr->
encs = convconfig;
7059 oflags = rb_io_fmode_oflags(fptr->
mode);
7062 fptr->
pathv = fname;
7064 fptr->
fd = rb_sysopen(fptr->
pathv, oflags, 0666);
7070 if (io_fflush(fptr) < 0)
7073 fptr->
rbuf.off = fptr->
rbuf.len = 0;
7077 rb_io_oflags_modestr(oflags),
7090 else if (fptr->
stdio_file == stdout && isatty(fptr->
fd)) {
7096 int tmpfd = rb_sysopen(fptr->
pathv, oflags, 0666);
7132 #if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK) 7133 if (fptr->
finalize == pipe_finalize)
7134 pipe_add_fptr(fptr);
7137 fd = ruby_dup(orig->
fd);
7142 if (fptr->
mode & FMODE_BINMODE) {
7147 if (io != write_io) {
7184 rb_f_printf(
int argc,
VALUE *argv)
7188 if (argc == 0)
return Qnil;
7238 for (i=0; i<
argc; i++) {
7275 rb_f_print(
int argc,
const VALUE *argv)
7330 return rb_io_putc(recv, ch);
7344 if (len == 0)
return 0;
7346 return ptr[len - 1] == c;
7348 return rb_enc_ascget(ptr + ((len - 1) / n) * n, ptr + len, &n, enc) == c;
7409 for (i=0; i<
argc; i++) {
7468 rb_f_p_internal(
VALUE arg)
7471 int argc = arg1->
argc;
7476 for (i=0; i<
argc; i++) {
7482 else if (argc > 1) {
7544 rb_obj_display(
int argc,
VALUE *argv,
VALUE self)
7563 if (fwrite(mesg,
sizeof(
char), (
size_t)len, stderr) < (
size_t)len) {
7586 if (isatty(
fileno(stderr))) {
7590 if (fwrite(
RSTRING_PTR(mesg),
sizeof(
char), len, stderr) <
len) {
7605 return isatty(
fileno(stderr));
7622 must_respond_to(id_write, val,
id);
7627 prep_io(
int fd,
int fmode,
VALUE klass,
const char *path)
7630 VALUE io = io_alloc(klass);
7635 if (!io_check_tty(fp)) {
7652 if (path && strcmp(path,
"-")) klass =
rb_cFile;
7657 prep_stdio(
FILE *
f,
int fmode,
VALUE klass,
const char *path)
7664 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE 7665 fptr->
encs.
ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
7666 if (fmode & FMODE_READABLE) {
7679 int oflags = rb_io_fmode_oflags(fptr->
mode);
7695 rb_io_fptr_new(
void)
7705 rb_io_buffer_init(&fp->
wbuf);
7706 rb_io_buffer_init(&fp->
rbuf);
7707 rb_io_buffer_init(&fp->
cbuf);
7729 if (
RFILE(obj)->fptr) {
7732 RFILE(obj)->fptr = 0;
7734 fp = rb_io_fptr_new();
7735 RFILE(obj)->fptr = fp;
7890 rb_io_initialize(
int argc,
VALUE *argv,
VALUE io)
7894 int fd,
fmode, oflags = O_RDONLY;
7897 #if defined(HAVE_FCNTL) && defined(F_GETFL) 7904 argc =
rb_scan_args(argc, argv,
"11:", &fnum, &vmode, &opt);
7905 rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &fmode, &convconfig);
7911 #if defined(HAVE_FCNTL) && defined(F_GETFL) 7912 oflags =
fcntl(fd, F_GETFL);
7918 #if defined(HAVE_FCNTL) && defined(F_GETFL) 7934 fp->
encs = convconfig;
7939 else if (
fileno(stdout) == fd)
7941 else if (
fileno(stderr) == fd)
7975 rb_file_initialize(
int argc,
VALUE *argv,
VALUE io)
7977 if (
RFILE(io)->fptr) {
7980 if (0 < argc && argc < 3) {
7985 return rb_io_initialize(argc, argv, io);
7988 rb_open_file(argc, argv, io);
7995 rb_io_s_new(
int argc,
VALUE *argv,
VALUE klass)
8016 rb_io_s_for_fd(
int argc,
VALUE *argv,
VALUE klass)
8019 rb_io_initialize(argc, argv, io);
8032 rb_io_autoclose_p(
VALUE io)
8057 rb_io_set_autoclose(
VALUE io,
VALUE autoclose)
8061 if (!
RTEST(autoclose))
8069 argf_mark(
void *ptr)
8071 struct argf *p = ptr;
8080 argf_memsize(
const void *ptr)
8082 const struct argf *p = ptr;
8083 size_t size =
sizeof(*p);
8103 argf_alloc(
VALUE klass)
8119 argf_init(&
ARGF, argv);
8174 argf_lineno(
VALUE argf)
8180 argf_forward(
int argc,
VALUE *argv,
VALUE argf)
8185 #define next_argv() argf_next_argv(argf) 8186 #define ARGF_GENERIC_INPUT_P() \ 8187 (ARGF.current_file == rb_stdin && !RB_TYPE_P(ARGF.current_file, T_FILE)) 8188 #define ARGF_FORWARD(argc, argv) do {\ 8189 if (ARGF_GENERIC_INPUT_P())\ 8190 return argf_forward((argc), (argv), argf);\ 8192 #define NEXT_ARGF_FORWARD(argc, argv) do {\ 8193 if (!next_argv()) return Qnil;\ 8194 ARGF_FORWARD((argc), (argv));\ 8198 argf_close(
VALUE argf)
8210 argf_next_argv(
VALUE argf)
8214 int stdout_binmode = 0;
8219 if (fptr->
mode & FMODE_BINMODE)
8223 if (
ARGF.init_p == 0) {
8241 if (
ARGF.next_p == 1) {
8242 if (
ARGF.init_p == 1) argf_close(argf);
8252 rb_warn(
"Can't do inplace edit for stdio; skipping");
8258 int fr = rb_sysopen(filename, O_RDONLY, 0);
8262 #ifndef NO_SAFE_RENAME 8281 #ifdef NO_SAFE_RENAME 8289 fr = rb_sysopen(str, O_RDONLY, 0);
8300 #ifdef NO_SAFE_RENAME 8301 rb_fatal(
"Can't do inplace edit without backup");
8303 if (unlink(fn) < 0) {
8311 fw = rb_sysopen(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
8312 #ifndef NO_SAFE_RENAME 8317 chmod(fn, st.st_mode);
8319 if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) {
8322 err = fchown(fw, st.st_uid, st.st_gid);
8324 err =
chown(fn, st.st_uid, st.st_gid);
8326 if (err &&
getuid() == 0 && st2.st_uid == 0) {
8342 if (!
ARGF.binmode) {
8346 if (!
NIL_P(write_io)) {
8352 if (
ARGF.encs.enc) {
8354 clear_codeconv(fptr);
8357 fptr->
encs.
ecflags &= ~ECONV_NEWLINE_DECORATOR_MASK;
8358 if (!
ARGF.binmode) {
8360 #ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE 8361 fptr->
encs.
ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
8372 else if (
ARGF.next_p == -1) {
8376 rb_warn(
"Can't do inplace edit for stdio");
8380 if (
ARGF.init_p == -1)
ARGF.init_p = 1;
8385 argf_getline(
int argc,
VALUE *argv,
VALUE argf)
8400 line = rb_io_getline(argc, argv,
ARGF.current_file);
8416 argf_lineno_getter(
ID id,
VALUE *var)
8427 ARGF.last_lineno =
ARGF.lineno = n;
8469 return argf_gets(argc, argv, argf);
8497 line = argf_getline(argc, argv, argf);
8509 return rb_f_gets(0, 0, argf);
8542 rb_f_readline(
int argc,
VALUE *argv,
VALUE recv)
8545 return argf_readline(argc, argv, argf);
8569 argf_readline(
int argc,
VALUE *argv,
VALUE argf)
8575 line = argf_gets(argc, argv, argf);
8596 rb_f_readlines(
int argc,
VALUE *argv,
VALUE recv)
8599 return argf_readlines(argc, argv, argf);
8621 argf_readlines(
int argc,
VALUE *argv,
VALUE argf)
8632 lines = rb_io_readlines(argc, argv,
ARGF.current_file);
8671 result = read_all(fptr, remain_size(fptr),
Qnil);
8679 #ifdef HAVE_SYS_SELECT_H 8680 #include <sys/select.h> 8703 if (max < fptr->fd) max = fptr->
fd;
8714 if (!
NIL_P(write)) {
8720 if (max < fptr->fd) max = fptr->
fd;
8727 if (!
NIL_P(except)) {
8734 if (max < fptr->fd) max = fptr->
fd;
8735 if (io != write_io) {
8738 if (max < fptr->fd) max = fptr->
fd;
8753 if (!pending && n == 0)
return Qnil;
8796 else if (io != write_io) {
8815 select_call(
VALUE arg)
8823 select_end(
VALUE arg)
8833 static VALUE sym_normal, sym_sequential, sym_random,
8834 sym_willneed, sym_dontneed, sym_noreuse;
8836 #ifdef HAVE_POSIX_FADVISE 8837 struct io_advise_struct {
8845 io_advise_internal(
void *arg)
8847 struct io_advise_struct *ptr = arg;
8848 return posix_fadvise(ptr->fd, ptr->offset, ptr->len, ptr->advice);
8854 #ifdef POSIX_FADV_NORMAL 8855 if (sym == sym_normal)
8856 return INT2NUM(POSIX_FADV_NORMAL);
8859 #ifdef POSIX_FADV_RANDOM 8860 if (sym == sym_random)
8861 return INT2NUM(POSIX_FADV_RANDOM);
8864 #ifdef POSIX_FADV_SEQUENTIAL 8865 if (sym == sym_sequential)
8866 return INT2NUM(POSIX_FADV_SEQUENTIAL);
8869 #ifdef POSIX_FADV_WILLNEED 8870 if (sym == sym_willneed)
8871 return INT2NUM(POSIX_FADV_WILLNEED);
8874 #ifdef POSIX_FADV_DONTNEED 8875 if (sym == sym_dontneed)
8876 return INT2NUM(POSIX_FADV_DONTNEED);
8879 #ifdef POSIX_FADV_NOREUSE 8880 if (sym == sym_noreuse)
8881 return INT2NUM(POSIX_FADV_NOREUSE);
8891 struct io_advise_struct ias;
8894 num_adv = io_advise_sym_to_const(advice);
8904 ias.advice =
NUM2INT(num_adv);
8905 ias.offset = offset;
8909 if (rv && rv != ENOSYS) {
8913 "(%"PRI_OFFT_PREFIX
"d, " 8914 "%"PRI_OFFT_PREFIX
"d, " 8916 fptr->
pathv, offset, len, advice);
8926 advice_arg_check(
VALUE advice)
8931 if (advice != sym_normal &&
8932 advice != sym_sequential &&
8933 advice != sym_random &&
8934 advice != sym_willneed &&
8935 advice != sym_dontneed &&
8936 advice != sym_noreuse) {
8984 rb_io_advise(
int argc,
VALUE *argv,
VALUE io)
8990 rb_scan_args(argc, argv,
"12", &advice, &offset, &len);
8991 advice_arg_check(advice);
8999 #ifdef HAVE_POSIX_FADVISE 9000 return do_io_advise(fptr, advice, off, l);
9002 ((void)off, (
void)l);
9149 rb_f_select(
int argc,
VALUE *argv,
VALUE obj)
9157 if (
NIL_P(timeout)) {
9171 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) 9173 # define NUM2IOCTLREQ(num) NUM2ULONG(num) 9176 # define NUM2IOCTLREQ(num) NUM2INT(num) 9187 nogvl_ioctl(
void *ptr)
9191 return (
VALUE)
ioctl(arg->fd, arg->cmd, arg->narg);
9195 do_ioctl(
int fd, ioctl_req_t cmd,
long narg)
9210 #define DEFULT_IOCTL_NARG_LEN (256) 9212 #if defined(__linux__) && defined(_IOC_SIZE) 9214 linux_iocparm_len(ioctl_req_t cmd)
9218 if ((cmd & 0xFFFF0000) == 0) {
9223 len = _IOC_SIZE(cmd);
9234 ioctl_narg_len(ioctl_req_t cmd)
9240 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) 9244 len = IOCPARM_LEN(cmd);
9245 #elif defined(__linux__) && defined(_IOC_SIZE) 9246 len = linux_iocparm_len(cmd);
9257 typedef long fcntl_arg_t;
9260 typedef int fcntl_arg_t;
9263 #if defined __native_client__ && !defined __GLIBC__ 9272 fcntl_narg_len(
int cmd)
9279 len =
sizeof(fcntl_arg_t);
9287 #ifdef F_DUPFD_CLOEXEC 9289 len =
sizeof(fcntl_arg_t);
9299 len =
sizeof(fcntl_arg_t);
9309 len =
sizeof(fcntl_arg_t);
9319 len =
sizeof(fcntl_arg_t);
9324 len =
sizeof(
struct f_owner_ex);
9329 len =
sizeof(
struct f_owner_ex);
9334 len =
sizeof(
struct flock);
9339 len =
sizeof(
struct flock);
9344 len =
sizeof(
struct flock);
9364 len =
sizeof(fcntl_arg_t);
9374 len =
sizeof(fcntl_arg_t);
9379 len =
sizeof(fcntl_arg_t);
9392 fcntl_narg_len(
int cmd)
9399 setup_narg(ioctl_req_t cmd,
VALUE *argp,
int io_p)
9410 else if (arg ==
Qtrue) {
9425 len = ioctl_narg_len(cmd);
9427 len = fcntl_narg_len((
int)cmd);
9456 narg = setup_narg(cmd, &arg, 1);
9458 retval = do_ioctl(fptr->
fd, cmd, narg);
9464 if (ptr[slen-1] != 17)
9490 return rb_ioctl(io, req, arg);
9493 #define rb_io_ioctl rb_f_notimplement 9504 nogvl_fcntl(
void *ptr)
9506 struct fcntl_arg *arg = ptr;
9508 #if defined(F_DUPFD) 9512 return (
VALUE)
fcntl(arg->fd, arg->cmd, arg->narg);
9516 do_fcntl(
int fd,
int cmd,
long narg)
9519 struct fcntl_arg arg;
9528 #if defined(F_DUPFD) 9531 #if defined(F_DUPFD_CLOEXEC) 9549 narg = setup_narg(cmd, &arg, 0);
9551 retval = do_fcntl(fptr->
fd, cmd, narg);
9557 if (ptr[slen-1] != 17)
9584 return rb_fcntl(io, req, arg);
9587 #define rb_io_fcntl rb_f_notimplement 9590 #if defined(HAVE_SYSCALL) || defined(HAVE___SYSCALL) 9629 #if SIZEOF_VOIDP == 8 && defined(HAVE___SYSCALL) && SIZEOF_INT != 8 9630 # define SYSCALL __syscall 9631 # define NUM2SYSCALLID(x) NUM2LONG(x) 9632 # define RETVAL2NUM(x) LONG2NUM(x) 9633 # if SIZEOF_LONG == 8 9634 long num, retval = -1;
9635 # elif SIZEOF_LONG_LONG == 8 9636 long long num, retval = -1;
9638 # error ---->> it is asserted that __syscall takes the first argument and returns retval in 64bit signed integer. <<---- 9640 #elif defined(__linux__) 9641 # define SYSCALL syscall 9642 # define NUM2SYSCALLID(x) NUM2LONG(x) 9643 # define RETVAL2NUM(x) LONG2NUM(x) 9651 long num, retval = -1;
9653 # define SYSCALL syscall 9654 # define NUM2SYSCALLID(x) NUM2INT(x) 9655 # define RETVAL2NUM(x) INT2NUM(x) 9656 int num, retval = -1;
9661 rb_warning(
"We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
9668 num = NUM2SYSCALLID(argv[0]); ++
argv;
9669 for (i = argc - 1; i--; ) {
9684 retval = SYSCALL(num);
9687 retval = SYSCALL(num, arg[0]);
9690 retval = SYSCALL(num, arg[0],arg[1]);
9693 retval = SYSCALL(num, arg[0],arg[1],arg[2]);
9696 retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3]);
9699 retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4]);
9702 retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
9705 retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
9711 return RETVAL2NUM(retval);
9713 #undef NUM2SYSCALLID 9717 #define rb_f_syscall rb_f_notimplement 9721 io_new_instance(
VALUE args)
9727 find_encoding(
VALUE v)
9742 enc2 = find_encoding(v1);
9751 enc = find_encoding(v2);
9758 enc = find_encoding(v2);
9770 rb_io_ext_int_to_encs(
NULL,
NULL, &enc, &enc2, 0);
9782 rb_io_ext_int_to_encs(find_encoding(v1),
NULL, &enc, &enc2, 0);
9788 validate_enc_binmode(&fptr->
mode, ecflags, enc, enc2);
9793 clear_codeconv(fptr);
9805 io_encoding_set_v(
VALUE v)
9808 io_encoding_set(arg->
fptr, arg->
v1, arg->
v2, arg->
opt);
9813 pipe_pair_close(
VALUE rw)
9816 return rb_ensure(io_close, rwp[0], io_close, rwp[1]);
9880 rb_io_s_pipe(
int argc,
VALUE *argv,
VALUE klass)
9882 int pipes[2], state;
9890 argc =
rb_scan_args(argc, argv,
"02:", &v1, &v2, &opt);
9927 extract_binmode(opt, &fmode);
9928 #if DEFAULT_TEXTMODE 9929 if ((fptr->
mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
9930 fptr->
mode &= ~FMODE_TEXTMODE;
9933 #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32) 9940 #if DEFAULT_TEXTMODE 9941 if ((fptr2->
mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
9942 fptr2->
mode &= ~FMODE_TEXTMODE;
9986 #if SIZEOF_LONG > SIZEOF_INT 10042 rb_io_s_foreach(
int argc,
VALUE *argv,
VALUE self)
10045 int orig_argc =
argc;
10051 extract_getline_args(argc-1, argv+1, &garg);
10052 open_key_args(argc, argv, opt, &arg);
10054 extract_getline_opts(opt, &garg);
10055 check_getline_args(&garg.
rs, &garg.
limit, garg.
io = arg.
io);
10062 return io_readlines(arg, arg->
io);
10093 rb_io_s_readlines(
int argc,
VALUE *argv,
VALUE io)
10100 extract_getline_args(argc-1, argv+1, &garg);
10101 open_key_args(argc, argv, opt, &arg);
10103 extract_getline_opts(opt, &garg);
10104 check_getline_args(&garg.
rs, &garg.
limit, garg.
io = arg.
io);
10111 return io_read(arg->
argc, arg->
argv, arg->
io);
10121 seek_before_access(
VALUE argp)
10171 rb_io_s_read(
int argc,
VALUE *argv,
VALUE io)
10177 open_key_args(argc, argv, opt, &arg);
10179 if (!
NIL_P(offset)) {
10210 rb_io_s_binread(
int argc,
VALUE *argv,
VALUE io)
10226 arg.
io = rb_io_open_generic(argv[0], oflags, fmode, &convconfig, 0);
10229 arg.
argc = (argc > 1) ? 1 : 0;
10230 if (!
NIL_P(offset)) {
10252 io_s_write(
int argc,
VALUE *argv,
int binary)
10265 int mode = O_WRONLY|O_CREAT;
10269 if (
NIL_P(offset)) mode |= O_TRUNC;
10272 open_key_args(argc,argv,opt,&arg);
10275 if (binary) rb_io_binmode_m(arg.
io);
10279 if (!
NIL_P(offset)) {
10344 rb_io_s_write(
int argc,
VALUE *argv,
VALUE io)
10346 return io_s_write(argc, argv, 0);
10359 rb_io_s_binwrite(
int argc,
VALUE *argv,
VALUE io)
10361 return io_s_write(argc, argv, 1);
10383 exec_interrupts(
void *arg)
10400 #if defined(ERESTART) 10415 #if defined(HAVE_POLL) && defined(__linux__) 10416 # define USE_POLL 1 10417 # define IOWAIT_SYSCALL "poll" 10419 # define IOWAIT_SYSCALL "select" 10420 # define USE_POLL 0 10425 nogvl_wait_for_single_fd(
int fd,
short events)
10430 fds.events = events;
10432 return poll(&fds, 1, -1);
10445 ret = nogvl_wait_for_single_fd(stp->
src_fd, POLLIN);
10447 }
while (ret == -1 && maygvl_copy_stream_continue_p(has_gvl, stp));
10475 }
while (ret == -1 && maygvl_copy_stream_continue_p(has_gvl, stp));
10493 ret = nogvl_wait_for_single_fd(stp->
dst_fd, POLLOUT);
10499 }
while (ret == -1 && maygvl_copy_stream_continue_p(0, stp));
10509 #if defined __linux__ && defined __NR_copy_file_range 10510 # define USE_COPY_FILE_RANGE 10513 #ifdef USE_COPY_FILE_RANGE 10516 simple_copy_file_range(
int in_fd,
off_t *in_offset,
int out_fd,
off_t *out_offset,
size_t count,
unsigned int flags)
10518 return syscall(__NR_copy_file_range, in_fd, in_offset, out_fd, out_offset, count, flags);
10524 struct stat src_stat, dst_stat;
10528 off_t copy_length, src_offset, *src_offset_ptr;
10536 if (!
S_ISREG(src_stat.st_mode))
10547 if (src_offset != (
off_t)-1) {
10548 src_offset_ptr = &src_offset;
10551 src_offset_ptr =
NULL;
10555 if (copy_length == (
off_t)-1) {
10556 if (src_offset == (
off_t)-1) {
10557 off_t current_offset;
10565 copy_length = src_stat.st_size - current_offset;
10568 copy_length = src_stat.st_size - src_offset;
10572 retry_copy_file_range:
10573 # if SIZEOF_OFF_T > SIZEOF_SIZE_T 10577 ss = (ssize_t)copy_length;
10579 ss = simple_copy_file_range(stp->
src_fd, src_offset_ptr, stp->
dst_fd,
NULL, ss, 0);
10583 if (0 < copy_length) {
10584 goto retry_copy_file_range;
10588 if (maygvl_copy_stream_continue_p(0, stp)) {
10589 goto retry_copy_file_range;
10601 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 10604 if (nogvl_copy_stream_wait_write(stp) == -1)
10606 goto retry_copy_file_range;
10608 stp->
syserr =
"copy_file_range";
10616 #ifdef HAVE_SENDFILE 10619 # define USE_SENDFILE 10621 # ifdef HAVE_SYS_SENDFILE_H 10622 # include <sys/sendfile.h> 10626 simple_sendfile(
int out_fd,
int in_fd,
off_t *offset,
off_t count)
10628 return sendfile(out_fd, in_fd, offset, (
size_t)count);
10631 # elif 0 || defined(__APPLE__) 10635 # define USE_SENDFILE 10638 simple_sendfile(
int out_fd,
int in_fd,
off_t *offset,
off_t count)
10644 r = sendfile(in_fd, out_fd, pos, &count,
NULL, 0);
10647 r = sendfile(in_fd, out_fd, pos, (
size_t)count,
NULL, &sbytes, 0);
10649 if (r != 0 && sbytes == 0)
return -1;
10656 return (ssize_t)sbytes;
10663 #ifdef USE_SENDFILE 10667 struct stat src_stat, dst_stat;
10681 if (!
S_ISREG(src_stat.st_mode))
10691 if ((dst_stat.st_mode & S_IFMT) != S_IFSOCK)
10696 use_pread = src_offset != (
off_t)-1;
10699 if (copy_length == (
off_t)-1) {
10701 copy_length = src_stat.st_size - src_offset;
10711 copy_length = src_stat.st_size - cur;
10716 # if SIZEOF_OFF_T > SIZEOF_SIZE_T 10720 ss = (ssize_t)copy_length;
10723 ss = simple_sendfile(stp->
dst_fd, stp->
src_fd, &src_offset, ss);
10731 if (0 < copy_length) {
10732 goto retry_sendfile;
10736 if (maygvl_copy_stream_continue_p(0, stp))
10737 goto retry_sendfile;
10745 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 10756 if (maygvl_copy_stream_wait_read(0, stp) == -1)
10759 if (nogvl_copy_stream_wait_write(stp) == -1)
10761 goto retry_sendfile;
10763 stp->
syserr =
"sendfile";
10772 maygvl_read(
int has_gvl,
int fd,
void *buf,
size_t count)
10775 return rb_read_internal(fd, buf, count);
10777 return read(fd, buf, count);
10785 if (offset == (
off_t)-1) {
10786 ss = maygvl_read(has_gvl, stp->
src_fd, buf, len);
10790 ss = pread(stp->
src_fd, buf, len, offset);
10800 if (maygvl_copy_stream_continue_p(has_gvl, stp))
10804 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 10807 if (maygvl_copy_stream_wait_read(has_gvl, stp) == -1)
10816 stp->
syserr = offset == (
off_t)-1 ?
"read" :
"pread";
10829 ss = write(stp->
dst_fd, buf+off, len);
10831 if (maygvl_copy_stream_continue_p(0, stp))
10834 if (nogvl_copy_stream_wait_write(stp) == -1)
10862 use_eof = copy_length == (
off_t)-1;
10864 use_pread = src_offset != (
off_t)-1;
10875 src_offset = (
off_t)-1;
10879 while (use_eof || 0 < copy_length) {
10880 if (!use_eof && copy_length < (
off_t)
sizeof(
buf)) {
10881 len = (size_t)copy_length;
10887 ss = maygvl_copy_stream_read(0, stp, buf, len, src_offset);
10892 ss = maygvl_copy_stream_read(0, stp, buf, len, (
off_t)-1);
10897 ret = nogvl_copy_stream_write(stp, buf, ss);
10907 nogvl_copy_stream_func(
void *arg)
10910 #ifdef USE_SENDFILE 10914 #ifdef USE_COPY_FILE_RANGE 10915 ret = nogvl_copy_file_range(stp);
10920 #ifdef USE_SENDFILE 10921 ret = nogvl_copy_stream_sendfile(stp);
10926 nogvl_copy_stream_read_write(stp);
10928 #ifdef USE_SENDFILE 10935 copy_stream_fallback_body(
VALUE arg)
10938 const int buflen = 16*1024;
10943 ID read_method = id_readpartial;
10945 if (stp->
src_fd == -1) {
10947 read_method = id_read;
10960 l = buflen < rest ? buflen : (long)rest;
10962 if (stp->
src_fd == -1) {
10965 if (read_method == id_read &&
NIL_P(rc))
10971 ss = maygvl_copy_stream_read(1, stp,
RSTRING_PTR(buf), l, off);
10977 if (off != (
off_t)-1)
10982 stp->
total += numwrote;
10984 if (read_method == id_read &&
RSTRING_LEN(buf) == 0) {
11005 copy_stream_body(
VALUE arg)
11009 rb_io_t *src_fptr = 0, *dst_fptr = 0;
11011 const int common_oflags = 0
11021 if (src_io == argf ||
11029 if (!
NIL_P(tmp_io)) {
11036 args[1] =
INT2NUM(O_RDONLY|common_oflags);
11043 src_fd = src_fptr->
fd;
11047 if (dst_io == argf ||
11055 if (!
NIL_P(tmp_io)) {
11062 args[1] =
INT2NUM(O_WRONLY|O_CREAT|O_TRUNC|common_oflags);
11074 dst_fd = dst_fptr->fd;
11083 io_ascii8bit_binmode(dst_fptr);
11086 size_t len = src_fptr->
rbuf.len;
11093 read_buffered_data(
RSTRING_PTR(str), len, src_fptr);
11105 if (dst_fptr && io_fflush(dst_fptr) < 0) {
11112 if (src_fd == -1 || dst_fd == -1) {
11113 return copy_stream_fallback(stp);
11124 copy_stream_finalize(
VALUE arg)
11128 rb_io_close_m(stp->
src);
11131 rb_io_close_m(stp->
dst);
11177 rb_io_s_copy_stream(
int argc,
VALUE *argv,
VALUE io)
11184 rb_scan_args(argc, argv,
"22", &src, &dst, &length, &src_offset);
11194 if (
NIL_P(src_offset))
11214 rb_io_external_encoding(
VALUE io)
11239 rb_io_internal_encoding(
VALUE io)
11268 rb_io_set_encoding(
int argc,
VALUE *argv,
VALUE io)
11274 return rb_funcallv(io, id_set_encoding, argc, argv);
11277 argc =
rb_scan_args(argc, argv,
"11:", &v1, &v2, &opt);
11279 io_encoding_set(fptr, v1, v2, opt);
11288 rb_io_set_encoding(1, &val,
rb_stdin);
11289 rb_io_set_encoding(1, &val,
rb_stdout);
11290 rb_io_set_encoding(1, &val,
rb_stderr);
11294 global_argf_p(
VALUE arg)
11296 return arg == argf;
11316 argf_external_encoding(
VALUE argf)
11338 argf_internal_encoding(
VALUE argf)
11378 argf_set_encoding(
int argc,
VALUE *argv,
VALUE argf)
11385 rb_io_set_encoding(argc, argv,
ARGF.current_file);
11404 argf_tell(
VALUE argf)
11410 return rb_io_tell(
ARGF.current_file);
11421 argf_seek_m(
int argc,
VALUE *argv,
VALUE argf)
11427 return rb_io_seek_m(argc, argv,
ARGF.current_file);
11448 return rb_io_set_pos(
ARGF.current_file, offset);
11464 argf_rewind(
VALUE argf)
11473 old_lineno =
RFILE(
ARGF.current_file)->fptr->lineno;
11474 ret = rb_io_rewind(
ARGF.current_file);
11475 if (!global_argf_p(argf)) {
11476 ARGF.last_lineno =
ARGF.lineno -= old_lineno;
11492 argf_fileno(
VALUE argf)
11498 return rb_io_fileno(
ARGF.current_file);
11514 argf_to_io(
VALUE argf)
11518 return ARGF.current_file;
11540 argf_eof(
VALUE argf)
11603 argf_read(
int argc,
VALUE *argv,
VALUE argf)
11605 VALUE tmp, str, length;
11609 if (!
NIL_P(length)) {
11623 tmp = argf_forward(argc, argv, argf);
11626 tmp = io_read(argc, argv,
ARGF.current_file);
11628 if (
NIL_P(str)) str = tmp;
11631 if (
ARGF.next_p != -1) {
11637 else if (argc >= 1) {
11655 argf_forward_call(
VALUE arg)
11686 argf_readpartial(
int argc,
VALUE *argv,
VALUE argf)
11688 return argf_getpartial(argc, argv, argf,
Qnil, 0);
11700 argf_read_nonblock(
int argc,
VALUE *argv,
VALUE argf)
11709 return argf_getpartial(argc, argv, argf, opts, 1);
11713 argf_getpartial(
int argc,
VALUE *argv,
VALUE argf,
VALUE opts,
int nonblock)
11715 VALUE tmp, str, length;
11738 tmp = io_getpartial(argc, argv,
ARGF.current_file, opts, nonblock);
11741 if (
ARGF.next_p == -1) {
11742 return io_nonblock_eof(opts);
11747 return io_nonblock_eof(opts);
11780 argf_getc(
VALUE argf)
11790 ch = rb_io_getc(
ARGF.current_file);
11820 argf_getbyte(
VALUE argf)
11860 argf_readchar(
VALUE argf)
11870 ch = rb_io_getc(
ARGF.current_file);
11900 argf_readbyte(
VALUE argf)
11905 c = argf_getbyte(argf);
11912 #define FOREACH_ARGF() while (next_argv()) 11917 const VALUE current =
ARGF.current_file;
11919 if (
ARGF.init_p == -1 || current !=
ARGF.current_file) {
11926 argf_block_call(
ID mid,
int argc,
VALUE *argv,
VALUE argf)
11935 if (!global_argf_p(argf)) {
11938 return argf_block_call_i(i, argf, argc, argv, blockarg);
11942 argf_block_call_line(
ID mid,
int argc,
VALUE *argv,
VALUE argf)
11981 argf_each_line(
int argc,
VALUE *argv,
VALUE argf)
11985 argf_block_call_line(
rb_intern(
"each_line"), argc, argv, argf);
11995 argf_lines(
int argc,
VALUE *argv,
VALUE argf)
11997 rb_warn(
"ARGF#lines is deprecated; use #each_line instead");
12000 return argf_each_line(argc, argv, argf);
12028 argf_each_byte(
VALUE argf)
12032 argf_block_call(
rb_intern(
"each_byte"), 0, 0, argf);
12042 argf_bytes(
VALUE argf)
12044 rb_warn(
"ARGF#bytes is deprecated; use #each_byte instead");
12047 return argf_each_byte(argf);
12067 argf_each_char(
VALUE argf)
12071 argf_block_call(
rb_intern(
"each_char"), 0, 0, argf);
12081 argf_chars(
VALUE argf)
12083 rb_warn(
"ARGF#chars is deprecated; use #each_char instead");
12086 return argf_each_char(argf);
12106 argf_each_codepoint(
VALUE argf)
12110 argf_block_call(
rb_intern(
"each_codepoint"), 0, 0, argf);
12120 argf_codepoints(
VALUE argf)
12122 rb_warn(
"ARGF#codepoints is deprecated; use #each_codepoint instead");
12125 return argf_each_codepoint(argf);
12151 argf_filename(
VALUE argf)
12154 return ARGF.filename;
12158 argf_filename_getter(
ID id,
VALUE *var)
12160 return argf_filename(*var);
12182 argf_file(
VALUE argf)
12185 return ARGF.current_file;
12200 argf_binmode_m(
VALUE argf)
12223 argf_binmode_p(
VALUE argf)
12243 argf_skip(
VALUE argf)
12245 if (
ARGF.init_p &&
ARGF.next_p == 0) {
12270 argf_close_m(
VALUE argf)
12274 if (
ARGF.next_p != -1) {
12289 argf_closed(
VALUE argf)
12293 return rb_io_closed(
ARGF.current_file);
12303 argf_to_s(
VALUE argf)
12317 argf_inplace_mode_get(
VALUE argf)
12327 return argf_inplace_mode_get(*var);
12351 argf_inplace_mode_set(
VALUE argf,
VALUE val)
12371 argf_inplace_mode_set(*var, val);
12401 argf_argv(
VALUE argf)
12407 argf_argv_getter(
ID id,
VALUE *var)
12409 return argf_argv(*var);
12426 argf_write_io(
VALUE argf)
12462 #if EAGAIN != EWOULDBLOCK 12479 #if EAGAIN != EWOULDBLOCK 12492 rb_bug(
"invalid read/write type passed to rb_readwrite_sys_fail: %d", writable);
12655 #define rb_intern(str) rb_intern_const(str) 12659 #include <sys/cygwin.h> 12660 static struct __cygwin_perfile pf[] =
12668 cygwin_internal(CW_PERFILE, pf);
12678 id_readpartial =
rb_intern(
"readpartial");
12679 id_set_encoding =
rb_intern(
"set_encoding");
12708 #if EAGAIN == EWOULDBLOCK 12709 rb_eEWOULDBLOCKWaitReadable = rb_eEAGAINWaitReadable;
12712 rb_eEWOULDBLOCKWaitWritable = rb_eEAGAINWaitWritable;
12868 rb_stdin = prep_stdio(stdin, FMODE_READABLE,
rb_cIO,
"<STDIN>");
12955 rb_define_method(rb_cARGF,
"external_encoding", argf_external_encoding, 0);
12956 rb_define_method(rb_cARGF,
"internal_encoding", argf_internal_encoding, 0);
12977 #if defined (_WIN32) || defined(__CYGWIN__) 12978 atexit(pipe_atexit);
#define STRNCASECMP(s1, s2, n)
void rb_define_global_const(const char *, VALUE)
struct timeval rb_time_interval(VALUE num)
void rb_define_readonly_variable(const char *, const VALUE *)
unsigned long ruby_strtoul(const char *str, char **endptr, int base)
void rb_fatal(const char *fmt,...)
VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags)
void rb_execarg_setenv(VALUE execarg_obj, VALUE env)
void rb_thread_schedule(void)
const char * rb_econv_asciicompat_encoding(const char *encname)
VALUE rb_io_getbyte(VALUE io)
int rb_io_wait_writable(int f)
#define MBCLEN_CHARFOUND_P(ret)
void rb_thread_atfork(void)
#define ECONV_NEWLINE_DECORATOR_WRITE_MASK
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
void rb_warn(const char *fmt,...)
void rb_bug(const char *fmt,...)
VALUE rb_ary_entry(VALUE ary, long offset)
#define MBCLEN_CHARFOUND_LEN(ret)
void rb_syserr_fail(int e, const char *mesg)
#define RUBY_TYPED_FREE_IMMEDIATELY
long rb_str_coderange_scan_restartable(const char *, const char *, rb_encoding *, int *)
size_t strlen(const char *)
void rb_readwrite_sys_fail(enum rb_io_wait_readwrite writable, const char *mesg)
void rb_io_check_writable(rb_io_t *fptr)
int rb_io_modestr_fmode(const char *modestr)
VALUE rb_file_open_str(VALUE fname, const char *modestr)
void rb_define_virtual_variable(const char *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
VALUE rb_hash_dup(VALUE hash)
void rb_mod_sys_fail_str(VALUE mod, VALUE mesg)
VALUE rb_check_to_int(VALUE)
Tries to convert val into Integer.
#define ENCINDEX_UTF_16LE
void rb_str_tmp_frozen_release(VALUE str, VALUE tmp)
VALUE rb_io_eof(VALUE io)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
void rb_syserr_fail_str(int e, VALUE mesg)
char * rb_execarg_commandline(const struct rb_execarg *eargp, VALUE *prog)
int rb_block_given_p(void)
Determines if the current method is given a block.
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
int rb_w32_set_nonblock(int)
VALUE rb_f_sprintf(int, const VALUE *)
void rb_io_set_nonblock(rb_io_t *fptr)
VALUE rb_fstring_cstr(const char *str)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_str_cat(VALUE, const char *, long)
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
#define ARGF_FORWARD(argc, argv)
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
VALUE rb_io_binmode(VALUE io)
int rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char *errmsg, size_t errmsg_buflen)
#define OBJ_INIT_COPY(obj, orig)
#define ENC_CODERANGE_SET(obj, cr)
#define READ_DATA_PENDING_COUNT(fptr)
VALUE rb_ary_shift(VALUE ary)
int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen)
#define ECONV_ERROR_HANDLER_MASK
void * rb_thread_call_without_gvl2(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
rb_encoding * rb_to_encoding(VALUE enc)
void rb_fd_fix_cloexec(int fd)
void rb_econv_close(rb_econv_t *ec)
VALUE rb_str_unlocktmp(VALUE)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
SOCKET rb_w32_get_osfhandle(int)
rb_encoding * rb_default_internal_encoding(void)
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
VALUE rb_ary_push(VALUE ary, VALUE item)
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
int rb_stderr_tty_p(void)
VALUE rb_ary_tmp_new(long capa)
int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *)
void ruby_sized_xfree(void *x, size_t size)
rb_pid_t rb_fork_ruby(int *status)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
#define ENCINDEX_UTF_16BE
VALUE rb_str_locktmp_ensure(VALUE str, VALUE(*func)(VALUE), VALUE arg)
void rb_str_set_len(VALUE, long)
int writeconv_pre_ecflags
#define RBASIC_SET_CLASS(obj, cls)
int rb_enc_str_coderange(VALUE)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
int rb_cloexec_dup2(int oldfd, int newfd)
#define SET_BINARY_MODE_WITH_SEEK_CUR(fptr)
VALUE rb_obj_dup(VALUE)
call-seq: obj.dup -> an_object
int writeconv_initialized
#define RSTRING_GETMEM(str, ptrvar, lenvar)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
VALUE rb_ary_clear(VALUE ary)
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
#define NEED_WRITECONV(fptr)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
int rb_io_modestr_oflags(const char *modestr)
VALUE rb_execarg_new(int argc, const VALUE *argv, int accept_shell)
#define ENCODING_MAXNAMELEN
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
void rb_mutex_allow_trap(VALUE self, int val)
void rb_include_module(VALUE klass, VALUE module)
#define MORE_CHAR_FINISHED
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
int rb_notify_fd_close(int fd)
void rb_gc_mark(VALUE ptr)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
void rb_io_check_initialized(rb_io_t *fptr)
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
An equivalent to ensure clause.
void rb_gc_force_recycle(VALUE obj)
VALUE writeconv_pre_ecopts
void rb_update_max_fd(int fd)
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
RUBY_FUNC_EXPORTED size_t rb_io_memsize(const rb_io_t *fptr)
#define GetOpenFile(obj, fp)
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
An equivalent of rescue clause.
VALUE rb_io_ascii8bit_binmode(VALUE io)
#define ENC_CODERANGE_7BIT
RUBY_EXTERN void * memmove(void *, const void *, size_t)
int rb_gc_for_fd(int err)
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
VALUE rb_io_write(VALUE io, VALUE str)
VALUE rb_str_buf_cat(VALUE, const char *, long)
rb_io_t * rb_io_make_open_file(VALUE obj)
#define NEWOBJ_OF(obj, type, klass, flags)
#define rb_fd_isset(n, f)
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
VALUE rb_io_gets_internal(VALUE io)
#define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags)
#define rb_io_set_close_on_exec
VALUE rb_io_close(VALUE io)
VALUE rb_io_flush_raw(VALUE io, int sync)
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
#define RB_TYPE_P(obj, type)
int rb_thread_fd_writable(int)
VALUE rb_econv_make_exception(rb_econv_t *ec)
#define MEMZERO(p, type, n)
void rb_econv_check_error(rb_econv_t *ec)
VALUE rb_lastline_get(void)
int rb_to_encoding_index(VALUE enc)
rb_encoding * rb_default_external_encoding(void)
void rb_str_setter(VALUE, ID, VALUE *)
void rb_maygvl_fd_fix_cloexec(int fd)
void rb_thread_sleep(int)
struct rb_execarg * rb_execarg_get(VALUE execarg_obj)
#define ECONV_NEWLINE_DECORATOR_READ_MASK
VALUE rb_class_name(VALUE)
VALUE rb_str_chomp_string(VALUE str, VALUE chomp)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
void rb_io_unbuffered(rb_io_t *fptr)
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
void rb_write_error2(const char *mesg, long len)
VALUE rb_str_encode_ospath(VALUE path)
VALUE rb_str_substr(VALUE, long, long)
RUBY_EXTERN VALUE rb_cObject
#define PREP_STDIO_NAME(f)
#define FMODE_SETENC_BY_BOM
#define MBCLEN_NEEDMORE_P(ret)
FILE * rb_io_stdio_file(rb_io_t *fptr)
int rb_io_oflags_fmode(int oflags)
VALUE rb_str_cat2(VALUE, const char *)
VALUE rb_obj_as_string(VALUE)
#define ECONV_STATEFUL_DECORATOR_MASK
rb_econv_t * rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts)
VALUE rb_io_get_write_io(VALUE io)
VALUE rb_io_print(int argc, const VALUE *argv, VALUE out)
VALUE rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash)
#define ARGF_GENERIC_INPUT_P()
#define ECONV_PARTIAL_INPUT
struct rb_execarg::@81::@83 cmd
VALUE rb_io_ungetbyte(VALUE io, VALUE b)
VALUE rb_any_to_s(VALUE)
call-seq: obj.to_s -> string
#define ECONV_AFTER_OUTPUT
RUBY_EXTERN VALUE rb_mKernel
VALUE rb_thread_current(void)
VALUE rb_check_to_integer(VALUE, const char *)
Tries to convert val into Integer.
int rb_cloexec_fcntl_dupfd(int fd, int minfd)
VALUE rb_io_flush(VALUE io)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
const char * ruby_get_inplace_mode(void)
int chown(const char *, int, int)
#define ECONV_DEFAULT_NEWLINE_DECORATOR
VALUE rb_mutex_synchronize(VALUE mutex, VALUE(*func)(VALUE arg), VALUE arg)
#define MODE_BINARY(a, b)
rb_pid_t rb_fork_async_signal_safe(int *status, int(*chfunc)(void *, char *, size_t), void *charg, VALUE fds, char *errmsg, size_t errmsg_buflen)
void rb_define_const(VALUE, const char *, VALUE)
int rb_io_wait_readable(int f)
rb_atomic_t cnt[RUBY_NSIG]
VALUE rb_io_check_io(VALUE io)
void rb_lastline_set(VALUE)
#define MBCLEN_NEEDMORE_LEN(ret)
struct rb_io_t::rb_io_enc_t encs
void rb_notimplement(void)
#define NUM2IOCTLREQ(num)
struct rb_execarg::@81::@82 sh
#define READ_DATA_PENDING(fptr)
VALUE writeconv_asciicompat
#define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr)
void rb_gc_register_mark_object(VALUE obj)
VALUE rb_io_get_io(VALUE io)
#define RUBY_FUNC_EXPORTED
union rb_execarg::@81 invoke
#define ENC_CODERANGE_BROKEN
#define rb_enc_codepoint(p, e, enc)
#define rb_enc_mbminlen(enc)
VALUE rb_io_gets(VALUE io)
int rb_cloexec_dup(int oldfd)
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
#define ENC_CODERANGE_VALID
#define ATOMIC_CAS(var, oldval, newval)
#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n)
VALUE rb_str_resize(VALUE, long)
void rb_sys_fail(const char *mesg)
rb_encoding * rb_find_encoding(VALUE enc)
int rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc)
#define NEXT_ARGF_FORWARD(argc, argv)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_cloexec_pipe(int fildes[2])
void ruby_set_inplace_mode(const char *suffix)
#define RARRAY_CONST_PTR(a)
VALUE rb_io_puts(int argc, const VALUE *argv, VALUE out)
VALUE rb_obj_freeze(VALUE)
call-seq: obj.freeze -> obj
void rb_last_status_clear(void)
VALUE rb_sprintf(const char *format,...)
void rb_execarg_parent_start(VALUE execarg_obj)
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
#define IO_RBUF_CAPA_FOR(fptr)
void rb_gvar_readonly_setter(VALUE v, ID id, void *d, struct rb_global_variable *g)
#define NEED_READCONV(fptr)
void rb_last_status_set(int status, rb_pid_t pid)
#define MEMMOVE(p1, p2, type, n)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
void rb_write_error_str(VALUE mesg)
void rb_str_modify_expand(VALUE, long)
void rb_thread_execute_interrupts(VALUE th)
VALUE rb_ivar_set(VALUE, ID, VALUE)
VALUE rb_check_hash_type(VALUE hash)
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_assoc_new(VALUE car, VALUE cdr)
void rb_thread_wait_fd(int)
rb_encoding * rb_usascii_encoding(void)
VALUE tied_io_for_writing
#define RUBY_METHOD_FUNC(func)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
VALUE rb_io_printf(int argc, const VALUE *argv, VALUE out)
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite writable, int n, const char *mesg)
size_t rb_econv_memsize(rb_econv_t *)
VALUE rb_eSystemCallError
char * strchr(char *, char)
#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr)
int rb_utf8_encindex(void)
#define ECONV_NEWLINE_DECORATOR_MASK
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
void rb_io_synchronized(rb_io_t *fptr)
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
#define rb_enc_asciicompat(enc)
VALUE rb_str_new_cstr(const char *)
int memcmp(const void *s1, const void *s2, size_t len)
VALUE rb_uninterruptible(VALUE(*b_proc)(ANYARGS), VALUE data)
struct rb_io_buffer_t rb_io_buffer_t
int rb_reserved_fd_p(int fd)
void rb_define_hooked_variable(const char *, VALUE *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
#define READ_DATA_BUFFERED(fptr)
#define rb_io_close_on_exec_p
int rb_respond_to(VALUE, ID)
int rb_thread_to_be_killed(VALUE thread)
register unsigned int len
VALUE rb_define_module_under(VALUE outer, const char *name)
#define StringValueCStr(v)
int rb_str_end_with_asciichar(VALUE str, int c)
void rb_iter_break_value(VALUE val)
int rb_econv_putbackable(rb_econv_t *ec)
void rb_str_modify(VALUE)
#define ENCODING_GET(obj)
rb_encoding * rb_enc_get(VALUE obj)
void rb_insecure_operation(void)
VALUE rb_yield_values2(int n, const VALUE *argv)
int rb_freopen(VALUE fname, const char *mode, FILE *file)
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
#define MBCLEN_INVALID_P(ret)
#define RARRAY_AREF(a, i)
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)
int rb_io_fptr_finalize(rb_io_t *fptr)
VALUE rb_io_fdopen(int fd, int oflags, const char *path)
VALUE rb_str_buf_cat_ascii(VALUE, const char *)
VALUE rb_check_array_type(VALUE ary)
RUBY_SYMBOL_EXPORT_BEGIN void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
VALUE rb_hash_aref(VALUE hash, VALUE key)
void rb_error_arity(int argc, int min, int max)
ID rb_frame_this_func(void)
The original name of the current method.
#define rb_fd_select(n, rfds, wfds, efds, timeout)
VALUE rb_str_catf(VALUE str, const char *format,...)
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, const VALUE *argv)
long rb_w32_write_console(uintptr_t, int)
VALUE rb_check_string_type(VALUE)
#define is_socket(fd, path)
RUBY_EXTERN char * strerror(int)
#define ARGVSTR2ARGV(argv_str)
void rb_thread_check_ints(void)
void rb_warning(const char *fmt,...)
VALUE rb_str_locktmp(VALUE)
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
struct rb_encoding_entry * list
size_t rb_str_capacity(VALUE str)
int rb_method_basic_definition_p(VALUE, ID)
void rb_define_variable(const char *, VALUE *)
void rb_io_check_readable(rb_io_t *fptr)
FILE * rb_fdopen(int fd, const char *modestr)
void(* finalize)(struct rb_io_t *, int)
#define TypedData_Make_Struct(klass, type, data_type, sval)
#define rb_enc_left_char_head(s, p, e, enc)
VALUE rb_ary_concat(VALUE x, VALUE y)
#define RETURN_ENUMERATOR(obj, argc, argv)
#define SafeStringValue(v)
void rb_enc_warn(rb_encoding *enc, const char *fmt,...)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
#define rb_sys_fail_path(path)
VALUE rb_io_addstr(VALUE io, VALUE str)
void rb_set_class_path(VALUE, VALUE, const char *)
int rb_thread_interrupted(VALUE thval)
VALUE rb_io_taint_check(VALUE io)
int rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
#define READ_CHAR_PENDING_PTR(fptr)
#define MakeOpenFile(obj, fp)
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len, rb_encoding *from, int ecflags, VALUE ecopts)
#define MORE_CHAR_SUSPENDED
RUBY_EXTERN int dup2(int, int)
VALUE rb_str_new_frozen(VALUE)
struct rb_io_enc_t convconfig_t
rb_encoding * rb_ascii8bit_encoding(void)
int rb_enc_find_index(const char *name)
#define rb_syserr_fail_path(err, path)
int rb_io_read_pending(rb_io_t *fptr)
#define rb_check_frozen(obj)
#define NEED_NEWLINE_DECORATOR_ON_READ(fptr)
#define CONST_ID(var, str)
ssize_t rb_io_bufread(VALUE io, void *buf, size_t size)
VALUE rb_str_tmp_frozen_acquire(VALUE str)
#define RUBY_TYPED_DEFAULT_FREE
#define MODE_BTMODE(a, b, c)
#define rb_intern_const(str)
void rb_execarg_parent_end(VALUE execarg_obj)
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts)
char rb_w32_fd_is_text(int)
#define io_seek(fptr, ofs, whence)
int fchmod(int fd, int mode)
#define READ_CHAR_PENDING_COUNT(fptr)
void rb_stdio_set_default_encoding(void)
VALUE rb_str_buf_new(long)
VALUE rb_usascii_str_new(const char *, long)
void rb_io_read_check(rb_io_t *fptr)
#define RB_INTEGER_TYPE_P(obj)
#define DEFULT_IOCTL_NARG_LEN
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size)
#define READ_CHAR_PENDING(fptr)
#define READ_DATA_PENDING_PTR(fptr)
void rb_sys_fail_str(VALUE mesg)
rb_pid_t rb_waitpid(rb_pid_t pid, int *status, int flags)
VALUE rb_class_new(VALUE super)
Creates a new class.
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_str_append(VALUE, VALUE)
VALUE rb_file_open(const char *fname, const char *modestr)
#define ENCINDEX_UTF_32LE
void rb_io_check_byte_readable(rb_io_t *fptr)
void rb_io_check_char_readable(rb_io_t *fptr)
int rb_econv_prepare_options(VALUE opthash, VALUE *ecopts, int ecflags)
void rb_econv_binmode(rb_econv_t *ec)
#define ENCINDEX_UTF_32BE
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR
VALUE rb_io_set_write_io(VALUE io, VALUE w)
VALUE rb_io_ungetc(VALUE io, VALUE c)
VALUE rb_mutex_owned_p(VALUE self)
VALUE rb_to_int(VALUE)
Converts val into Integer.
void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n)
void rb_io_check_closed(rb_io_t *fptr)
VALUE rb_attr_get(VALUE, ID)
#define SET_BINARY_MODE(fptr)
char * strrchr(const char *, const char)
VALUE rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags)
void rb_write_error(const char *mesg)
rb_encoding * rb_enc_from_index(int index)
VALUE rb_str_new(const char *, long)