From e3ea7047d8d6288ee1cc1ff13c453638a9f5e378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=96=B5?= <478688389@qq.com> Date: Wed, 3 Jul 2024 14:24:09 +0800 Subject: [PATCH] fix redirect when reuse fd --- src/demo/platform/process.c | 2 ++ src/tbox/platform/posix/process.c | 36 +++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/demo/platform/process.c b/src/demo/platform/process.c index 95e3e81f7..5adb1f019 100644 --- a/src/demo/platform/process.c +++ b/src/demo/platform/process.c @@ -21,6 +21,8 @@ static tb_void_t tb_demo_process_test_pipe(tb_char_t** argv) tb_process_attr_t attr = {0}; attr.out.pipe = file[1]; attr.outtype = TB_PROCESS_REDIRECT_TYPE_PIPE; + attr.err.pipe = file[1]; + attr.errtype = TB_PROCESS_REDIRECT_TYPE_PIPE; tb_process_ref_t process = tb_process_init(argv[1], (tb_char_t const**)(argv + 1), &attr); if (process) { diff --git a/src/tbox/platform/posix/process.c b/src/tbox/platform/posix/process.c index 67cc6644c..40d757fa7 100644 --- a/src/tbox/platform/posix/process.c +++ b/src/tbox/platform/posix/process.c @@ -300,6 +300,10 @@ static tb_process_ref_t tb_process_init_spawn(tb_char_t const* pathname, tb_char // set attributes if (attr) { + tb_int_t oriin = -1; + tb_int_t oriout = -1; + tb_int_t orierr = -1; + // redirect the stdin if (attr->intype == TB_PROCESS_REDIRECT_TYPE_FILEPATH && attr->in.path) { @@ -312,8 +316,8 @@ static tb_process_ref_t tb_process_init_spawn(tb_char_t const* pathname, tb_char { // duplicate inpipe/file fd to stdin in the child process tb_int_t infd = attr->intype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->in.pipe) : tb_file2fd(attr->in.file); + oriin = infd; posix_spawn_file_actions_adddup2(&process->spawn_action, infd, STDIN_FILENO); - posix_spawn_file_actions_addclose(&process->spawn_action, infd); } // redirect the stdout @@ -328,8 +332,8 @@ static tb_process_ref_t tb_process_init_spawn(tb_char_t const* pathname, tb_char { // duplicate outpipe/file fd to stdout in the child process tb_int_t outfd = attr->outtype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->out.pipe) : tb_file2fd(attr->out.file); + oriout = outfd; posix_spawn_file_actions_adddup2(&process->spawn_action, outfd, STDOUT_FILENO); - posix_spawn_file_actions_addclose(&process->spawn_action, outfd); } // redirect the stderr @@ -344,10 +348,18 @@ static tb_process_ref_t tb_process_init_spawn(tb_char_t const* pathname, tb_char { // duplicate errpipe/file fd to stderr in the child process tb_int_t errfd = attr->errtype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->err.pipe) : tb_file2fd(attr->err.file); + orierr = errfd; posix_spawn_file_actions_adddup2(&process->spawn_action, errfd, STDERR_FILENO); - posix_spawn_file_actions_addclose(&process->spawn_action, errfd); } + // close fd + if (oriin != -1) + posix_spawn_file_actions_addclose(&process->spawn_action, oriin); + if (oriout != -1 && oriout != oriin) + posix_spawn_file_actions_addclose(&process->spawn_action, oriout); + if (orierr != -1 && orierr != oriin && orierr != oriout) + posix_spawn_file_actions_addclose(&process->spawn_action, orierr); + // change the current working directory for child process #ifdef TB_CONFIG_POSIX_HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP if (attr->curdir) @@ -475,6 +487,10 @@ static tb_process_ref_t tb_process_init_fork(tb_char_t const* pathname, tb_char_ // set attributes if (attr) { + tb_int_t oriin = -1; + tb_int_t oriout = -1; + tb_int_t orierr = -1; + // redirect the stdin if (attr->intype == TB_PROCESS_REDIRECT_TYPE_FILEPATH && attr->in.path) { @@ -491,8 +507,8 @@ static tb_process_ref_t tb_process_init_fork(tb_char_t const* pathname, tb_char_ { // duplicate inpipe fd to stdin in the child process tb_int_t infd = attr->intype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->in.pipe) : tb_file2fd(attr->in.file); + oriin = infd; dup2(infd, STDIN_FILENO); - close(infd); } // redirect the stdout @@ -511,8 +527,8 @@ static tb_process_ref_t tb_process_init_fork(tb_char_t const* pathname, tb_char_ { // duplicate outpipe fd to stdout in the child process tb_int_t outfd = attr->outtype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->out.pipe) : tb_file2fd(attr->out.file); + oriout = outfd; dup2(outfd, STDOUT_FILENO); - close(outfd); } // redirect the stderr @@ -531,10 +547,18 @@ static tb_process_ref_t tb_process_init_fork(tb_char_t const* pathname, tb_char_ { // duplicate errpipe fd to stderr in the child process tb_int_t errfd = attr->errtype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->err.pipe) : tb_file2fd(attr->err.file); + orierr = errfd; dup2(errfd, STDERR_FILENO); - close(errfd); } + // close fd + if (oriin != -1) + close(oriin); + if (oriout != -1 && oriout != oriin) + close(oriout); + if (orierr != -1 && orierr != oriin && orierr != oriout) + close(orierr); + // change the current working directory for child process if (attr->curdir && 0 != chdir(attr->curdir)) _exit(-1);