~ubuntu-branches/ubuntu/intrepid/ruby1.9/intrepid-updates

« back to all changes in this revision

Viewing changes to io.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-09-04 16:01:17 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20070904160117-i15zckg2nhxe9fyw
Tags: 1.9.0+20070830-2ubuntu1
* Sync from Debian; remaining changes:
  - Add -g to CFLAGS.
* Fixes build failure on ia64.
* Fixes build failure with gcc-4.2 on lpia.
* Robustify check for target_os, fixing build failure on lpia.
* Set Ubuntu maintainer address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
  io.c -
4
4
 
5
5
  $Author: matz $
6
 
  $Date: 2007-06-05 16:35:34 +0900 (火, 05  6月 2007) $
 
6
  $Date: 2007-08-27 02:22:26 +0900 (月, 27  8月 2007) $
7
7
  created at: Fri Oct 15 18:08:59 JST 1993
8
8
 
9
 
  Copyright (C) 1993-2003 Yukihiro Matsumoto
 
9
  Copyright (C) 1993-2007 Yukihiro Matsumoto
10
10
  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
11
11
  Copyright (C) 2000  Information-technology Promotion Agency, Japan
12
12
 
13
13
**********************************************************************/
14
14
 
15
 
#include "ruby.h"
16
 
#include "rubyio.h"
17
 
#include "rubysig.h"
 
15
#include "ruby/ruby.h"
 
16
#include "ruby/io.h"
 
17
#include "ruby/signal.h"
18
18
#include <ctype.h>
19
19
#include <errno.h>
20
20
 
 
21
#if defined(DOSISH) || defined(__CYGWIN__)
 
22
#include <io.h>
 
23
#endif
 
24
 
21
25
#include <sys/types.h>
22
26
#if !defined(_WIN32) && !defined(__DJGPP__)
23
27
# if defined(__BEOS__)
87
91
#include <net/socket.h>
88
92
#endif
89
93
 
90
 
#include "util.h"
 
94
#include "ruby/util.h"
91
95
 
92
96
#ifndef O_ACCMODE
93
97
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
242
246
    return rb_check_convert_type(io, T_FILE, "IO", "to_io");
243
247
}
244
248
 
 
249
/*
 
250
 *  call-seq:
 
251
 *     IO.try_convert(obj) -> io or nil
 
252
 *
 
253
 *  Try to convert <i>obj</i> into an IO, using to_io method.
 
254
 *  Returns converted IO or nil if <i>obj</i> cannot be converted
 
255
 *  for any reason.
 
256
 *
 
257
 *     IO.try_convert(STDOUT)     # => STDOUT
 
258
 *     IO.try_convert("STDOUT")   # => nil
 
259
 */
 
260
static VALUE
 
261
rb_io_s_try_convert(VALUE dummy, VALUE io)
 
262
{
 
263
    return rb_io_check_io(io);
 
264
}
 
265
 
245
266
static void
246
267
io_unread(rb_io_t *fptr)
247
268
{
261
282
    return;
262
283
}
263
284
 
264
 
static int
265
 
io_ungetc(int c, rb_io_t *fptr)
 
285
static void
 
286
io_ungetc(VALUE str, rb_io_t *fptr)
266
287
{
 
288
    int len = RSTRING_LEN(str);
 
289
 
267
290
    if (fptr->rbuf == NULL) {
268
291
        fptr->rbuf_off = 0;
269
292
        fptr->rbuf_len = 0;
270
 
        fptr->rbuf_capa = 8192;
 
293
        if (len > 8192)
 
294
            fptr->rbuf_capa = len;
 
295
        else
 
296
            fptr->rbuf_capa = 8192;
271
297
        fptr->rbuf = ALLOC_N(char, fptr->rbuf_capa);
272
298
    }
273
 
    if (c < 0 || fptr->rbuf_len == fptr->rbuf_capa) {
274
 
        return -1;
275
 
    }
276
299
    if (fptr->rbuf_off == 0) {
277
 
        if (fptr->rbuf_len)
278
 
            MEMMOVE(fptr->rbuf+1, fptr->rbuf, char, fptr->rbuf_len);
279
 
        fptr->rbuf_off = 1;
280
 
    }
281
 
    fptr->rbuf_off--;
282
 
    fptr->rbuf_len++;
283
 
    fptr->rbuf[fptr->rbuf_off] = c;
284
 
    return c;
 
300
        if (fptr->rbuf_len) {
 
301
            MEMMOVE(fptr->rbuf+len, fptr->rbuf, char, fptr->rbuf_len);
 
302
        }
 
303
        fptr->rbuf_off = len;
 
304
    }
 
305
    else if (fptr->rbuf_off < len) {
 
306
        int capa = fptr->rbuf_len + len;
 
307
        char *buf = ALLOC_N(char, capa);
 
308
 
 
309
        if (fptr->rbuf_len) {
 
310
            MEMMOVE(buf+len, fptr->rbuf+fptr->rbuf_off, char, fptr->rbuf_len);
 
311
        }
 
312
        fptr->rbuf_off = len;
 
313
    }
 
314
    fptr->rbuf_off-=len;
 
