[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 06/07: fixup! Make system* and piped-process internally
From: |
Ludovic Courtès |
Subject: |
[Guile-commits] 06/07: fixup! Make system* and piped-process internally use spawn. |
Date: |
Fri, 23 Dec 2022 05:45:31 -0500 (EST) |
civodul pushed a commit to branch wip-posix-spawn
in repository guile.
commit d4ece4b74d9920bd07e5bfe875ce85abe623f98e
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Fri Dec 23 11:26:55 2022 +0100
fixup! Make system* and piped-process internally use spawn.
Avoid extra 'fork' upon error in 'system*'.
---
libguile/posix.c | 117 ++++++++++++++++++++++++++++++++++---------------------
1 file changed, 72 insertions(+), 45 deletions(-)
diff --git a/libguile/posix.c b/libguile/posix.c
index de2a31aae..79b066bb3 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -78,6 +78,7 @@
#include "threads.h"
#include "values.h"
#include "vectors.h"
+#include "verify.h"
#include "version.h"
#if (SCM_ENABLE_DEPRECATED == 1)
@@ -96,6 +97,13 @@
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
+#ifndef W_EXITCODE
+/* Macro for constructing a status value. Found in glibc. */
+# define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
+#endif
+verify (WEXITSTATUS (W_EXITCODE (127, 0)) == 127);
+
+
#include <signal.h>
#ifdef HAVE_GRP_H
@@ -1424,15 +1432,14 @@ SCM_DEFINE (scm_spawn_process, "spawn*", 5, 0, 0,
#undef FUNC_NAME
#ifdef HAVE_FORK
-static SCM
-scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
+static int
+piped_process (pid_t *pid, SCM prog, SCM args, SCM from, SCM to)
#define FUNC_NAME "piped-process"
{
int reading, writing;
int c2p[2]; /* Child to parent. */
int p2c[2]; /* Parent to child. */
int in = -1, out = -1, err = -1;
- int pid;
char *exec_file;
char **exec_argv;
char **exec_env = environ;
@@ -1468,48 +1475,57 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
in = SCM_FPORT_FDES (port);
}
- pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err);
- int errno_save = errno;
-
- if (pid == -1)
- {
- /* 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;
-
- default:
- /* Else create a dummy process that exits with value 127 */
- 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);
+ *pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err);
+ int errno_save = (*pid < 0) ? errno : 0;
if (reading)
close (c2p[1]);
if (writing)
close (p2c[0]);
+ if (*pid == -1)
+ switch (errno_save)
+ {
+ /* Errors that seemingly come from fork. */
+ case EAGAIN:
+ case ENOMEM:
+ case ENOSYS:
+ errno = err;
+ free (exec_file);
+ SCM_SYSERROR;
+ break;
+
+ default: /* ENOENT, etc. */
+ /* Create a dummy process that exits with value 127. */
+ dprintf (err, "In execvp of %s: %s\n", exec_file,
+ strerror (errno_save));
+ }
+
+ free (exec_file);
+
+ return errno_save;
+}
+#undef FUNC_NAME
+
+static SCM
+scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
+#define FUNC_NAME "piped-process"
+{
+ pid_t pid;
+
+ (void) piped_process (&pid, prog, args, from, to);
+ if (pid == -1)
+ {
+ /* Create a dummy process that exits with value 127 to mimic the
+ previous fork + exec implementation. TODO: This is a
+ compatibility shim to remove in the next stable series. */
+ pid = fork ();
+ if (pid == -1)
+ SCM_SYSERROR;
+ if (pid == 0)
+ _exit (127);
+ }
+
return scm_from_int (pid);
}
#undef FUNC_NAME
@@ -1555,8 +1571,9 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
"Example: (system* \"echo\" \"foo\" \"bar\")")
#define FUNC_NAME s_scm_system_star
{
- SCM prog, pid;
- int status, wait_result;
+ SCM prog;
+ pid_t pid;
+ int err, status, wait_result;
if (scm_is_null (args))
SCM_WRONG_NUM_ARGS ();
@@ -1574,10 +1591,20 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
SCM_UNDEFINED);
#endif
- pid = scm_piped_process (prog, args, SCM_UNDEFINED, SCM_UNDEFINED);
- SCM_SYSCALL (wait_result = waitpid (scm_to_int (pid), &status, 0));
- if (wait_result == -1)
- SCM_SYSERROR;
+ err = piped_process (&pid, prog, args,
+ SCM_UNDEFINED, SCM_UNDEFINED);
+ if (err != 0)
+ /* ERR might be ENOENT or similar. For backward compatibility with
+ the previous implementation based on fork + exec, pretend the
+ child process exited with code 127. TODO: Remove this
+ compatibility shim in the next stable series. */
+ status = W_EXITCODE (127, 0);
+ else
+ {
+ SCM_SYSCALL (wait_result = waitpid (pid, &status, 0));
+ if (wait_result == -1)
+ SCM_SYSERROR;
+ }
scm_dynwind_end ();
- [Guile-commits] branch wip-posix-spawn created (now 7073b5f67), Ludovic Courtès, 2022/12/23
- [Guile-commits] 04/07: Reduce redundant 'close' calls when forking on some systems., Ludovic Courtès, 2022/12/23
- [Guile-commits] 06/07: fixup! Make system* and piped-process internally use spawn.,
Ludovic Courtès <=
- [Guile-commits] 05/07: fixup! Make system* and piped-process internally use spawn., Ludovic Courtès, 2022/12/23
- [Guile-commits] 02/07: Add spawn*., Ludovic Courtès, 2022/12/23
- [Guile-commits] 07/07: fixup! Make system* and piped-process internally use spawn., Ludovic Courtès, 2022/12/23
- [Guile-commits] 01/07: Update gnulib to 0.1.5414-8204d and add posix_spawn, posix_spawnp., Ludovic Courtès, 2022/12/23
- [Guile-commits] 03/07: Make system* and piped-process internally use spawn., Ludovic Courtès, 2022/12/23