Skip to content

Commit

Permalink
posix: Add test for pipe fd leak if redirecting both stdout and stderr
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Klauer <[email protected]>
  • Loading branch information
dkl authored and klemens-morgenstern committed Jun 4, 2024
1 parent e8b5bf1 commit e455a12
Showing 1 changed file with 44 additions and 1 deletion.
45 changes: 44 additions & 1 deletion test/posix_specific.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,47 @@ BOOST_AUTO_TEST_CASE(leak_test, *boost::unit_test::timeout(5))

BOOST_CHECK_EQUAL(fd_list.size(), fd_list_new.size());

}
}

BOOST_AUTO_TEST_CASE(pipe_fd_is_not_leaked, *boost::unit_test::timeout(5))
{
const std::string partner = boost::unit_test::framework::master_test_suite().argv[1];

#define test(parent_closes_source, fd_to_check, expected_exitcode, call_args...) \
do { \
boost::asio::io_context ioctx; \
bp::async_pipe pipe(ioctx); \
BOOST_CHECK_NE(pipe.native_source(), -1); \
BOOST_CHECK_NE(pipe.native_sink(), -1); \
BOOST_CHECK_EQUAL(bp::system(partner, "--has-handle", std::to_string(fd_to_check), call_args), expected_exitcode); \
if (parent_closes_source) { \
BOOST_CHECK_EQUAL(pipe.native_source(), -1); \
BOOST_CHECK_NE(pipe.native_sink(), -1); \
} else { \
BOOST_CHECK_NE(pipe.native_source(), -1); \
BOOST_CHECK_EQUAL(pipe.native_sink(), -1); \
} \
} while (0)

// Both parent and child processes must close the end of the pipe which they don't use,
// and pipe_in/pipe_out must close the original source/sink fd after redirecting in the child process,
// so that they don't keep the pipe open unnecessarily.
test(true, STDIN_FILENO , EXIT_SUCCESS, bp::std_in < pipe);
test(true, pipe.native_source(), EXIT_FAILURE, bp::std_in < pipe);
test(true, pipe.native_sink() , EXIT_FAILURE, bp::std_in < pipe);

test(false, STDOUT_FILENO , EXIT_SUCCESS, bp::std_out > pipe);
test(false, pipe.native_source(), EXIT_FAILURE, bp::std_out > pipe);
test(false, pipe.native_sink() , EXIT_FAILURE, bp::std_out > pipe);

test(false, STDERR_FILENO , EXIT_SUCCESS, bp::std_err > pipe);
test(false, pipe.native_source(), EXIT_FAILURE, bp::std_err > pipe);
test(false, pipe.native_sink() , EXIT_FAILURE, bp::std_err > pipe);

test(false, STDOUT_FILENO , EXIT_SUCCESS, (bp::std_out & bp::std_err) > pipe);
test(false, STDERR_FILENO , EXIT_SUCCESS, (bp::std_out & bp::std_err) > pipe);
test(false, pipe.native_source(), EXIT_FAILURE, (bp::std_out & bp::std_err) > pipe);
test(false, pipe.native_sink() , EXIT_FAILURE, (bp::std_out & bp::std_err) > pipe);

#undef test
}

0 comments on commit e455a12

Please sign in to comment.