1/**********************************************************************
2
3  rubyio.h -
4
5  $Author: nagachika $
6  created at: Fri Nov 12 16:47:09 JST 1993
7
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10**********************************************************************/
11
12#ifndef RUBY_IO_H
13#define RUBY_IO_H 1
14
15#if defined(__cplusplus)
16extern "C" {
17#if 0
18} /* satisfy cc-mode */
19#endif
20#endif
21
22#include <stdio.h>
23#include <errno.h>
24#include "ruby/encoding.h"
25
26#if defined(HAVE_STDIO_EXT_H)
27#include <stdio_ext.h>
28#endif
29
30#include "ruby/config.h"
31#if defined(HAVE_POLL)
32#  ifdef _AIX
33#    define reqevents events
34#    define rtnevents revents
35#  endif
36#  include <poll.h>
37#  ifdef _AIX
38#    undef reqevents
39#    undef rtnevents
40#    undef events
41#    undef revents
42#  endif
43#  define RB_WAITFD_IN  POLLIN
44#  define RB_WAITFD_PRI POLLPRI
45#  define RB_WAITFD_OUT POLLOUT
46#else
47#  define RB_WAITFD_IN  0x001
48#  define RB_WAITFD_PRI 0x002
49#  define RB_WAITFD_OUT 0x004
50#endif
51
52#if defined __GNUC__ && __GNUC__ >= 4
53#pragma GCC visibility push(default)
54#endif
55
56typedef struct {
57    char *ptr;                  /* off + len <= capa */
58    int off;
59    int len;
60    int capa;
61} rb_io_buffer_t;
62
63typedef struct rb_io_t {
64    int fd;                     /* file descriptor */
65    FILE *stdio_file;		/* stdio ptr for read/write if available */
66    int mode;			/* mode flags: FMODE_XXXs */
67    rb_pid_t pid;		/* child's pid (for pipes) */
68    int lineno;			/* number of lines read */
69    VALUE pathv;		/* pathname for file */
70    void (*finalize)(struct rb_io_t*,int); /* finalize proc */
71
72    rb_io_buffer_t wbuf, rbuf;
73
74    VALUE tied_io_for_writing;
75
76    /*
77     * enc  enc2 read action                      write action
78     * NULL NULL force_encoding(default_external) write the byte sequence of str
79     * e1   NULL force_encoding(e1)               convert str.encoding to e1
80     * e1   e2   convert from e2 to e1            convert str.encoding to e2
81     */
82    struct rb_io_enc_t {
83        rb_encoding *enc;
84        rb_encoding *enc2;
85        int ecflags;
86        VALUE ecopts;
87    } encs;
88
89    rb_econv_t *readconv;
90    rb_io_buffer_t cbuf;
91
92    rb_econv_t *writeconv;
93    VALUE writeconv_asciicompat;
94    int writeconv_pre_ecflags;
95    VALUE writeconv_pre_ecopts;
96    int writeconv_initialized;
97
98    VALUE write_lock;
99} rb_io_t;
100
101#define HAVE_RB_IO_T 1
102
103#define FMODE_READABLE              0x00000001
104#define FMODE_WRITABLE              0x00000002
105#define FMODE_READWRITE             (FMODE_READABLE|FMODE_WRITABLE)
106#define FMODE_BINMODE               0x00000004
107#define FMODE_SYNC                  0x00000008
108#define FMODE_TTY                   0x00000010
109#define FMODE_DUPLEX                0x00000020
110#define FMODE_APPEND                0x00000040
111#define FMODE_CREATE                0x00000080
112/* #define FMODE_NOREVLOOKUP        0x00000100 */
113#define FMODE_WSPLIT                0x00000200
114#define FMODE_WSPLIT_INITIALIZED    0x00000400
115#define FMODE_TRUNC                 0x00000800
116#define FMODE_TEXTMODE              0x00001000
117/* #define FMODE_PREP               0x00010000 */
118#define FMODE_SETENC_BY_BOM         0x00100000
119
120#define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)
121
122#define RB_IO_BUFFER_INIT(buf) do {\
123    (buf).ptr = NULL;\
124    (buf).off = 0;\
125    (buf).len = 0;\
126    (buf).capa = 0;\
127} while (0)
128
129#define MakeOpenFile(obj, fp) do {\
130    if (RFILE(obj)->fptr) {\
131	rb_io_close(obj);\
132	rb_io_fptr_finalize(RFILE(obj)->fptr);\
133	RFILE(obj)->fptr = 0;\
134    }\
135    (fp) = 0;\
136    RB_IO_FPTR_NEW(fp);\
137    RFILE(obj)->fptr = (fp);\
138} while (0)
139
140#define RB_IO_FPTR_NEW(fp) do {\
141    (fp) = ALLOC(rb_io_t);\
142    (fp)->fd = -1;\
143    (fp)->stdio_file = NULL;\
144    (fp)->mode = 0;\
145    (fp)->pid = 0;\
146    (fp)->lineno = 0;\
147    (fp)->pathv = Qnil;\
148    (fp)->finalize = 0;\
149    RB_IO_BUFFER_INIT((fp)->wbuf);\
150    RB_IO_BUFFER_INIT((fp)->rbuf);\
151    RB_IO_BUFFER_INIT((fp)->cbuf);\
152    (fp)->readconv = NULL;\
153    (fp)->writeconv = NULL;\
154    (fp)->writeconv_asciicompat = Qnil;\
155    (fp)->writeconv_pre_ecflags = 0;\
156    (fp)->writeconv_pre_ecopts = Qnil;\
157    (fp)->writeconv_initialized = 0;\
158    (fp)->tied_io_for_writing = 0;\
159    (fp)->encs.enc = NULL;\
160    (fp)->encs.enc2 = NULL;\
161    (fp)->encs.ecflags = 0;\
162    (fp)->encs.ecopts = Qnil;\
163    (fp)->write_lock = 0;\
164} while (0)
165
166FILE *rb_io_stdio_file(rb_io_t *fptr);
167
168FILE *rb_fdopen(int, const char*);
169int rb_io_modestr_fmode(const char *modestr);
170int rb_io_modestr_oflags(const char *modestr);
171int rb_io_oflags_fmode(int oflags);
172void rb_io_check_writable(rb_io_t*);
173void rb_io_check_readable(rb_io_t*);
174void rb_io_check_char_readable(rb_io_t *fptr);
175void rb_io_check_byte_readable(rb_io_t *fptr);
176int rb_io_fptr_finalize(rb_io_t*);
177void rb_io_synchronized(rb_io_t*);
178void rb_io_check_initialized(rb_io_t*);
179void rb_io_check_closed(rb_io_t*);
180VALUE rb_io_get_io(VALUE io);
181VALUE rb_io_check_io(VALUE io);
182VALUE rb_io_get_write_io(VALUE io);
183VALUE rb_io_set_write_io(VALUE io, VALUE w);
184int rb_io_wait_readable(int);
185int rb_io_wait_writable(int);
186int rb_wait_for_single_fd(int fd, int events, struct timeval *tv);
187void rb_io_set_nonblock(rb_io_t *fptr);
188int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p);
189ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size);
190
191/* compatibility for ruby 1.8 and older */
192#define rb_io_mode_flags(modestr) rb_io_modestr_fmode(modestr)
193#define rb_io_modenum_flags(oflags) rb_io_oflags_fmode(oflags)
194
195VALUE rb_io_taint_check(VALUE);
196NORETURN(void rb_eof_error(void));
197
198void rb_io_read_check(rb_io_t*);
199int rb_io_read_pending(rb_io_t*);
200DEPRECATED(void rb_read_check(FILE*));
201
202#if defined __GNUC__ && __GNUC__ >= 4
203#pragma GCC visibility pop
204#endif
205
206#if defined(__cplusplus)
207#if 0
208{ /* satisfy cc-mode */
209#endif
210}  /* extern "C" { */
211#endif
212
213#endif /* RUBY_IO_H */
214