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/