summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-10-28 12:17:54 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-10-28 12:17:54 +0000
commit605102f3cb3c1a3e12a6df6adfebd88498da95fe (patch)
treed38b81bc1afb6fa3fc3795883a01becefa71f69a /io.c
parent9b663af885784659e61819021095d98603e7d9de (diff)
merge from trunk (r19984, r19985, r19991-r19998)
* io.c (extract_binmode): new function to extract binmode/textmode options from hash. * io.c (rb_io_extract_modeenc): use above function. * io.c (rb_io_s_pipe): recognize binmode/textmode options. * io.c (make_readconv): now can specify the size of cbuf. * io.c (read_all, appendline, io_getc, rb_io_ungetc): follow above change. * win32/win32.c (rb_w32_pipe_exec): internal fds should be always binmode. * test/ruby/test_file.rb (test_each_char_extended_file, test_getbyte_extended_file): add tests. * test/ruby/test_file.rb (test_*_extended_file): test in default/text/ binary mode. * test/ruby/test_file.rb (test_para_gets_extended_file): output file should be binmode. * test/ruby/test_io.rb (test_copy_stream, test_copy_stream_socket): skip some tests if there isn't IO#nonblock=. * test/ruby/test_io.rb (test_close_on_exec): skip if there isn't IO#close_on_exec=. * test/ruby/test_io.rb (test_bytes, test_readbyte): depend on binmode. * test/ruby/test_io.rb (test_sysopen): should specify the mode of IO::for_fd if F_GETFL is not available. * test/ruby/test_io_m17n.rb (test_getc_invalid3): should set binmode if enc is not compatible with ASCII. * test/ruby/test_require.rb (test_require_too_long_filename): too long commandline may be rejected by OS. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@19999 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/io.c b/io.c
index 6e76f23c8b..772d9e4d71 100644
--- a/io.c
+++ b/io.c
@@ -1430,7 +1430,7 @@ io_enc_str(VALUE str, rb_io_t *fptr)
}
static void
-make_readconv(rb_io_t *fptr)
+make_readconv(rb_io_t *fptr, int size)
{
if (!fptr->readconv) {
int ecflags;
@@ -1452,7 +1452,7 @@ make_readconv(rb_io_t *fptr)
rb_exc_raise(rb_econv_open_exc(sname, dname, ecflags));
fptr->cbuf_off = 0;
fptr->cbuf_len = 0;
- fptr->cbuf_capa = 1024;
+ fptr->cbuf_capa = size < 1024 ? 1024 : size;
fptr->cbuf = ALLOC_N(char, fptr->cbuf_capa);
}
}
@@ -1558,7 +1558,7 @@ read_all(rb_io_t *fptr, long siz, VALUE str)
if (NEED_READCONV(fptr)) {
if (NIL_P(str)) str = rb_str_new(NULL, 0);
else rb_str_set_len(str, 0);
- make_readconv(fptr);
+ make_readconv(fptr, 0);
while (1) {
if (fptr->cbuf_len) {
io_shift_cbuf(fptr, fptr->cbuf_len, &str);
@@ -1940,7 +1940,7 @@ appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp)
long limit = *lp;
if (NEED_READCONV(fptr)) {
- make_readconv(fptr);
+ make_readconv(fptr, 0);
while (1) {
const char *p, *e;
int searchlen;
@@ -2473,7 +2473,7 @@ io_getc(rb_io_t *fptr, rb_encoding *enc)
if (NEED_READCONV(fptr)) {
VALUE str = Qnil;
- make_readconv(fptr);
+ make_readconv(fptr, 0);
while (1) {
if (fptr->cbuf_len) {
@@ -2825,8 +2825,8 @@ rb_io_ungetc(VALUE io, VALUE c)
SafeStringValue(c);
}
if (NEED_READCONV(fptr)) {
- make_readconv(fptr);
len = RSTRING_LEN(c);
+ make_readconv(fptr, len);
if (fptr->cbuf_capa - fptr->cbuf_len < len)
rb_raise(rb_eIOError, "ungetc failed");
if (fptr->cbuf_off < len) {
@@ -3923,6 +3923,23 @@ validate_enc_binmode(int fmode, rb_encoding *enc, rb_encoding *enc2)
}
static void
+extract_binmode(VALUE opthash, int *fmode)
+{
+ if (!NIL_P(opthash)) {
+ VALUE v;
+ v = rb_hash_aref(opthash, sym_textmode);
+ if (!NIL_P(v) && RTEST(v))
+ *fmode |= FMODE_TEXTMODE;
+ v = rb_hash_aref(opthash, sym_binmode);
+ if (!NIL_P(v) && RTEST(v))
+ *fmode |= FMODE_BINMODE;
+
+ if ((*fmode & FMODE_BINMODE) && (*fmode & FMODE_TEXTMODE))
+ rb_raise(rb_eArgError, "both textmode and binmode specified");
+ }
+}
+
+static void
rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
int *oflags_p, int *fmode_p, convconfig_t *convconfig_p)
{
@@ -3975,16 +3992,11 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
}
else {
VALUE v;
- v = rb_hash_aref(opthash, sym_textmode);
- if (!NIL_P(v) && RTEST(v))
- fmode |= FMODE_TEXTMODE;
- v = rb_hash_aref(opthash, sym_binmode);
- if (!NIL_P(v) && RTEST(v)) {
- fmode |= FMODE_BINMODE;
+ extract_binmode(opthash, &fmode);
#ifdef O_BINARY
+ if (fmode & FMODE_BINMODE)
oflags |= O_BINARY;
#endif
- }
if (!has_vmode) {
v = rb_hash_aref(opthash, sym_mode);
if (!NIL_P(v)) {
@@ -4017,9 +4029,6 @@ rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
}
}
- if ((fmode & FMODE_BINMODE) && (fmode & FMODE_TEXTMODE))
- rb_raise(rb_eArgError, "both textmode and binmode specified");
-
validate_enc_binmode(fmode, enc, enc2);
*vmode_p = vmode;
@@ -6825,7 +6834,8 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
int pipes[2], state;
VALUE r, w, args[3], v1, v2;
VALUE opt;
- rb_io_t *fptr;
+ rb_io_t *fptr, *fptr2;
+ int fmode = 0;
opt = pop_last_hash(&argc, argv);
rb_scan_args(argc, argv, "02", &v1, &v2);
@@ -6851,7 +6861,12 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
if (!NIL_P(r)) rb_io_close(r);
rb_jump_tag(state);
}
- rb_io_synchronized(RFILE(w)->fptr);
+ GetOpenFile(w, fptr2);
+ rb_io_synchronized(fptr2);
+
+ extract_binmode(opt, &fmode);
+ fptr->mode |= fmode;
+ fptr2->mode |= fmode;
return rb_assoc_new(r, w);
}