315
    fptr->rbuf_len+=len;
 
316
    MEMMOVE(fptr->rbuf+fptr->rbuf_off, RSTRING_PTR(str), char, len);
285
317
}
286
318
 
287
319
static rb_io_t *
858
890
}
859
891
 
860
892
static int
861
 
io_getc(rb_io_t *fptr)
 
893
io_fillbuf(rb_io_t *fptr)
862
894
{
863
895
    int r;
864
 
    if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && TYPE(rb_stdout) == T_FILE) {
865
 
        rb_io_t *ofp;
866
 
        GetOpenFile(rb_stdout, ofp);
867
 
        if (ofp->mode & FMODE_TTY) {
868
 
            rb_io_flush(rb_stdout);
869
 
        }
870
 
    }
 
896
 
871
897
    if (fptr->rbuf == NULL) {
872
898
        fptr->rbuf_off = 0;
873
899
        fptr->rbuf_len = 0;
889
915
        if (r == 0)
890
916
            return -1; /* EOF */
891
917
    }
892
 
    fptr->rbuf_off++;
893
 
    fptr->rbuf_len--;
894
 
    return (unsigned char)fptr->rbuf[fptr->rbuf_off-1];
 
918
    return 0;
895
919
}
896
920
 
897
921
/*
930
954
rb_io_eof(VALUE io)
931
955
{
932
956
    rb_io_t *fptr;
933
 
    int ch;
934
957
 
935
958
    GetOpenFile(io, fptr);
936
959
    rb_io_check_readable(fptr);
937
960
 
938
961
    if (READ_DATA_PENDING(fptr)) return Qfalse;
939
962
    READ_CHECK(fptr);
940
 
    ch = io_getc(fptr);
941
 
 
942
 
    if (ch != EOF) {
943
 
        io_ungetc(ch, fptr);
944
 
        return Qfalse;
 
963
    if (io_fillbuf(fptr) < 0) {
 
964
        return Qtrue;
945
965
    }
946
 
    return Qtrue;
 
966
    return Qfalse;
947
967
}
948
968
 
949
969
/*
1150
1170
        }
1151
1171
        rb_thread_wait_fd(fptr->fd);
1152
1172
        rb_io_check_closed(fptr);
1153
 
        c = io_getc(fptr);
1154
 
        if (c < 0) {
 
1173
        if (io_fillbuf(fptr) < 0) {
1155
1174
            break;
1156
1175
        }
1157
 
        RSTRING_PTR(str)[offset++] = c;
1158
 
        if (offset > RSTRING_LEN(str)) break;
1159
 
        n--;
1160
1176
    }
1161
1177
    return len - n;
1162
1178
}
1582
1598
        }
1583
1599
        rb_thread_wait_fd(fptr->fd);
1584
1600
        rb_io_check_closed(fptr);
1585
 
        c = io_getc(fptr);
1586
 
        limit--;
1587
 
        if (c < 0) {
 
1601
        if (io_fillbuf(fptr) < 0) {
1588
1602
            *lp = limit;
1589
1603
            return c;
1590
1604
        }
1606
1620
static inline int
1607
1621
swallow(rb_io_t *fptr, int term)
1608
1622
{
1609
 
    int c;
1610
 
 
1611
1623
    do {
1612
1624
        long cnt;
1613
1625
        while ((cnt = READ_DATA_PENDING_COUNT(fptr)) > 0) {
1623
1635
        }
1624
1636
        rb_thread_wait_fd(fptr->fd);
1625
1637
        rb_io_check_closed(fptr);
1626
 
        c = io_getc(fptr);
1627
 
        if (c != term) {
1628
 
            io_ungetc(c, fptr);
1629
 
            return Qtrue;
1630
 
        }
1631
 
    } while (c != EOF);
 
1638
    } while (io_fillbuf(fptr) == 0);
1632
1639
    return Qfalse;
1633
1640
}
1634
1641
 
2003
2010
rb_io_each_byte(VALUE io)
2004
2011
{
2005
2012
    rb_io_t *fptr;
2006
 
    int c;
 
2013
    char *p, *e;
2007
2014
 
2008
2015
    RETURN_ENUMERATOR(io, 0, 0);
2009
2016
    GetOpenFile(io, fptr);
2010
2017
 
2011
2018
    for (;;) {
 
2019
        p = fptr->rbuf+fptr->rbuf_off;
 
2020
        e = p + fptr->rbuf_len;
 
2021
        while (p < e) {
 
2022
            rb_yield(INT2FIX(*p & 0xff));
 
2023
            p++;
 
2024
        }
 
2025
        fptr->rbuf_off += fptr->rbuf_len;
 
2026
        fptr->rbuf_len = 0;
2012
2027
        rb_io_check_readable(fptr);
2013
2028
        READ_CHECK(fptr);
2014
 
        c = io_getc(fptr);
2015
 
        if (c < 0) {
 
2029
        if (io_fillbuf(fptr) < 0) {
2016
2030
            break;
2017
2031
        }
2018
 
        rb_yield(INT2FIX(c & 0xff));
2019
2032
    }
2020
2033
    return io;
2021
2034
}
2053
2066
    return rb_enumeratorize(str, ID2SYM(rb_intern("each_byte")), 0, 0);
2054
2067
}
2055
2068
 
2056
 
VALUE
2057
 
rb_io_getc(VALUE io)
2058
 
{
2059
 
    rb_io_t *fptr;
2060
 
    int c;
2061
 
 
2062
 
    GetOpenFile(io, fptr);
2063
 
    rb_io_check_readable(fptr);
2064
 
 
2065
 
    READ_CHECK(fptr);
2066
 
    c = io_getc(fptr);
2067
 
 
2068
 
    if (c < 0) {
2069
 
        return Qnil;
2070
 
    }
2071
 
    return INT2FIX(c & 0xff);
2072
 
}
2073
 
 
2074
2069
/*
2075
2070
 *  call-seq:
2076
 
 *     ios.getc   => string or nil
2077
 
 *
 
2071
 *     ios.getc   => fixnum or nil
 
2072
 *  
2078
2073
 *  Reads a one-character string from <em>ios</em>. Returns
2079
2074
 *  <code>nil</code> if called at end of file.
2080
 
 *
 
2075
 *     
2081
2076
 *     f = File.new("testfile")
2082
2077
 *     f.getc   #=> "8"
2083
2078
 *     f.getc   #=> "1"
2084
2079
 */
