From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Josselin Poiret via "Bug reports for GUILE, GNU's Ubiquitous Extension Language" Newsgroups: gmane.lisp.guile.bugs Subject: bug#52835: [PATCH v6 2/3] Make system* and piped-process internally use spawn. Date: Thu, 22 Dec 2022 13:49:09 +0100 Message-ID: References: Reply-To: Josselin Poiret Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33355"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 52835@debbugs.gnu.org, Timothy Sample , Josselin Poiret To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-X-From: bug-guile-bounces+guile-bugs=m.gmane-mx.org@gnu.org Thu Dec 22 13:51:13 2022 Return-path: Envelope-to: guile-bugs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1p8L2W-0008PB-3u for guile-bugs@m.gmane-mx.org; Thu, 22 Dec 2022 13:51:12 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p8L1W-0003tp-Qp; Thu, 22 Dec 2022 07:50:10 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p8L1O-0003qj-Ud for bug-guile@gnu.org; Thu, 22 Dec 2022 07:50:06 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p8L1O-0003Zd-Md for bug-guile@gnu.org; Thu, 22 Dec 2022 07:50:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1p8L1O-0001d3-J7 for bug-guile@gnu.org; Thu, 22 Dec 2022 07:50:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Josselin Poiret Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Thu, 22 Dec 2022 12:50:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 52835 X-GNU-PR-Package: guile X-GNU-PR-Keywords: patch Original-Received: via spool by 52835-submit@debbugs.gnu.org id=B52835.16717133756218 (code B ref 52835); Thu, 22 Dec 2022 12:50:02 +0000 Original-Received: (at 52835) by debbugs.gnu.org; 22 Dec 2022 12:49:35 +0000 Original-Received: from localhost ([127.0.0.1]:58193 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p8L0w-0001c3-NQ for submit@debbugs.gnu.org; Thu, 22 Dec 2022 07:49:35 -0500 Original-Received: from jpoiret.xyz ([206.189.101.64]:41548) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p8L0t-0001bb-LJ for 52835@debbugs.gnu.org; Thu, 22 Dec 2022 07:49:32 -0500 Original-Received: from authenticated-user (jpoiret.xyz [206.189.101.64]) by jpoiret.xyz (Postfix) with ESMTPA id 4E10B185316; Thu, 22 Dec 2022 12:49:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jpoiret.xyz; s=dkim; t=1671713370; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Yi0eZsNOSmpXzvPzihGMhAbkrRzqL2sKBtI+TnZoy6g=; b=KNJnkztoVfP4PTG5FG3LFWCMvvC6CUPo4dafkuoRdkklzLpoSYuUYTShJCaWkv5dalyGC6 SW9v4ZWMub1nkmv3/VTM3meC2mmW1shlvdXYtOw3+LMCBv5bLQzwLCTdL/JwUa8vYFI+ep WfSGE9kcEf2wSQ/yHWe/oCJ1Q+y05nUNqrV7+1gjXmJVJtuLg3PHzYqSVJCY8dfSj5/0Qx /qYpH2+npj33HnW4wR4VwJsLf3Fm1BhA7k54kPGbZ8l3nNpt0bQKxFDQTw6ebCkwAM4xPQ UmxDRxTTDdZ8H9fVSfrjhBpwutDV7ECuC5/IYbqI7OdBTM5eGD++73kTETxpqw== In-Reply-To: Authentication-Results: jpoiret.xyz; auth=pass smtp.auth=jpoiret@jpoiret.xyz smtp.mailfrom=dev@jpoiret.xyz X-Spamd-Bar: / X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane-mx.org@gnu.org Original-Sender: bug-guile-bounces+guile-bugs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.lisp.guile.bugs:10484 Archived-At: * libguile/posix.c (scm_system_star, scm_piped_process): Use do_spawn. (start_child): Remove function. --- libguile/posix.c | 181 ++++++++++------------------------------------- 1 file changed, 39 insertions(+), 142 deletions(-) diff --git a/libguile/posix.c b/libguile/posix.c index e92625483..f9c36d7ac 100644 --- a/libguile/posix.c +++ b/libguile/posix.c @@ -1308,125 +1308,6 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0, #undef FUNC_NAME #endif /* HAVE_FORK */ -#ifdef HAVE_FORK -/* 'renumber_file_descriptor' is a helper function for 'start_child' - below, and is specialized for that particular environment where it - doesn't make sense to report errors via exceptions. It uses dup(2) - to duplicate the file descriptor FD, closes the original FD, and - returns the new descriptor. If dup(2) fails, print an error message - to ERR and abort. */ -static int -renumber_file_descriptor (int fd, int err) -{ - int new_fd; - - do - new_fd = dup (fd); - while (new_fd == -1 && errno == EINTR); - - if (new_fd == -1) - { - /* At this point we are in the child process before exec. We - cannot safely raise an exception in this environment. */ - const char *msg = strerror (errno); - fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg); - _exit (127); /* Use exit status 127, as with other exec errors. */ - } - - close (fd); - return new_fd; -} -#endif /* HAVE_FORK */ - -#ifdef HAVE_FORK -#define HAVE_START_CHILD 1 -/* Since Guile uses threads, we have to be very careful to avoid calling - functions that are not async-signal-safe in the child. That's why - this function is implemented in C. */ -static pid_t -start_child (const char *exec_file, char **exec_argv, - int reading, int c2p[2], int writing, int p2c[2], - int in, int out, int err) -{ - int pid; - int max_fd = 1024; - -#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE) - { - struct rlimit lim = { 0, 0 }; - if (getrlimit (RLIMIT_NOFILE, &lim) == 0) - max_fd = lim.rlim_cur; - } -#endif - - pid = fork (); - - if (pid != 0) - /* The parent, with either and error (pid == -1), or the PID of the - child. Return directly in either case. */ - return pid; - - /* The child. */ - if (reading) - close (c2p[0]); - if (writing) - close (p2c[1]); - - /* Close all file descriptors in ports inherited from the parent - except for in, out, and err. Heavy-handed, but robust. */ - while (max_fd--) - if (max_fd != in && max_fd != out && max_fd != err) - close (max_fd); - - /* Ignore errors on these open() calls. */ - if (in == -1) - in = open ("/dev/null", O_RDONLY); - if (out == -1) - out = open ("/dev/null", O_WRONLY); - if (err == -1) - err = open ("/dev/null", O_WRONLY); - - if (in > 0) - { - if (out == 0) - out = renumber_file_descriptor (out, err); - if (err == 0) - err = renumber_file_descriptor (err, err); - do dup2 (in, 0); while (errno == EINTR); - close (in); - } - if (out > 1) - { - if (err == 1) - err = renumber_file_descriptor (err, err); - do dup2 (out, 1); while (errno == EINTR); - if (out > 2) - close (out); - } - if (err > 2) - { - do dup2 (err, 2); while (errno == EINTR); - close (err); - } - - execvp (exec_file, exec_argv); - - /* The exec failed! There is nothing sensible to do. */ - { - const char *msg = strerror (errno); - fprintf (fdopen (2, "a"), "In execvp of %s: %s\n", - exec_file, msg); - } - - /* Use exit status 127, like shells in this case, as per POSIX - . */ - _exit (127); - - /* Not reached. */ - return -1; -} -#endif - static int do_spawn (char *exec_file, char **exec_argv, char **exec_env, int in, int out, int err) { @@ -1507,7 +1388,7 @@ SCM_DEFINE (scm_spawn_process, "spawn*", 5, 0, 0, } #undef FUNC_NAME -#ifdef HAVE_START_CHILD +#ifdef HAVE_FORK static SCM scm_piped_process (SCM prog, SCM args, SCM from, SCM to) #define FUNC_NAME "piped-process" @@ -1519,6 +1400,7 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to) int pid; char *exec_file; char **exec_argv; + char **exec_env = environ; exec_file = scm_to_locale_string (prog); exec_argv = scm_i_allocate_string_pointers (scm_cons (prog, args)); @@ -1551,27 +1433,44 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to) in = SCM_FPORT_FDES (port); } - pid = start_child (exec_file, exec_argv, reading, c2p, writing, p2c, - in, out, err); + pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err); + int errno_save = errno; if (pid == -1) { - int errno_save = errno; - free (exec_file); - if (reading) - { - close (c2p[0]); - close (c2p[1]); - } - if (writing) - { - close (p2c[0]); - close (p2c[1]); - } - errno = errno_save; - SCM_SYSERROR; + /* TODO This is a compatibility shim until the next major release */ + switch (errno) { + /* If the error seemingly comes from fork */ + case EAGAIN: + case ENOMEM: + case ENOSYS: + free (exec_file); + + if (reading) + { + close (c2p[0]); + } + if (writing) + { + close (p2c[1]); + } + errno = errno_save; + SCM_SYSERROR; + break; + /* Else create a dummy process that exits with value 127 */ + default: + dprintf (err, "In execvp of %s: %s\n", exec_file, + strerror (errno_save)); + pid = fork (); + if (pid == -1) + SCM_SYSERROR; + if (pid == 0) + _exit (127); + } } + free (exec_file); + if (reading) close (c2p[1]); if (writing) @@ -1651,7 +1550,7 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1, return scm_from_int (status); } #undef FUNC_NAME -#endif /* HAVE_START_CHILD */ +#endif /* HAVE_FORK */ #ifdef HAVE_UNAME SCM_DEFINE (scm_uname, "uname", 0, 0, 0, @@ -2497,13 +2396,13 @@ SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0, #endif /* HAVE_GETHOSTNAME */ -#ifdef HAVE_START_CHILD +#ifdef HAVE_FORK static void scm_init_popen (void) { scm_c_define_gsubr ("piped-process", 2, 2, 0, scm_piped_process); } -#endif /* HAVE_START_CHILD */ +#endif /* HAVE_FORK */ void scm_init_posix () @@ -2621,12 +2520,10 @@ scm_init_posix () #ifdef HAVE_FORK scm_add_feature ("fork"); -#endif /* HAVE_FORK */ -#ifdef HAVE_START_CHILD scm_add_feature ("popen"); scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION, "scm_init_popen", (scm_t_extension_init_func) scm_init_popen, NULL); -#endif /* HAVE_START_CHILD */ +#endif /* HAVE_FORK */ } -- 2.38.1