Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix redirect when reuse fd #261

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 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
51 changes: 33 additions & 18 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 infd = -1;
tb_int_t outfd = -1;
tb_int_t errfd = -1;

// redirect the stdin
if (attr->intype == TB_PROCESS_REDIRECT_TYPE_FILEPATH && attr->in.path)
{
Expand All @@ -311,9 +315,8 @@ static tb_process_ref_t tb_process_init_spawn(tb_char_t const* pathname, tb_char
(attr->intype == TB_PROCESS_REDIRECT_TYPE_FILE && attr->in.file))
{
// 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);
infd = attr->intype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->in.pipe) : tb_file2fd(attr->in.file);
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 @@ -327,9 +330,8 @@ static tb_process_ref_t tb_process_init_spawn(tb_char_t const* pathname, tb_char
(attr->outtype == TB_PROCESS_REDIRECT_TYPE_FILE && attr->out.file))
{
// 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);
outfd = attr->outtype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->out.pipe) : tb_file2fd(attr->out.file);
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 @@ -343,11 +345,18 @@ static tb_process_ref_t tb_process_init_spawn(tb_char_t const* pathname, tb_char
(attr->errtype == TB_PROCESS_REDIRECT_TYPE_FILE && attr->err.file))
{
// 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);
errfd = attr->errtype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->err.pipe) : tb_file2fd(attr->err.file);
posix_spawn_file_actions_adddup2(&process->spawn_action, errfd, STDERR_FILENO);
posix_spawn_file_actions_addclose(&process->spawn_action, errfd);
}

// close fd
if (infd != -1)
posix_spawn_file_actions_addclose(&process->spawn_action, infd);
if (outfd != -1)
posix_spawn_file_actions_addclose(&process->spawn_action, outfd);
if (errfd != -1 && errfd != outfd)
posix_spawn_file_actions_addclose(&process->spawn_action, errfd);

ChrisCatCP marked this conversation as resolved.
Show resolved Hide resolved
// 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,66 +484,72 @@ static tb_process_ref_t tb_process_init_fork(tb_char_t const* pathname, tb_char_
// set attributes
if (attr)
{
tb_int_t infd = -1;
tb_int_t outfd = -1;
tb_int_t errfd = -1;

// redirect the stdin
if (attr->intype == TB_PROCESS_REDIRECT_TYPE_FILEPATH && attr->in.path)
{
// open file
tb_int_t infd = open(attr->in.path, tb_process_file_flags(attr->inmode), tb_process_file_modes(attr->inmode));
infd = open(attr->in.path, tb_process_file_flags(attr->inmode), tb_process_file_modes(attr->inmode));
tb_assertf_pass_and_check_break(infd, "cannot redirect stdin to file: %s, error: %d", attr->in.path, errno);

// redirect it
dup2(infd, STDIN_FILENO);
close(infd);
}
else if ((attr->intype == TB_PROCESS_REDIRECT_TYPE_PIPE && attr->in.pipe) ||
(attr->intype == TB_PROCESS_REDIRECT_TYPE_FILE && attr->in.file))
{
// 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);
infd = attr->intype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->in.pipe) : tb_file2fd(attr->in.file);
dup2(infd, STDIN_FILENO);
close(infd);
}

// redirect the stdout
if (attr->outtype == TB_PROCESS_REDIRECT_TYPE_FILEPATH && attr->out.path)
{
// open file
tb_int_t outfd = open(attr->out.path, tb_process_file_flags(attr->outmode), tb_process_file_modes(attr->outmode));
outfd = open(attr->out.path, tb_process_file_flags(attr->outmode), tb_process_file_modes(attr->outmode));
tb_assertf_pass_and_check_break(outfd, "cannot redirect stdout to file: %s, error: %d", attr->out.path, errno);

// redirect it
dup2(outfd, STDOUT_FILENO);
close(outfd);
}
else if ((attr->outtype == TB_PROCESS_REDIRECT_TYPE_PIPE && attr->out.pipe) ||
(attr->outtype == TB_PROCESS_REDIRECT_TYPE_FILE && attr->out.file))
{
// 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);
outfd = attr->outtype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->out.pipe) : tb_file2fd(attr->out.file);
dup2(outfd, STDOUT_FILENO);
close(outfd);
}

// redirect the stderr
if (attr->errtype == TB_PROCESS_REDIRECT_TYPE_FILEPATH && attr->err.path)
{
// open file
tb_int_t errfd = open(attr->err.path, tb_process_file_flags(attr->errmode), tb_process_file_modes(attr->errmode));
errfd = open(attr->err.path, tb_process_file_flags(attr->errmode), tb_process_file_modes(attr->errmode));
tb_assertf_pass_and_check_break(errfd, "cannot redirect stderr to file: %s, error: %d", attr->err.path, errno);

// redirect it
dup2(errfd, STDERR_FILENO);
close(errfd);
}
else if ((attr->errtype == TB_PROCESS_REDIRECT_TYPE_PIPE && attr->err.pipe) ||
(attr->errtype == TB_PROCESS_REDIRECT_TYPE_FILE && attr->err.file))
{
// 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);
errfd = attr->errtype == TB_PROCESS_REDIRECT_TYPE_PIPE? tb_pipefile2fd(attr->err.pipe) : tb_file2fd(attr->err.file);
dup2(errfd, STDERR_FILENO);
close(errfd);
}

// close fd
if (infd != -1)
close(infd);
if (outfd != -1)
close(outfd);
if (errfd != -1 && errfd != outfd)
close(errfd);

// change the current working directory for child process
if (attr->curdir && 0 != chdir(attr->curdir))
_exit(-1);
Expand Down