2085
2080
 
2086
 
VALUE
2087
 
rb_io_getc_m(VALUE io)
 
2081
static VALUE
 
2082
rb_io_getc(VALUE io)
2088
2083
{
2089
 
    char ch;
 
2084
    rb_encoding *enc;
2090
2085
    rb_io_t *fptr;
2091
 
    int c;
 
2086
    int n, left;
 
2087
    VALUE str;
2092
2088
 
2093
2089
    GetOpenFile(io, fptr);
2094
2090
    rb_io_check_readable(fptr);
 
2091
    enc = rb_enc_get(io);
2095
2092
 
2096
2093
    READ_CHECK(fptr);
2097
 
    c = io_getc(fptr);
2098
 
 
2099
 
    if (c < 0) {
 
2094
    if (io_fillbuf(fptr) < 0) {
2100
2095
        return Qnil;
2101
2096
    }
2102
 
    ch = c & 0xff; 
2103
 
    return rb_str_new(&ch, 1);
 
2097
    n = rb_enc_mbclen(fptr->rbuf+fptr->rbuf_off, enc);
 
2098
    if (n < fptr->rbuf_len) {
 
2099
        str = rb_str_new(fptr->rbuf+fptr->rbuf_off, n);
 
2100
        fptr->rbuf_off += n;
 
2101
        fptr->rbuf_len -= n;
 
2102
    }
 
2103
    else {
 
2104
        str = rb_str_new(0, n);
 
2105
        left = fptr->rbuf_len;
 
2106
        MEMCPY(RSTRING_PTR(str), fptr->rbuf+fptr->rbuf_off, char, left);
 
2107
        if (io_fillbuf(fptr) < 0) {
 
2108
            return Qnil;
 
2109
        }
 
2110
        MEMCPY(RSTRING_PTR(str)+left, fptr->rbuf, char, n-left);
 
2111
        fptr->rbuf_off += left;
 
2112
        fptr->rbuf_len -= left;
 
2113
    }
 
2114
    rb_enc_associate(str, enc);
 
2115
 
 
2116
    return str;
2104
2117
}
2105
2118
 
2106
2119
int
2122
2135
 *  call-seq:
2123
2136
 *     ios.readchar   => string
2124
2137
 *
 
2138
 *  Reads a one-character string from <em>ios</em>. Raises an
 
2139
 *  <code>EOFError</code> on end of file.
 
2140
 *
 
2141
 *     f = File.new("testfile")
 
2142
 *     f.readchar   #=> "8"
 
2143
 *     f.readchar   #=> "1"
 
2144
 */
 
2145
 
 
2146
static VALUE
 
2147
rb_io_readchar(VALUE io)
 
2148
{
 
2149
    VALUE c = rb_io_getc(io);
 
2150
 
 
2151
    if (NIL_P(c)) {
 
2152
        rb_eof_error();
 
2153
    }
 
2154
    return c;
 
2155
}
 
2156
 
 
2157
/*
 
2158
 *  call-seq:
 
2159
 *     ios.getbyte   => fixnum or nil
 
2160
 *
 
2161
 *  Gets the next 8-bit byte (0..255) from <em>ios</em>. Returns
 
2162
 *  <code>nil</code> if called at end of file.
 
2163
 *
 
2164
 *     f = File.new("testfile")
 
2165
 *     f.getbyte   #=> 84
 
2166
 *     f.getbyte   #=> 104
 
2167
 */
 
2168
 
 
2169
VALUE
 
2170
rb_io_getbyte(VALUE io)
 
2171
{
 
2172
    rb_io_t *fptr;
 
2173
    int c;
 
2174
 
 
2175
    GetOpenFile(io, fptr);
 
2176
    rb_io_check_readable(fptr);
 
2177
    READ_CHECK(fptr);
 
2178
    if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && TYPE(rb_stdout) == T_FILE) {
 
2179
        rb_io_t *ofp;
 
2180
        GetOpenFile(rb_stdout, ofp);
 
2181
        if (ofp->mode & FMODE_TTY) {
 
2182
            rb_io_flush(rb_stdout);
 
2183
        }
 
2184
    }
 
2185
    if (io_fillbuf(fptr) < 0) {
 
2186
        return Qnil;
 
2187
    }
 
2188
    fptr->rbuf_off++;
 
2189
    fptr->rbuf_len--;
 
2190
    c = (unsigned char)fptr->rbuf[fptr->rbuf_off-1];
 
2191
    return INT2FIX(c & 0xff);
 
2192
}
 
