1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15: #include "ruby/ruby.h"
16: #include "ruby/io.h"
17: #include "ruby/signal.h"
18: #include <ctype.h>
19: #include <errno.h>
20:
21: #if defined(DOSISH) || defined(__CYGWIN__)
22: #include <io.h>
23: #endif
24:
25: #include <sys/types.h>
26: #if !defined(_WIN32) && !defined(__DJGPP__)
27: # if defined(__BEOS__)
28: # include <net/socket.h>
29: # else
30: # include <sys/socket.h>
31: # endif
32: #endif
33:
34: #if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32) || defined(__human68k__) || defined(__EMX__) || defined(__BEOS__)
35: # define NO_SAFE_RENAME
36: #endif
37:
38: #if defined(MSDOS) || defined(__CYGWIN__) || defined(_WIN32)
39: # define NO_LONG_FNAME
40: #endif
41:
42: #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(sun) || defined(_nec_ews)
43: # define USE_SETVBUF
44: #endif
45:
46: #ifdef __QNXNTO__
47: #include "unix.h"
48: #endif
49:
50: #include <sys/types.h>
51: #if defined(HAVE_SYS_IOCTL_H) && !defined(DJGPP) && !defined(_WIN32) && !defined(__human68k__)
52: #include <sys/ioctl.h>
53: #endif
54: #if defined(HAVE_FCNTL_H) || defined(_WIN32)
55: #include <fcntl.h>
56: #elif defined(HAVE_SYS_FCNTL_H)
57: #include <sys/fcntl.h>
58: #endif
59:
60: #if !HAVE_OFF_T && !defined(off_t)
61: # define off_t long
62: #endif
63:
64: #include <sys/stat.h>
65:
66:
67: #if defined(HAVE_SYS_PARAM_H) && !(defined(__EMX__) || defined(__HIUX_MPP__))
68: # include <sys/param.h>
69: #endif
70:
71: #if !defined NOFILE
72: # define NOFILE 64
73: #endif
74:
75: #ifdef HAVE_UNISTD_H
76: #include <unistd.h>
77: #endif
78:
79: #ifdef HAVE_SYSCALL_H
80: #include <syscall.h>
81: #elif defined HAVE_SYS_SYSCALL_H
82: #include <sys/syscall.h>
83: #endif
84:
85: extern void Init_File(void);
86:
87: #ifdef __BEOS__
88: # ifndef NOFILE
89: # define NOFILE (OPEN_MAX)
90: # endif
91: #include <net/socket.h>
92: #endif
93:
94: #include "ruby/util.h"
95:
96: #ifndef O_ACCMODE
97: #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
98: #endif
99:
100: #if SIZEOF_OFF_T > SIZEOF_LONG && !defined(HAVE_LONG_LONG)
101: # error off_t is bigger than long, but you have no long long...
102: #endif
103:
104: #ifndef PIPE_BUF
105: # ifdef _POSIX_PIPE_BUF
106: # define PIPE_BUF _POSIX_PIPE_BUF
107: # else
108: # define PIPE_BUF 512
109: # endif
110: #endif
111:
112: VALUE rb_cIO;
113: VALUE rb_eEOFError;
114: VALUE rb_eIOError;
115:
116: VALUE rb_stdin, rb_stdout, rb_stderr;
117: VALUE rb_deferr;
118: static VALUE orig_stdout, orig_stderr;
119:
120: VALUE rb_output_fs;
121: VALUE rb_rs;
122: VALUE rb_output_rs;
123: VALUE rb_default_rs;
124:
125: static VALUE argf;
126:
127: static ID id_write, id_read, id_getc, id_flush, id_encode;
128:
129: extern char *ruby_inplace_mode;
130:
131: struct timeval rb_time_interval(VALUE);
132:
133: static VALUE filename, current_file;
134: static int gets_lineno;
135: static int init_p = 0, next_p = 0;
136: static VALUE lineno = INT2FIX(0);
137:
138: #ifdef _STDIO_USES_IOSTREAM
139: # ifdef _IO_fpos_t
140: # define STDIO_READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end)
141: # else
142: # define STDIO_READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr)
143: # endif
144: #elif defined(FILE_COUNT)
145: # define STDIO_READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0)
146: #elif defined(FILE_READEND)
147: # define STDIO_READ_DATA_PENDING(fp) ((fp)->FILE_READPTR < (fp)->FILE_READEND)
148: #elif defined(__BEOS__)
149: # define STDIO_READ_DATA_PENDING(fp) (fp->_state._eof == 0)
150: #elif defined(__VMS)
151: # define STDIO_READ_DATA_PENDING(fp) (((unsigned int)(*(fp))->_cnt) > 0)
152: #else
153: # define STDIO_READ_DATA_PENDING(fp) (!feof(fp))
154: #endif
155:
156: #if defined(__VMS)
157: #define fopen(file_spec, mode) fopen(file_spec, mode, "rfm=stmlf")
158: #define open(file_spec, flags, mode) open(file_spec, flags, mode, "rfm=stmlf")
159: #endif
160:
161: #define GetWriteIO(io) rb_io_get_write_io(io)
162:
163: #define READ_DATA_PENDING(fptr) ((fptr)->rbuf_len)
164: #define READ_DATA_PENDING_COUNT(fptr) ((fptr)->rbuf_len)
165: #define READ_DATA_PENDING_PTR(fptr) ((fptr)->rbuf+(fptr)->rbuf_off)
166: #define READ_DATA_BUFFERED(fptr) READ_DATA_PENDING(fptr)
167:
168: #define READ_CHECK(fptr) do {\
169: if (!READ_DATA_PENDING(fptr)) {\
170: rb_thread_wait_fd((fptr)->fd);\
171: rb_io_check_closed(fptr);\
172: }\
173: } while(0)
174:
175: #ifndef S_ISSOCK
176: # ifdef _S_ISSOCK
177: # define S_ISSOCK(m) _S_ISSOCK(m)
178: # else
179: # ifdef _S_IFSOCK
180: # define S_ISSOCK(m) ((m & S_IFMT) == _S_IFSOCK)
181: # else
182: # ifdef S_IFSOCK
183: # define S_ISSOCK(m) ((m & S_IFMT) == S_IFSOCK)
184: # endif
185: # endif
186: # endif
187: #endif
188:
189: #if defined(_WIN32)
190: #define is_socket(fd, path) rb_w32_is_socket(fd)
191: #elif !defined(S_ISSOCK)
192: #define is_socket(fd, path) 0
193: #define shutdown(a,b) 0
194: #else
195: static int
196: is_socket(int fd, const char *path)
197: {
198: struct stat sbuf;
199: if (fstat(fd, &sbuf) < 0)
200: rb_sys_fail(path);
201: return S_ISSOCK(sbuf.st_mode);
202: }
203: #endif
204:
205: void
206: rb_eof_error(void)
207: {
208: rb_raise(rb_eEOFError, "end of file reached");
209: }
210:
211: VALUE
212: rb_io_taint_check(VALUE io)
213: {
214: if (!OBJ_TAINTED(io) && rb_safe_level() >= 4)
215: rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
216: rb_check_frozen(io);
217: return io;
218: }
219:
220: void
221: rb_io_check_initialized(rb_io_t *fptr)
222: {
223: if (!fptr) {
224: rb_raise(rb_eIOError, "uninitialized stream");
225: }
226: }
227:
228: void
229: rb_io_check_closed(rb_io_t *fptr)
230: {
231: rb_io_check_initialized(fptr);
232: if (fptr->fd < 0) {
233: rb_raise(rb_eIOError, "closed stream");
234: }
235: }
236:
237: static int io_fflush(rb_io_t *);
238:
239: static VALUE
240: rb_io_get_io(VALUE io)
241: {
242: return rb_convert_type(io, T_FILE, "IO", "to_io");
243: }
244:
245: static VALUE
246: rb_io_check_io(VALUE io)
247: {
248: return rb_check_convert_type(io, T_FILE, "IO", "to_io");
249: }
250:
251: VALUE
252: rb_io_get_write_io(VALUE io)
253: {
254: VALUE write_io;
255: write_io = RFILE(io)->fptr->tied_io_for_writing;
256: if (write_io) {
257: return write_io;
258: }
259: return io;
260: }
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273: static VALUE
274: rb_io_s_try_convert(VALUE dummy, VALUE io)
275: {
276: return rb_io_check_io(io);
277: }
278:
279: static void
280: io_unread(rb_io_t *fptr)
281: {
282: off_t r;
283: rb_io_check_closed(fptr);
284: if (fptr->rbuf_len == 0 || fptr->mode & FMODE_DUPLEX)
285: return;
286:
287: r = lseek(fptr->fd, -fptr->rbuf_len, SEEK_CUR);
288: if (r < 0) {
289: if (errno == ESPIPE)
290: fptr->mode |= FMODE_DUPLEX;
291: return;
292: }
293: fptr->rbuf_off = 0;
294: fptr->rbuf_len = 0;
295: return;
296: }
297:
298: static void
299: io_ungetc(VALUE str, rb_io_t *fptr)
300: {
301: int len = RSTRING_LEN(str);
302:
303: if (fptr->rbuf == NULL) {
304: fptr->rbuf_off = 0;
305: fptr->rbuf_len = 0;
306: if (len > 8192)
307: fptr->rbuf_capa = len;
308: else
309: fptr->rbuf_capa = 8192;
310: fptr->rbuf = ALLOC_N(char, fptr->rbuf_capa);
311: }
312: if (fptr->rbuf_off < len) {
313: rb_raise(rb_eIOError, "ungetc failed");
314: }
315: fptr->rbuf_off-=len;
316: fptr->rbuf_len+=len;
317: MEMMOVE(fptr->rbuf+fptr->rbuf_off, RSTRING_PTR(str), char, len);
318: }
319:
320: static rb_io_t *
321: flush_before_seek(rb_io_t *fptr)
322: {
323: io_fflush(fptr);
324: io_unread(fptr);
325: errno = 0;
326: return fptr;
327: }
328:
329: #define io_seek(fptr, ofs, whence) lseek(flush_before_seek(fptr)->fd, ofs, whence)
330: #define io_tell(fptr) lseek(flush_before_seek(fptr)->fd, 0, SEEK_CUR)
331:
332: #ifndef SEEK_CUR
333: # define SEEK_SET 0
334: # define SEEK_CUR 1
335: # define SEEK_END 2
336: #endif
337:
338: #define FMODE_SYNCWRITE (FMODE_SYNC|FMODE_WRITABLE)
339:
340: void
341: rb_io_check_readable(rb_io_t *fptr)
342: {
343: rb_io_check_closed(fptr);
344: if (!(fptr->mode & FMODE_READABLE)) {
345: rb_raise(rb_eIOError, "not opened for reading");
346: }
347: if (fptr->wbuf_len) {
348: io_fflush(fptr);
349: }
350: if (!fptr->enc && fptr->fd == 0) {
351: fptr->enc = rb_default_external_encoding();
352: }
353: }
354:
355: static rb_encoding*
356: io_read_encoding(rb_io_t *fptr)
357: {
358: if (fptr->enc) {
359: return fptr->enc;
360: }
361: return (fptr->mode & FMODE_BINMODE)
362: ? rb_ascii8bit_encoding()
363: : rb_default_external_encoding();
364: }
365:
366: static rb_encoding*
367: io_input_encoding(rb_io_t *fptr)
368: {
369: if (fptr->enc2) {
370: return fptr->enc2;
371: }
372: return io_read_encoding(fptr);
373: }
374:
375: void
376: rb_io_check_writable(rb_io_t *fptr)
377: {
378: rb_io_check_closed(fptr);
379: if (!(fptr->mode & FMODE_WRITABLE)) {
380: rb_raise(rb_eIOError, "not opened for writing");
381: }
382: if (fptr->rbuf_len) {
383: io_unread(fptr);
384: }
385: }
386:
387: int
388: rb_read_pending(FILE *fp)
389: {
390: return STDIO_READ_DATA_PENDING(fp);
391: }
392:
393: int
394: rb_io_read_pending(rb_io_t *fptr)
395: {
396: return READ_DATA_PENDING(fptr);
397: }
398:
399: void
400: rb_read_check(FILE *fp)
401: {
402: if (!STDIO_READ_DATA_PENDING(fp)) {
403: rb_thread_wait_fd(fileno(fp));
404: }
405: }
406:
407: void
408: rb_io_read_check(rb_io_t *fptr)
409: {
410: if (!READ_DATA_PENDING(fptr)) {
411: rb_thread_wait_fd(fptr->fd);
412: }
413: return;
414: }
415:
416: static int
417: ruby_dup(int orig)
418: {
419: int fd;
420:
421: fd = dup(orig);
422: if (fd < 0) {
423: if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
424: rb_gc();
425: fd = dup(orig);
426: }
427: if (fd < 0) {
428: rb_sys_fail(0);
429: }
430: }
431: return fd;
432: }
433:
434: static VALUE
435: io_alloc(VALUE klass)
436: {
437: NEWOBJ(io, struct RFile);
438: OBJSETUP(io, klass, T_FILE);
439:
440: io->fptr = 0;
441:
442: return (VALUE)io;
443: }
444:
445: #ifndef S_ISREG
446: # define S_ISREG(m) ((m & S_IFMT) == S_IFREG)
447: #endif
448:
449: static int
450: wsplit_p(rb_io_t *fptr)
451: {
452: int r;
453: if (!(fptr->mode & FMODE_WSPLIT_INITIALIZED)) {
454: struct stat buf;
455: if (fstat(fptr->fd, &buf) == 0 &&
456: !S_ISREG(buf.st_mode)
457: #if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(O_NONBLOCK)
458: && (r = fcntl(fptr->fd, F_GETFL)) != -1 &&
459: !(r & O_NONBLOCK)
460: #endif
461: ) {
462: fptr->mode |= FMODE_WSPLIT;
463: }
464: fptr->mode |= FMODE_WSPLIT_INITIALIZED;
465: }
466: return fptr->mode & FMODE_WSPLIT;
467: }
468:
469: struct io_internal_struct {
470: int fd;
471: void *buf;
472: size_t capa;
473: int is_read;
474: };
475:
476: static VALUE
477: internal_io_func(void *ptr)
478: {
479: struct io_internal_struct *iis = (struct io_internal_struct*)ptr;
480: if (iis->is_read) {
481: return read(iis->fd, iis->buf, iis->capa);
482: }
483: else {
484: return write(iis->fd, iis->buf, iis->capa);
485: }
486: }
487:
488: static int
489: rb_read_internal(int fd, void *buf, size_t count)
490: {
491: struct io_internal_struct iis;
492: iis.fd = fd;
493: iis.buf = buf;
494: iis.capa = count;
495: iis.is_read = 1;
496:
497: return rb_thread_blocking_region(internal_io_func, &iis, RB_UBF_DFL, 0);
498: }
499:
500: static int
501: rb_write_internal(int fd, void *buf, size_t count)
502: {
503: struct io_internal_struct iis;
504: iis.fd = fd;
505: iis.buf = buf;
506: iis.capa = count;
507: iis.is_read = 0;
508:
509: return rb_thread_blocking_region(internal_io_func, &iis, RB_UBF_DFL, 0);
510: }
511:
512: static int
513: io_fflush(rb_io_t *fptr)
514: {
515: int r, l;
516: int wbuf_off, wbuf_len;
517:
518: rb_io_check_closed(fptr);
519: if (fptr->wbuf_len == 0)
520: return 0;
521: if (!rb_thread_fd_writable(fptr->fd)) {
522: rb_io_check_closed(fptr);
523: }
524: retry:
525: if (fptr->wbuf_len == 0)
526: return 0;
527: wbuf_off = fptr->wbuf_off;
528: wbuf_len = fptr->wbuf_len;
529: l = fptr->wbuf_len;
530: if (PIPE_BUF < l &&
531: !rb_thread_critical &&
532: !rb_thread_alone() &&
533: wsplit_p(fptr)) {
534: l = PIPE_BUF;
535: }
536: r = rb_write_internal(fptr->fd, fptr->wbuf+fptr->wbuf_off, l);
537:
538: if (r == fptr->wbuf_len) {
539: fptr->wbuf_off = 0;
540: fptr->wbuf_len = 0;
541: return 0;
542: }
543: if (0 <= r) {
544: fptr->wbuf_off = (wbuf_off += r);
545: fptr->wbuf_len = (wbuf_len -= r);
546: errno = EAGAIN;
547: }
548: if (rb_io_wait_writable(fptr->fd)) {
549: rb_io_check_closed(fptr);
550: goto retry;
551: }
552: return -1;
553: }
554:
555: #ifdef HAVE_RB_FD_INIT
556: static VALUE
557: wait_readable(VALUE p)
558: {
559: rb_fdset_t *rfds = (rb_fdset_t *)p;
560:
561: return rb_thread_select(rb_fd_max(rfds), rb_fd_ptr(rfds), NULL, NULL, NULL);
562: }
563: #endif
564:
565: int
566: rb_io_wait_readable(int f)
567: {
568: rb_fdset_t rfds;
569:
570: switch (errno) {
571: case EINTR:
572: #if defined(ERESTART)
573: case ERESTART:
574: #endif
575: rb_thread_wait_fd(f);
576: return Qtrue;
577:
578: case EAGAIN:
579: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
580: case EWOULDBLOCK:
581: #endif
582: rb_fd_init(&rfds);
583: rb_fd_set(f, &rfds);
584: #ifdef HAVE_RB_FD_INIT
585: rb_ensure(wait_readable, (VALUE)&rfds,
586: (VALUE (*)(VALUE))rb_fd_term, (VALUE)&rfds);
587: #else
588: rb_thread_select(f + 1, &rfds, NULL, NULL, NULL);
589: #endif
590: return Qtrue;
591:
592: default:
593: return Qfalse;
594: }
595: }
596