From f5dc5ea66cc6c396359c37c7c4193066c996ba27 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov <gorcunov@gmail.com> Date: Mon, 2 Mar 2020 19:43:22 +0300 Subject: [PATCH] popen: handle sid on macos Due to os specifics we can't call setsid after vfork on macos (vfork is not longer a part of posix btw). Instead we can use ioctl to clear the session, then initiate a new process group. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> --- src/lib/core/popen.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/lib/core/popen.c b/src/lib/core/popen.c index 6e5ca21bd9..a0630e3d90 100644 --- a/src/lib/core/popen.c +++ b/src/lib/core/popen.c @@ -16,6 +16,10 @@ #include "coio.h" #include "say.h" +#ifdef TARGET_OS_DARWIN +# include <sys/ioctl.h> +#endif + /* A mapping to find popens by their pids in a signal handler */ static struct mh_i32ptr_t *popen_pids_map = NULL; @@ -833,15 +837,29 @@ popen_new(struct popen_opts *opts) if (opts->flags & POPEN_FLAG_RESTORE_SIGNALS) signal_reset(); - /* - * We have to be a session leader otherwise - * won't be able to kill a group of children. - */ if (opts->flags & POPEN_FLAG_SETSID) { +#ifndef TARGET_OS_DARWIN if (setsid() == -1) { say_syserror("child: setsid failed"); goto exit_child; } +#else + /* + * Note that on MacOS we're not allowed to + * set sid after vfork (it is OS specific) + * thus use ioctl instead. + */ + int ttyfd = open("/dev/tty", O_RDWR, 0); + if (ttyfd >= 0) { + ioctl(ttyfd, TIOCNOTTY, 0); + close(ttyfd); + } + + if (setpgrp() == -1) { + say_syserror("child: setpgrp failed"); + goto exit_child; + } +#endif } if (opts->flags & POPEN_FLAG_CLOSE_FDS) { -- GitLab