e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek/*
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek Authors:
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek Copyright (C) 2014 Red Hat
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek SSSD tests: Child handlers
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek This program is free software; you can redistribute it and/or modify
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek it under the terms of the GNU General Public License as published by
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek the Free Software Foundation; either version 3 of the License, or
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek (at your option) any later version.
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek This program is distributed in the hope that it will be useful,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek GNU General Public License for more details.
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek You should have received a copy of the GNU General Public License
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek*/
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include <talloc.h>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include <tevent.h>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include <errno.h>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include <popt.h>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include "util/child_common.h"
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include "tests/cmocka/common_mock.h"
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
fb3c5cdfcda069a5fbeb7b9d200c0881911364b8Jakub Hrozek#define TEST_BIN "dummy-child"
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#define ECHO_STR "Hello child"
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekstatic int destructor_called;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozekstruct child_test_ctx {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int pipefd_to_child[2];
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int pipefd_from_child[2];
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct sss_test_ctx *test_ctx;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek int save_debug_timestamps;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek};
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozekstatic int child_test_setup(void **state)
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek{
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx *child_tctx;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek errno_t ret;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
9c62d6619b87f1255ef6515280a20552fca9d925Lukas Slebodnik assert_true(leak_check_setup());
9c62d6619b87f1255ef6515280a20552fca9d925Lukas Slebodnik
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx = talloc(global_talloc_context, struct child_test_ctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_non_null(child_tctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->test_ctx = create_ev_test_ctx(child_tctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_non_null(child_tctx->test_ctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = pipe(child_tctx->pipefd_from_child);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_not_equal(ret, -1);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "from_child: %d:%d\n",
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_from_child[0],
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_from_child[1]);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = pipe(child_tctx->pipefd_to_child);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_not_equal(ret, -1);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "to_child: %d:%d\n",
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_to_child[0],
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_to_child[1]);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek *state = child_tctx;
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek return 0;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek}
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozekstatic int child_test_teardown(void **state)
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek{
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek talloc_free(child_tctx);
20a2be57d764f58c4a6532310331e26a3273ada8Lukas Slebodnik
9c62d6619b87f1255ef6515280a20552fca9d925Lukas Slebodnik assert_true(leak_check_teardown());
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek return 0;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek}
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek/* Just make sure the exec works. The child does nothing but exits */
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozekvoid test_exec_child(void **state)
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek{
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek errno_t ret;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek pid_t child_pid;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int status;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_pid = fork();
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_not_equal(child_pid, -1);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek if (child_pid == 0) {
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek exec_child(child_tctx,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_to_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_from_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2);
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek } else {
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek do {
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek errno = 0;
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek ret = waitpid(child_pid, &status, 0);
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek } while (ret == -1 && errno == EINTR);
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek if (ret > 0) {
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek ret = EIO;
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek if (WIFEXITED(status)) {
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek ret = WEXITSTATUS(status);
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek assert_int_equal(ret, 0);
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek }
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek } else {
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek DEBUG(SSSDBG_FUNC_DATA,
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek "Failed to wait for children %d\n", child_pid);
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek ret = EIO;
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek }
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek }
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek}
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozekstatic int only_extra_args_setup(void **state)
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek{
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek struct child_test_ctx *child_tctx;
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek errno_t ret;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek ret = child_test_setup((void **) &child_tctx);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek if (ret != 0) {
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek return ret;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek }
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek child_tctx->save_debug_timestamps = debug_timestamps;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek *state = child_tctx;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek return 0;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek}
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozekstatic int only_extra_args_teardown(void **state)
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek{
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek struct child_test_ctx);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek errno_t ret;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek debug_timestamps = child_tctx->save_debug_timestamps;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek ret = child_test_teardown((void **) &child_tctx);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek if (ret != 0) {
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek return ret;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek }
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek return 0;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek}
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozekstatic void extra_args_test(struct child_test_ctx *child_tctx,
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek bool extra_args_only)
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek{
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek pid_t child_pid;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek errno_t ret;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek int status;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek const char *extra_args[] = { "--guitar=george",
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek "--drums=ringo",
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek NULL };
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek child_pid = fork();
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek assert_int_not_equal(child_pid, -1);
b4f87b42b18888c396e44e7359f7aafb092221bfJakub Hrozek if (child_pid == 0) {
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek debug_timestamps = 1;
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek exec_child_ex(child_tctx,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_to_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_from_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2, extra_args,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek extra_args_only,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek STDIN_FILENO, STDOUT_FILENO);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek } else {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek do {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek errno = 0;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = waitpid(child_pid, &status, 0);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek } while (ret == -1 && errno == EINTR);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek if (ret > 0) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = EIO;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek if (WIFEXITED(status)) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = WEXITSTATUS(status);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_equal(ret, 0);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek } else {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek DEBUG(SSSDBG_FUNC_DATA,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek "Failed to wait for children %d\n", child_pid);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = EIO;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek}
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek/* Make sure extra arguments are passed correctly */
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozekvoid test_exec_child_extra_args(void **state)
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek{
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek struct child_test_ctx);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek setenv("TEST_CHILD_ACTION", "check_extra_args", 1);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek extra_args_test(child_tctx, false);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek}
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek/* Make sure extra arguments are passed correctly */
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozekvoid test_exec_child_only_extra_args(void **state)
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek{
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek struct child_test_ctx);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek setenv("TEST_CHILD_ACTION", "check_only_extra_args", 1);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek extra_args_test(child_tctx, true);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek}
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozekvoid test_exec_child_only_extra_args_neg(void **state)
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek{
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek struct child_test_ctx);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek setenv("TEST_CHILD_ACTION", "check_only_extra_args_neg", 1);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek extra_args_test(child_tctx, false);
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek}
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekstruct tevent_req *echo_child_write_send(TALLOC_CTX *mem_ctx,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_tctx,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_io_fds *io_fds,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek const char *input);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekstatic void echo_child_write_done(struct tevent_req *subreq);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekstatic void echo_child_read_done(struct tevent_req *subreq);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekint __real_child_io_destructor(void *ptr);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekint __wrap_child_io_destructor(void *ptr)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek destructor_called = 1;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek return __real_child_io_destructor(ptr);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek/* Test that writing to the pipes works as expected */
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekvoid test_exec_child_io_destruct(void **state)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_io_fds *io_fds;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds = talloc(child_tctx, struct child_io_fds);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds->read_from_child_fd = -1;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds->write_to_child_fd = -1;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_non_null(io_fds);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek talloc_set_destructor((void *) io_fds, child_io_destructor);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds->read_from_child_fd = child_tctx->pipefd_from_child[0];
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds->write_to_child_fd = child_tctx->pipefd_to_child[1];
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek destructor_called = 0;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek talloc_free(io_fds);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(destructor_called, 1);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno = 0;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek close(child_tctx->pipefd_from_child[0]);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(errno, EBADF);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno = 0;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek close(child_tctx->pipefd_from_child[1]);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(errno, 0);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno = 0;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek close(child_tctx->pipefd_to_child[0]);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(errno, 0);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno = 0;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek close(child_tctx->pipefd_to_child[1]);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(errno, EBADF);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekvoid test_child_cb(int child_status,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct tevent_signal *sige,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek void *pvt);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek/* Test that writing to the pipes works as expected */
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekvoid test_exec_child_handler(void **state)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno_t ret;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek pid_t child_pid;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct sss_child_ctx_old *child_old_ctx;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = unsetenv("TEST_CHILD_ACTION");
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, 0);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_pid = fork();
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_not_equal(child_pid, -1);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek if (child_pid == 0) {
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek exec_child(child_tctx,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_to_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_from_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek }
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek test_child_cb, child_tctx, &child_old_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = test_ev_loop(child_tctx->test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(child_tctx->test_ctx->error, 0);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekvoid test_child_cb(int child_status,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct tevent_signal *sige,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek void *pvt)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_ctx = talloc_get_type(pvt, struct child_test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_ctx->test_ctx->error = EIO;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek if (WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0) {
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_ctx->test_ctx->error = 0;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek }
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_ctx->test_ctx->done = true;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek/* Test that writing to the pipes works as expected */
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekvoid test_exec_child_echo(void **state)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno_t ret;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek pid_t child_pid;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct tevent_req *req;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_io_fds *io_fds;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek setenv("TEST_CHILD_ACTION", "echo", 1);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds = talloc(child_tctx, struct child_io_fds);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_non_null(io_fds);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds->read_from_child_fd = -1;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds->write_to_child_fd = -1;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek talloc_set_destructor((void *) io_fds, child_io_destructor);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_pid = fork();
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_not_equal(child_pid, -1);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek if (child_pid == 0) {
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek exec_child_ex(child_tctx,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_to_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_from_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2, NULL, false,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek STDIN_FILENO, 3);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek }
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek DEBUG(SSSDBG_FUNC_DATA, "Forked into %d\n", child_pid);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds->read_from_child_fd = child_tctx->pipefd_from_child[0];
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek close(child_tctx->pipefd_from_child[1]);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek io_fds->write_to_child_fd = child_tctx->pipefd_to_child[1];
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek close(child_tctx->pipefd_to_child[0]);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
f3d91181d4ee9da3f8bbf4ddf8782951c0ae46c1Jakub Hrozek sss_fd_nonblocking(io_fds->write_to_child_fd);
f3d91181d4ee9da3f8bbf4ddf8782951c0ae46c1Jakub Hrozek sss_fd_nonblocking(io_fds->read_from_child_fd);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek NULL, NULL, NULL);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek req = echo_child_write_send(child_tctx, child_tctx, io_fds, ECHO_STR);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_non_null(req);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = test_ev_loop(child_tctx->test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek talloc_free(io_fds);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekstruct test_exec_echo_state {
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_io_fds *io_fds;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct io_buffer buf;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_test_ctx;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek};
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekstruct tevent_req *echo_child_write_send(TALLOC_CTX *mem_ctx,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_tctx,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_io_fds *io_fds,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek const char *input)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct tevent_req *req;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct tevent_req *subreq;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct test_exec_echo_state *echo_state;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek req = tevent_req_create(mem_ctx, &echo_state, struct test_exec_echo_state);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_non_null(req);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->child_test_ctx = child_tctx;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->buf.data = (unsigned char *) talloc_strdup(echo_state, input);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_non_null(echo_state->buf.data);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->buf.size = strlen(input) + 1;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->io_fds = io_fds;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Writing..\n");
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek subreq = write_pipe_send(child_tctx, child_tctx->test_ctx->ev,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->buf.data, echo_state->buf.size,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->io_fds->write_to_child_fd);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_non_null(subreq);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek tevent_req_set_callback(subreq, echo_child_write_done, req);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek return req;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekstatic void echo_child_write_done(struct tevent_req *subreq)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct tevent_req *req;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct test_exec_echo_state *echo_state;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno_t ret;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state = tevent_req_data(req, struct test_exec_echo_state);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = write_pipe_recv(subreq);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Writing OK\n");
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek talloc_zfree(subreq);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek close(echo_state->io_fds->write_to_child_fd);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->io_fds->write_to_child_fd = -1;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Reading..\n");
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek subreq = read_pipe_send(echo_state,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->child_test_ctx->test_ctx->ev,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->io_fds->read_from_child_fd);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_non_null(subreq);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek tevent_req_set_callback(subreq, echo_child_read_done, req);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekstatic void echo_child_read_done(struct tevent_req *subreq)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct tevent_req *req;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct test_exec_echo_state *echo_state;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno_t ret;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ssize_t len;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek uint8_t *buf;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state = tevent_req_data(req, struct test_exec_echo_state);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = read_pipe_recv(subreq, echo_state, &buf, &len);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek talloc_zfree(subreq);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Reading OK\n");
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek close(echo_state->io_fds->read_from_child_fd);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->io_fds->read_from_child_fd = -1;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_string_equal(buf, echo_state->buf.data);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek echo_state->child_test_ctx->test_ctx->done = true;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekvoid sss_child_cb(int pid, int wait_status, void *pvt);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek/* Just make sure the exec works. The child does nothing but exits */
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekvoid test_sss_child(void **state)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek errno_t ret;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek pid_t child_pid;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct sss_sigchild_ctx *sc_ctx;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct sss_child_ctx *sss_child;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = unsetenv("TEST_CHILD_ACTION");
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, 0);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = sss_sigchld_init(child_tctx, child_tctx->test_ctx->ev, &sc_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_pid = fork();
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_not_equal(child_pid, -1);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek if (child_pid == 0) {
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek exec_child(child_tctx,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_to_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek child_tctx->pipefd_from_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek }
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = sss_child_register(child_tctx, sc_ctx,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_pid,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek sss_child_cb,
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_tctx, &sss_child);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek ret = test_ev_loop(child_tctx->test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(ret, EOK);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek assert_int_equal(child_tctx->test_ctx->error, 0);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozekvoid sss_child_cb(int pid, int wait_status, void *pvt)
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek{
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek struct child_test_ctx *child_ctx = talloc_get_type(pvt, struct child_test_ctx);
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_ctx->test_ctx->error = EIO;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek if (WIFEXITED(wait_status) && WEXITSTATUS(wait_status) == 0) {
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_ctx->test_ctx->error = 0;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek }
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek child_ctx->test_ctx->done = true;
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek}
44703b84feaafa4f0a4f8df11c5a503dcf48616eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozekint main(int argc, const char *argv[])
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek{
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int rv;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek poptContext pc;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int opt;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct poptOption long_options[] = {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek POPT_AUTOHELP
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek SSSD_DEBUG_OPTS
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek POPT_TABLEEND
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek };
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek const struct CMUnitTest tests[] = {
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_setup,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_teardown),
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_extra_args,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_setup,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_teardown),
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_io_destruct,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_setup,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_teardown),
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_handler,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_setup,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_teardown),
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_echo,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_setup,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_teardown),
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek cmocka_unit_test_setup_teardown(test_sss_child,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_setup,
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek child_test_teardown),
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_only_extra_args,
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek only_extra_args_setup,
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek only_extra_args_teardown),
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_only_extra_args_neg,
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek only_extra_args_setup,
b5797517abb117cff7330acc894b71deda74be3dJakub Hrozek only_extra_args_teardown),
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek };
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek /* Set debug level to invalid value so we can deside if -d 0 was used. */
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek debug_level = SSSDBG_INVALID;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek pc = poptGetContext(argv[0], argc, argv, long_options, 0);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek while((opt = poptGetNextOpt(pc)) != -1) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek switch(opt) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek default:
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek fprintf(stderr, "\nInvalid option %s: %s\n\n",
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek poptBadOption(pc, 0), poptStrerror(opt));
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek poptPrintUsage(pc, stderr, 0);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek return 1;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek poptFreeContext(pc);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek DEBUG_CLI_INIT(debug_level);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek rv = cmocka_run_group_tests(tests, NULL, NULL);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek return rv;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek}