diff options
| author | oehhar <harald.oehlmann@elmicron.de> | 2023-06-08 12:01:40 (GMT) |
|---|---|---|
| committer | oehhar <harald.oehlmann@elmicron.de> | 2023-06-08 12:01:40 (GMT) |
| commit | 4314e8e4388010c2f0151e3a8953db113beda7cc (patch) | |
| tree | bb26093f2189bc279bf1635d6012f49adbad53d1 /unix/tclUnixPipe.c | |
| parent | 02f302c8cf626bcf0452b5da0290fcb1212701bf (diff) | |
| download | tcl-4314e8e4388010c2f0151e3a8953db113beda7cc.zip tcl-4314e8e4388010c2f0151e3a8953db113beda7cc.tar.gz tcl-4314e8e4388010c2f0151e3a8953db113beda7cc.tar.bz2 | |
ticket [c54e4a1aeb] patch: Use vfork instead fork.
Diffstat (limited to 'unix/tclUnixPipe.c')
| -rw-r--r-- | unix/tclUnixPipe.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index 75e2879..9b66083 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -13,6 +13,12 @@ #include "tclInt.h" +#define USE_POSIX_SPAWN 1 + +#ifdef USE_POSIX_SPAWN +# include <spawn.h> +#endif + #ifdef USE_VFORK #define fork vfork #endif @@ -439,7 +445,7 @@ TclpCreateProcess( newArgv[i] = Tcl_UtfToExternalDString(NULL, argv[i], -1, &dsArray[i]); } -#ifdef USE_VFORK +#if defined(USE_VFORK) || defined(USE_POSIX_SPAWN) /* * After vfork(), do not call code in the child that changes global state, * because it is using the parent's memory space at that point and writes @@ -452,14 +458,52 @@ TclpCreateProcess( Tcl_GetStdChannel(TCL_STDIN); } if (!outputFile) { - Tcl_GetStdChannel(TCL_STDOUT); + Tcl_GetStdChannel(TCL_STDOUT); } if (!errorFile) { - Tcl_GetStdChannel(TCL_STDERR); + Tcl_GetStdChannel(TCL_STDERR); } #endif +#ifdef USE_POSIX_SPAWN + { + posix_spawn_file_actions_t actions; + posix_spawnattr_t attr; + + posix_spawn_file_actions_init(&actions); + posix_spawnattr_init(&attr); + + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF| +# ifdef POSIX_SPAWN_USEVFORK + POSIX_SPAWN_USEVFORK +# else + 0 +# endif + ); + posix_spawn_file_actions_adddup2(&actions, GetFd(inputFile), 0); + posix_spawn_file_actions_adddup2(&actions, GetFd(outputFile), 1); + posix_spawn_file_actions_adddup2(&actions, GetFd(errorFile), 2); + + status = posix_spawnp(&pid, newArgv[0], &actions, &attr, newArgv, environ); + + posix_spawn_file_actions_destroy(&actions); + posix_spawnattr_destroy(&attr); + + /* + * Fork semantics: + * - pid == 0: child process + * - pid == -1: error + * - pid > 0: parent process + * + * Mimic fork semantics to minimize changes below + */ + if (status != 0) { + pid = -1; + } + } +#else pid = fork(); +#endif if (pid == 0) { size_t len; int joinThisError = errorFile && (errorFile == outputFile); |
