[前][次][番号順一覧][スレッド一覧]

ruby-changes:9530

From: yugui <ko1@a...>
Date: Fri, 26 Dec 2008 20:16:41 +0900 (JST)
Subject: [ruby-changes:9530] Ruby:r21069 (ruby_1_9_1): merges r21059 from trunk into ruby_1_9_1.

yugui	2008-12-26 20:16:07 +0900 (Fri, 26 Dec 2008)

  New Revision: 21069

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=21069

  Log:
    merges r21059 from trunk into ruby_1_9_1.
    * io.c (fptr_finalize): close the IO object even if finish_writeconv or
      flush is failed.
      (finish_writeconv): don't raise.  return errno or exception.
      (finish_writeconv_arg): removed.
      (finish_writeconv_sync): follow finish_writeconv change.
    * transcode.c (rb_econv_make_exception): new function.
    
    * include/ruby/encoding.h (rb_econv_make_exception): declared.

  Modified files:
    branches/ruby_1_9_1/ChangeLog
    branches/ruby_1_9_1/include/ruby/encoding.h
    branches/ruby_1_9_1/io.c
    branches/ruby_1_9_1/transcode.c

Index: ruby_1_9_1/include/ruby/encoding.h
===================================================================
--- ruby_1_9_1/include/ruby/encoding.h	(revision 21068)
+++ ruby_1_9_1/include/ruby/encoding.h	(revision 21069)
@@ -248,6 +248,9 @@
 /* raise an error if the last rb_econv_convert is error */
 void rb_econv_check_error(rb_econv_t *ec);
 
+/* returns an exception object or nil */
+VALUE rb_econv_make_exception(rb_econv_t *ec);
+
 int rb_econv_putbackable(rb_econv_t *ec);
 void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n);
 
Index: ruby_1_9_1/ChangeLog
===================================================================
--- ruby_1_9_1/ChangeLog	(revision 21068)
+++ ruby_1_9_1/ChangeLog	(revision 21069)
@@ -1,3 +1,15 @@
+Fri Dec 26 14:01:38 2008  Tanaka Akira  <akr@f...>
+
+	* io.c (fptr_finalize): close the IO object even if finish_writeconv or
+	  flush is failed.
+	  (finish_writeconv): don't raise.  return errno or exception.
+	  (finish_writeconv_arg): removed.
+	  (finish_writeconv_sync): follow finish_writeconv change.
+
+	* transcode.c (rb_econv_make_exception): new function.
+
+	* include/ruby/encoding.h (rb_econv_make_exception): declared.
+
 Fri Dec 26 17:04:14 2008  Yuki Sonoda (Yugui)  <yugui@y...>
 
 	* lib/irb/input-method.rb (IRB::StdioInputMethod#initialize):
Index: ruby_1_9_1/io.c
===================================================================
--- ruby_1_9_1/io.c	(revision 21068)
+++ ruby_1_9_1/io.c	(revision 21069)
@@ -3020,11 +3020,12 @@
 #define IS_PREP_STDIO(f) ((f)->mode & FMODE_PREP)
 #define PREP_STDIO_NAME(f) (RSTRING_PTR((f)->pathv))
 
-static void
-finish_writeconv(rb_io_t *fptr, int noraise)
+static VALUE
+finish_writeconv(rb_io_t *fptr)
 {
     unsigned char *ds, *dp, *de;
     rb_econv_result_t res;
+    VALUE err;
 
     if (!fptr->wbuf) {
         unsigned char buf[1024];
@@ -3044,104 +3045,90 @@
                     ds += r;
                 }
                 if (rb_io_wait_writable(fptr->fd)) {
-                    if (!noraise)
-                        rb_io_check_closed(fptr);
-                    else if (fptr->fd < 0)
-                        return;
+                    if (fptr->fd < 0)
+                        return rb_exc_new3(rb_eIOError, rb_str_new_cstr("closed stream"));
                     goto retry;
                 }
-                return;
+                return INT2NUM(errno);
             }
-            if (!noraise) {
-                rb_econv_check_error(fptr->writeconv);
-            }
-            if (res == econv_invalid_byte_sequence ||
-                res == econv_incomplete_input ||
-                res == econv_undefined_conversion) {
-                break;
-            }
+            if (!NIL_P(err = rb_econv_make_exception(fptr->writeconv)))
+                return err;
         }
 
