diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-08-05 22:11:52 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-09-25 22:57:28 +0900 |
commit | 7e2775b057d19d5ed06877c3b02299e3b5d2beb7 (patch) | |
tree | bc78bf65a2be58d00212e1eb4dcbc927be968560 /io.c | |
parent | 0f642907046e98cc026b50416bd63212b92112cd (diff) | |
download | ruby-7e2775b057d19d5ed06877c3b02299e3b5d2beb7.tar.gz |
Invoke the command when RUBY_BUGREPORT_PATH starts with `|`
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -170,6 +170,7 @@ off_t __syscall(quad_t number, ...); #define open rb_w32_uopen #undef rename #define rename(f, t) rb_w32_urename((f), (t)) +#include "win32/file.h" #endif VALUE rb_cIO; @@ -7955,6 +7956,60 @@ popen_finish(VALUE port, VALUE klass) return port; } +#if defined(HAVE_WORKING_FORK) && !defined(__EMSCRIPTEN__) +struct popen_writer_arg { + char *const *argv; + struct popen_arg popen; +}; + +static int +exec_popen_writer(void *arg, char *errmsg, size_t buflen) +{ + struct popen_writer_arg *pw = arg; + pw->popen.modef = FMODE_WRITABLE; + popen_redirect(&pw->popen); + execv(pw->argv[0], pw->argv); + strlcpy(errmsg, strerror(errno), buflen); + return -1; +} +#endif + +FILE * +ruby_popen_writer(char *const *argv, rb_pid_t *pid) +{ +#if (defined(HAVE_WORKING_FORK) && !defined(__EMSCRIPTEN__)) || defined(_WIN32) +# ifdef HAVE_WORKING_FORK + struct popen_writer_arg pw; + int *const write_pair = pw.popen.pair; +# else + int write_pair[2]; +# endif + + int result = rb_cloexec_pipe(write_pair); + *pid = -1; + if (result == 0) { +# ifdef HAVE_WORKING_FORK + pw.argv = argv; + int status; + char errmsg[80] = {'\0'}; + *pid = rb_fork_async_signal_safe(&status, exec_popen_writer, &pw, Qnil, errmsg, sizeof(errmsg)); +# else + *pid = rb_w32_uspawn_process(P_NOWAIT, argv[0], argv, write_pair[0], -1, -1, 0); + const char *errmsg = (*pid < 0) ? strerror(errno) : NULL; +# endif + close(write_pair[0]); + if (*pid < 0) { + close(write_pair[1]); + fprintf(stderr, "ruby_popen_writer(%s): %s\n", argv[0], errmsg); + } + else { + return fdopen(write_pair[1], "w"); + } + } +#endif + return NULL; +} + static void rb_scan_open_args(int argc, const VALUE *argv, VALUE *fname_p, int *oflags_p, int *fmode_p, |