1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <CUnit/CUnit.h>
#include "process.h"
#include "test_process.h"
void test_wait_for_death(void)
{
pid_t pid = fork();
if (pid == 0) {
usleep(20000);
execl("/bin/true", "/bin/true", NULL);
_exit(1);
}
CU_ASSERT(!wait_for_death(pid, 0, 2000));
CU_ASSERT(wait_for_death(pid, 0, 20000));
}
void test_ensure_death(void)
{
pid_t pid = fork();
if (pid == 0) {
signal(SIGTERM, SIG_IGN);
signal(SIGHUP, SIG_IGN);
execl("/bin/true", "/bin/true", NULL);
_exit(0);
}
ensure_death(pid);
CU_ASSERT(waitpid(pid, NULL, WNOHANG) < 0);
CU_ASSERT(errno == ECHILD);
}
int child_function(void *a)
{
char *s = a;
ssize_t l = strlen(s);
char buffer[LINE_MAX];
ssize_t l_in;
ssize_t l_out;
if (write(STDOUT_FILENO, s, l) < l)
return 1;
l_in = read(STDIN_FILENO, buffer, sizeof buffer);
if (l_in <= 0)
return 1;
l_out = write(STDOUT_FILENO, buffer, l_in);
if (l_out != l_in)
return 1;
return 0;
}
void test_create_child_function(void)
{
char *s1 = "hello";
char *s2 = "world";
ssize_t l1 = strlen(s1);
ssize_t l2 = strlen(s2);
struct child_process child = {
.function = child_function,
.argument = s1,
.stdin_fd = REDIRECT_PIPE,
.stdout_fd = REDIRECT_PIPE,
.stderr_fd = REDIRECT_DEV_NULL,
};
int status;
char buffer[LINE_MAX];
CU_ASSERT(create_child(&child));
CU_ASSERT(child.pid > 0);
CU_ASSERT(read(child.stdout_fd, buffer, sizeof buffer) == l1);
CU_ASSERT(strncmp(buffer, s1, l1) == 0);
CU_ASSERT(waitpid(child.pid, NULL, WNOHANG) == 0);
CU_ASSERT(write(child.stdin_fd, s2, l2) == l2);
CU_ASSERT(read(child.stdout_fd, buffer, sizeof buffer) == l2);
CU_ASSERT(strncmp(buffer, s2, l2) == 0);
CU_ASSERT(waitpid(child.pid, &status, 0) == child.pid);
CU_ASSERT(WIFEXITED(status));
CU_ASSERT(WEXITSTATUS(status) == 0);
(void) close(child.stdin_fd);
(void) close(child.stdout_fd);
}
void test_create_child_process(void)
{
const char *s1 = "hello\n";
const char *s2 = "olleh\n";
ssize_t l1 = strlen(s1);
ssize_t l2 = strlen(s2);
const char *argv[] = { "sh", "-c", "rev", NULL };
struct child_process child = {
.path = "/bin/sh",
.argv = argv,
.stdin_fd = REDIRECT_PIPE,
.stdout_fd = REDIRECT_PIPE,
.stderr_fd = REDIRECT_DEV_NULL,
.function = NULL,
};
char buffer[LINE_MAX];
CU_ASSERT(create_child(&child));
CU_ASSERT(write(child.stdin_fd, s1, l1) == l1);
(void) close(child.stdin_fd);
CU_ASSERT(read(child.stdout_fd, buffer, sizeof buffer) == l2);
(void) close(child.stdout_fd);
CU_ASSERT(strncmp(buffer, s2, l2) == 0);
CU_ASSERT(wait_for_death(child.pid, 0, 0));
}
CU_TestInfo process_tests[] = {
{ "test_wait_for_death", test_wait_for_death },
{ "test_ensure_death", test_ensure_death },
{ "test_create_child_function", test_create_child_function },
{ "test_create_child_process", test_create_child_process },
CU_TEST_INFO_NULL,
};
|