-        return;
+        return Qnil;
     }
 
     res = econv_destination_buffer_full;
     while (res == econv_destination_buffer_full) {
         if (fptr->wbuf_len == fptr->wbuf_capa) {
-            if (io_fflush(fptr) < 0 && !noraise)
-                rb_sys_fail(0);
+            if (io_fflush(fptr) < 0)
+                return INT2NUM(errno);
         }
 
         ds = dp = (unsigned char *)fptr->wbuf + fptr->wbuf_off + fptr->wbuf_len;
         de = (unsigned char *)fptr->wbuf + fptr->wbuf_capa;
         res = rb_econv_convert(fptr->writeconv, NULL, NULL, &dp, de, 0);
         fptr->wbuf_len += dp - ds;
-        if (!noraise) {
-            rb_econv_check_error(fptr->writeconv);
-        }
-        if (res == econv_invalid_byte_sequence ||
-            res == econv_incomplete_input ||
-            res == econv_undefined_conversion) {
-            break;
-        }
+        if (!NIL_P(err = rb_econv_make_exception(fptr->writeconv)))
+            return err;
     }
-
+    return Qnil;
 }
 
-struct finish_writeconv_arg {
-    rb_io_t *fptr;
-    int noraise;
-};
-
 static VALUE
 finish_writeconv_sync(VALUE arg)
 {
-    struct finish_writeconv_arg *p = (struct finish_writeconv_arg *)arg;
-    finish_writeconv(p->fptr, p->noraise);
-    return Qnil;
+    rb_io_t *fptr = (rb_io_t *)arg;
+    return finish_writeconv(fptr);
 }
 
 static void
 fptr_finalize(rb_io_t *fptr, int noraise)
 {
-    int close_failure = 0;
+    VALUE err = Qnil;
     if (fptr->writeconv) {
 	if (fptr->write_lock) {
-	    struct finish_writeconv_arg arg;
-	    arg.fptr = fptr;
-	    arg.noraise = noraise;
-	    rb_mutex_synchronize(fptr->write_lock, finish_writeconv_sync, (VALUE)&arg);
+	    err = rb_mutex_synchronize(fptr->write_lock, finish_writeconv_sync, (VALUE)fptr);
 	}
 	else {
-	    finish_writeconv(fptr, noraise);
+	    err = finish_writeconv(fptr);
 	}
     }
     if (fptr->wbuf_len) {
-        if (io_fflush(fptr) < 0 && !noraise)
-            rb_sys_fail(0);
+        if (io_fflush(fptr) < 0 && NIL_P(err))
+            err = INT2NUM(errno);
     }
-    if (IS_PREP_STDIO(fptr) ||
-        fptr->fd <= 2) {
-	return;
+    if (IS_PREP_STDIO(fptr) || fptr->fd <= 2) {
+        goto check_err;
     }
     if (fptr->stdio_file) {
         /* fptr->stdio_file is deallocated anyway
          * even if fclose failed.  */
-        if (fclose(fptr->stdio_file) < 0)
-            close_failure = 1;
+        if (fclose(fptr->stdio_file) < 0 && NIL_P(err))
+            err = INT2NUM(errno);
     }
     else if (0 <= fptr->fd) {
         /* fptr->fd may be closed even if close fails.
          * POSIX doesn't specify it.
          * We assumes it is closed.  */
-        if (close(fptr->fd) < 0)
-            close_failure = 1;
+        if (close(fptr->fd) < 0 && NIL_P(err))
+            err = INT2NUM(errno);
     }
     fptr->fd = -1;
     fptr->stdio_file = 0;
     fptr->mode &= ~(FMODE_READABLE|FMODE_WRITABLE);
-    if (close_failure && !noraise) {
-        rb_sys_fail_path(fptr->pathv);
+
+  check_err:
+    if (!NIL_P(err) && !noraise) {
+        switch(TYPE(err)) {
+          case T_FIXNUM:
+          case T_BIGNUM:
+            errno = NUM2INT(err);
+            rb_sys_fail_path(fptr->pathv);
+
+          default:
+            rb_exc_raise(err);
+        }
     }
 }
 
Index: ruby_1_9_1/transcode.c
===================================================================
--- ruby_1_9_1/transcode.c	(revision 21068)
+++ ruby_1_9_1/transcode.c	(revision 21069)
@@ -3854,6 +3854,12 @@
     return arg;
 }
 
+VALUE
+rb_econv_make_exception(rb_econv_t *ec)
+{
+    return make_econv_exception(ec);
+}
+
 void
 rb_econv_check_error(rb_econv_t *ec)
 {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]