summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS.md8
-rw-r--r--ruby.c29
2 files changed, 37 insertions, 0 deletions
diff --git a/NEWS.md b/NEWS.md
index 15c7125deb..890306ca86 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -54,6 +54,13 @@ sufficient information, see the ChangeLog file or Redmine
## Command line options
+### `--help` option
+
+When the environment variable `RUBY_PAGER` or `PAGER` is present and has
+non-empty value, and the standard input and output are tty, `--help`
+option shows the help message via the pager designated by the value.
+[[Feature #16754]]
+
## Core classes updates
Outstanding ones only.
@@ -192,4 +199,5 @@ Excluding feature bug fixes.
[Feature #15921]: https://bugs.ruby-lang.org/issues/15921
[Feature #16555]: https://bugs.ruby-lang.org/issues/16555
[Feature #16746]: https://bugs.ruby-lang.org/issues/16746
+[Feature #16754]: https://bugs.ruby-lang.org/issues/16754
[GH-2991]: https://github.com/ruby/ruby/pull/2991
diff --git a/ruby.c b/ruby.c
index 78127cbe4b..a3d67d3f46 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1606,6 +1606,35 @@ 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);
+ int fds[2];
+ if (rb_pipe(fds) == 0) {
+ rb_pid_t pid = fork();
+ if (pid > 0) {
+ /* exec PAGER with reading from child */
+ dup2(fds[0], 0);
+ }
+ else if (pid == 0) {
+ /* send the help message to the parent PAGER */
+ dup2(fds[1], 1);
+ dup2(fds[1], 2);
+ }
+ close(fds[0]);
+ close(fds[1]);
+ if (pid > 0) {
+ rb_f_exec(1, &pager);
+ kill(SIGTERM, pid);
+ rb_waitpid(pid, 0, 0);
+ }
+ }
+ }
+ }
+#endif
usage(progname, (opt->dump & DUMP_BIT(help)));
return Qtrue;
}