Skip to content

Commit

Permalink
fix redirect when reuse fd
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisCatCP committed Jul 3, 2024
1 parent 36c7364 commit 668f3ff
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
6 changes: 4 additions & 2 deletions src/demo/platform/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -139,7 +141,7 @@ tb_int_t tb_demo_platform_process_main(tb_int_t argc, tb_char_t** argv)
tb_used(tb_demo_process_test_run);
#endif

#if 0
#if 1
tb_demo_process_test_pipe(argv);
#else
tb_used(tb_demo_process_test_pipe);
Expand All @@ -151,7 +153,7 @@ tb_int_t tb_demo_platform_process_main(tb_int_t argc, tb_char_t** argv)
tb_used(tb_demo_process_test_waitlist);
#endif

#if 1
#if 0
// we can run `xxx.bat` or `xxx.sh` shell command to test it
// @see https://github.com/xmake-io/xmake/issues/719
tb_demo_process_test_exit(argv, tb_false);
Expand Down
37 changes: 31 additions & 6 deletions src/tbox/platform/posix/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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
Expand All @@ -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
Expand All @@ -344,10 +348,19 @@ 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)
Expand Down Expand Up @@ -475,6 +488,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)
{
Expand All @@ -491,8 +508,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
Expand All @@ -511,8 +528,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
Expand All @@ -531,10 +548,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);
Expand Down

0 comments on commit 668f3ff

Please sign in to comment.