2193
 
 
2194
/*
 
2195
 *  call-seq:
 
2196
 *     ios.readbyte   => fixnum
 
2197
 *
2125
2198
 *  Reads a character as with <code>IO#getc</code>, but raises an
2126
2199
 *  <code>EOFError</code> on end of file.
2127
2200
 */
2128
2201
 
2129
2202
static VALUE
2130
 
rb_io_readchar(VALUE io)
 
2203
rb_io_readbyte(VALUE io)
2131
2204
{
2132
 
    VALUE c = rb_io_getc_m(io);
 
2205
    VALUE c = rb_io_getbyte(io);
2133
2206
 
2134
2207
    if (NIL_P(c)) {
2135
2208
        rb_eof_error();
2156
2229
VALUE
2157
2230
rb_io_ungetc(VALUE io, VALUE c)
2158
2231
{
 
2232
    rb_encoding *enc;
2159
2233
    rb_io_t *fptr;
2160
 
    int cc;
2161
2234
 
2162
2235
    GetOpenFile(io, fptr);
2163
2236
    rb_io_check_readable(fptr);
2164
2237
    if (NIL_P(c)) return Qnil;
 
2238
    enc = rb_enc_get(io);
2165
2239
    if (FIXNUM_P(c)) {
2166
 
        cc = FIX2INT(c);
 
2240
        int cc = FIX2INT(c);
 
2241
        char buf[16];
 
2242
 
 
2243
        rb_enc_mbcput(cc, buf, enc);
 
2244
        c = rb_str_new(buf, rb_enc_codelen(cc, enc));
2167
2245
    }
2168
2246
    else {
2169
2247
        SafeStringValue(c);
2170
 
        if (RSTRING_LEN(c) > 1) {
2171
 
            rb_warn("IO#ungetc pushes back only one byte");
2172
 
        }
2173
 
        cc = (unsigned char)RSTRING_PTR(c)[0];
2174
 
    }
2175
 
    if (io_ungetc(cc, fptr) == EOF && cc != EOF) {
2176
 
        rb_raise(rb_eIOError, "ungetc failed");
2177
 
    }
 
2248
    }
 
2249
    io_ungetc(c, fptr);
2178
2250
    return Qnil;
2179
2251
}
2180
2252
 
3050
3122
#endif
3051
3123
 
3052
3124
static VALUE
3053
 
pipe_open(int argc, VALUE *argv, const char *mode)
 
3125
pipe_open(const char *cmd, int argc, VALUE *argv, const char *mode)
3054
3126
{
3055
3127
    int modef = rb_io_mode_flags(mode);
3056
3128
    int pid = 0;
3057
3129
    rb_io_t *fptr;
3058
 
    VALUE port, prog;
 
3130
    VALUE port;
3059
3131
#if defined(HAVE_FORK)
3060
3132
    int status;
3061
3133
    struct popen_arg arg;
3062
3134
#elif defined(_WIN32)
3063
3135
    int openmode = rb_io_mode_modenum(mode);
3064
 
    char *exename = NULL;
 
3136
    const char *exename = NULL;
3065
3137
#endif
3066
 
    volatile int doexec;
3067
 
    char *cmd;
3068
3138
    FILE *fp = 0;
3069
3139
    int fd = -1;
3070
3140
 
3071
 
    prog = rb_check_argv(argc, argv);
3072
 
    if (!prog) {
3073
 
        if (argc == 1) argc = 0;
3074
 
        prog = argv[0];
3075
 
    }
3076
 
 
3077
 
    cmd = StringValueCStr(prog);
3078
 
    doexec = (strcmp("-", cmd) != 0);
3079
 
 
3080
 
#if !defined(HAVE_FORK)
3081
 
    if (!doexec) {
3082
 
        rb_raise(rb_eNotImpError,
3083
 
                 "fork() function is unimplemented on this machine");
3084
 
    }
3085
 
#endif
3086
 
 
3087
3141
#if defined(HAVE_FORK)
3088
 
    if (!doexec) {
3089
 
        fflush(stdin);          /* is it really needed? */
3090
 
        rb_io_flush(rb_stdout);
3091
 
        rb_io_flush(rb_stderr);
3092
 
    }
3093
3142
    arg.modef = modef;
3094
3143
    arg.pair[0] = arg.pair[1] = -1;
3095
3144
    switch (modef & (FMODE_READABLE|FMODE_WRITABLE)) {
3110
3159
      default:
3111
3160
        rb_sys_fail(cmd);
3112
3161
    }
3113
 
    if (doexec) {
 
3162
    if (cmd) {
3114
3163
        arg.exec.argc = argc;
3115
3164
        arg.exec.argv = argv;
3116
3165
        arg.exec.prog = cmd;
3117
3166
        pid = rb_fork(&status, popen_exec, &arg);
3118
3167
    }
3119
3168
    else {
 
3169
        fflush(stdin);          /* is it really needed? */
 
3170
        rb_io_flush(rb_stdout);
 
3171
        rb_io_flush(rb_stderr);
3120
3172
        pid = rb_fork(&status, 0, 0);
3121
3173
        if (pid == 0) {         /* child */
3122
3174
            popen_redirect(&arg);
3155
3207
            args[i] = RSTRING_PTR(argv[i]);
3156
3208
        }
3157
3209
        args[i] = NULL;
3158
 
        cmd = ALLOCA_N(char, rb_w32_argv_size(args));
3159
 
        rb_w32_join_argv(cmd, args);
3160
 
        exename = RSTRING_PTR(prog);
 
3210
        exename = cmd;
 
3211
        cmd = rb_w32_join_argv(ALLOCA_N(char, rb_w32_argv_size(args)), args);
3161
3212
    }
3162
3213
    while ((pid = rb_w32_pipe_exec(cmd, exename, openmode, &fd)) == -1) {
3163
3214
        /* exec failed */
3169
3220
            rb_thread_sleep(1);
3170
3221
            break;
3171
3222
          default:
3172
 
            rb_sys_fail(RSTRING_PTR(prog));
 
3223
            rb_sys_fail(cmd);
3173
3224
            break;
3174
3225
        }
3175
3226
    }
3197
3248
    return port;
3198
3249
}
3199
3250
 
 
3251
static VALUE
 
3252
pipe_open_v(int argc, VALUE *argv, const char *mode)
 
3253
{
 
3254
    VALUE prog = rb_check_argv(argc, argv);
 
3255
    const char *cmd;
 
3256
 
 
3257
    if (!RB_GC_GUARD(prog)) prog = argv[0];
 
3258
    cmd = RSTRING_PTR(prog);
 
3259
    return pipe_open(cmd, argc, argv, mode);
 
3260
}
 
3261
 
 
3262
static VALUE
 
3263
pipe_open_s(VALUE prog, const char *mode)
 
3264
{
 
3265
    const char *cmd = (rb_check_argv(1, &prog), RSTRING_PTR(prog));
 
3266
 
 
3267
    if (strcmp("-", cmd) == 0) {
 
3268
#if !defined(HAVE_FORK)
 
3269
        rb_raise(rb_eNotImpError,
 
3270
                 "fork() function is unimplemented on this machine");
 
3271
#endif
 
3272
        cmd = 0;
 
3273
    }
 
3274
    return pipe_open(cmd, 0, &prog, mode);
 
3275
}
 
3276
 
3200
3277
/*
3201
3278
 *  call-seq:
3202
3279
 *     IO.popen(cmd, mode="r")               => io
3267
3344
    }
3268
3345
    tmp = rb_check_array_type(pname);
3269
3346
    if (!NIL_P(tmp)) {
3270
 
        VALUE *argv = ALLOCA_N(VALUE, RARRAY_LEN(tmp));
 
3347
        long len = RARRAY_LEN(tmp);
 
3348
        VALUE *args = ALLOCA_N(VALUE, len);
3271
3349
 
3272
 
        MEMCPY(argv, RARRAY_PTR(tmp), VALUE, RARRAY_LEN(tmp));
3273
 
        port = pipe_open(RARRAY_LEN(tmp), argv, mode);
3274
 
        pname = tmp;
 
3350
        MEMCPY(args, RARRAY_PTR(tmp), VALUE, len);
 
3351
        port = pipe_open_v(len, args, mode);
3275
3352
    }
3276
3353
    else {
3277
3354
        SafeStringValue(pname);
3278
 
        port = pipe_open(1, &pname, mode);
 
3355
        port = pipe_open_s(pname, mode);
3279
3356
    }
3280
3357
    if (NIL_P(port)) {
3281
3358
        /* child */
3500
3577
{
3501
3578
    if (fname[0] == '|') {
3502
3579
        VALUE cmd = rb_str_new2(fname+1);
3503
 
        return pipe_open(1, &cmd, mode);
 
3580
        return pipe_open_s(cmd, mode);
3504
3581
    }
3505
3582
    else {
3506
3583
        return rb_file_open(fname, mode);
3991
4068
    if (argc == 1) {
3992
4069
        ret = argv[0];
3993
4070
    }
3994
 
    else {
 
4071
    else if (argc > 1) {
3995
4072
        ret = rb_ary_new4(argc, argv);
3996
4073
    }
3997
4074
    if (TYPE(rb_stdout) == T_FILE) {
4152
4229
{
4153
4230
    VALUE fnum, mode, orig;
4154
4231
    rb_io_t *fp, *ofp = NULL;
4155
 
    int fd, flags, fmode;
 
4232
    int fd, fmode, flags = O_RDONLY;
4156
4233
 
4157
4234
    rb_secure(4);
4158
4235
    rb_scan_args(argc, argv, "11", &fnum, &mode);
4172
4249
#if defined(HAVE_FCNTL) && defined(F_GETFL)
4173
4250
            flags = fcntl(fd, F_GETFL);
4174
4251
            if (flags == -1) rb_sys_fail(0);
4175
 
#else
4176
 
            flags = O_RDONLY;
4177
4252
#endif
4178
4253
        }
4179
4254
        MakeOpenFile(io, fp);
4305
4380
}
4306
4381
 
4307
4382
#define ARGF_FORWARD(argc, argv) do {\
4308
 
  if (TYPE(current_file) != T_FILE)\
 
4383
  if (current_file == rb_stdin && TYPE(current_file) != T_FILE)\
4309
4384
     return argf_forward(argc, argv);\
4310
4385
} while (0)
4311
4386
#define NEXT_ARGF_FORWARD(argc, argv) do {\
4316
4391
static void
4317
4392
argf_close(VALUE file)
4318
4393
{
4319
 
    if (TYPE(file) == T_FILE)
4320
 
        rb_io_close(file);
4321
 
    else
4322
 
        rb_funcall3(file, rb_intern("close"), 0, 0);
 
4394
    rb_funcall3(file, rb_intern("close"), 0, 0);
4323
4395
}
4324
4396
 
4325
4397
static int
4364
4436
                int fr = rb_sysopen(fn, O_RDONLY, 0);
4365
4437
 
4366
4438
                if (ruby_inplace_mode) {
4367
 
                    struct stat st, st2;
 
4439
                    struct stat st;
 
4440
#ifndef NO_SAFE_RENAME
 
4441
                    struct stat st2;
 
4442
#endif
4368
4443
                    VALUE str;
4369
4444
                    int fw;
4370
4445
 
4447
4522
 
4448
4523
  retry:
4449
4524
    if (!next_argv()) return Qnil;
4450
 
    if (argc == 0 && rb_rs == rb_default_rs) {
4451
 
        line = rb_io_gets(current_file);
 
4525
    if (current_file == rb_stdin && TYPE(current_file) != T_FILE) {
 
4526
        line = rb_funcall3(current_file, rb_intern("gets"), argc, argv);
4452
4527
    }
4453
4528
    else {
4454
 
        line = rb_io_getline(argc, argv, current_file);
4455
 
    }
4456
 
    if (NIL_P(line) && next_p != -1) {
4457
 
        argf_close(current_file);
4458
 
        next_p = 1;
4459
 
        goto retry;
 
4529
        if (argc == 0 && rb_rs == rb_default_rs) {
 
4530
            line = rb_io_gets(current_file);
 
4531
        }
 
4532
        else {
 
4533
            line = rb_io_getline(argc, argv, current_file);
 
4534
        }
 
4535
        if (NIL_P(line) && next_p != -1) {
 
4536
            argf_close(current_file);
 
4537
            next_p = 1;
 
4538
            goto retry;
 
4539
        }
4460
4540
    }
4461
4541
    if (!NIL_P(line)) {
4462
4542
        gets_lineno++;
4503
4583
{
4504
4584
    VALUE line;
4505
4585
 
4506
 
    if (!next_argv()) return Qnil;
4507
 
    if (TYPE(current_file) != T_FILE) {
4508
 
        line = rb_funcall3(current_file, rb_intern("gets"), argc, argv);
4509
 
    }
4510
 
    else {
4511
 
        line = argf_getline(argc, argv);
4512
 
    }
 
4586
    line = argf_getline(argc, argv);
4513
4587
    rb_lastline_set(line);
4514
4588
    return line;
4515
4589
}
4527
4601
    if (!next_argv()) return Qnil;
4528
4602
    line = rb_io_gets(current_file);
4529
4603
    if (NIL_P(line) && next_p != -1) {
4530
 
        argf_close(current_file);
 
4604
        rb_io_close(current_file);
4531
4605
        next_p = 1;
4532
4606
        goto retry;
4533
4607
    }
4566
4640
}
4567
4641
 
4568
4642
/*
4569
 
 * obsolete
4570
 
 */
4571
 
static VALUE
4572
 
rb_f_getc(void)
4573
 
{
4574
 
    rb_warn("getc is obsolete; use STDIN.getc instead");
4575
 
    if (TYPE(rb_stdin) != T_FILE) {
4576
 
        return rb_funcall3(rb_stdin, rb_intern("getc"), 0, 0);
4577
 
    }
4578
 
    return rb_io_getc(rb_stdin);
4579
 
}
4580
 
 
4581
 
/*
4582
4643
 *  call-seq:
4583
4644
 *     readlines(sep=$/)    => array
4584
4645
 *     readlines(limit)     => array
4593
4654
{
4594
4655
    VALUE line, ary;
4595
4656
 
4596
 
    NEXT_ARGF_FORWARD(argc, argv);
4597
4657
    ary = rb_ary_new();
4598
4658
    while (!NIL_P(line = argf_getline(argc, argv))) {
4599
4659
        rb_ary_push(ary, line);
4624
4684
    rb_io_t *fptr;
4625
4685
 
4626
4686
    SafeStringValue(str);
4627
 
    port = pipe_open(1, &str, "r");
 
4687
    port = pipe_open_s(str, "r");
4628
4688
    if (NIL_P(port)) return rb_str_new(0,0);
4629
4689
 
4630
4690
    GetOpenFile(port, fptr);
5200
5260
    VALUE fname;
5201
5261
    struct foreach_arg arg;
5202
5262
 
 
5263
    rb_scan_args(argc, argv, "12", &fname, NULL, NULL);
5203
5264
    RETURN_ENUMERATOR(self, argc, argv);
5204
 
    rb_scan_args(argc, argv, "12", &fname, NULL, NULL);
5205
5265
    FilePathValue(fname);
5206
5266
    arg.io = rb_io_open(RSTRING_PTR(fname), "r");
5207
5267
    if (NIL_P(arg.io)) return Qnil;
5374
5434
    if (!next_argv()) {
5375
5435
        return str;
5376
5436
    }
5377
 
    if (TYPE(current_file) != T_FILE) {
 
5437
    if (current_file == rb_stdin && TYPE(current_file) != T_FILE) {
5378
5438
        tmp = argf_forward(argc, argv);
5379
5439
    }
5380
5440
    else {
5399
5459
    return str;
5400
5460
}
5401
5461
 
 
5462
struct argf_call_arg {
 
5463
    int argc;
 
5464
    VALUE *argv;
 
5465
};
 
5466
 
5402
5467
static VALUE
5403
 
argf_readpartial_rescue(VALUE dummy)
 
5468
argf_forward_call(VALUE arg)
5404
5469
{
 
5470
    struct argf_call_arg *p = (struct argf_call_arg *)arg;
 
5471
    argf_forward(p->argc, p->argv);
5405
5472
    return Qnil;
5406
5473
}
5407
5474
 
5420
5487
        rb_str_resize(str, 0);
5421
5488
        rb_eof_error();
5422
5489
    }
5423
 
    if (TYPE(current_file) != T_FILE) {
5424
 
        tmp = rb_rescue2(argf_forward, (VALUE)argv,
5425
 
                         argf_readpartial_rescue, (VALUE)Qnil,
5426
 
                         rb_eEOFError, (VALUE)0);
 
5490
    if (current_file == rb_stdin && TYPE(current_file) != T_FILE) {
 
5491
        struct argf_call_arg arg;
 
5492
        arg.argc = argc;
 
5493
        arg.argv = argv;
 
5494
        tmp = rb_rescue2(argf_forward_call, (VALUE)&arg,
 
5495
                         RUBY_METHOD_FUNC(0), Qnil, rb_eEOFError, (VALUE)0);
5427
5496
    }
5428
5497
    else {
5429
5498
        tmp = io_getpartial(argc, argv, current_file, 0);
5450
5519
 
5451
5520
  retry:
5452
5521
    if (!next_argv()) return Qnil;
 
5522
    if (current_file == rb_stdin && TYPE(current_file) != T_FILE) {
 
5523
        ch = rb_funcall3(current_file, rb_intern("getc"), 0, 0);
 
5524
    }
 
5525
    else {
 
5526
        ch = rb_io_getc(current_file);
 
5527
    }
 
5528
    if (NIL_P(ch) && next_p != -1) {
 
5529
        argf_close(current_file);
 
5530
        next_p = 1;
 
5531
        goto retry;
 
5532
    }
 
5533
 
 
5534
    return ch;
 
5535
}
 
5536
 
 
5537
static VALUE
 
5538
argf_getbyte(void)
 
5539
{
 
5540
    VALUE ch;
 
5541
 
 
5542
  retry:
 
5543
    if (!next_argv()) return Qnil;
5453
5544
    if (TYPE(current_file) != T_FILE) {
5454
 
        ch = rb_funcall3(current_file, rb_intern("getc"), 0, 0);
 
5545
        ch = rb_funcall3(current_file, rb_intern("getbyte"), 0, 0);
5455
5546
    }
5456
5547
    else {
5457
 
        ch = rb_io_getc_m(current_file);
 
5548
        ch = rb_io_getbyte(current_file);
5458
5549
    }
5459
5550
    if (NIL_P(ch) && next_p != -1) {
5460
5551
        argf_close(current_file);
5468
5559
static VALUE
5469
5560
argf_readchar(void)
5470
5561
{
 
5562
    VALUE ch;
 
5563
 
 
5564
  retry:
 
5565
    if (!next_argv()) return Qnil;
 
5566
    if (TYPE(current_file) != T_FILE) {
 
5567
        ch = rb_funcall3(current_file, rb_intern("getc"), 0, 0);
 
5568
    }
 
5569
    else {
 
5570
        ch = rb_io_getc(current_file);
 
5571
    }
 
5572
    if (NIL_P(ch) && next_p != -1) {
 
5573
        argf_close(current_file);
 
5574
        next_p = 1;
 
5575
        goto retry;
 
5576
    }
 
5577
 
 
5578
    return ch;
 
5579
}
 
5580
 
 
5581
static VALUE
 
5582
argf_readbyte(void)
 
5583
{
5471
5584
    VALUE c;
5472
5585
 
5473
5586
    NEXT_ARGF_FORWARD(0, 0);
5474
 
    c = argf_getc();
 
5587
    c = argf_getbyte();
5475
5588
    if (NIL_P(c)) {
5476
5589
        rb_eof_error();
5477
5590
    }
5481
5594
static VALUE
5482
5595
argf_each_line(int argc, VALUE *argv, VALUE self)
5483
5596
{
5484
 
    VALUE str;
5485
 
 
5486
5597
    RETURN_ENUMERATOR(self, argc, argv);
5487
 
    if (!next_argv()) return Qnil;
5488
 
    if (TYPE(current_file) != T_FILE) {
5489
 
        for (;;) {
5490
 
            if (!next_argv()) return argf;
5491
 
            rb_block_call(current_file, rb_intern("each"), 0, 0, rb_yield, 0);
5492
 
            next_p = 1;
5493
 
        }
5494
 
    }
5495
 
    while (!NIL_P(str = argf_getline(argc, argv))) {
5496
 
        rb_yield(str);
5497
 
    }
5498
 
    return argf;
 
5598
    for (;;) {
 
5599
        if (!next_argv()) return Qnil;
 
5600
        rb_block_call(current_file, rb_intern("each_line"), 0, 0, rb_yield, 0);
 
5601
        next_p = 1;
 
5602
    }
 
5603
    return self;
5499
5604
}
5500
5605
 
5501
5606
static VALUE
5502
5607
argf_each_byte(VALUE self)
5503
5608
{
5504
 
    VALUE byte;
5505
 
 
5506
5609
    RETURN_ENUMERATOR(self, 0, 0);
5507
 
    while (!NIL_P(byte = argf_getc())) {
5508
 
        rb_yield(byte);
 
5610
    for (;;) {
 
5611
        if (!next_argv()) return Qnil;
 
5612
        rb_block_call(current_file, rb_intern("each_byte"), 0, 0, rb_yield, 0);
 
5613
        next_p = 1;
5509
5614
    }
5510
 
    return argf;
5511
5615
}
5512
5616
 
5513
5617
static VALUE
5700
5804
    rb_define_global_function("puts", rb_f_puts, -1);
5701
5805
    rb_define_global_function("gets", rb_f_gets, -1);
5702
5806
    rb_define_global_function("readline", rb_f_readline, -1);
5703
 
    rb_define_global_function("getc", rb_f_getc, 0);
5704
5807
    rb_define_global_function("select", rb_f_select, -1);
5705
5808
 
5706
5809
    rb_define_global_function("readlines", rb_f_readlines, -1);
5724
5827
    rb_define_singleton_method(rb_cIO, "read", rb_io_s_read, -1);
5725
5828
    rb_define_singleton_method(rb_cIO, "select", rb_f_select, -1);
5726
5829
    rb_define_singleton_method(rb_cIO, "pipe", rb_io_s_pipe, 0);
 
5830
    rb_define_singleton_method(rb_cIO, "try_convert", rb_io_s_try_convert, 1);
5727
5831
 
5728
5832
    rb_define_method(rb_cIO, "initialize", rb_io_initialize, -1);
5729
5833
 
5778
5882
    rb_define_method(rb_cIO, "write", io_write, 1);
5779
5883
    rb_define_method(rb_cIO, "gets",  rb_io_gets_m, -1);
5780
5884
    rb_define_method(rb_cIO, "readline",  rb_io_readline, -1);
5781
 
    rb_define_method(rb_cIO, "getc",  rb_io_getc_m, 0);
 
5885
    rb_define_method(rb_cIO, "getc",  rb_io_getc, 0);
 
5886
    rb_define_method(rb_cIO, "getbyte",  rb_io_getbyte, 0);
5782
5887
    rb_define_method(rb_cIO, "readchar",  rb_io_readchar, 0);
 
5888
    rb_define_method(rb_cIO, "readbyte",  rb_io_readbyte, 0);
5783
5889
    rb_define_method(rb_cIO, "ungetc",rb_io_ungetc, 1);
5784
5890
    rb_define_method(rb_cIO, "<<",    rb_io_addstr, 1);
5785
5891
    rb_define_method(rb_cIO, "flush", rb_io_flush, 0);
5849
5955
    rb_define_singleton_method(argf, "gets", rb_f_gets, -1);
5850
5956
    rb_define_singleton_method(argf, "readline", rb_f_readline, -1);
5851
5957
    rb_define_singleton_method(argf, "getc", argf_getc, 0);
 
5958
    rb_define_singleton_method(argf, "getbyte", argf_getbyte, 0);
5852
5959
    rb_define_singleton_method(argf, "readchar", argf_readchar, 0);
 
5960
    rb_define_singleton_method(argf, "readbyte", argf_readbyte, 0);
5853
5961
    rb_define_singleton_method(argf, "tell", argf_tell, 0);
5854
5962
    rb_define_singleton_method(argf, "seek", argf_seek_m, -1);
5855
5963
    rb_define_singleton_method(argf, "rewind", argf_rewind, 0);