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

ruby-changes:60751

From: Nobuyoshi <ko1@a...>
Date: Sun, 12 Apr 2020 14:58:30 +0900 (JST)
Subject: [ruby-changes:60751] e6551d835f (master): PAGER without fork&exec too [Feature #16754]

https://git.ruby-lang.org/ruby.git/commit/?id=e6551d835f

From e6551d835febe00fce6c6a3b12c4e394d2a05bd6 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Tue, 4 Feb 2020 11:28:20 +0900
Subject: PAGER without fork&exec too [Feature #16754]


diff --git a/internal/io.h b/internal/io.h
index a08601f..6578d0b 100644
--- a/internal/io.h
+++ b/internal/io.h
@@ -23,6 +23,7 @@ void rb_io_fptr_finalize_internal(void *ptr); https://github.com/ruby/ruby/blob/trunk/internal/io.h#L23
 # undef rb_io_fptr_finalize
 #endif
 #define rb_io_fptr_finalize rb_io_fptr_finalize_internal
+VALUE rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt);
 
 RUBY_SYMBOL_EXPORT_BEGIN
 /* io.c (export) */
diff --git a/io.c b/io.c
index 2cdfd80..4be5f05 100644
--- a/io.c
+++ b/io.c
@@ -6868,6 +6868,8 @@ pipe_close(VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L6868
     return Qnil;
 }
 
+static VALUE popen_finish(VALUE port, VALUE klass);
+
 /*
  *  call-seq:
  *     IO.popen([env,] cmd, mode="r" [, opt])               -> io
@@ -6957,10 +6959,7 @@ pipe_close(VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L6959
 static VALUE
 rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
 {
-    const char *modestr;
-    VALUE pname, pmode = Qnil, port, tmp, opt = Qnil, env = Qnil, execarg_obj = Qnil;
-    int oflags, fmode;
-    convconfig_t convconfig;
+    VALUE pname, pmode = Qnil, opt = Qnil, env = Qnil;
 
     if (argc > 1 && !NIL_P(opt = rb_check_hash_type(argv[argc-1]))) --argc;
     if (argc > 1 && !NIL_P(env = rb_check_hash_type(argv[0]))) --argc, ++argv;
@@ -6976,6 +6975,16 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/io.c#L6975
 	    rb_error_arity(argc + ex, 1 + ex, 2 + ex);
 	}
     }
+    return popen_finish(rb_io_popen(pname, pmode, env, opt), klass);
+}
+
+VALUE
+rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt)
+{
+    const char *modestr;
+    VALUE tmp, execarg_obj = Qnil;
+    int oflags, fmode;
+    convconfig_t convconfig;
 
     tmp = rb_check_array_type(pname);
     if (!NIL_P(tmp)) {
@@ -7003,7 +7012,12 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/io.c#L7012
     rb_io_extract_modeenc(&pmode, 0, opt, &oflags, &fmode, &convconfig);
     modestr = rb_io_oflags_modestr(oflags);
 
-    port = pipe_open(execarg_obj, modestr, fmode, &convconfig);
+    return pipe_open(execarg_obj, modestr, fmode, &convconfig);
+}
+
+static VALUE
+popen_finish(VALUE port, VALUE klass)
+{
     if (NIL_P(port)) {
 	/* child */
 	if (rb_block_given_p()) {
diff --git a/ruby.c b/ruby.c
index a3d67d3..79cd595 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1606,12 +1606,12 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt) https://github.com/ruby/ruby/blob/trunk/ruby.c#L1606
 	    (argc > 0 && argv && argv[0] ? argv[0] :
 	     origarg.argc > 0 && origarg.argv && origarg.argv[0] ? origarg.argv[0] :
 	     ruby_engine);
-#ifdef HAVE_WORKING_FORK
         if (opt->dump & DUMP_BIT(help)) {
             const char *pager_env = getenv("RUBY_PAGER");
             if (!pager_env) pager_env = getenv("PAGER");
             if (pager_env && *pager_env && isatty(0) && isatty(1)) {
                 VALUE pager = rb_str_new_cstr(pager_env);
+#ifdef HAVE_WORKING_FORK
                 int fds[2];
                 if (rb_pipe(fds) == 0) {
                     rb_pid_t pid = fork();
@@ -1632,9 +1632,24 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt) https://github.com/ruby/ruby/blob/trunk/ruby.c#L1632
                         rb_waitpid(pid, 0, 0);
                     }
                 }
+#else
+                VALUE port = rb_io_popen(pager, rb_str_new_lit("w"), Qnil, Qnil);
+                if (!NIL_P(port)) {
+                    int oldout = dup(1);
+                    int olderr = dup(2);
+                    int fd = RFILE(port)->fptr->fd;
+                    dup2(fd, 1);
+                    dup2(fd, 2);
+                    usage(progname, 1);
+                    fflush(stdout);
+                    dup2(oldout, 1);
+                    dup2(olderr, 2);
+                    rb_io_close(port);
+                    return Qtrue;
+                }
+#endif
             }
         }
-#endif
 	usage(progname, (opt->dump & DUMP_BIT(help)));
 	return Qtrue;
     }
-- 
cgit v0.10.2


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

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