PAGER without fork&exec too [Feature #16754]
This commit is contained in:
parent
f22c4ff359
commit
e6551d835f
Notes:
git
2020-04-12 14:58:38 +09:00
@ -23,6 +23,7 @@ void rb_io_fptr_finalize_internal(void *ptr);
|
||||
# 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) */
|
||||
|
24
io.c
24
io.c
@ -6868,6 +6868,8 @@ pipe_close(VALUE io)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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()) {
|
||||
|
19
ruby.c
19
ruby.c
@ -1606,12 +1606,12 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
|
||||
(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)
|
||||
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
|
||||
}
|
||||
}
|
||||
usage(progname, (opt->dump & DUMP_BIT(help)));
|
||||
return Qtrue;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user