29# if defined(__linux__)
32# if defined(__FreeBSD_version) && __FreeBSD_version >= 1100000
42#define free(x) xfree(x)
44#if defined(DOSISH) || defined(__CYGWIN__)
49#if defined HAVE_NET_SOCKET_H
50# include <net/socket.h>
51#elif defined HAVE_SYS_SOCKET_H
52# include <sys/socket.h>
55#if defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32)
56# define NO_SAFE_RENAME
59#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__sun) || defined(_nec_ews)
68#if defined(HAVE_SYS_IOCTL_H) && !defined(_WIN32)
71#if defined(HAVE_FCNTL_H) || defined(_WIN32)
73#elif defined(HAVE_SYS_FCNTL_H)
77#if !HAVE_OFF_T && !defined(off_t)
87#if defined(HAVE_SYS_PARAM_H) || defined(__HIUX_MPP__)
88# include <sys/param.h>
101#elif defined HAVE_SYS_SYSCALL_H
102#include <sys/syscall.h>
109#ifdef HAVE_SYS_WAIT_H
110# include <sys/wait.h>
113#ifdef HAVE_COPYFILE_H
114# include <copyfile.h>
118#include "ccan/list/list.h"
124#include "internal/error.h"
132#include "internal/variable.h"
146#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
149#if SIZEOF_OFF_T > SIZEOF_LONG && !defined(HAVE_LONG_LONG)
150# error off_t is bigger than long, but you have no long long...
154# ifdef _POSIX_PIPE_BUF
155# define PIPE_BUF _POSIX_PIPE_BUF
162# define EWOULDBLOCK EAGAIN
165#if defined(HAVE___SYSCALL) && (defined(__APPLE__) || defined(__OpenBSD__))
167off_t __syscall(quad_t number, ...);
170#define IO_RBUF_CAPA_MIN 8192
171#define IO_CBUF_CAPA_MIN (128*1024)
172#define IO_RBUF_CAPA_FOR(fptr) (NEED_READCONV(fptr) ? IO_CBUF_CAPA_MIN : IO_RBUF_CAPA_MIN)
173#define IO_WBUF_CAPA_MIN 8192
178#define open rb_w32_uopen
180#define rename(f, t) rb_w32_urename((f), (t))
189static VALUE rb_eEAGAINWaitReadable;
190static VALUE rb_eEAGAINWaitWritable;
191static VALUE rb_eEWOULDBLOCKWaitReadable;
192static VALUE rb_eEWOULDBLOCKWaitWritable;
193static VALUE rb_eEINPROGRESSWaitWritable;
194static VALUE rb_eEINPROGRESSWaitReadable;
197static VALUE orig_stdout, orig_stderr;
206static ID id_write, id_read, id_getc, id_flush, id_readpartial, id_set_encoding;
207static VALUE sym_mode, sym_perm, sym_flags, sym_extenc, sym_intenc, sym_encoding, sym_open_args;
208static VALUE sym_textmode, sym_binmode, sym_autoclose;
209static VALUE sym_SET, sym_CUR, sym_END;
210static VALUE sym_wait_readable, sym_wait_writable;
212static VALUE sym_DATA;
215static VALUE sym_HOLE;
231static rb_atomic_t max_file_descriptor =
NOFILE;
235 rb_atomic_t afd = (rb_atomic_t)fd;
236 rb_atomic_t max_fd = max_file_descriptor;
239 if (fd < 0 || afd <= max_fd)
242#if defined(HAVE_FCNTL) && defined(F_GETFL)
250 if (
err && errno == EBADF) {
251 rb_bug(
"rb_update_max_fd: invalid fd (%d) given.", fd);
254 while (max_fd < afd) {
255 max_fd =
ATOMIC_CAS(max_file_descriptor, max_fd, afd);
263#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
264 int flags, flags2, ret;
267 rb_bug(
"rb_maygvl_fd_fix_cloexec: fcntl(%d, F_GETFD) failed: %s", fd,
strerror(errno));
270 flags2 = flags & ~FD_CLOEXEC;
273 if (flags != flags2) {
276 rb_bug(
"rb_maygvl_fd_fix_cloexec: fcntl(%d, F_SETFD, %d) failed: %s", fd, flags2,
strerror(errno));
291rb_fix_detect_o_cloexec(
int fd)
293#if defined(O_CLOEXEC) && defined(F_GETFD)
297 rb_bug(
"rb_fix_detect_o_cloexec: fcntl(%d, F_GETFD) failed: %s", fd,
strerror(errno));
310 static int o_cloexec_state = -1;
312 static const int retry_interval = 0;
313 static const int retry_max_count = 10000;
320#elif defined O_NOINHERIT
321 flags |= O_NOINHERIT;
324 while ((ret = open(pathname, flags,
mode)) == -1) {
327 if (retry_count++ >= retry_max_count)
break;
329 sleep(retry_interval);
332 if (ret < 0)
return ret;
333 if (ret <= 2 || o_cloexec_state == 0) {
336 else if (o_cloexec_state > 0) {
340 o_cloexec_state = rb_fix_detect_o_cloexec(ret);
359 if (oldfd == newfd) {
363#if defined(HAVE_DUP3) && defined(O_CLOEXEC)
364 static int try_dup3 = 1;
365 if (2 < newfd && try_dup3) {
370 if (errno == ENOSYS) {
372 ret =
dup2(oldfd, newfd);
376 ret =
dup2(oldfd, newfd);
379 ret =
dup2(oldfd, newfd);
381 if (ret < 0)
return ret;
388rb_fd_set_nonblock(
int fd)
392#elif defined(F_GETFL)
393 int oflags =
fcntl(fd, F_GETFL);
411 int result = pipe(descriptors);
418 if (result == 0 && descriptors[1] == -1) {
419 close(descriptors[0]);
431 rb_fd_set_nonblock(descriptors[0]);
432 rb_fd_set_nonblock(descriptors[1]);
444#if defined(HAVE_FCNTL) && defined(F_DUPFD_CLOEXEC) && defined(F_DUPFD)
445 static int try_dupfd_cloexec = 1;
446 if (try_dupfd_cloexec) {
454 if (errno == EINVAL) {
457 try_dupfd_cloexec = 0;
464#elif defined(HAVE_FCNTL) && defined(F_DUPFD)
466#elif defined(HAVE_DUP)
468 if (ret >= 0 && ret < minfd) {
469 const int prev_fd = ret;
475# error "dup() or fcntl(F_DUPFD) must be supported."
477 if (ret < 0)
return ret;
482#define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
483#define ARGF argf_of(argf)
485#define GetWriteIO(io) rb_io_get_write_io(io)
487#define READ_DATA_PENDING(fptr) ((fptr)->rbuf.len)
488#define READ_DATA_PENDING_COUNT(fptr) ((fptr)->rbuf.len)
489#define READ_DATA_PENDING_PTR(fptr) ((fptr)->rbuf.ptr+(fptr)->rbuf.off)
490#define READ_DATA_BUFFERED(fptr) READ_DATA_PENDING(fptr)
492#define READ_CHAR_PENDING(fptr) ((fptr)->cbuf.len)
493#define READ_CHAR_PENDING_COUNT(fptr) ((fptr)->cbuf.len)
494#define READ_CHAR_PENDING_PTR(fptr) ((fptr)->cbuf.ptr+(fptr)->cbuf.off)
497#define WAIT_FD_IN_WIN32(fptr) \
498 (rb_w32_io_cancelable_p((fptr)->fd) ? 0 : rb_thread_wait_fd((fptr)->fd))
500#define WAIT_FD_IN_WIN32(fptr)
503#define READ_CHECK(fptr) do {\
504 if (!READ_DATA_PENDING(fptr)) {\
505 WAIT_FD_IN_WIN32(fptr);\
506 rb_io_check_closed(fptr);\
512# define S_ISSOCK(m) _S_ISSOCK(m)
515# define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
518# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
524static int io_fflush(
rb_io_t *);
527#define FMODE_PREP (1<<16)
528#define FMODE_SIGNAL_ON_EPIPE (1<<17)
530#define fptr_signal_on_epipe(fptr) \
531 (((fptr)->mode & FMODE_SIGNAL_ON_EPIPE) != 0)
533#define fptr_set_signal_on_epipe(fptr, flag) \
535 (fptr)->mode |= FMODE_SIGNAL_ON_EPIPE : \
536 (fptr)->mode &= ~FMODE_SIGNAL_ON_EPIPE)
557#define rb_sys_fail_on_write(fptr) \
560 raise_on_write(fptr, e, rb_syserr_new_path(e, (fptr)->pathv)); \
563#define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE)
564#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) ((fptr)->mode & FMODE_TEXTMODE)
565#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
567# define DEFAULT_TEXTMODE FMODE_TEXTMODE
568# define TEXTMODE_NEWLINE_DECORATOR_ON_WRITE ECONV_CRLF_NEWLINE_DECORATOR
576#define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || (fptr)->encs.ecflags & ~ECONV_CRLF_NEWLINE_DECORATOR)
577#define WRITECONV_MASK ( \
578 (ECONV_DECORATOR_MASK & ~ECONV_CRLF_NEWLINE_DECORATOR)|\
579 ECONV_STATEFUL_DECORATOR_MASK|\
581#define NEED_WRITECONV(fptr) ( \
582 ((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || \
583 ((fptr)->encs.ecflags & WRITECONV_MASK) || \
585#define SET_BINARY_MODE(fptr) setmode((fptr)->fd, O_BINARY)
587#define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr) do {\
588 if (NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {\
589 if (((fptr)->mode & FMODE_READABLE) &&\
590 !((fptr)->encs.ecflags & ECONV_NEWLINE_DECORATOR_MASK)) {\
591 setmode((fptr)->fd, O_BINARY);\
594 setmode((fptr)->fd, O_TEXT);\
599#define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags) do {\
600 if ((enc2) && ((ecflags) & ECONV_DEFAULT_NEWLINE_DECORATOR)) {\
601 (ecflags) |= ECONV_UNIVERSAL_NEWLINE_DECORATOR;\
627 if (r < 0 && errno) {
639 if (pos < 0 && errno) {
646 extra_max = (
long)(pos - fptr->
rbuf.len);
647 p = fptr->
rbuf.ptr + fptr->
rbuf.off;
650 if (*(fptr->
rbuf.ptr + fptr->
rbuf.capa - 1) ==
'\r') {
654 for (i = 0; i < fptr->
rbuf.len; i++) {
655 if (*p ==
'\n') newlines++;
656 if (extra_max == newlines)
break;
661 while (newlines >= 0) {
663 if (newlines == 0)
break;
668 read_size = _read(fptr->
fd,
buf, fptr->
rbuf.len + newlines);
674 if (read_size == fptr->
rbuf.len) {
696set_binary_mode_with_seek_cur(
rb_io_t *fptr)
703 flush_before_seek(fptr);
706#define SET_BINARY_MODE_WITH_SEEK_CUR(fptr) set_binary_mode_with_seek_cur(fptr)
710# define DEFAULT_TEXTMODE 0
711#define NEED_READCONV(fptr) ((fptr)->encs.enc2 != NULL || NEED_NEWLINE_DECORATOR_ON_READ(fptr))
712#define NEED_WRITECONV(fptr) ( \
713 ((fptr)->encs.enc != NULL && (fptr)->encs.enc != rb_ascii8bit_encoding()) || \
714 NEED_NEWLINE_DECORATOR_ON_WRITE(fptr) || \
715 ((fptr)->encs.ecflags & (ECONV_DECORATOR_MASK|ECONV_STATEFUL_DECORATOR_MASK)) || \
717#define SET_BINARY_MODE(fptr) (void)(fptr)
718#define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr) (void)(fptr)
719#define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags) ((void)(enc2), (void)(ecflags))
720#define SET_BINARY_MODE_WITH_SEEK_CUR(fptr) (void)(fptr)
723#if !defined HAVE_SHUTDOWN && !defined shutdown
724#define shutdown(a,b) 0
728#define is_socket(fd, path) rb_w32_is_socket(fd)
729#elif !defined(S_ISSOCK)
730#define is_socket(fd, path) 0
736 if (
fstat(fd, &sbuf) < 0)
738 return S_ISSOCK(sbuf.st_mode);
742static const char closed_stream[] =
"closed stream";
745io_fd_check_closed(
int fd)
778 io_fd_check_closed(fptr->
fd);
782rb_io_get_fptr(
VALUE io)
816 rb_io_t *fptr = rb_io_get_fptr(io);
825 return write_io ? write_io :
Qnil;
851#if !(defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32))
862 if (r < 0 && errno) {
884#if SIZEOF_LONG > SIZEOF_INT
891 fptr->
rbuf.capa = min_capa;
900 char, fptr->
rbuf.len);
909flush_before_seek(
rb_io_t *fptr)
911 if (io_fflush(fptr) < 0)
918#define io_seek(fptr, ofs, whence) (errno = 0, lseek(flush_before_seek(fptr)->fd, (ofs), (whence)))
919#define io_tell(fptr) lseek(flush_before_seek(fptr)->fd, 0, SEEK_CUR)
934 if (fptr->
wbuf.len) {
935 if (io_fflush(fptr) < 0)
941 if (io_fflush(wfptr) < 0)
971io_input_encoding(
rb_io_t *fptr)
976 return io_read_encoding(fptr);
986 if (fptr->
rbuf.len) {
1012 if (
err == EMFILE ||
err == ENFILE ||
err == ENOMEM) {
1039io_alloc(
VALUE klass)
1049# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
1067struct io_internal_writev_struct {
1070 const struct iovec *iov;
1074static int nogvl_wait_for_single_fd(
VALUE th,
int fd,
short events);
1076internal_read_func(
void *
ptr)
1094#if defined __APPLE__
1095# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE)
1097# define do_write_retry(code) ret = code
1100internal_write_func(
void *
ptr)
1109internal_write_func2(
void *
ptr)
1111 return (
void*)internal_write_func(
ptr);
1116internal_writev_func(
void *
ptr)
1118 struct io_internal_writev_struct *iis =
ptr;
1126rb_read_internal(
int fd,
void *
buf,
size_t count)
1140rb_write_internal(
int fd,
const void *
buf,
size_t count)
1152rb_write_internal2(
int fd,
const void *
buf,
size_t count)
1166rb_writev_internal(
int fd,
const struct iovec *iov,
int iovcnt)
1168 struct io_internal_writev_struct iis = {
1179io_flush_buffer_sync(
void *arg)
1182 long l = fptr->
wbuf.len;
1183 ssize_t r =
write(fptr->
fd, fptr->
wbuf.ptr+fptr->
wbuf.off, (
size_t)l);
1185 if (fptr->
wbuf.len <= r) {
1199io_flush_buffer_sync2(
void *arg)
1201 VALUE result = io_flush_buffer_sync(arg);
1207 return !result ? (
void*)1 : (
void*)result;
1211io_flush_buffer_async(
VALUE arg)
1218io_flush_buffer_async2(
VALUE arg)
1230 else if (ret == 1) {
1241 return (
int)io_flush_buffer_async2((
VALUE)fptr);
1246 return (
int)io_flush_buffer_async((
VALUE)fptr);
1254 if (fptr->
wbuf.len == 0)
1256 while (fptr->
wbuf.len > 0 && io_flush_buffer(fptr) != 0) {
1269 if (scheduler !=
Qnil) {
1279 if (timeout !=
Qnil) {
1301rb_io_from_fd(
int fd)
1311 io_fd_check_closed(
f);
1316#if defined(ERESTART)
1323#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
1326 if (scheduler !=
Qnil) {
1345 io_fd_check_closed(
f);
1350#if defined(ERESTART)
1366#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
1369 if (scheduler !=
Qnil) {
1388 if (scheduler !=
Qnil) {
1401 const char *senc, *denc;
1408 ecflags = fptr->
encs.
ecflags & ~ECONV_NEWLINE_DECORATOR_READ_MASK;
1468io_binwrite_string(
VALUE arg)
1475 struct iovec iov[2];
1482 r = rb_writev_internal(fptr->
fd, iov, 2);
1487 if (fptr->
wbuf.len <= r) {
1488 r -= fptr->
wbuf.len;
1499 r = rb_write_internal(fptr->
fd, p->
ptr, p->
length);
1506io_binwrite_string(
VALUE arg)
1515 if (
fptr->
wbuf.len+len <= fptr->wbuf.capa) {
1524 if (io_fflush(
fptr) < 0)
1545 if ((n =
len) <= 0)
return n;
1579 r = io_binwrite_string((
VALUE)&arg);
1582 if (r == n)
return len;
1608# define MODE_BTMODE(a,b,c) ((fmode & FMODE_BINMODE) ? (b) : \
1609 (fmode & FMODE_TEXTMODE) ? (c) : (a))
1611#define MODE_BTXMODE(a, b, c, d, e, f) ((fmode & FMODE_EXCL) ? \
1612 MODE_BTMODE(d, e, f) : \
1613 MODE_BTMODE(a, b, c))
1622 make_writeconv(
fptr);
1625#define fmode (fptr->mode)
1629 rb_raise(
rb_eArgError,
"ASCII incompatible string written for text mode IO without encoding conversion: %s",
1641 if (!
NIL_P(common_encoding)) {
1652#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
1653#define fmode (fptr->mode)
1660 setmode(
fptr->
fd, O_TEXT);
1663 rb_raise(
rb_eArgError,
"ASCII incompatible string written for text mode IO without encoding conversion: %s",
1691 n = io_binwrite(tmp,
ptr,
len,
fptr, nosync);
1704 return (ssize_t)io_binwrite(0,
buf, (
long)
size,
fptr, 0);
1727 n = io_fwrite(
str,
fptr, nosync);
1734struct binwritev_arg {
1736 const struct iovec *iov;
1741call_writev_internal(
VALUE arg)
1743 struct binwritev_arg *p = (
struct binwritev_arg *)arg;
1744 return rb_writev_internal(p->fptr->fd, p->iov, p->iovcnt);
1748io_binwritev(
struct iovec *iov,
int iovcnt,
rb_io_t *fptr)
1751 long r, total = 0, written_len = 0;
1756 if (iovcnt == 0)
return 0;
1757 for (i = 1; i < iovcnt; i++) total += iov[i].iov_len;
1768 if (fptr->
wbuf.ptr && fptr->
wbuf.len) {
1770 if (
offset + total <= fptr->wbuf.capa) {
1771 for (i = 1; i < iovcnt; i++) {
1775 fptr->
wbuf.len += total;
1785 if (!--iovcnt)
return 0;
1790 struct binwritev_arg arg;
1793 arg.iovcnt = iovcnt;
1797 r = rb_writev_internal(fptr->
fd, iov, iovcnt);
1802 if (fptr->
wbuf.ptr && fptr->
wbuf.len) {
1803 if (written_len < fptr->wbuf.len) {
1804 fptr->
wbuf.off += r;
1805 fptr->
wbuf.len -= r;
1808 written_len -= fptr->
wbuf.len;
1813 if (written_len == total)
return total;
1815 while (r >= (ssize_t)iov->
iov_len) {
1820 if (!--iovcnt)
return total;
1839 int i, converted, iovcnt =
argc + 1;
1841 VALUE v1, v2,
str, tmp, *tmp_array;
1847 for (i = 0; i <
argc; i++) {
1850 str = do_writeconv(
str, fptr, &converted);
1861 n = io_binwritev(iov, iovcnt, fptr);
1864 for (i = 0; i <
argc; i++) {
1874iovcnt_ok(
int iovcnt)
1877 return iovcnt < IOV_MAX;
1903 for (i = 0; i <
argc; i +=
cnt) {
1906 n = io_fwritev(
cnt, &
argv[i], fptr);
1948 return io_write(io,
str, 0);
1966 " which accepts just one argument",
2000nogvl_fsync(
void *
ptr)
2017 if (!RB_TYPE_P(io,
T_FILE)) {
2025 if (io_fflush(fptr) < 0)
2079 pos -= fptr->
rbuf.len;
2091 pos =
io_seek(fptr, pos, whence);
2098interpret_seek_whence(
VALUE vwhence)
2100 if (vwhence == sym_SET)
2102 if (vwhence == sym_CUR)
2104 if (vwhence == sym_END)
2107 if (vwhence == sym_DATA)
2111 if (vwhence == sym_HOLE)
2145 whence = interpret_seek_whence(ptrname);
2148 return rb_io_seek(io,
offset, whence);
2178static void clear_readconv(
rb_io_t *fptr);
2197rb_io_rewind(
VALUE io)
2203 if (io ==
ARGF.current_file) {
2208 clear_readconv(fptr);
2215fptr_wait_readable(
rb_io_t *fptr)
2238 if (fptr->
rbuf.len == 0) {
2241 r = rb_read_internal(fptr->
fd, fptr->
rbuf.ptr, fptr->
rbuf.capa);
2244 if (fptr_wait_readable(fptr))
2308#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
2313 if (io_fillbuf(fptr) < 0) {
2368 fptr->
mode &= ~FMODE_SYNC;
2394 if (io_fflush(fptr) < 0)
2401# define rb_io_fsync rb_f_notimplement
2402# define rb_io_sync rb_f_notimplement
2411#ifdef HAVE_FDATASYNC
2413nogvl_fdatasync(
void *
ptr)
2421 return (
VALUE)fdatasync(fptr->
fd);
2443 if (io_fflush(fptr) < 0)
2453#define rb_io_fdatasync rb_io_fsync
2469rb_io_fileno(
VALUE io)
2520rb_io_inspect(
VALUE obj)
2524 static const char closed[] =
" (closed)";
2526 fptr =
RFILE(obj)->fptr;
2556rb_io_to_io(
VALUE io)
2568 if (n <= 0)
return 0;
2571 fptr->
rbuf.off += n;
2572 fptr->
rbuf.len -= n;
2589 if (fptr_wait_readable(fptr))
2594 if ((n -= c) <= 0)
break;
2600 c = read_buffered_data(
ptr+
offset, n, fptr);
2603 if ((n -= c) <= 0)
break;
2606 if (io_fillbuf(fptr) < 0) {
2622bufread_call(
VALUE arg)
2664#
if defined(__HAIKU__)
2669 if (io_fflush(fptr) < 0)
2672 if (st.st_size >= pos && pos >= 0) {
2673 siz += st.st_size - pos;
2698 const char *sname, *dname;
2699 ecflags = fptr->
encs.
ecflags & ~ECONV_NEWLINE_DECORATOR_WRITE_MASK;
2719#define MORE_CHAR_SUSPENDED Qtrue
2720#define MORE_CHAR_FINISHED Qnil
2722fill_cbuf(
rb_io_t *fptr,
int ec_flags)
2724 const unsigned char *ss, *sp, *se;
2725 unsigned char *ds, *
dp, *de;
2733 if (fptr->
cbuf.len == fptr->
cbuf.capa)
2735 if (fptr->
cbuf.len == 0)
2737 else if (fptr->
cbuf.off + fptr->
cbuf.len == fptr->
cbuf.capa) {
2742 cbuf_len0 = fptr->
cbuf.len;
2745 ss = sp = (
const unsigned char *)fptr->
rbuf.ptr + fptr->
rbuf.off;
2746 se = sp + fptr->
rbuf.len;
2747 ds =
dp = (
unsigned char *)fptr->
cbuf.ptr + fptr->
cbuf.off + fptr->
cbuf.len;
2748 de = (
unsigned char *)fptr->
cbuf.ptr + fptr->
cbuf.capa;
2750 fptr->
rbuf.off += (
int)(sp - ss);
2751 fptr->
rbuf.len -= (
int)(sp - ss);
2757 fptr->
rbuf.off -= putbackable;
2758 fptr->
rbuf.len += putbackable;
2765 if (cbuf_len0 != fptr->
cbuf.len)
2773 if (fptr->
rbuf.len == 0) {
2775 if (io_fillbuf(fptr) < 0) {
2779 ds =
dp = (
unsigned char *)fptr->
cbuf.ptr + fptr->
cbuf.off + fptr->
cbuf.len;
2780 de = (
unsigned char *)fptr->
cbuf.ptr + fptr->
cbuf.capa;
2789 if (cbuf_len0 != fptr->
cbuf.len)
2822 if (fptr->
cbuf.len == 0)
2824 else if (fptr->
cbuf.capa/2 < fptr->
cbuf.off) {
2854#define MAX_REALLOC_GAP 4096
2856io_shrink_read_string(
VALUE str,
long n)
2864io_set_read_length(
VALUE str,
long n,
int shrinkable)
2869 if (shrinkable) io_shrink_read_string(
str, n);
2886 shrinkable = io_setstrbuf(&
str,0);
2887 make_readconv(fptr, 0);
2890 if (fptr->
cbuf.len) {
2892 io_shift_cbuf(fptr, fptr->
cbuf.len, &
str);
2894 v = fill_cbuf(fptr, 0);
2896 if (fptr->
cbuf.len) {
2898 io_shift_cbuf(fptr, fptr->
cbuf.len, &
str);
2903 clear_readconv(fptr);
2906 return io_enc_str(
str, fptr);
2915 enc = io_read_encoding(fptr);
2918 if (siz == 0) siz = BUFSIZ;
2919 shrinkable = io_setstrbuf(&
str, siz);
2922 n = io_fread(
str, bytes, siz - bytes, fptr);
2923 if (n == 0 && bytes == 0) {
2931 if (bytes < siz)
break;
2936 str = io_enc_str(
str, fptr);
2944 if (rb_fd_set_nonblock(fptr->
fd) != 0) {
2950read_internal_call(
VALUE arg)
2963#define no_exception_p(opts) !rb_opts_exception_p((opts), TRUE)
2980 shrinkable = io_setstrbuf(&
str,
len);
2986 io_set_read_length(
str, 0, shrinkable);
3004 n = read_internal_locktmp(
str, &iis);
3007 if (!
nonblock && fptr_wait_readable(fptr))
3011 return sym_wait_readable;
3014 e,
"read would block");
3019 io_set_read_length(
str, n, shrinkable);
3104io_nonblock_eof(
int no_exception)
3106 if (!no_exception) {
3125 shrinkable = io_setstrbuf(&
str,
len);
3132 io_set_read_length(
str, 0, shrinkable);
3139 shrinkable |= io_setstrbuf(&
str,
len);
3144 n = read_internal_locktmp(
str, &iis);
3148 if (!ex)
return sym_wait_readable;
3150 e,
"read would block");
3155 io_set_read_length(
str, n, shrinkable);
3158 if (!ex)
return Qnil;
3180 if (io_fflush(fptr) < 0)
3191 return sym_wait_writable;
3277#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
3283 if (
NIL_P(length)) {
3286 return read_all(fptr, remain_size(fptr),
str);
3293 shrinkable = io_setstrbuf(&
str,
len);
3298 io_set_read_length(
str, 0, shrinkable);
3303#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
3304 previous_mode = set_binary_mode_with_seek_cur(fptr);
3306 n = io_fread(
str, 0,
len, fptr);
3307 io_set_read_length(
str, n, shrinkable);
3308#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
3309 if (previous_mode == O_TEXT) {
3310 setmode(fptr->
fd, O_TEXT);
3313 if (n == 0)
return Qnil;
3319rscheck(
const char *rsptr,
long rslen,
VALUE rs)
3327appendline(
rb_io_t *fptr,
int delim,
VALUE *strp,
long *lp)
3334 make_readconv(fptr, 0);
3340 if (0 < limit && limit < searchlen)
3341 searchlen = (
int)limit;
3342 e = memchr(p, delim, searchlen);
3360 fptr->
cbuf.off += searchlen;
3361 fptr->
cbuf.len -= searchlen;
3370 clear_readconv(fptr);
3383 if (limit > 0 && pending > limit) pending = limit;
3384 e = memchr(p, delim, pending);
3385 if (e) pending = e - p + 1;
3398 if (e)
return delim;
3403 }
while (io_fillbuf(fptr) >= 0);
3415 make_readconv(fptr, 0);
3424 while (--i && *++p ==
term);
3427 const char *e = p +
cnt;
3432 io_shift_cbuf(fptr, (
int)
cnt - i,
NULL);
3448 while (--i && *++p ==
term);
3449 if (!read_buffered_data(
buf,
cnt - i, fptr))
3453 }
while (io_fillbuf(fptr) == 0);
3473 e = memchr(p,
'\n', pending);
3475 pending = (
int)(e - p + 1);
3477 chomplen = (pending > 1 && *(e-1) ==
'\r') + 1;
3482 fptr->
rbuf.off += pending;
3483 fptr->
rbuf.len -= pending;
3488 fptr->
rbuf.off += chomplen;
3489 fptr->
rbuf.len -= chomplen;
3490 if (pending == 1 && chomplen == 1 &&
len > 0) {
3497 len += pending - chomplen;
3503 }
while (io_fillbuf(fptr) >= 0);
3506 str = io_enc_str(
str, fptr);
3517 unsigned int chomp: 1;
3528 kwds[0] = rb_intern_const(
"chomp");
3533 args->
chomp = chomp;
3551 else if (2 <=
argc) {
3561check_getline_args(
VALUE *rsp,
long *limit,
VALUE io)
3571 enc_io = io_read_encoding(fptr);
3572 if (enc_io != enc_rs &&
3594 extract_getline_args(
argc,
argv, args);
3595 extract_getline_opts(opts, args);
3596 check_getline_args(&args->
rs, &args->
limit, io);
3600rb_io_getline_0(
VALUE rs,
long limit,
int chomp,
rb_io_t *fptr)
3607 if (
NIL_P(rs) && limit < 0) {
3608 str = read_all(fptr, 0,
Qnil);
3612 else if (limit == 0) {
3618 return rb_io_getline_fast(fptr, enc, chomp);
3621 int c, newline = -1;
3622 const char *rsptr = 0;
3625 int extra_limit = 16;
3626 int chomp_cr = chomp;
3629 enc = io_read_encoding(fptr);
3637 swallow(fptr,
'\n');
3650 newline = (
unsigned char)rsptr[rslen - 1];
3651 chomp_cr = chomp && rslen == 1 && newline ==
'\n';
3655 while ((c = appendline(fptr, newline, &
str, &limit)) !=
EOF) {
3656 const char *s, *p, *pp, *e;
3661 e = RSTRING_END(
str);
3664 if (pp != p)
continue;
3665 if (!rspara) rscheck(rsptr, rslen, rs);
3666 if (
memcmp(p, rsptr, rslen) == 0) {
3668 if (chomp_cr && p > s && *(p-1) ==
'\r') --p;
3676 p = RSTRING_END(
str);
3692 if (rspara && c !=
EOF)
3693 swallow(fptr,
'\n');
3695 str = io_enc_str(
str, fptr);
3706rb_io_getline_1(
VALUE rs,
long limit,
int chomp,
VALUE io)
3709 int old_lineno, new_lineno;
3713 old_lineno = fptr->
lineno;
3714 str = rb_io_getline_0(rs, limit, chomp, fptr);
3716 if (io ==
ARGF.current_file) {
3717 ARGF.lineno += new_lineno - old_lineno;
3721 ARGF.last_lineno = new_lineno;
3907 return io_readlines(&args,
io);
3915 if (arg->
limit == 0)
3963 if (args.
limit == 0)
3997 while (fptr->
rbuf.len > 0) {
3998 char *p = fptr->
rbuf.ptr + fptr->
rbuf.off++;
4005 }
while (io_fillbuf(fptr) >= 0);
4020 make_readconv(fptr, 0);
4023 if (fptr->
cbuf.len) {
4029 if (fptr->
cbuf.len == fptr->
cbuf.capa) {
4035 if (fptr->
cbuf.len == 0) {
4036 clear_readconv(fptr);
4041 fptr->
cbuf.off += 1;
4042 fptr->
cbuf.len -= 1;
4043 if (fptr->
cbuf.len == 0) clear_readconv(fptr);
4052 io_shift_cbuf(fptr, r, &
str);
4063 str = io_enc_str(
str, fptr);
4069 if (io_fillbuf(fptr) < 0) {
4074 fptr->
rbuf.off += 1;
4075 fptr->
rbuf.len -= 1;
4083 fptr->
rbuf.off += n;
4084 fptr->
rbuf.len -= n;
4091 if (io_fillbuf(fptr) != -1) {
4111 str = io_enc_str(
str, fptr);
4142 enc = io_input_encoding(fptr);
4144 while (!
NIL_P(c = io_getc(fptr, enc))) {
4182 make_readconv(fptr, 0);
4184 if (fptr->
cbuf.len) {
4193 if (fptr->
cbuf.len == fptr->
cbuf.capa) {
4198 clear_readconv(fptr);
4217 c = (
unsigned char)fptr->
cbuf.ptr[fptr->
cbuf.off];
4219 fptr->
cbuf.off += n;
4220 fptr->
cbuf.len -= n;
4226 enc = io_input_encoding(fptr);
4227 while (io_fillbuf(fptr) >= 0) {
4234 fptr->
rbuf.off += n;
4235 fptr->
rbuf.len -= n;
4242 char cbuf[8], *p = cbuf;
4244 if (more >
numberof(cbuf))
goto invalid;
4245 more += n = fptr->
rbuf.len;
4246 if (more >
numberof(cbuf))
goto invalid;
4247 while ((n = (
int)read_buffered_data(p, more, fptr)) > 0 &&
4248 (p += n, (more -= n) > 0)) {
4249 if (io_fillbuf(fptr) < 0)
goto invalid;
4250 if ((n = fptr->
rbuf.len) > more) n = more;
4290 enc = io_input_encoding(fptr);
4292 return io_getc(fptr, enc);
4347 if (io_fillbuf(fptr) < 0) {
4352 c = (
unsigned char)fptr->
rbuf.ptr[fptr->
rbuf.off-1];
4405 unsigned char c =
NUM2INT(v) & 0xFF;
4411 io_ungetbyte(b, fptr);
4451#if SIZEOF_LONG > SIZEOF_INT
4455 make_readconv(fptr, (
int)
len);
4461 char, fptr->
cbuf.len);
4470 io_ungetbyte(c, fptr);
4493 if (isatty(fptr->
fd) == 0)
4498#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
4521 if (
io != write_io) {
4523 if (fptr && 0 <= (fd = fptr->
fd)) {
4530 if (fptr && 0 <= (fd = fptr->
fd)) {
4537#define rb_io_close_on_exec_p rb_f_notimplement
4540#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
4570 if (
io != write_io) {
4572 if (fptr && 0 <= (fd = fptr->
fd)) {
4575 ret = (ret & ~FD_CLOEXEC) | flag;
4584 if (fptr && 0 <= (fd = fptr->
fd)) {
4587 ret = (ret & ~FD_CLOEXEC) | flag;
4595#define rb_io_set_close_on_exec rb_f_notimplement
4598#define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
4599#define PREP_STDIO_NAME(f) (RSTRING_PTR((f)->pathv))
4602finish_writeconv(
rb_io_t *fptr,
int noalloc)
4604 unsigned char *ds, *
dp, *de;
4607 if (!fptr->
wbuf.ptr) {
4608 unsigned char buf[1024];
4619 r = rb_write_internal2(fptr->
fd, ds,
dp-ds);
4621 r = rb_write_internal(fptr->
fd, ds,
dp-ds);
4646 if (fptr->
wbuf.len == fptr->
wbuf.capa) {
4647 if (io_fflush(fptr) < 0)
4651 ds =
dp = (
unsigned char *)fptr->
wbuf.ptr + fptr->
wbuf.off + fptr->
wbuf.len;
4652 de = (
unsigned char *)fptr->
wbuf.ptr + fptr->
wbuf.capa;
4670finish_writeconv_sync(
VALUE arg)
4677nogvl_close(
void *
ptr)
4681 return (
void*)(
intptr_t)close(*fd);
4685maygvl_close(
int fd,
int keepgvl)
4698nogvl_fclose(
void *
ptr)
4706maygvl_fclose(
FILE *
file,
int keepgvl)
4709 return fclose(
file);
4718fptr_finalize_flush(
rb_io_t *
fptr,
int noraise,
int keepgvl,
4719 struct list_head *busy)
4730 arg.noalloc = noraise;
4734 err = finish_writeconv(
fptr, noraise);
4739 io_flush_buffer_sync(
fptr);
4762 else if (stdio_file) {
4765 if ((maygvl_fclose(stdio_file, noraise) < 0) &&
NIL_P(
err))
4776 if ((maygvl_close(fd, keepgvl) < 0) &&
NIL_P(
err))
4791 fptr_finalize_flush(
fptr, noraise,
FALSE, 0);
4794 clear_codeconv(
fptr);
4804 fptr_finalize(
fptr, noraise);
4840 clear_readconv(
fptr);
4841 clear_writeconv(
fptr);
4856 clear_codeconv(
fptr);
4860#undef rb_io_fptr_finalize
4872#define rb_io_fptr_finalize(fptr) rb_io_fptr_finalize_internal(fptr)
4874RUBY_FUNC_EXPORTED
size_t
4888# define KEEPGVL TRUE
4890# define KEEPGVL FALSE
4895io_close_fptr(
VALUE io)
4900 struct list_head busy;
4902 list_head_init(&busy);
4904 if (io != write_io) {
4905 write_fptr =
RFILE(write_io)->fptr;
4906 if (write_fptr && 0 <= write_fptr->
fd) {
4907 rb_io_fptr_cleanup(write_fptr,
TRUE);
4911 fptr =
RFILE(io)->fptr;
4912 if (!fptr)
return 0;
4913 if (fptr->
fd < 0)
return 0;
4919 rb_io_fptr_cleanup(fptr,
FALSE);
4924fptr_waitpid(
rb_io_t *fptr,
int nohang)
4937 rb_io_t *fptr = io_close_fptr(io);
4938 if (fptr) fptr_waitpid(fptr, 0);
4958rb_io_close_m(
VALUE io)
4960 rb_io_t *fptr = rb_io_get_fptr(io);
4969io_call_close(
VALUE io)
4978 enum {mesg_len =
sizeof(closed_stream)-1};
4993 rb_rescue2(io_call_close, io, ignore_closed_stream, io,
5018rb_io_closed(
VALUE io)
5025 if (io != write_io) {
5026 write_fptr =
RFILE(write_io)->fptr;
5027 if (write_fptr && 0 <= write_fptr->
fd) {
5032 fptr = rb_io_get_fptr(io);
5057rb_io_close_read(
VALUE io)
5063 if (fptr->
fd < 0)
return Qnil;
5070 fptr->
mode &= ~FMODE_READABLE;
5077 if (io != write_io) {
5082 RFILE(io)->fptr = wfptr;
5085 RFILE(write_io)->fptr = fptr;
5086 rb_io_fptr_cleanup(fptr,
FALSE);
5119rb_io_close_write(
VALUE io)
5126 if (fptr->
fd < 0)
return Qnil;
5133 fptr->
mode &= ~FMODE_WRITABLE;
5143 if (io != write_io) {
5173 whence = interpret_seek_whence(ptrname);
5182 rb_warn(
"sysseek for buffered IO");
5185 pos = lseek(fptr->
fd, pos, whence);
5219 if (fptr->
wbuf.len) {
5220 rb_warn(
"syswrite for buffered IO");
5225 n = rb_write_internal(fptr->
fd,
ptr,
len);
5263 shrinkable = io_setstrbuf(&
str, ilen);
5264 if (ilen == 0)
return str;
5284 io_setstrbuf(&
str, ilen);
5289 n = read_internal_locktmp(
str, &iis);
5294 io_set_read_length(
str, n, shrinkable);
5295 if (n == 0 && ilen > 0) {
5302#if defined(HAVE_PREAD) || defined(HAVE_PWRITE)
5303struct prdwr_internal_arg {
5311#if defined(HAVE_PREAD)
5313internal_pread_func(
void *arg)
5315 struct prdwr_internal_arg *p = arg;
5316 return (
VALUE)pread(p->fd, p->buf, p->count, p->offset);
5320pread_internal_call(
VALUE arg)
5322 struct prdwr_internal_arg *p = (
struct prdwr_internal_arg *)arg;
5354 struct prdwr_internal_arg arg;
5361 shrinkable = io_setstrbuf(&
str, (
long)arg.count);
5362 if (arg.count == 0)
return str;
5377 io_set_read_length(
str, n, shrinkable);
5378 if (n == 0 && arg.count > 0) {
5385# define rb_io_pread rb_f_notimplement
5388#if defined(HAVE_PWRITE)
5390internal_pwrite_func(
void *
ptr)
5392 struct prdwr_internal_arg *arg =
ptr;
5394 return (
VALUE)pwrite(arg->fd, arg->buf, arg->count, arg->offset);
5421 struct prdwr_internal_arg arg;
5445# define rb_io_pwrite rb_f_notimplement
5459 fptr->
mode &= ~FMODE_TEXTMODE;
5473io_ascii8bit_binmode(
rb_io_t *fptr)
5484 fptr->
mode &= ~FMODE_TEXTMODE;
5491 clear_codeconv(fptr);
5500 io_ascii8bit_binmode(fptr);
5518rb_io_binmode_m(
VALUE io)
5537rb_io_binmode_p(
VALUE io)
5545rb_io_fmode_modestr(
int fmode)
5559 return MODE_BTXMODE(
"w",
"wb",
"wt",
"wx",
"wbx",
"wtx");
5562 return MODE_BTXMODE(
"w+",
"wb+",
"wt+",
"w+x",
"wb+x",
"wt+x");
5568static const char bom_prefix[] =
"bom|";
5569static const char utf_prefix[] =
"utf-";
5574io_encname_bom_p(
const char *
name,
long len)
5583 const char *m = modestr, *p =
NULL;
5611 if (modestr[0] !=
'w')
5619 if (io_encname_bom_p(m, p ? (
long)(p - m) : (
long)
strlen(m)))
5653 if (oflags & O_APPEND) {
5656 if (oflags & O_TRUNC) {
5659 if (oflags & O_CREAT) {
5662 if (oflags & O_EXCL) {
5675rb_io_fmode_oflags(
int fmode)
5719rb_io_oflags_modestr(
int oflags)
5722# define MODE_BINARY(a,b) ((oflags & O_BINARY) ? (b) : (a))
5724# define MODE_BINARY(a,b) (a)
5727 if (oflags & O_EXCL) {
5730 accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR);
5731 if (oflags & O_APPEND) {
5732 if (accmode == O_WRONLY) {
5735 if (accmode == O_RDWR) {
5747 if (oflags & O_TRUNC) {
5762 int default_ext = 0;
5772 else if (intern ==
NULL) {
5778 *enc = (default_ext && intern != ext) ?
NULL : ext;
5794parse_mode_enc(
const char *estr,
rb_encoding *estr_enc,
5800 int fmode = fmode_p ? *fmode_p : 0;
5807 len = p ? (p++ - estr) : (
long)
strlen(estr);
5815 rb_enc_warn(estr_enc,
"BOM with non-UTF encoding %s is nonsense", estr);
5816 fmode &= ~FMODE_SETENC_BY_BOM;
5825 encname[
len] =
'\0';
5830 if (fmode_p) *fmode_p =
fmode;
5836 unsupported_encoding(estr, estr_enc);
5842 if (*p ==
'-' && *(p+1) ==
'\0') {
5849 unsupported_encoding(p, estr_enc);
5858 rb_io_ext_int_to_encs(ext_enc, int_enc, enc_p, enc2_p,
fmode);
5872 if (v !=
Qnil) encoding = v;
5874 if (v !=
Qnil) extenc = v;
5876 if (v !=
Qundef) intenc = v;
5883 encoding, extenc ==
Qundef ?
"internal" :
"external");
5891 if (
NIL_P(intenc)) {
5898 if (*p ==
'-' && *(p+1) ==
'\0') {
5909 if (extencoding == intencoding) {
5913 if (!
NIL_P(encoding)) {
5917 enc_p, enc2_p, fmode_p);
5925 rb_io_ext_int_to_encs(extencoding, intencoding, enc_p, enc2_p, 0);
5935 int fmode = *fmode_p;
5951#if !DEFAULT_TEXTMODE
5953 fmode &= ~FMODE_TEXTMODE;
5962 if (!
NIL_P(opthash)) {
5990 int *oflags_p,
int *fmode_p,
convconfig_t *convconfig_p)
5997 int has_enc = 0, has_vmode = 0;
6003 rb_io_ext_int_to_encs(
NULL,
NULL, &enc, &enc2, 0);
6021 oflags = rb_io_fmode_oflags(
fmode);
6031 rb_io_ext_int_to_encs(e,
NULL, &enc, &enc2,
fmode);
6035 if (
NIL_P(opthash)) {
6039#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
6042 0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
6054 else if (
NIL_P(vmode)) {
6064 if (!
NIL_P(vmode)) {
6079 extract_binmode(opthash, &
fmode);
6088 else if (
NIL_P(vmode)) {
6095 if (!
NIL_P(*vperm_p)) {
6107#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
6110 0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
6122 validate_enc_binmode(&
fmode, ecflags, enc, enc2);
6128 convconfig_p->enc = enc;
6129 convconfig_p->enc2 = enc2;
6130 convconfig_p->ecflags = ecflags;
6131 convconfig_p->ecopts = ecopts;
6141sysopen_func(
void *
ptr)
6169 fd = rb_sysopen_internal(&data);
6173 fd = rb_sysopen_internal(&data);
6206 if (e == 0) e = EINVAL;
6208 if (e == 0) e = EMFILE;
6216 if (setvbuf(
file,
NULL, _IOFBF, 0) != 0)
6217 rb_warn(
"setvbuf() can't be honoured (fd=%d)", fd);
6225 int t = isatty(fptr->
fd);
6235io_strip_bom(
VALUE io)
6237 VALUE b1, b2, b3, b4;
6298io_set_encoding_by_bom(
VALUE io)
6300 int idx = io_strip_bom(io);
6308 rb_io_internal_encoding(io),
Qnil);
6325 rb_io_ext_int_to_encs(
NULL,
NULL, &cc.enc, &cc.enc2,
fmode);
6330 validate_enc_binmode(&
fmode, convconfig->ecflags,
6331 convconfig->enc, convconfig->enc2);
6335 fptr->
encs = *convconfig;
6338 if (!(
oflags & O_TMPFILE)) {
6339 fptr->
pathv = pathv;
6342 fptr->
pathv = pathv;
6355 const char *p =
strchr(modestr,
':');
6360 &convconfig.enc, &convconfig.enc2, &
fmode);
6361 convconfig.ecflags = 0;
6362 convconfig.ecopts =
Qnil;
6369 rb_io_ext_int_to_encs(e,
NULL, &convconfig.enc, &convconfig.enc2,
fmode);
6370 convconfig.ecflags = 0;
6371 convconfig.ecopts =
Qnil;
6374 return rb_file_open_generic(io,
filename,
6375 rb_io_fmode_oflags(
fmode),
6385 return rb_file_open_internal(io_alloc(
rb_cFile),
fname, modestr);
6394#if defined(__CYGWIN__) || !defined(HAVE_WORKING_FORK)
6395static struct pipe_list {
6397 struct pipe_list *next;
6403 struct pipe_list *list;
6405 list =
ALLOC(
struct pipe_list);
6407 list->next = pipe_list;
6414 struct pipe_list **prev = &pipe_list;
6415 struct pipe_list *tmp;
6417 while ((tmp = *prev) != 0) {
6418 if (tmp->fptr == fptr) {
6427#if defined (_WIN32) || defined(__CYGWIN__)
6431 struct pipe_list *list = pipe_list;
6432 struct pipe_list *tmp;
6443pipe_finalize(
rb_io_t *fptr,
int noraise)
6445#if !defined(HAVE_WORKING_FORK) && !defined(_WIN32)
6454 fptr_finalize(fptr, noraise);
6456 pipe_del_fptr(fptr);
6463#if defined(__CYGWIN__) || !defined(HAVE_WORKING_FORK)
6471#if defined(__CYGWIN__) || !defined(HAVE_WORKING_FORK)
6472 if (old_finalize != pipe_finalize) {
6473 struct pipe_list *list;
6474 for (list = pipe_list; list; list = list->next) {
6475 if (list->fptr == fptr)
break;
6477 if (!list) pipe_add_fptr(fptr);
6480 pipe_del_fptr(fptr);
6516#define HAVE_SPAWNV 1
6517#define spawnv(mode, cmd, args) rb_w32_uaspawn((mode), (cmd), (args))
6518#define spawn(mode, cmd) rb_w32_uspawn((mode), (cmd), 0)
6521#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
6531#ifdef HAVE_WORKING_FORK
6533popen_redirect(
struct popen_arg *p)
6536 close(p->write_pair[1]);
6537 if (p->write_pair[0] != 0) {
6538 dup2(p->write_pair[0], 0);
6539 close(p->write_pair[0]);
6542 if (p->pair[1] != 1) {
6543 dup2(p->pair[1], 1);
6549 if (p->pair[1] != 1) {
6550 dup2(p->pair[1], 1);
6556 if (p->pair[0] != 0) {
6557 dup2(p->pair[0], 0);
6563#if defined(__linux__)
6574linux_get_maxfd(
void)
6577 char buf[4096], *p, *np, *e;
6580 if (fd < 0)
return fd;
6582 if (ss < 0)
goto err;
6585 while ((
int)
sizeof(
"FDSize:\t0\n")-1 <= e-p &&
6586 (np = memchr(p,
'\n', e-p)) !=
NULL) {
6587 if (
memcmp(p,
"FDSize:",
sizeof(
"FDSize:")-1) == 0) {
6589 p +=
sizeof(
"FDSize:")-1;
6609#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
6611 int max = (
int)max_file_descriptor;
6614 ret =
fcntl(0, F_MAXFD);
6616 maxhint =
max = ret;
6617# elif defined(__linux__)
6618 ret = linux_get_maxfd();
6625 for (fd = lowfd; fd <=
max; fd++) {
6626 if (!
NIL_P(noclose_fds) &&
6633# define CONTIGUOUS_CLOSED_FDS 20
6635 if (
max < fd + CONTIGUOUS_CLOSED_FDS)
6636 max = fd + CONTIGUOUS_CLOSED_FDS;
6643popen_exec(
void *pp,
char *errmsg,
size_t errmsg_len)
6645 struct popen_arg *p = (
struct popen_arg*)pp;
6651#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
6653rb_execarg_fixup_v(
VALUE execarg_obj)
6663pipe_open(
VALUE execarg_obj,
const char *modestr,
int fmode,
6673#if defined(HAVE_WORKING_FORK)
6675 char errmsg[80] = {
'\0' };
6677#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
6679 struct popen_arg arg;
6682#if defined(HAVE_SPAWNV)
6683# if defined(HAVE_SPAWNVE)
6684# define DO_SPAWN(cmd, args, envp) ((args) ? \
6685 spawnve(P_NOWAIT, (cmd), (args), (envp)) : \
6686 spawne(P_NOWAIT, (cmd), (envp)))
6688# define DO_SPAWN(cmd, args, envp) ((args) ? \
6689 spawnv(P_NOWAIT, (cmd), (args)) : \
6690 spawn(P_NOWAIT, (cmd)))
6692# if !defined(HAVE_WORKING_FORK)
6694# if defined(HAVE_SPAWNVE)
6699#if !defined(HAVE_WORKING_FORK)
6705#if !defined(HAVE_WORKING_FORK)
6706 const char *
cmd = 0;
6712#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
6713 arg.execarg_obj = execarg_obj;
6716 arg.pair[0] = arg.pair[1] = -1;
6717 arg.write_pair[0] = arg.write_pair[1] = -1;
6718# if !defined(HAVE_WORKING_FORK)
6725 if (
rb_pipe(arg.write_pair) < 0)
6729 close(arg.write_pair[0]);
6730 close(arg.write_pair[1]);
6753 if (!
NIL_P(execarg_obj)) {
6756 if (0 <= arg.write_pair[0]) close(arg.write_pair[0]);
6757 if (0 <= arg.write_pair[1]) close(arg.write_pair[1]);
6758 if (0 <= arg.pair[0]) close(arg.pair[0]);
6759 if (0 <= arg.pair[1]) close(arg.pair[1]);
6764# if defined(HAVE_WORKING_FORK)
6768# if defined(HAVE_SPAWNVE)
6771 while ((pid = DO_SPAWN(
cmd, args, envp)) < 0) {
6773 switch (e = errno) {
6775# if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
6789# if defined(HAVE_WORKING_FORK)
6793 popen_redirect(&arg);
6805# if defined(HAVE_WORKING_FORK)
6811 close(arg.write_pair[0]);
6812 close(arg.write_pair[1]);
6814# if defined(HAVE_WORKING_FORK)
6823 close(arg.write_pair[0]);
6824 write_fd = arg.write_pair[1];
6836 if (!
NIL_P(execarg_obj)) {
6840 fp = popen(
cmd, modestr);
6856 fptr->
encs = *convconfig;
6857#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
6867#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
6869 fptr->
encs.
ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
6875 if (0 <= write_fd) {
6876 write_port = io_alloc(
rb_cIO);
6878 write_fptr->
fd = write_fd;
6880 fptr->
mode &= ~FMODE_WRITABLE;
6885#if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK)
6887 pipe_add_fptr(fptr);
6896#if !defined(HAVE_WORKING_FORK)
6898 "fork() function is unimplemented on this machine");
6914 if (!is_popen_fork(
prog))
6916 return pipe_open(execarg_obj, modestr,
fmode, convconfig);
6922 rb_io_t *fptr = io_close_fptr(io);
7032 int ex = !
NIL_P(opt);
7042 const char *modestr;
7050#if SIZEOF_LONG > SIZEOF_INT
7051 if (
len > INT_MAX) {
7061 if (!is_popen_fork(pname))
7064 if (!
NIL_P(execarg_obj)) {
7071 modestr = rb_io_oflags_modestr(oflags);
7073 return pipe_open(execarg_obj, modestr,
fmode, &convconfig);
7089 RBASIC_SET_CLASS(port, klass);
7098 VALUE *fname_p,
int *oflags_p,
int *fmode_p,
7101 VALUE opt, fname, vmode, vperm;
7126 rb_scan_open_args(
argc,
argv, &fname, &oflags, &
fmode, &convconfig, &perm);
7127 rb_file_open_generic(io, fname, oflags,
fmode, &convconfig, perm);
7194 VALUE fname, vmode, vperm;
7210 if (
NIL_P(vperm)) perm = 0666;
7214 fd = rb_sysopen(fname, oflags, perm);
7219check_pipe_command(
VALUE filename_or_command)
7335 int redirect =
FALSE;
7349 VALUE cmd = check_pipe_command(tmp);
7379 return rb_io_open_generic(io,
filename, oflags,
fmode, &convconfig, perm);
7388 return pipe_open_s(
cmd, rb_io_oflags_modestr(oflags),
fmode, convconfig);
7391 return rb_file_open_generic(io_alloc(klass),
filename,
7392 oflags,
fmode, convconfig, perm);
7407 if (fptr == orig)
return io;
7413 "%s can't change access mode from \"%s\" to \"%s\"",
7415 rb_io_fmode_modestr(orig->
mode));
7419 if (io_fflush(fptr) < 0)
7423 flush_before_seek(fptr);
7429 if (io_fflush(orig) < 0)
7439 fptr_copy_finalizer(fptr, orig);
7512 VALUE fname, nmode, opt;
7519 return io_reopen(
file, tmp);
7539 "%s can't change access mode from \"%s\" to \"%s\"",
7541 rb_io_fmode_modestr(
fmode));
7544 fptr->
encs = convconfig;
7547 oflags = rb_io_fmode_oflags(fptr->
mode);
7550 fptr->
pathv = fname;
7552 fptr->
fd = rb_sysopen(fptr->
pathv, oflags, 0666);
7558 if (io_fflush(fptr) < 0)
7561 fptr->
rbuf.off = fptr->
rbuf.len = 0;
7565 rb_io_oflags_modestr(oflags),
7578 else if (fptr->
stdio_file == stdout && isatty(fptr->
fd)) {
7584 int tmpfd = rb_sysopen(fptr->
pathv, oflags, 0666);
7614 fptr->
mode = orig->
mode & ~FMODE_PREP;
7619 fptr_copy_finalizer(fptr, orig);
7621 fd = ruby_dup(orig->
fd);
7631 if (io != write_io) {
7734 for (i=0; i<
argc; i++) {
7825 if (recv == r_stdout) {
7826 return rb_io_putc(recv, ch);
7840 if (
len == 0)
return 0;
7842 return ptr[
len - 1] == c;
7898 VALUE line, args[2];
7905 for (i=0; i<
argc; i++) {
7921 rb_io_writev(
out, n, args);
7940 if (recv == r_stdout) {
7953 if (RB_TYPE_P(r_stdout,
T_FILE) &&
7955 io_writev(2, args, r_stdout);
7958 rb_io_writev(r_stdout, 2, args);
7977 else if (
argc > 1) {
7981 if (RB_TYPE_P(r_stdout,
T_FILE)) {
8009 for (i=0; i<
argc; i++) {
8052rb_stderr_to_original_p(
void)
8060 if (rb_stderr_to_original_p()) {
8062 if (isatty(
fileno(stderr))) {
8066 if (fwrite(mesg,
sizeof(
char), (
size_t)
len, stderr) < (
size_t)
len) {
8086 if (rb_stderr_to_original_p()) {
8089 if (isatty(
fileno(stderr))) {
8107 if (rb_stderr_to_original_p())
8108 return isatty(
fileno(stderr));
8113must_respond_to(
ID mid,
VALUE val,
ID id)
8137 must_respond_to(id_write, val,
id);
8150 must_respond_to(id_write, val,
id);
8161prep_io(
int fd,
int fmode,
VALUE klass,
const char *path)
8164 VALUE io = io_alloc(klass);
8170 if (!io_check_tty(fp)) {
8187 if (path && strcmp(path,
"-")) klass =
rb_cFile;
8199#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
8200 fptr->
encs.
ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
8232 int oflags = rb_io_fmode_oflags(fptr->
mode) & ~O_EXCL;
8259 rb_io_buffer_init(&fp->
wbuf);
8260 rb_io_buffer_init(&fp->
rbuf);
8261 rb_io_buffer_init(&fp->
cbuf);
8283 if (
RFILE(obj)->fptr) {
8286 RFILE(obj)->fptr = 0;
8288 fp = rb_io_fptr_new();
8290 RFILE(obj)->fptr = fp;
8452 int fd,
fmode, oflags = O_RDONLY;
8455#if defined(HAVE_FCNTL) && defined(F_GETFL)
8469#if defined(HAVE_FCNTL) && defined(F_GETFL)
8470 oflags =
fcntl(fd, F_GETFL);
8476#if defined(HAVE_FCNTL) && defined(F_GETFL)
8493 fp->
encs = convconfig;
8498 else if (
fileno(stdout) == fd)
8500 else if (
fileno(stderr) == fd)
8526rb_io_set_encoding_by_bom(
VALUE io)
8541 if (!io_set_encoding_by_bom(io))
return Qnil;
8573 if (
RFILE(io)->fptr) {
8581 return rb_io_initialize(
argc,
argv, io);
8628rb_io_autoclose_p(
VALUE io)
8653rb_io_set_autoclose(
VALUE io,
VALUE autoclose)
8657 if (!
RTEST(autoclose))
8660 fptr->
mode &= ~FMODE_PREP;
8676argf_memsize(
const void *
ptr)
8679 size_t size =
sizeof(*p);
8699argf_alloc(
VALUE klass)
8781#define next_argv() argf_next_argv(argf)
8782#define ARGF_GENERIC_INPUT_P() \
8783 (ARGF.current_file == rb_stdin && !RB_TYPE_P(ARGF.current_file, T_FILE))
8784#define ARGF_FORWARD(argc, argv) do {\
8785 if (ARGF_GENERIC_INPUT_P())\
8786 return argf_forward((argc), (argv), argf);\
8788#define NEXT_ARGF_FORWARD(argc, argv) do {\
8789 if (!next_argv()) return Qnil;\
8790 ARGF_FORWARD((argc), (argv));\
8810 int stdout_binmode = 0;
8815 if (RB_TYPE_P(r_stdout,
T_FILE)) {
8821 if (
ARGF.init_p == 0) {
8839 if (
ARGF.next_p == 1) {
8840 if (
ARGF.init_p == 1) argf_close(
argf);
8851 rb_warn(
"Can't do inplace edit for stdio; skipping");
8857 int fr = rb_sysopen(
filename, O_RDONLY, 0);
8861#ifndef NO_SAFE_RENAME
8867 if (RB_TYPE_P(r_stdout,
T_FILE) && r_stdout != orig_stdout) {
8880#ifdef NO_SAFE_RENAME
8888 fr = rb_sysopen(
str, O_RDONLY, 0);
8899#ifdef NO_SAFE_RENAME
8900 rb_fatal(
"Can't do inplace edit without backup");
8902 if (unlink(fn) < 0) {
8910 fw = rb_sysopen(
filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
8911#ifndef NO_SAFE_RENAME
8916 chmod(fn, st.st_mode);
8918 if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) {
8921 err = fchown(fw, st.st_uid, st.st_gid);
8923 err =
chown(fn, st.st_uid, st.st_gid);
8925 if (
err &&
getuid() == 0 && st2.st_uid == 0) {
8941 if (!
ARGF.binmode) {
8945 if (!
NIL_P(write_io)) {
8952 if (
ARGF.encs.enc) {
8954 clear_codeconv(fptr);
8957 fptr->
encs.
ecflags &= ~ECONV_NEWLINE_DECORATOR_MASK;
8958 if (!
ARGF.binmode) {
8960#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
8961 fptr->
encs.
ecflags |= TEXTMODE_NEWLINE_DECORATOR_ON_WRITE;
8972 else if (
ARGF.next_p == -1) {
8976 rb_warn(
"Can't do inplace edit for stdio");
8980 if (
ARGF.init_p == -1)
ARGF.init_p = 1;
8988 long lineno =
ARGF.lineno;
9009 ARGF.lineno = ++lineno;
9016argf_lineno_getter(
ID id,
VALUE *var)
9027 ARGF.last_lineno =
ARGF.lineno = n;
9109 return rb_f_gets(0, 0,
argf);
9223 long lineno =
ARGF.lineno;
9232 lines = rb_io_readlines(
argc,
argv,
ARGF.current_file);
9271 result = read_all(fptr, remain_size(fptr),
Qnil);
9280#ifdef HAVE_SYS_SELECT_H
9281#include <sys/select.h>
9304 if (max < fptr->fd)
max = fptr->
fd;
9307 timerec.tv_sec = timerec.tv_usec = 0;
9321 if (max < fptr->fd)
max = fptr->
fd;
9328 if (!
NIL_P(except)) {
9335 if (max < fptr->fd)
max = fptr->
fd;
9336 if (io != write_io) {
9339 if (max < fptr->fd)
max = fptr->
fd;
9354 if (!pending && n == 0)
return Qnil;
9397 else if (io != write_io) {
9416select_call(
VALUE arg)
9424select_end(
VALUE arg)
9434static VALUE sym_normal, sym_sequential, sym_random,
9435 sym_willneed, sym_dontneed, sym_noreuse;
9437#ifdef HAVE_POSIX_FADVISE
9438struct io_advise_struct {
9446io_advise_internal(
void *arg)
9448 struct io_advise_struct *
ptr = arg;
9449 return posix_fadvise(
ptr->fd,
ptr->offset,
ptr->len,
ptr->advice);
9455#ifdef POSIX_FADV_NORMAL
9456 if (
sym == sym_normal)
9457 return INT2NUM(POSIX_FADV_NORMAL);
9460#ifdef POSIX_FADV_RANDOM
9461 if (
sym == sym_random)
9462 return INT2NUM(POSIX_FADV_RANDOM);
9465#ifdef POSIX_FADV_SEQUENTIAL
9466 if (
sym == sym_sequential)
9467 return INT2NUM(POSIX_FADV_SEQUENTIAL);
9470#ifdef POSIX_FADV_WILLNEED
9471 if (
sym == sym_willneed)
9472 return INT2NUM(POSIX_FADV_WILLNEED);
9475#ifdef POSIX_FADV_DONTNEED
9476 if (
sym == sym_dontneed)
9477 return INT2NUM(POSIX_FADV_DONTNEED);
9480#ifdef POSIX_FADV_NOREUSE
9481 if (
sym == sym_noreuse)
9482 return INT2NUM(POSIX_FADV_NOREUSE);
9492 struct io_advise_struct ias;
9495 num_adv = io_advise_sym_to_const(advice);
9505 ias.advice =
NUM2INT(num_adv);
9510 if (rv && rv != ENOSYS) {
9514 "(%"PRI_OFFT_PREFIX
"d, "
9515 "%"PRI_OFFT_PREFIX
"d, "
9527advice_arg_check(
VALUE advice)
9532 if (advice != sym_normal &&
9533 advice != sym_sequential &&
9534 advice != sym_random &&
9535 advice != sym_willneed &&
9536 advice != sym_dontneed &&
9537 advice != sym_noreuse) {
9592 advice_arg_check(advice);
9600#ifdef HAVE_POSIX_FADVISE
9601 return do_io_advise(fptr, advice, off, l);
9603 ((void)off, (
void)l);
9757 if (
NIL_P(timeout)) {
9762 args.timeout = &timerec;
9765 for (i = 0; i <
numberof(args.fdsets); ++i)
9771#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
9773# define NUM2IOCTLREQ(num) NUM2ULONG(num)
9776# define NUM2IOCTLREQ(num) ((int)NUM2LONG(num))
9787nogvl_ioctl(
void *
ptr)
9791 return (
VALUE)
ioctl(arg->fd, arg->cmd, arg->narg);
9810#define DEFULT_IOCTL_NARG_LEN (256)
9812#if defined(__linux__) && defined(_IOC_SIZE)
9818 if ((cmd & 0xFFFF0000) == 0) {
9823 len = _IOC_SIZE(cmd);
9840#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
9844 len = IOCPARM_LEN(cmd);
9845#elif defined(__linux__) && defined(_IOC_SIZE)
9846 len = linux_iocparm_len(cmd);
9857typedef long fcntl_arg_t;
9860typedef int fcntl_arg_t;
9864fcntl_narg_len(
int cmd)
9871 len =
sizeof(fcntl_arg_t);
9879#ifdef F_DUPFD_CLOEXEC
9881 len =
sizeof(fcntl_arg_t);
9891 len =
sizeof(fcntl_arg_t);
9901 len =
sizeof(fcntl_arg_t);
9911 len =
sizeof(fcntl_arg_t);
9916 len =
sizeof(
struct f_owner_ex);
9921 len =
sizeof(
struct f_owner_ex);
9956 len =
sizeof(fcntl_arg_t);
9966 len =
sizeof(fcntl_arg_t);
9971 len =
sizeof(fcntl_arg_t);
9984fcntl_narg_len(
int cmd)
10002 else if (arg ==
Qtrue) {
10017 len = ioctl_narg_len(cmd);
10019 len = fcntl_narg_len((
int)cmd);
10024 if (slen <
len+1) {
10031 ptr[slen - 1] = 17;
10048 narg = setup_narg(cmd, &arg, 1);
10050 retval = do_ioctl(fptr->
fd, cmd, narg);
10056 if (
ptr[slen-1] != 17)
10058 ptr[slen-1] =
'\0';
10082 return rb_ioctl(io, req, arg);
10085#define rb_io_ioctl rb_f_notimplement
10096nogvl_fcntl(
void *
ptr)
10098 struct fcntl_arg *arg =
ptr;
10100#if defined(F_DUPFD)
10104 return (
VALUE)
fcntl(arg->fd, arg->cmd, arg->narg);
10108do_fcntl(
int fd,
int cmd,
long narg)
10111 struct fcntl_arg arg;
10118 if (retval != -1) {
10120#if defined(F_DUPFD)
10123#if defined(F_DUPFD_CLOEXEC)
10141 narg = setup_narg(cmd, &arg, 0);
10143 retval = do_fcntl(fptr->
fd, cmd, narg);
10149 if (
ptr[slen-1] != 17)
10151 ptr[slen-1] =
'\0';
10176 return rb_fcntl(io, req, arg);
10179#define rb_io_fcntl rb_f_notimplement
10182#if defined(HAVE_SYSCALL) || defined(HAVE___SYSCALL)
10221#if SIZEOF_VOIDP == 8 && defined(HAVE___SYSCALL) && SIZEOF_INT != 8
10222# define SYSCALL __syscall
10223# define NUM2SYSCALLID(x) NUM2LONG(x)
10224# define RETVAL2NUM(x) LONG2NUM(x)
10225# if SIZEOF_LONG == 8
10226 long num, retval = -1;
10227# elif SIZEOF_LONG_LONG == 8
10228 long long num, retval = -1;
10230# error ---->> it is asserted that __syscall takes the first argument and returns retval in 64bit signed integer. <<----
10232#elif defined(__linux__)
10233# define SYSCALL syscall
10234# define NUM2SYSCALLID(x) NUM2LONG(x)
10235# define RETVAL2NUM(x) LONG2NUM(x)
10243 long num, retval = -1;
10245# define SYSCALL syscall
10246# define NUM2SYSCALLID(x) NUM2INT(x)
10247# define RETVAL2NUM(x) INT2NUM(x)
10248 int num, retval = -1;
10254 "We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
10262 for (i =
argc - 1; i--; ) {
10277 retval = SYSCALL(
num);
10280 retval = SYSCALL(
num, arg[0]);
10283 retval = SYSCALL(
num, arg[0],arg[1]);
10286 retval = SYSCALL(
num, arg[0],arg[1],arg[2]);
10289 retval = SYSCALL(
num, arg[0],arg[1],arg[2],arg[3]);
10292 retval = SYSCALL(
num, arg[0],arg[1],arg[2],arg[3],arg[4]);
10295 retval = SYSCALL(
num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
10298 retval = SYSCALL(
num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
10304 return RETVAL2NUM(retval);
10306#undef NUM2SYSCALLID
10310#define rb_f_syscall rb_f_notimplement
10314io_new_instance(
VALUE args)
10320find_encoding(
VALUE v)
10335 enc2 = find_encoding(v1);
10344 enc = find_encoding(v2);
10351 enc = find_encoding(v2);
10363 rb_io_ext_int_to_encs(
NULL,
NULL, &enc, &enc2, 0);
10375 rb_io_ext_int_to_encs(find_encoding(v1),
NULL, &enc, &enc2, 0);
10381 validate_enc_binmode(&fptr->
mode, ecflags, enc, enc2);
10386 clear_codeconv(fptr);
10398io_encoding_set_v(
VALUE v)
10401 io_encoding_set(arg->
fptr, arg->
v1, arg->
v2, arg->
opt);
10406pipe_pair_close(
VALUE rw)
10409 return rb_ensure(io_close, rwp[0], io_close, rwp[1]);
10475 int pipes[2],
state;
10498 ies_args.fptr =
fptr;
10501 ies_args.opt =
opt;
10527#if DEFAULT_TEXTMODE
10532#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
10539#if DEFAULT_TEXTMODE
10541 fptr2->
mode &= ~FMODE_TEXTMODE;
10583 n = RARRAY_LENINT(v);
10587 arg->
io = rb_io_open(klass, path, vmode, vperm, opt);
10591io_s_foreach(
VALUE v)
10635 int orig_argc =
argc;
10641 extract_getline_args(
argc-1,
argv+1, &garg);
10642 open_key_args(self,
argc,
argv, opt, &arg);
10644 extract_getline_opts(opt, &garg);
10645 check_getline_args(&garg.rs, &garg.limit, garg.io = arg.
io);
10650io_s_readlines(
VALUE v)
10653 return io_readlines(arg, arg->
io);
10694 extract_getline_args(
argc-1,
argv+1, &garg);
10697 extract_getline_opts(opt, &garg);
10698 check_getline_args(&garg.rs, &garg.limit, garg.io = arg.
io);
10706 return io_read(arg->
argc, arg->
argv, arg->
io);
10716seek_before_access(
VALUE argp)
10785 if (arg.argc == 2) arg.argc = 1;
10821 arg.
io = rb_io_open_generic(
io,
argv[0], oflags,
fmode, &convconfig, 0);
10824 arg.argc = (
argc > 1) ? 1 : 0;
10841io_s_write0(
VALUE v)
10861 int mode = O_WRONLY|O_CREAT;
10868 open_key_args(klass,
argc,
argv, opt, &arg);
10871 if (binary) rb_io_binmode_m(arg.
io);
10976#ifdef HAVE_FCOPYFILE
10977 copyfile_state_t copyfile_state;
10982exec_interrupts(
void *arg)
10999#if defined(ERESTART)
11023rb_thread_scheduler_wait_for_single_fd(
void * _args)
11033# define IOWAIT_SYSCALL "poll"
11049 fds.events = events;
11051 return poll(&fds, 1, -1);
11054# define IOWAIT_SYSCALL "select"
11056nogvl_wait_for_single_fd(
VALUE th,
int fd,
short events)
11059 if (scheduler !=
Qnil) {
11099 }
while (ret < 0 && maygvl_copy_stream_continue_p(has_gvl, stp));
11116 }
while (ret < 0 && maygvl_copy_stream_continue_p(0, stp));
11126#ifdef USE_COPY_FILE_RANGE
11129simple_copy_file_range(
int in_fd,
off_t *in_offset,
int out_fd,
off_t *out_offset,
size_t count,
unsigned int flags)
11131#ifdef HAVE_COPY_FILE_RANGE
11132 return copy_file_range(in_fd, in_offset, out_fd, out_offset,
count, flags);
11134 return syscall(__NR_copy_file_range, in_fd, in_offset, out_fd, out_offset,
count, flags);
11143 off_t copy_length, src_offset, *src_offset_ptr;
11150 if (src_offset >= (
off_t)0) {
11151 src_offset_ptr = &src_offset;
11154 src_offset_ptr =
NULL;
11158 if (copy_length < (
off_t)0) {
11159 if (src_offset < (
off_t)0) {
11160 off_t current_offset;
11163 if (current_offset < (
off_t)0 && errno) {
11166 return (
int)current_offset;
11168 copy_length = src_size - current_offset;
11171 copy_length = src_size - src_offset;
11175 retry_copy_file_range:
11176# if SIZEOF_OFF_T > SIZEOF_SIZE_T
11180 ss = (ssize_t)copy_length;
11182 ss = simple_copy_file_range(stp->
src_fd, src_offset_ptr, stp->
dst_fd,
NULL, ss, 0);
11186 if (0 < copy_length) {
11187 goto retry_copy_file_range;
11191 if (maygvl_copy_stream_continue_p(0, stp)) {
11192 goto retry_copy_file_range;
11206#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
11210 int ret = nogvl_copy_stream_wait_write(stp);
11211 if (ret < 0)
return ret;
11213 goto retry_copy_file_range;
11219 if (flags != -1 && flags & O_APPEND) {
11225 stp->
syserr =
"copy_file_range";
11233#ifdef HAVE_FCOPYFILE
11258 if (end > (
off_t)0)
return 0;
11261 if (src_offset > (
off_t)0) {
11267 if (cur < (
off_t)0 && errno) {
11274 if (r < (
off_t)0 && errno) {
11280 stp->copyfile_state = copyfile_state_alloc();
11281 ret = fcopyfile(stp->
src_fd, stp->
dst_fd, stp->copyfile_state, COPYFILE_DATA);
11282 copyfile_state_get(stp->copyfile_state, COPYFILE_STATE_COPIED, &ss);
11286 if (src_offset > (
off_t)0) {
11291 if (r < (
off_t)0 && errno) {
11304 stp->
syserr =
"fcopyfile";
11312#ifdef HAVE_SENDFILE
11315# define USE_SENDFILE
11317# ifdef HAVE_SYS_SENDFILE_H
11318# include <sys/sendfile.h>
11324 return sendfile(out_fd, in_fd,
offset, (
size_t)
count);
11327# elif 0 || defined(__APPLE__)
11331# define USE_SENDFILE
11340 r = sendfile(in_fd, out_fd, pos, &
count,
NULL, 0);
11343 r = sendfile(in_fd, out_fd, pos, (
size_t)
count,
NULL, &sbytes, 0);
11345 if (r != 0 && sbytes == 0)
return r;
11352 return (ssize_t)sbytes;
11374 if ((stp->
dst_stat.st_mode & S_IFMT) != S_IFSOCK)
11379 use_pread = src_offset >= (
off_t)0;
11382 if (copy_length < (
off_t)0) {
11384 copy_length = src_size - src_offset;
11389 if (cur < (
off_t)0 && errno) {
11394 copy_length = src_size - cur;
11399# if SIZEOF_OFF_T > SIZEOF_SIZE_T
11403 ss = (ssize_t)copy_length;
11406 ss = simple_sendfile(stp->
dst_fd, stp->
src_fd, &src_offset, ss);
11414 if (0 < copy_length) {
11415 goto retry_sendfile;
11419 if (maygvl_copy_stream_continue_p(0, stp))
11420 goto retry_sendfile;
11433#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
11446 ret = maygvl_copy_stream_wait_read(0, stp);
11447 if (ret < 0)
return ret;
11449 ret = nogvl_copy_stream_wait_write(stp);
11450 if (ret < 0)
return ret;
11452 goto retry_sendfile;
11454 stp->
syserr =
"sendfile";
11463maygvl_read(
int has_gvl,
int fd,
void *
buf,
size_t count)
11491 if (maygvl_copy_stream_continue_p(has_gvl, stp))
11495#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
11499 int ret = maygvl_copy_stream_wait_read(has_gvl, stp);
11500 if (ret < 0)
return ret;
11523 if (maygvl_copy_stream_continue_p(0, stp))
11526 int ret = nogvl_copy_stream_wait_write(stp);
11527 if (ret < 0)
return ret;
11554 use_eof = copy_length < (
off_t)0;
11556 use_pread = src_offset >= (
off_t)0;
11562 if (r < (
off_t)0 && errno) {
11567 src_offset = (
off_t)-1;
11571 while (use_eof || 0 < copy_length) {
11572 if (!use_eof && copy_length < (
off_t)
sizeof(
buf)) {
11573 len = (size_t)copy_length;
11579 ss = maygvl_copy_stream_read(0, stp,
buf,
len, src_offset);
11584 ss = maygvl_copy_stream_read(0, stp,
buf,
len, (
off_t)-1);
11589 ret = nogvl_copy_stream_write(stp,
buf, ss);
11599nogvl_copy_stream_func(
void *arg)
11602#if defined(USE_SENDFILE) || defined(USE_COPY_FILE_RANGE) || defined(HAVE_FCOPYFILE)
11606#ifdef USE_COPY_FILE_RANGE
11607 ret = nogvl_copy_file_range(stp);
11612#ifdef HAVE_FCOPYFILE
11613 ret = nogvl_fcopyfile(stp);
11619 ret = nogvl_copy_stream_sendfile(stp);
11624 nogvl_copy_stream_read_write(stp);
11626#if defined(USE_SENDFILE) || defined(USE_COPY_FILE_RANGE) || defined(HAVE_FCOPYFILE)
11633copy_stream_fallback_body(
VALUE arg)
11636 const int buflen = 16*1024;
11641 ID read_method = id_readpartial;
11645 read_method = id_read;
11660 l = buflen < rest ? buflen : (
long)rest;
11665 if (read_method == id_read &&
NIL_P(rc))
11677 if (off >= (
off_t)0)
11682 stp->
total += numwrote;
11705copy_stream_body(
VALUE arg)
11709 rb_io_t *src_fptr = 0, *dst_fptr = 0;
11711 const int common_oflags = 0
11721 if (src_io ==
argf ||
11722 !(RB_TYPE_P(src_io,
T_FILE) ||
11730 if (!
NIL_P(tmp_io)) {
11733 else if (!RB_TYPE_P(src_io,
T_FILE)) {
11737 args[1] =
INT2NUM(O_RDONLY|common_oflags);
11747 if (stat_ret < 0) {
11755 if (dst_io ==
argf ||
11756 !(RB_TYPE_P(dst_io,
T_FILE) ||
11764 if (!
NIL_P(tmp_io)) {
11767 else if (!RB_TYPE_P(dst_io,
T_FILE)) {
11771 args[1] =
INT2NUM(O_WRONLY|O_CREAT|O_TRUNC|common_oflags);
11786 if (stat_ret < 0) {
11799 io_ascii8bit_binmode(dst_fptr);
11802 size_t len = src_fptr->
rbuf.len;
11822 if (dst_fptr && io_fflush(dst_fptr) < 0) {
11830 return copy_stream_fallback(stp);
11838copy_stream_finalize(
VALUE arg)
11842#ifdef HAVE_FCOPYFILE
11843 if (stp->copyfile_state) {
11844 copyfile_state_free(stp->copyfile_state);
11849 rb_io_close_m(stp->
src);
11852 rb_io_close_m(stp->
dst);
11909 st.copy_length = (
off_t)-1;
11911 st.copy_length =
NUM2OFFT(length);
11914 st.src_offset = (
off_t)-1;
11932rb_io_external_encoding(
VALUE io)
11957rb_io_internal_encoding(
VALUE io)
11991 if (!RB_TYPE_P(io,
T_FILE)) {
11997 io_encoding_set(fptr, v1, v2, opt);
12006 rb_io_set_encoding(1, &val,
rb_stdin);
12007 rb_io_set_encoding(1, &val,
rb_stdout);
12008 rb_io_set_encoding(1, &val,
rb_stderr);
12012global_argf_p(
VALUE arg)
12014 return arg ==
argf;
12128 return rb_io_tell(
ARGF.current_file);
12166 return rb_io_set_pos(
ARGF.current_file,
offset);
12191 old_lineno =
RFILE(
ARGF.current_file)->fptr->lineno;
12192 ret = rb_io_rewind(
ARGF.current_file);
12193 if (!global_argf_p(
argf)) {
12194 ARGF.last_lineno =
ARGF.lineno -= old_lineno;
12216 return rb_io_fileno(
ARGF.current_file);
12236 return ARGF.current_file;
12327 if (!
NIL_P(length)) {
12349 if (
ARGF.next_p != -1) {
12355 else if (
argc >= 1) {
12373argf_forward_call(
VALUE arg)
12459 tmp = io_getpartial(
argc,
argv,
ARGF.current_file, no_exception, nonblock);
12462 if (
ARGF.next_p == -1) {
12463 return io_nonblock_eof(no_exception);
12468 return io_nonblock_eof(no_exception);
12511 ch = rb_io_getc(
ARGF.current_file);
12547 if (!RB_TYPE_P(
ARGF.current_file,
T_FILE)) {
12587 if (!RB_TYPE_P(
ARGF.current_file,
T_FILE)) {
12591 ch = rb_io_getc(
ARGF.current_file);
12626 c = argf_getbyte(
argf);
12633#define FOREACH_ARGF() while (next_argv())
12638 const VALUE current =
ARGF.current_file;
12640 if (
ARGF.init_p == -1 || current !=
ARGF.current_file) {
12646#define ARGF_block_call(mid, argc, argv, func, argf) \
12647 rb_block_call_kw(ARGF.current_file, mid, argc, argv, \
12648 func, argf, rb_keyword_given_p())
12660 if (!global_argf_p(
argf)) {
12663 return argf_block_call_i(i,
argf,
argc,
argv, blockarg);
12832 return ARGF.filename;
12836argf_filename_getter(
ID id,
VALUE *var)
12838 return argf_filename(*var);
12863 return ARGF.current_file;
12923 if (
ARGF.init_p &&
ARGF.next_p == 0) {
12952 if (
ARGF.next_p != -1) {
12971 return rb_io_closed(
ARGF.current_file);
13005 return argf_inplace_mode_get(*var);
13046 argf_inplace_mode_set(*var, val);
13076argf_argv_getter(
ID id,
VALUE *var)
13078 return argf_argv(*var);
13130 c = rb_eEAGAINWaitWritable;
13132#if EAGAIN != EWOULDBLOCK
13134 c = rb_eEWOULDBLOCKWaitWritable;
13138 c = rb_eEINPROGRESSWaitWritable;
13147 c = rb_eEAGAINWaitReadable;
13149#if EAGAIN != EWOULDBLOCK
13151 c = rb_eEWOULDBLOCKWaitReadable;
13155 c = rb_eEINPROGRESSWaitReadable;
13162 rb_bug(
"invalid read/write type passed to rb_readwrite_sys_fail: %d", waiting);
13168get_LAST_READ_LINE(
ID _x,
VALUE *_y)
13339#include <sys/cygwin.h>
13340 static struct __cygwin_perfile pf[] =
13348 cygwin_internal(CW_PERFILE, pf);
13354 id_write = rb_intern_const(
"write");
13355 id_read = rb_intern_const(
"read");
13356 id_getc = rb_intern_const(
"getc");
13357 id_flush = rb_intern_const(
"flush");
13358 id_readpartial = rb_intern_const(
"readpartial");
13359 id_set_encoding = rb_intern_const(
"set_encoding");
13396#if EAGAIN == EWOULDBLOCK
13397 rb_eEWOULDBLOCKWaitReadable = rb_eEAGAINWaitReadable;
13400 rb_eEWOULDBLOCKWaitWritable = rb_eEAGAINWaitWritable;
13648 rb_define_method(rb_cARGF,
"external_encoding", argf_external_encoding, 0);
13649 rb_define_method(rb_cARGF,
"internal_encoding", argf_internal_encoding, 0);
13672#if defined (_WIN32) || defined(__CYGWIN__)
13673 atexit(pipe_atexit);
13680 sym_mode =
ID2SYM(rb_intern_const(
"mode"));
13681 sym_perm =
ID2SYM(rb_intern_const(
"perm"));
13682 sym_flags =
ID2SYM(rb_intern_const(
"flags"));
13683 sym_extenc =
ID2SYM(rb_intern_const(
"external_encoding"));
13684 sym_intenc =
ID2SYM(rb_intern_const(
"internal_encoding"));
13686 sym_open_args =
ID2SYM(rb_intern_const(
"open_args"));
13687 sym_textmode =
ID2SYM(rb_intern_const(
"textmode"));
13688 sym_binmode =
ID2SYM(rb_intern_const(
"binmode"));
13689 sym_autoclose =
ID2SYM(rb_intern_const(
"autoclose"));
13690 sym_normal =
ID2SYM(rb_intern_const(
"normal"));
13691 sym_sequential =
ID2SYM(rb_intern_const(
"sequential"));
13692 sym_random =
ID2SYM(rb_intern_const(
"random"));
13693 sym_willneed =
ID2SYM(rb_intern_const(
"willneed"));
13694 sym_dontneed =
ID2SYM(rb_intern_const(
"dontneed"));
13695 sym_noreuse =
ID2SYM(rb_intern_const(
"noreuse"));
13696 sym_SET =
ID2SYM(rb_intern_const(
"SET"));
13697 sym_CUR =
ID2SYM(rb_intern_const(
"CUR"));
13698 sym_END =
ID2SYM(rb_intern_const(
"END"));
13700 sym_DATA =
ID2SYM(rb_intern_const(
"DATA"));
13703 sym_HOLE =
ID2SYM(rb_intern_const(
"HOLE"));
13705 sym_wait_readable =
ID2SYM(rb_intern_const(
"wait_readable"));
13706 sym_wait_writable =
ID2SYM(rb_intern_const(
"wait_writable"));
VALUE rb_ary_shift(VALUE ary)
VALUE rb_to_array_type(VALUE ary)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_concat(VALUE x, VALUE y)
VALUE rb_check_array_type(VALUE ary)
VALUE rb_ary_entry(VALUE ary, long offset)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
#define UNREACHABLE_RETURN
#define rb_category_warn(category,...)
Our own, locale independent, character handling routines.
unsigned long ruby_strtoul(const char *str, char **endptr, int base)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
char * strchr(char *, char)
#define ENCINDEX_UTF_32BE
#define ENCINDEX_UTF_32LE
#define ENCINDEX_UTF_16BE
#define ENCINDEX_UTF_16LE
#define rb_utf8_encindex()
rb_encoding * rb_find_encoding(VALUE enc)
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
int rb_to_encoding_index(VALUE enc)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
rb_encoding * rb_ascii8bit_encoding(void)
rb_encoding * rb_enc_from_index(int index)
rb_encoding * rb_default_internal_encoding(void)
rb_encoding * rb_enc_get(VALUE obj)
rb_encoding * rb_default_external_encoding(void)
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
rb_encoding * rb_to_encoding(VALUE enc)
rb_encoding * rb_usascii_encoding(void)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
int rb_enc_find_index(const char *name)
int rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc)
char str[HTML_ESCAPE_MAX_LEN+1]
char * strrchr(const char *, const char)
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
VALUE rb_str_encode_ospath(VALUE path)
void rb_gc_force_recycle(VALUE obj)
void rb_gc_mark(VALUE ptr)
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
void rb_include_module(VALUE klass, VALUE module)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
VALUE rb_class_new(VALUE super)
Creates a new class.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_module_under(VALUE outer, const char *name)
ID rb_frame_this_func(void)
The original name of the current method.
int rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt,...)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
int rb_block_given_p(void)
Determines if the current method is given a block.
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
void rb_notimplement(void)
void rb_syserr_fail(int e, const char *mesg)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_enc_warn(rb_encoding *enc, const char *fmt,...)
VALUE rb_rescue2(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2,...)
An equivalent of rescue clause.
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
void rb_bug(const char *fmt,...)
void rb_syserr_fail_str(int e, VALUE mesg)
void rb_sys_fail_str(VALUE mesg)
void rb_fatal(const char *fmt,...)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
void rb_category_warning(rb_warning_category_t category, const char *fmt,...)
void rb_warn_deprecated(const char *fmt, const char *suggest,...)
void rb_warn(const char *fmt,...)
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
int rb_str_end_with_asciichar(VALUE str, int c)
void rb_sys_fail(const char *mesg)
void rb_mod_syserr_fail_str(VALUE mod, int e, VALUE mesg)
VALUE rb_eSystemCallError
VALUE rb_mKernel
Kernel module.
VALUE rb_check_to_int(VALUE)
Tries to convert val into Integer.
VALUE rb_cObject
Object class.
VALUE rb_any_to_s(VALUE)
Default implementation of #to_s.
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
VALUE rb_class_new_instance_kw(int, const VALUE *, VALUE, int)
int rb_bool_expected(VALUE, const char *)
VALUE rb_obj_class(VALUE)
VALUE rb_obj_dup(VALUE)
Equivalent to Object#dup in Ruby.
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
VALUE rb_convert_type_with_id(VALUE v, int t, const char *nam, ID mid)
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
VALUE rb_check_to_integer(VALUE, const char *)
Tries to convert val into Integer.
VALUE rb_to_int(VALUE)
Converts val into Integer.
unsigned char suffix[65536]
VALUE rb_check_hash_type(VALUE hash)
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
VALUE rb_hash_aref(VALUE hash, VALUE key)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
VALUE rb_hash_dup(VALUE hash)
#define ECONV_AFTER_OUTPUT
int rb_econv_prepare_options(VALUE opthash, VALUE *ecopts, int ecflags)
#define ENC_CODERANGE_7BIT
#define ENC_CODERANGE_VALID
VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags)
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR
#define rb_enc_left_char_head(s, p, e, enc)
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)
@ econv_undefined_conversion
@ econv_source_buffer_empty
@ econv_destination_buffer_full
@ econv_invalid_byte_sequence
int rb_econv_putbackable(rb_econv_t *ec)
int rb_enc_str_coderange(VALUE)
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
#define ENCODING_MAXNAMELEN
#define MBCLEN_NEEDMORE_LEN(ret)
#define ENCODING_GET(obj)
const char * rb_econv_asciicompat_encoding(const char *encname)
VALUE rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags)
rb_econv_t * rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts)
#define MBCLEN_CHARFOUND_LEN(ret)
#define rb_enc_asciicompat(enc)
void rb_econv_binmode(rb_econv_t *ec)
#define rb_enc_codepoint(p, e, enc)
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts)
VALUE rb_econv_make_exception(rb_econv_t *ec)
#define MBCLEN_INVALID_P(ret)
void rb_econv_check_error(rb_econv_t *ec)
#define ECONV_STATEFUL_DECORATOR_MASK
#define MBCLEN_NEEDMORE_P(ret)
#define rb_enc_mbminlen(enc)
#define ECONV_PARTIAL_INPUT
#define ECONV_ERROR_HANDLER_MASK
#define ENC_CODERANGE_BROKEN
long rb_str_coderange_scan_restartable(const char *, const char *, rb_encoding *, int *)
#define MBCLEN_CHARFOUND_P(ret)
void rb_econv_close(rb_econv_t *ec)
#define ECONV_NEWLINE_DECORATOR_MASK
#define ENC_CODERANGE_SET(obj, cr)
void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n)
#define ECONV_DEFAULT_NEWLINE_DECORATOR
Thin wrapper to ruby/config.h.
@ RB_WARN_CATEGORY_DEPRECATED
void rb_iter_break_value(VALUE)
#define RB_IO_WAIT_WRITABLE
#define RB_IO_WAIT_READABLE
VALUE rb_funcallv_kw(VALUE, ID, int, const VALUE *, int)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Defines RBIMPL_HAS_BUILTIN.
#define RETURN_ENUMERATOR(obj, argc, argv)
void rb_error_arity(int, int, int)
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds)
int rb_reserved_fd_p(int fd)
#define OBJ_INIT_COPY(obj, orig)
VALUE rb_lastline_get(void)
void rb_lastline_set(VALUE)
int rb_obj_method_arity(VALUE, ID)
rb_pid_t rb_waitpid(rb_pid_t pid, int *status, int flags)
void rb_last_status_set(int status, rb_pid_t pid)
VALUE rb_str_unlocktmp(VALUE)
VALUE rb_str_resize(VALUE, long)
#define rb_str_new(str, len)
VALUE rb_str_cat(VALUE, const char *, long)
#define rb_usascii_str_new(str, len)
void rb_str_set_len(VALUE, long)
VALUE rb_str_substr(VALUE, long, long)
void rb_str_modify(VALUE)
VALUE rb_str_buf_new(long)
VALUE rb_check_string_type(VALUE)
rb_gvar_setter_t rb_str_setter
VALUE rb_str_append(VALUE, VALUE)
VALUE rb_str_buf_cat_ascii(VALUE, const char *)
VALUE rb_str_new_frozen(VALUE)
void rb_str_modify_expand(VALUE, long)
VALUE rb_str_locktmp(VALUE)
VALUE rb_obj_as_string(VALUE)
size_t rb_str_capacity(VALUE)
#define rb_str_new_cstr(str)
int rb_thread_interrupted(VALUE thval)
void rb_thread_wait_fd(int)
VALUE rb_mutex_synchronize(VALUE mutex, VALUE(*func)(VALUE arg), VALUE arg)
void rb_thread_check_ints(void)
int rb_thread_fd_writable(int)
void rb_thread_atfork(void)
VALUE rb_thread_current(void)
void rb_thread_fd_close(int)
void rb_thread_sleep(int)
void rb_thread_schedule(void)
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
struct timeval rb_time_interval(VALUE num)
VALUE rb_class_name(VALUE)
void rb_set_class_path(VALUE, VALUE, const char *)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_ivar_set(VALUE, ID, VALUE)
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
int rb_respond_to(VALUE, ID)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
const char * rb_id2name(ID)
ID rb_intern(const char *)
void rb_define_global_const(const char *, VALUE)
rb_gvar_setter_t rb_gvar_readonly_setter
void rb_define_const(VALUE, const char *, VALUE)
void rb_define_readonly_variable(const char *, const VALUE *)
#define FMODE_SETENC_BY_BOM
struct rb_io_enc_t rb_io_enc_t
#define RB_IO_POINTER(obj, fp)
struct rb_io_buffer_t rb_io_buffer_t
void * memmove(void *, const void *, size_t)
void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
void * rb_thread_call_without_gvl2(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
Internal header aggregating init functions.
Internal header for Encoding.
#define rb_syserr_fail_path(err, path)
#define rb_sys_fail_path(path)
Internal header for Numeric.
VALUE rb_int_modulo(VALUE x, VALUE y)
VALUE rb_fix_plus(VALUE x, VALUE y)
Internal header for Object.
Internal header for Process.
struct rb_execarg * rb_execarg_get(VALUE execarg_obj)
void rb_execarg_parent_end(VALUE execarg_obj)
rb_pid_t rb_fork_ruby(int *status)
void rb_last_status_clear(void)
void rb_execarg_setenv(VALUE execarg_obj, VALUE env)
VALUE rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash)
int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen)
VALUE rb_execarg_new(int argc, const VALUE *argv, int accept_shell, int allow_exc_opt)
void rb_execarg_parent_start(VALUE execarg_obj)
int rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
int rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char *errmsg, size_t errmsg_buflen)
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)
VALUE rb_str_locktmp_ensure(VALUE str, VALUE(*func)(VALUE), VALUE arg)
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len, rb_encoding *from, int ecflags, VALUE ecopts)
#define rb_fstring_lit(str)
VALUE rb_str_tmp_frozen_acquire(VALUE str)
void rb_str_tmp_frozen_release(VALUE str, VALUE tmp)
VALUE rb_str_chomp_string(VALUE str, VALUE chomp)
Internal header for Thread.
void rb_mutex_allow_trap(VALUE self, int val)
VALUE rb_mutex_owned_p(VALUE self)
int rb_thread_to_be_killed(VALUE thread)
VALUE rb_uninterruptible(VALUE(*b_proc)(VALUE), VALUE data)
void rb_thread_execute_interrupts(VALUE th)
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
int rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout)
void rb_gvar_ractor_local(const char *name)
#define rb_method_basic_definition_p(...)
#define rb_io_fptr_finalize(fptr)
VALUE rb_io_gets(VALUE io)
int rb_io_wait_writable(int f)
#define io_seek(fptr, ofs, whence)
int rb_io_modestr_fmode(const char *modestr)
VALUE rb_io_taint_check(VALUE io)
#define do_write_retry(code)
VALUE rb_io_get_io(VALUE io)
VALUE rb_io_addstr(VALUE io, VALUE str)
void rb_io_fptr_finalize_internal(void *ptr)
void rb_io_read_check(rb_io_t *fptr)
int rb_io_modestr_oflags(const char *modestr)
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite waiting, int n, const char *mesg)
VALUE rb_io_fdopen(int fd, int oflags, const char *path)
#define NEXT_ARGF_FORWARD(argc, argv)
VALUE rb_io_ungetbyte(VALUE io, VALUE b)
VALUE rb_io_gets_internal(VALUE io)
int rb_io_wait_readable(int f)
VALUE rb_io_getbyte(VALUE io)
#define SET_BINARY_MODE_WITH_SEEK_CUR(fptr)
void ruby_set_inplace_mode(const char *suffix)
#define NUM2IOCTLREQ(num)
int rb_cloexec_dup2(int oldfd, int newfd)
void rb_write_error_str(VALUE mesg)
int rb_wait_for_single_fd(int fd, int events, struct timeval *timeout)
#define READ_DATA_PENDING(fptr)
void rb_io_check_byte_readable(rb_io_t *fptr)
rb_io_t * rb_io_make_open_file(VALUE obj)
#define READ_DATA_PENDING_COUNT(fptr)
void rb_io_check_readable(rb_io_t *fptr)
#define rb_io_close_on_exec_p
#define ARGF_GENERIC_INPUT_P()
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
void rb_maygvl_fd_fix_cloexec(int fd)
#define READ_CHAR_PENDING_PTR(fptr)
#define FMODE_SIGNAL_ON_EPIPE
#define fptr_signal_on_epipe(fptr)
#define NEED_WRITECONV(fptr)
int rb_io_oflags_fmode(int oflags)
VALUE rb_io_prep_stderr(void)
#define MODE_BTMODE(a, b, c)
#define no_exception_p(opts)
VALUE rb_io_prep_stdout(void)
void rb_update_max_fd(int fd)
FILE * rb_fdopen(int fd, const char *modestr)
int rb_gc_for_fd(int err)
VALUE rb_io_write(VALUE io, VALUE str)
#define NEED_NEWLINE_DECORATOR_ON_WRITE(fptr)
#define rb_sys_fail_on_write(fptr)
VALUE rb_io_prep_stdin(void)
VALUE rb_io_puts(int argc, const VALUE *argv, VALUE out)
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
FILE * rb_io_stdio_file(rb_io_t *fptr)
#define PREP_STDIO_NAME(f)
#define DEFULT_IOCTL_NARG_LEN
VALUE rb_io_eof(VALUE io)
size_t rb_io_memsize(const rb_io_t *fptr)
void rb_stdio_set_default_encoding(void)
#define NEED_NEWLINE_DECORATOR_ON_READ(fptr)
struct rb_io_enc_t convconfig_t
#define ARGF_FORWARD(argc, argv)
#define READ_DATA_PENDING_PTR(fptr)
#define NEED_READCONV(fptr)
#define is_socket(fd, path)
#define READ_CHAR_PENDING(fptr)
void rb_fd_fix_cloexec(int fd)
VALUE rb_io_flush(VALUE io)
#define READ_CHAR_PENDING_COUNT(fptr)
void rb_io_check_initialized(rb_io_t *fptr)
VALUE rb_io_ascii8bit_binmode(VALUE io)
VALUE rb_io_binmode(VALUE io)
VALUE rb_io_check_io(VALUE io)
VALUE rb_io_printf(int argc, const VALUE *argv, VALUE out)
VALUE rb_io_ungetc(VALUE io, VALUE c)
#define IO_RBUF_CAPA_FOR(fptr)
#define MORE_CHAR_SUSPENDED
#define NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr)
void rb_io_unbuffered(rb_io_t *fptr)
int rb_notify_fd_close(int fd, struct list_head *)
int rb_stderr_tty_p(void)
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size)
VALUE rb_io_flush_raw(VALUE io, int sync)
int rb_cloexec_fcntl_dupfd(int fd, int minfd)
#define MODE_BINARY(a, b)
#define MODE_BTXMODE(a, b, c, d, e, f)
void rb_io_check_char_readable(rb_io_t *fptr)
#define READ_DATA_BUFFERED(fptr)
#define SET_BINARY_MODE(fptr)
#define ARGF_block_call(mid, argc, argv, func, argf)
int rb_io_read_pending(rb_io_t *fptr)
VALUE rb_io_get_write_io(VALUE io)
void rb_io_set_nonblock(rb_io_t *fptr)
void rb_readwrite_sys_fail(enum rb_io_wait_readwrite waiting, const char *mesg)
VALUE rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt)
#define MORE_CHAR_FINISHED
#define rb_io_set_close_on_exec
VALUE rb_file_open(const char *fname, const char *modestr)
int rb_cloexec_pipe(int descriptors[2])
int rb_cloexec_dup(int oldfd)
VALUE rb_io_set_write_io(VALUE io, VALUE w)
VALUE rb_file_open_str(VALUE fname, const char *modestr)
void rb_write_error(const char *mesg)
void rb_io_check_writable(rb_io_t *fptr)
#define SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags)
char * rb_execarg_commandline(const struct rb_execarg *eargp, VALUE *prog)
VALUE rb_io_print(int argc, const VALUE *argv, VALUE out)
void rb_io_check_closed(rb_io_t *fptr)
void rb_write_error2(const char *mesg, long len)
void rb_io_synchronized(rb_io_t *fptr)
VALUE rb_io_wait(VALUE io, VALUE events, VALUE timeout)
VALUE rb_io_close(VALUE io)
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
VALUE rb_yield_values2(int n, const VALUE *argv)
int memcmp(const void *s1, const void *s2, size_t len)
#define MEMZERO(p, type, n)
#define MEMMOVE(p1, p2, type, n)
void rb_define_hooked_variable(const char *q, VALUE *w, type *e, void_type *r)
Define a function-backended global variable.
void rb_define_virtual_variable(const char *q, type *w, void_type *e)
Define a function-backended global variable.
#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n)
#define RARRAY_CONST_PTR(s)
#define RARRAY_AREF(a, i)
void rb_ractor_stdout_set(VALUE)
void rb_ractor_stdin_set(VALUE)
VALUE rb_ractor_stderr(void)
VALUE rb_ractor_stdin(void)
VALUE rb_ractor_stdout(void)
void rb_ractor_stderr_set(VALUE)
#define SafeStringValue(v)
#define RSTRING_GETMEM(str, ptrvar, lenvar)
#define StringValueCStr(v)
#define RUBY_TYPED_DEFAULT_FREE
@ RUBY_TYPED_FREE_IMMEDIATELY
#define TypedData_Make_Struct(klass, type, data_type, sval)
#define ATOMIC_CAS(var, oldval, newval)
#define RB_INTEGER_TYPE_P(obj)
#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS
#define RB_PASS_CALLED_KEYWORDS
Internal header for Scheduler.
VALUE rb_scheduler_io_wait_writable(VALUE scheduler, VALUE io)
VALUE rb_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout)
VALUE rb_scheduler_current()
VALUE rb_scheduler_timeout(struct timeval *timeout)
int rb_scheduler_supports_io_read(VALUE scheduler)
VALUE rb_scheduler_io_wait_readable(VALUE scheduler, VALUE io)
VALUE rb_thread_scheduler_current(VALUE thread)
int rb_scheduler_supports_io_write(VALUE scheduler)
VALUE rb_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
VALUE rb_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length)
int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *)
rb_atomic_t cnt[RUBY_NSIG]
VALUE rb_str_catf(VALUE, const char *,...)
VALUE rb_f_sprintf(int, const VALUE *)
VALUE rb_sprintf(const char *,...)
size_t strlen(const char *)
#define rb_io_extract_modeenc
struct rb_execarg::@113::@114 sh
struct rb_execarg::@113::@115 cmd
union rb_execarg::@113 invoke
struct rb_io_t::rb_io_enc_t encs
VALUE writeconv_asciicompat
int writeconv_initialized
int writeconv_pre_ecflags
VALUE writeconv_pre_ecopts
VALUE tied_io_for_writing
void(* finalize)(struct rb_io_t *, int)
Internal header for Encoding::Converter.
size_t rb_econv_memsize(rb_econv_t *)
void error(const char *msg)
#define VM_UNREACHABLE(func)
int fchmod(int fd, int mode)
long rb_w32_write_console(uintptr_t, int)
SOCKET rb_w32_get_osfhandle(int)
char rb_w32_fd_is_text(int)
int rb_w32_set_nonblock(int)
int chown(const char *, int, int)
if((ID)(DISPID) nameid !=nameid)
int write(ozstream &zs, const T *x, Items items)
int read(izstream &zs, T *x, Items items)
#define ZALLOC(strm, items, size)