[#32185] Date#+に大きな数字を与えるとおかしな日付に — "madoka yamamoto" <yamamotomadoka@...>

こんにちは、山本と申します。

26 messages 2007/11/08
[#32186] Re: Date#+に大きな数字を与えるとおかしな日付に — Tadayoshi Funaba <tadf@...> 2007/11/08

> Dateオブジェクトに+で大きな数字を与えるとおかしくなるようです。

[#32188] Re: Date#+に大きな数字を与えるとおかしな日付に — "madoka yamamoto" <yamamotomadoka@...> 2007/11/09

山本です。

[#32191] Re: Date#+に大きな数字を与えるとおかしな日付に — tadf@... 2007/11/09

> アルゴリズムの意味がわからないで書いた、表層的なパッチなので

[#32194] Re: Date#+に大きな数字を与えるとおかしな日付に — Yukihiro Matsumoto <matz@...> 2007/11/09

Hi,

[#32200] Re: rational (Re: Date#+に大きな数字を与えるとおかしな日付に) — Tadayoshi Funaba <tadf@...> 2007/11/10

> 1.9ではRationalとComplexを組み込みに、という話はありましたが、

[#32225] Re: rational (Re: Date#+に大きな数字を与えるとおかしな日付に) — Shin-ichiro HARA <sinara@...> 2007/11/12

原です。

[#32198] [提案] Array#tail — "Yusuke ENDOH" <mame@...>

遠藤と申します。

21 messages 2007/11/09
[#32199] Re: [提案] Array#tail — Yukihiro Matsumoto <matz@...> 2007/11/10

まつもと ゆきひろです

[#32352] 1.9.1のリリース時期について — KIMURA Koichi <hogemuta@...>

木村です。

16 messages 2007/11/24
[#32353] Re: 1.9.1のリリース時期について — Yukihiro Matsumoto <matz@...> 2007/11/24

まつもと ゆきひろです

[#32403] Next 1.8.6 patch release? (was Re: 1.9.1のリリース時期について) — Takahiro Kambe <taca@...>

こんばんは。

32 messages 2007/11/29
[#32414] Re: Next 1.8.6 patch release? (was Re: 1.9.1のリリース時期について) — Urabe Shyouhei <shyouhei@...> 2007/11/30

卜部です。

[#32444] Re: Next 1.8.6 patch release? (was Re: 1.9.1のリリース時期について) — Yukihiro Matsumoto <matz@...> 2007/12/03

まつもと ゆきひろです

[#32488] Re: Next 1.8.6 patch release? (was Re: 1.9.1のリリース時期について) — Urabe Shyouhei <shyouhei@...> 2007/12/08

卜部です。

[#32525] Re: Next 1.8.6 patch release? (was Re: 1.9.1のリリース時期について) — "Yusuke ENDOH" <mame@...> 2007/12/10

遠藤と申します。

[#32643] Re: Next 1.8.6 patch release? (was Re: 1.9.1のリリース時期について) — "Yusuke ENDOH" <mame@...> 2007/12/19

遠藤です。

[#32409] Re: [ruby-cvs:21293] Ruby:r14056 (trunk): * signal.c (trap_signm): SIGVTALRM no longer used for green — SASADA Koichi <ko1@...>

 ささだです.

10 messages 2007/11/30

[ruby-dev:32226] Re: Use two pipes for duplex IO.popen

From: Tanaka Akira <akr@...>
Date: 2007-11-12 06:19:01 UTC
List: ruby-dev #32226
In article <20071112024704.798C8E0486@mail.bc9.jp>,
  Nobuyoshi Nakada <nobu@ruby-lang.org> writes:

> そのままwrite_ioとか、長いのがよければtied_io_for_writingとかで
> はどうでしょうか。

tied_io_for_writing ならこうですかね。

Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(リビジョン 13873)
+++ include/ruby/intern.h	(作業コピー)
@@ -353,6 +353,7 @@
 VALUE rb_io_print(int, VALUE*, VALUE);
 VALUE rb_io_puts(int, VALUE*, VALUE);
 VALUE rb_io_fdopen(int, int, const char*);
+VALUE rb_io_get_write_io(VALUE);
 VALUE rb_file_open(const char*, const char*);
 VALUE rb_gets(void);
 void rb_write_error(const char*);
Index: include/ruby/io.h
===================================================================
--- include/ruby/io.h	(リビジョン 13873)
+++ include/ruby/io.h	(作業コピー)
@@ -45,6 +45,7 @@
     int rbuf_off;
     int rbuf_len;
     int rbuf_capa;
+    VALUE tied_io_for_writing;
     rb_encoding *enc;
 } rb_io_t;
 
@@ -88,8 +89,12 @@
     fp->rbuf_off = 0;\
     fp->rbuf_len = 0;\
     fp->rbuf_capa = 0;\
+    fp->tied_io_for_writing = 0;\
 } while (0)
 
+#define GetReadIO(io) (io)
+#define GetWriteIO(io) rb_io_get_write_io(io)
+
 FILE *rb_io_stdio_file(rb_io_t *fptr);
 
 FILE *rb_fopen(const char*, const char*);
Index: io.c
===================================================================
--- io.c	(リビジョン 13873)
+++ io.c	(作業コピー)
@@ -246,6 +246,17 @@
     return rb_check_convert_type(io, T_FILE, "IO", "to_io");
 }
 
+VALUE
+rb_io_get_write_io(VALUE io)
+{
+    VALUE write_io;
+    write_io = RFILE(io)->fptr->tied_io_for_writing;
+    if (write_io) {
+        return write_io;
+    }
+    return io;
+}
+
 /*
  *  call-seq:
  *     IO.try_convert(obj) -> io or nil
@@ -676,6 +687,7 @@
     VALUE tmp;
 
     rb_secure(4);
+    io = GetWriteIO(io);
     str = rb_obj_as_string(str);
     tmp = rb_io_check_io(io);
     if (NIL_P(tmp)) {
@@ -748,6 +760,7 @@
         return rb_funcall(io, id_flush, 0);
     }
 
+    io = GetWriteIO(io);
     GetOpenFile(io, fptr);
 
     if (fptr->mode & FMODE_WRITABLE) {
@@ -982,6 +995,7 @@
 {
     rb_io_t *fptr;
 
+    io = GetWriteIO(io);
     GetOpenFile(io, fptr);
     return (fptr->mode & FMODE_SYNC) ? Qtrue : Qfalse;
 }
@@ -1006,6 +1020,7 @@
 {
     rb_io_t *fptr;
 
+    io = GetWriteIO(io);
     GetOpenFile(io, fptr);
     if (RTEST(mode)) {
 	fptr->mode |= FMODE_SYNC;
@@ -1034,6 +1049,7 @@
 #ifdef HAVE_FSYNC
     rb_io_t *fptr;
 
+    io = GetWriteIO(io);
     GetOpenFile(io, fptr);
 
     io_fflush(fptr);
@@ -1464,6 +1480,7 @@
     if (TYPE(str) != T_STRING)
 	str = rb_obj_as_string(str);
 
+    io = GetWriteIO(io);
     GetOpenFile(io, fptr);
     rb_io_check_writable(fptr);
 
@@ -2348,7 +2365,17 @@
 {
     rb_io_t *fptr;
     int fd;
+    VALUE write_io;
+    rb_io_t *write_fptr;
 
+    write_io = GetWriteIO(io);
+    if (io != write_io) {
+        write_fptr = RFILE(write_io)->fptr;
+        if (write_fptr && 0 <= write_fptr->fd) {
+            rb_io_fptr_cleanup(write_fptr, Qtrue);
+        }
+    }
+
     fptr = RFILE(io)->fptr;
     if (!fptr) return Qnil;
     if (fptr->fd < 0) return Qnil;
@@ -2425,7 +2452,17 @@
 rb_io_closed(VALUE io)
 {
     rb_io_t *fptr;
+    VALUE write_io;
+    rb_io_t *write_fptr;
 
+    write_io = GetWriteIO(io);
+    if (io != write_io) {
+        write_fptr = RFILE(write_io)->fptr;
+        if (write_fptr && 0 <= write_fptr->fd) {
+            return Qfalse;
+        }
+    }
+
     fptr = RFILE(io)->fptr;
     rb_io_check_initialized(fptr);
     return 0 <= fptr->fd ? Qfalse : Qtrue;
@@ -2453,6 +2490,7 @@
 rb_io_close_read(VALUE io)
 {
     rb_io_t *fptr;
+    VALUE write_io;
 
     if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
 	rb_raise(rb_eSecurityError, "Insecure: can't close");
@@ -2469,6 +2507,13 @@
             return rb_io_close(io);
         return Qnil;
     }
+
+    write_io = GetWriteIO(io);
+    if (io != write_io) {
+        fptr_finalize(fptr, Qfalse);
+        return Qnil;
+    }
+
     if (fptr->mode & FMODE_WRITABLE) {
 	rb_raise(rb_eIOError, "closing non-duplex IO for reading");
     }
@@ -2502,6 +2547,7 @@
     if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
 	rb_raise(rb_eSecurityError, "Insecure: can't close");
     }
+    io = GetWriteIO(io);
     GetOpenFile(io, fptr);
     if (is_socket(fptr->fd, fptr->path)) {
 #ifndef SHUT_WR
@@ -2582,6 +2628,7 @@
     if (TYPE(str) != T_STRING)
 	str = rb_obj_as_string(str);
 
+    io = GetWriteIO(io);
     GetOpenFile(io, fptr);
     rb_io_check_writable(fptr);
 
@@ -2666,15 +2713,6 @@
     return str;
 }
 
-/*
- *  call-seq:
- *     ios.binmode    => ios
- *
- *  Puts <em>ios</em> into binary mode. This is useful only in
- *  MS-DOS/Windows environments. Once a stream is in binary mode, it
- *  cannot be reset to nonbinary mode.
- */
-
 VALUE
 rb_io_binmode(VALUE io)
 {
@@ -2693,6 +2731,30 @@
     return io;
 }
 
+/*
+ *  call-seq:
+ *     ios.binmode    => ios
+ *
+ *  Puts <em>ios</em> into binary mode. This is useful only in
+ *  MS-DOS/Windows environments. Once a stream is in binary mode, it
+ *  cannot be reset to nonbinary mode.
+ */
+
+static VALUE
+rb_io_binmode_m(VALUE io)
+{
+#if defined(_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__)
+    VALUE write_io;
+
+    rb_io_binmode(io);
+
+    write_io = GetWriteIO(io);
+    if (write_io != io)
+        rb_io_binmode(write_io);
+#endif
+    return io;
+}
+
 static const char*
 rb_io_flags_mode(int flags)
 {
@@ -3078,17 +3140,23 @@
     struct rb_exec_arg exec;
     int modef;
     int pair[2];
+    int write_pair[2];
 };
 
 static void
 popen_redirect(struct popen_arg *p)
 {
     if ((p->modef & FMODE_READABLE) && (p->modef & FMODE_WRITABLE)) {
+        close(p->write_pair[1]);
+        if (p->write_pair[0] != 0) {
+            dup2(p->write_pair[0], 0);
+            close(p->write_pair[0]);
+        }
         close(p->pair[0]);
-        dup2(p->pair[1], 0);
-        dup2(p->pair[1], 1);
-        if (2 <= p->pair[1])
+        if (p->pair[1] != 1) {
+            dup2(p->pair[1], 1);
             close(p->pair[1]);
+        }
     }
     else if (p->modef & FMODE_READABLE) {
         close(p->pair[0]);
@@ -3132,6 +3200,8 @@
     int pid = 0;
     rb_io_t *fptr;
     VALUE port;
+    rb_io_t *write_fptr;
+    VALUE write_port;
 #if defined(HAVE_FORK)
     int status;
     struct popen_arg arg;
@@ -3141,17 +3211,24 @@
 #endif
     FILE *fp = 0;
     int fd = -1;
+    int write_fd = -1;
 
 #if defined(HAVE_FORK)
     arg.modef = modef;
     arg.pair[0] = arg.pair[1] = -1;
+    arg.write_pair[0] = arg.write_pair[1] = -1;
     switch (modef & (FMODE_READABLE|FMODE_WRITABLE)) {
-#if defined(HAVE_SOCKETPAIR)
       case FMODE_READABLE|FMODE_WRITABLE:
-        if (socketpair(AF_UNIX, SOCK_STREAM, 0, arg.pair) < 0)
+        if (pipe(arg.write_pair) < 0)
             rb_sys_fail(cmd);
+        if (pipe(arg.pair) < 0) {
+            int e = errno;
+            close(arg.write_pair[0]);
+            close(arg.write_pair[1]);
+            errno = e;
+            rb_sys_fail(cmd);
+        }
 	break;
-#endif
       case FMODE_READABLE:
         if (pipe(arg.pair) < 0)
             rb_sys_fail(cmd);
@@ -3187,12 +3264,18 @@
 	int e = errno;
 	close(arg.pair[0]);
 	close(arg.pair[1]);
+        if ((modef & (FMODE_READABLE|FMODE_WRITABLE)) == (FMODE_READABLE|FMODE_WRITABLE)) {
+            close(arg.write_pair[0]);
+            close(arg.write_pair[1]);
+        }
 	errno = e;
 	rb_sys_fail(cmd);
     }
     if ((modef & FMODE_READABLE) && (modef & FMODE_WRITABLE)) {
         close(arg.pair[1]);
         fd = arg.pair[0];
+        close(arg.write_pair[0]);
+        write_fd = arg.write_pair[1];
     }
     else if (modef & FMODE_READABLE) {
         close(arg.pair[1]);
@@ -3245,6 +3328,15 @@
     fptr->mode = modef | FMODE_SYNC|FMODE_DUPLEX;
     fptr->pid = pid;
 
+    if (0 <= write_fd) {
+        write_port = io_alloc(rb_cIO);
+        MakeOpenFile(write_port, write_fptr);
+        write_fptr->fd = write_fd;
+        write_fptr->mode = (modef & ~FMODE_READABLE)| FMODE_SYNC|FMODE_DUPLEX;
+        fptr->mode &= ~FMODE_WRITABLE;
+        fptr->tied_io_for_writing = write_port;
+    }
+
 #if defined (__CYGWIN__) || !defined(HAVE_FORK)
     fptr->finalize = pipe_finalize;
     pipe_add_fptr(fptr);
@@ -3375,7 +3467,23 @@
     return port;
 }
 
+/*
+ *  call-seq:
+ *     io.tied_io_for_writing -> io or nil
+ *
+ *  Return the tied IO for writing from the IO object
+ *  opened by duplex popen such as IO.popen("...", "r+").
+ */
 static VALUE
+rb_io_tied_io_for_writing(VALUE io)
+{
+    VALUE write_io = GetWriteIO(io);
+    if (write_io != io)
+        return write_io;
+    return Qnil;
+}
+
+static VALUE
 rb_open_file(int argc, VALUE *argv, VALUE io)
 {
     VALUE fname, vmode, perm;
@@ -3770,6 +3878,7 @@
 {
     rb_io_t *fptr, *orig;
     int fd;
+    VALUE write_io;
 
     io = rb_io_get_io(io);
     if (dest == io) return dest;
@@ -3792,6 +3901,12 @@
 	rb_io_binmode(dest);
     }
 
+    write_io = GetWriteIO(io);
+    if (io != write_io) {
+        write_io = rb_obj_dup(write_io);
+        fptr->tied_io_for_writing = write_io;
+    }
+
     return dest;
 }
 
@@ -4732,7 +4847,8 @@
     if (!NIL_P(write)) {
 	Check_Type(write, T_ARRAY);
 	for (i=0; i<RARRAY_LEN(write); i++) {
-	    GetOpenFile(rb_io_get_io(RARRAY_PTR(write)[i]), fptr);
+            VALUE write_io = GetWriteIO(rb_io_get_io(RARRAY_PTR(write)[i]));
+	    GetOpenFile(write_io, fptr);
 	    rb_fd_set(fptr->fd, &fds[1]);
 	    if (max < fptr->fd) max = fptr->fd;
 	}
@@ -4744,9 +4860,16 @@
     if (!NIL_P(except)) {
 	Check_Type(except, T_ARRAY);
 	for (i=0; i<RARRAY_LEN(except); i++) {
-	    GetOpenFile(rb_io_get_io(RARRAY_PTR(except)[i]), fptr);
+            VALUE io = rb_io_get_io(RARRAY_PTR(except)[i]);
+            VALUE write_io = GetWriteIO(io);
+	    GetOpenFile(io, fptr);
 	    rb_fd_set(fptr->fd, &fds[2]);
 	    if (max < fptr->fd) max = fptr->fd;
+            if (io != write_io) {
+                GetOpenFile(write_io, fptr);
+                rb_fd_set(fptr->fd, &fds[2]);
+                if (max < fptr->fd) max = fptr->fd;
+            }
 	}
 	ep = rb_fd_ptr(&fds[2]);
     }
@@ -4771,10 +4894,11 @@
 	if (rp) {
 	    list = RARRAY_PTR(res)[0];
 	    for (i=0; i< RARRAY_LEN(read); i++) {
-		GetOpenFile(rb_io_get_io(RARRAY_PTR(read)[i]), fptr);
+                VALUE io = rb_io_get_io(rb_ary_entry(read, i));
+		GetOpenFile(io, fptr);
 		if (rb_fd_isset(fptr->fd, &fds[0]) ||
 		    rb_fd_isset(fptr->fd, &fds[3])) {
-		    rb_ary_push(list, rb_ary_entry(read, i));
+		    rb_ary_push(list, io);
 		}
 	    }
 	}
@@ -4782,9 +4906,11 @@
 	if (wp) {
 	    list = RARRAY_PTR(res)[1];
 	    for (i=0; i< RARRAY_LEN(write); i++) {
-		GetOpenFile(rb_io_get_io(RARRAY_PTR(write)[i]), fptr);
+                VALUE io = rb_io_get_io(rb_ary_entry(write, i));
+                VALUE write_io = GetWriteIO(io);
+		GetOpenFile(write_io, fptr);
 		if (rb_fd_isset(fptr->fd, &fds[1])) {
-		    rb_ary_push(list, rb_ary_entry(write, i));
+		    rb_ary_push(list, io);
 		}
 	    }
 	}
@@ -4792,10 +4918,18 @@
 	if (ep) {
 	    list = RARRAY_PTR(res)[2];
 	    for (i=0; i< RARRAY_LEN(except); i++) {
-		GetOpenFile(rb_io_get_io(RARRAY_PTR(except)[i]), fptr);
+                VALUE io = rb_io_get_io(rb_ary_entry(write, i));
+                VALUE write_io = GetWriteIO(io);
+		GetOpenFile(io, fptr);
 		if (rb_fd_isset(fptr->fd, &fds[2])) {
-		    rb_ary_push(list, rb_ary_entry(except, i));
+		    rb_ary_push(list, io);
 		}
+                else if (io != write_io) {
+                    GetOpenFile(write_io, fptr);
+                    if (rb_fd_isset(fptr->fd, &fds[2])) {
+                        rb_ary_push(list, io);
+                    }
+                }
 	    }
 	}
     }
@@ -5830,6 +5964,8 @@
 
     rb_define_method(rb_cIO, "initialize", rb_io_initialize, -1);
 
+    rb_define_method(rb_cIO, "tied_io_for_writing",  rb_io_tied_io_for_writing, 0);
+
     rb_output_fs = Qnil;
     rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter);
 
@@ -5906,7 +6042,7 @@
 
     rb_define_method(rb_cIO, "isatty", rb_io_isatty, 0);
     rb_define_method(rb_cIO, "tty?", rb_io_isatty, 0);
-    rb_define_method(rb_cIO, "binmode",  rb_io_binmode, 0);
+    rb_define_method(rb_cIO, "binmode",  rb_io_binmode_m, 0);
     rb_define_method(rb_cIO, "sysseek", rb_io_sysseek, -1);
 
     rb_define_method(rb_cIO, "ioctl", rb_io_ioctl, -1);
Index: common.mk
===================================================================
--- common.mk	(リビジョン 13873)
+++ common.mk	(作業コピー)
@@ -434,7 +434,7 @@
 gc.$(OBJEXT): {$(VPATH)}gc.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
   {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
   {$(VPATH)}signal.h {$(VPATH)}st.h {$(VPATH)}node.h \
-  {$(VPATH)}re.h {$(VPATH)}regex.h {$(VPATH)}oniguruma.h \
+  {$(VPATH)}re.h {$(VPATH)}io.h {$(VPATH)}regex.h {$(VPATH)}oniguruma.h \
   {$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h \
   {$(VPATH)}thread_$(THREAD_MODEL).h
 hash.$(OBJEXT): {$(VPATH)}hash.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
Index: gc.c
===================================================================
--- gc.c	(リビジョン 13873)
+++ gc.c	(作業コピー)
@@ -17,6 +17,7 @@
 #include "ruby/st.h"
 #include "ruby/node.h"
 #include "ruby/re.h"
+#include "ruby/io.h"
 #include "vm_core.h"
 #include "gc.h"
 #include <stdio.h>
@@ -1080,6 +1081,9 @@
 	break;
 
       case T_FILE:
+	gc_mark(obj->as.file.fptr->tied_io_for_writing, lev);
+        break;
+
       case T_REGEXP:
       case T_FLOAT:
       case T_BIGNUM:
-- 
[田中 哲][たなか あきら][Tanaka Akira]

In This Thread