Changeset View
Changeset View
Standalone View
Standalone View
contrib/netbsd-tests/kernel/t_sysv.c
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
#include <sys/ipc.h> | #include <sys/ipc.h> | ||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <sys/msg.h> | #include <sys/msg.h> | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/sem.h> | #include <sys/sem.h> | ||||
#include <sys/shm.h> | #include <sys/shm.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
volatile int did_sigsys, did_sigchild; | volatile int did_sigsys; | ||||
volatile int child_status, child_count; | |||||
void sigsys_handler(int); | void sigsys_handler(int); | ||||
void sigchld_handler(int); | |||||
key_t get_ftok(int); | key_t get_ftok(int); | ||||
void print_msqid_ds(struct msqid_ds *, mode_t); | void print_msqid_ds(struct msqid_ds *, mode_t); | ||||
void receiver(void); | void receiver(void); | ||||
void print_semid_ds(struct semid_ds *, mode_t); | void print_semid_ds(struct semid_ds *, mode_t); | ||||
void waiter(void); | void waiter(void); | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
sigsys_handler(int signo) | sigsys_handler(int signo) | ||||
{ | { | ||||
did_sigsys = 1; | did_sigsys = 1; | ||||
} | } | ||||
void | |||||
sigchld_handler(int signo) | |||||
{ | |||||
int c_status; | |||||
did_sigchild = 1; | |||||
/* | |||||
* Reap the child and return its status | |||||
*/ | |||||
if (wait(&c_status) == -1) | |||||
child_status = -errno; | |||||
else | |||||
child_status = c_status; | |||||
child_count--; | |||||
} | |||||
key_t get_ftok(int id) | key_t get_ftok(int id) | ||||
{ | { | ||||
int fd; | int fd; | ||||
char token_key[64], token_dir[64]; | char token_key[64], token_dir[64]; | ||||
char *tmpdir; | char *tmpdir; | ||||
key_t key; | key_t key; | ||||
strlcpy(token_key, "/tmp/t_sysv.XXXXXX", sizeof(token_key)); | strlcpy(token_key, "/tmp/t_sysv.XXXXXX", sizeof(token_key)); | ||||
Show All 30 Lines | ATF_TC_HEAD(msg, tc) | ||||
atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing"); | atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing"); | ||||
} | } | ||||
ATF_TC_BODY(msg, tc) | ATF_TC_BODY(msg, tc) | ||||
{ | { | ||||
struct sigaction sa; | struct sigaction sa; | ||||
struct msqid_ds m_ds; | struct msqid_ds m_ds; | ||||
struct testmsg m; | struct testmsg m; | ||||
sigset_t sigmask; | |||||
int sender_msqid; | int sender_msqid; | ||||
int loop; | int loop; | ||||
int c_status; | int c_status; | ||||
pid_t wait_result; | |||||
if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) | |||||
atf_tc_skip("https://bugs.freebsd.org/233649"); | |||||
/* | /* | ||||
* Install a SIGSYS handler so that we can exit gracefully if | * Install a SIGSYS handler so that we can exit gracefully if | ||||
* System V Message Queue support isn't in the kernel. | * System V Message Queue support isn't in the kernel. | ||||
*/ | */ | ||||
did_sigsys = 0; | did_sigsys = 0; | ||||
sa.sa_handler = sigsys_handler; | sa.sa_handler = sigsys_handler; | ||||
sigemptyset(&sa.sa_mask); | sigemptyset(&sa.sa_mask); | ||||
sa.sa_flags = 0; | sa.sa_flags = 0; | ||||
ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, | ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, | ||||
"sigaction SIGSYS: %d", errno); | "sigaction SIGSYS: %d", errno); | ||||
/* | |||||
* Install a SIGCHLD handler to deal with all possible exit | |||||
* conditions of the receiver. | |||||
*/ | |||||
did_sigchild = 0; | |||||
child_count = 0; | |||||
sa.sa_handler = sigchld_handler; | |||||
sigemptyset(&sa.sa_mask); | |||||
sa.sa_flags = 0; | |||||
ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, | |||||
"sigaction SIGCHLD: %d", errno); | |||||
msgkey = get_ftok(4160); | msgkey = get_ftok(4160); | ||||
ATF_REQUIRE_MSG(msgkey != (key_t)-1, "get_ftok failed"); | ATF_REQUIRE_MSG(msgkey != (key_t)-1, "get_ftok failed"); | ||||
sender_msqid = msgget(msgkey, IPC_CREAT | 0640); | sender_msqid = msgget(msgkey, IPC_CREAT | 0640); | ||||
ATF_REQUIRE_MSG(sender_msqid != -1, "msgget: %d", errno); | ATF_REQUIRE_MSG(sender_msqid != -1, "msgget: %d", errno); | ||||
write_int("sender_msqid", sender_msqid); | write_int("sender_msqid", sender_msqid); | ||||
if (did_sigsys) { | if (did_sigsys) { | ||||
Show All 16 Lines | ATF_TC_BODY(msg, tc) | ||||
ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, | ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, | ||||
"msgctl IPC_STAT 2: %d", errno); | "msgctl IPC_STAT 2: %d", errno); | ||||
ATF_REQUIRE_MSG((m_ds.msg_perm.mode & 0777) == 0600, | ATF_REQUIRE_MSG((m_ds.msg_perm.mode & 0777) == 0600, | ||||
"IPC_SET of mode didn't hold"); | "IPC_SET of mode didn't hold"); | ||||
print_msqid_ds(&m_ds, 0600); | print_msqid_ds(&m_ds, 0600); | ||||
fflush(stdout); | |||||
switch ((child_pid = fork())) { | switch ((child_pid = fork())) { | ||||
case -1: | case -1: | ||||
atf_tc_fail("fork: %d", errno); | atf_tc_fail("fork: %d", errno); | ||||
return; | return; | ||||
case 0: | case 0: | ||||
child_count++; | |||||
receiver(); | receiver(); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
for (loop = 0; loop < maxloop; loop++) { | for (loop = 0; loop < maxloop; loop++) { | ||||
Show All 22 Lines | for (loop = 0; loop < maxloop; loop++) { | ||||
ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN, | ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN, | ||||
MTYPE_2_ACK, 0) == MESSAGE_TEXT_LEN, | MTYPE_2_ACK, 0) == MESSAGE_TEXT_LEN, | ||||
"sender: msgrcv 2 ack: %d", errno); | "sender: msgrcv 2 ack: %d", errno); | ||||
} | } | ||||
/* | /* | ||||
* Wait for child to finish | * Wait for child to finish | ||||
*/ | */ | ||||
sigemptyset(&sigmask); | wait_result = wait(&c_status); | ||||
(void) sigsuspend(&sigmask); | ATF_REQUIRE_EQ_MSG(wait_result, child_pid, "wait returned %d (%s)", | ||||
wait_result, wait_result == -1 ? strerror(errno) : ""); | |||||
ATF_REQUIRE_MSG(WIFEXITED(c_status), "child abnormal exit: %d (sig %d)", | |||||
c_status, WTERMSIG(c_status)); | |||||
ATF_REQUIRE_EQ_MSG(WEXITSTATUS(c_status), 0, "child status: %d", | |||||
WEXITSTATUS(c_status)); | |||||
/* | ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, | ||||
* ...and any other signal is an unexpected error. | "msgctl IPC_STAT: %d", errno); | ||||
*/ | |||||
if (did_sigchild) { | |||||
c_status = child_status; | |||||
if (c_status < 0) | |||||
atf_tc_fail("waitpid: %d", -c_status); | |||||
else if (WIFEXITED(c_status) == 0) | |||||
atf_tc_fail("child abnormal exit: %d", c_status); | |||||
else if (WEXITSTATUS(c_status) != 0) | |||||
atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); | |||||
else { | |||||
ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) | |||||
!= -1, "msgctl IPC_STAT: %d", errno); | |||||
print_msqid_ds(&m_ds, 0600); | print_msqid_ds(&m_ds, 0600); | ||||
atf_tc_pass(); | |||||
} | } | ||||
} else | |||||
atf_tc_fail("sender: received unexpected signal"); | |||||
} | |||||
ATF_TC_CLEANUP(msg, tc) | ATF_TC_CLEANUP(msg, tc) | ||||
{ | { | ||||
int sender_msqid; | int sender_msqid; | ||||
/* | /* | ||||
* Remove the message queue if it exists. | * Remove the message queue if it exists. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | for (loop = 0; loop < maxloop; loop++) { | ||||
/* | /* | ||||
* Receive the first message, print it, and send an ACK. | * Receive the first message, print it, and send an ACK. | ||||
*/ | */ | ||||
if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_1, 0) != MESSAGE_TEXT_LEN) | if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_1, 0) != MESSAGE_TEXT_LEN) | ||||
err(1, "receiver: msgrcv 1"); | err(1, "receiver: msgrcv 1"); | ||||
printf("%s\n", m.mtext); | printf("%s\n", m.mtext); | ||||
if (strcmp(m.mtext, m1_str) != 0) | if (strcmp(m.mtext, m1_str) != 0) | ||||
err(1, "receiver: message 1 data isn't correct"); | errx(1, "receiver: message 1 data isn't correct"); | ||||
m.mtype = MTYPE_1_ACK; | m.mtype = MTYPE_1_ACK; | ||||
if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1) | if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1) | ||||
err(1, "receiver: msgsnd ack 1"); | err(1, "receiver: msgsnd ack 1"); | ||||
/* | /* | ||||
* Receive the second message, print it, and send an ACK. | * Receive the second message, print it, and send an ACK. | ||||
*/ | */ | ||||
if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_2, 0) != MESSAGE_TEXT_LEN) | if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_2, 0) != MESSAGE_TEXT_LEN) | ||||
err(1, "receiver: msgrcv 2"); | err(1, "receiver: msgrcv 2"); | ||||
printf("%s\n", m.mtext); | printf("%s\n", m.mtext); | ||||
if (strcmp(m.mtext, m2_str) != 0) | if (strcmp(m.mtext, m2_str) != 0) | ||||
err(1, "receiver: message 2 data isn't correct"); | errx(1, "receiver: message 2 data isn't correct"); | ||||
m.mtype = MTYPE_2_ACK; | m.mtype = MTYPE_2_ACK; | ||||
if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1) | if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1) | ||||
err(1, "receiver: msgsnd ack 2"); | err(1, "receiver: msgsnd ack 2"); | ||||
} | } | ||||
exit(0); | exit(0); | ||||
Show All 11 Lines | ATF_TC_HEAD(sem, tc) | ||||
atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing"); | atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing"); | ||||
} | } | ||||
ATF_TC_BODY(sem, tc) | ATF_TC_BODY(sem, tc) | ||||
{ | { | ||||
struct sigaction sa; | struct sigaction sa; | ||||
union semun sun; | union semun sun; | ||||
struct semid_ds s_ds; | struct semid_ds s_ds; | ||||
sigset_t sigmask; | |||||
int sender_semid; | int sender_semid; | ||||
int i; | int i; | ||||
int c_status; | int c_status; | ||||
int child_count; | |||||
pid_t wait_result; | |||||
/* | /* | ||||
* Install a SIGSYS handler so that we can exit gracefully if | * Install a SIGSYS handler so that we can exit gracefully if | ||||
* System V Semaphore support isn't in the kernel. | * System V Semaphore support isn't in the kernel. | ||||
*/ | */ | ||||
did_sigsys = 0; | did_sigsys = 0; | ||||
sa.sa_handler = sigsys_handler; | sa.sa_handler = sigsys_handler; | ||||
sigemptyset(&sa.sa_mask); | sigemptyset(&sa.sa_mask); | ||||
sa.sa_flags = 0; | sa.sa_flags = 0; | ||||
ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, | ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, | ||||
"sigaction SIGSYS: %d", errno); | "sigaction SIGSYS: %d", errno); | ||||
/* | |||||
* Install a SIGCHLD handler to deal with all possible exit | |||||
* conditions of the receiver. | |||||
*/ | |||||
did_sigchild = 0; | |||||
child_count = 0; | |||||
sa.sa_handler = sigchld_handler; | |||||
sigemptyset(&sa.sa_mask); | |||||
sa.sa_flags = 0; | |||||
ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, | |||||
"sigaction SIGCHLD: %d", errno); | |||||
semkey = get_ftok(4160); | semkey = get_ftok(4160); | ||||
ATF_REQUIRE_MSG(semkey != (key_t)-1, "get_ftok failed"); | ATF_REQUIRE_MSG(semkey != (key_t)-1, "get_ftok failed"); | ||||
sender_semid = semget(semkey, 1, IPC_CREAT | 0640); | sender_semid = semget(semkey, 1, IPC_CREAT | 0640); | ||||
ATF_REQUIRE_MSG(sender_semid != -1, "semget: %d", errno); | ATF_REQUIRE_MSG(sender_semid != -1, "semget: %d", errno); | ||||
write_int("sender_semid", sender_semid); | write_int("sender_semid", sender_semid); | ||||
if (did_sigsys) { | if (did_sigsys) { | ||||
Show All 19 Lines | ATF_TC_BODY(sem, tc) | ||||
ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, | ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, | ||||
"semctl IPC_STAT: %d", errno); | "semctl IPC_STAT: %d", errno); | ||||
ATF_REQUIRE_MSG((s_ds.sem_perm.mode & 0777) == 0600, | ATF_REQUIRE_MSG((s_ds.sem_perm.mode & 0777) == 0600, | ||||
"IPC_SET of mode didn't hold"); | "IPC_SET of mode didn't hold"); | ||||
print_semid_ds(&s_ds, 0600); | print_semid_ds(&s_ds, 0600); | ||||
fflush(stdout); | |||||
for (child_count = 0; child_count < 5; child_count++) { | for (child_count = 0; child_count < 5; child_count++) { | ||||
switch ((child_pid = fork())) { | switch ((child_pid = fork())) { | ||||
case -1: | case -1: | ||||
atf_tc_fail("fork: %d", errno); | atf_tc_fail("fork: %d", errno); | ||||
return; | return; | ||||
case 0: | case 0: | ||||
waiter(); | waiter(); | ||||
Show All 22 Lines | ATF_TC_BODY(sem, tc) | ||||
*/ | */ | ||||
sun.val = 1; | sun.val = 1; | ||||
ATF_REQUIRE_MSG(semctl(sender_semid, 0, SETVAL, sun) != -1, | ATF_REQUIRE_MSG(semctl(sender_semid, 0, SETVAL, sun) != -1, | ||||
"sender: semctl SETVAL to 1: %d", errno); | "sender: semctl SETVAL to 1: %d", errno); | ||||
/* | /* | ||||
* Wait for all children to finish | * Wait for all children to finish | ||||
*/ | */ | ||||
sigemptyset(&sigmask); | while (child_count-- > 0) { | ||||
for (;;) { | wait_result = wait(&c_status); | ||||
(void) sigsuspend(&sigmask); | ATF_REQUIRE_MSG(wait_result != -1, "wait failed: %s", | ||||
if (did_sigchild) { | strerror(errno)); | ||||
c_status = child_status; | ATF_REQUIRE_MSG(WIFEXITED(c_status), | ||||
if (c_status < 0) | "child abnormal exit: %d (sig %d)", | ||||
atf_tc_fail("waitpid: %d", -c_status); | c_status, WTERMSIG(c_status)); | ||||
else if (WIFEXITED(c_status) == 0) | ATF_REQUIRE_EQ_MSG(WEXITSTATUS(c_status), 0, "child status: %d", | ||||
atf_tc_fail("c abnormal exit: %d", c_status); | |||||
else if (WEXITSTATUS(c_status) != 0) | |||||
atf_tc_fail("c status: %d", | |||||
WEXITSTATUS(c_status)); | WEXITSTATUS(c_status)); | ||||
else { | |||||
sun.buf = &s_ds; | sun.buf = &s_ds; | ||||
ATF_REQUIRE_MSG(semctl(sender_semid, 0, | ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, | ||||
IPC_STAT, sun) != -1, | |||||
"semctl IPC_STAT: %d", errno); | "semctl IPC_STAT: %d", errno); | ||||
print_semid_ds(&s_ds, 0600); | print_semid_ds(&s_ds, 0600); | ||||
atf_tc_pass(); | |||||
} | } | ||||
if (child_count <= 0) | |||||
break; | |||||
did_sigchild = 0; | |||||
} else { | |||||
atf_tc_fail("sender: received unexpected signal"); | |||||
break; | |||||
} | } | ||||
} | |||||
} | |||||
ATF_TC_CLEANUP(sem, tc) | ATF_TC_CLEANUP(sem, tc) | ||||
{ | { | ||||
int sender_semid; | int sender_semid; | ||||
/* | /* | ||||
* Remove the semaphore if it exists | * Remove the semaphore if it exists | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | waiter(void) | ||||
s.sem_num = 0; | s.sem_num = 0; | ||||
s.sem_op = -1; | s.sem_op = -1; | ||||
s.sem_flg = SEM_UNDO; | s.sem_flg = SEM_UNDO; | ||||
if (semop(semid, &s, 1) == -1) | if (semop(semid, &s, 1) == -1) | ||||
err(1, "waiter: semop -1"); | err(1, "waiter: semop -1"); | ||||
printf("WOO! GOT THE SEMAPHORE!\n"); | printf("WOO! GOT THE SEMAPHORE!\n"); | ||||
sleep(1); | usleep(10000); | ||||
/* | /* | ||||
* Release the semaphore and exit. | * Release the semaphore and exit. | ||||
*/ | */ | ||||
s.sem_num = 0; | s.sem_num = 0; | ||||
s.sem_op = 1; | s.sem_op = 1; | ||||
s.sem_flg = SEM_UNDO; | s.sem_flg = SEM_UNDO; | ||||
Show All 14 Lines | ATF_TC_HEAD(shm, tc) | ||||
atf_tc_set_md_var(tc, "timeout", "3"); | atf_tc_set_md_var(tc, "timeout", "3"); | ||||
atf_tc_set_md_var(tc, "descr", "Checks sysv shared memory"); | atf_tc_set_md_var(tc, "descr", "Checks sysv shared memory"); | ||||
} | } | ||||
ATF_TC_BODY(shm, tc) | ATF_TC_BODY(shm, tc) | ||||
{ | { | ||||
struct sigaction sa; | struct sigaction sa; | ||||
struct shmid_ds s_ds; | struct shmid_ds s_ds; | ||||
sigset_t sigmask; | |||||
char *shm_buf; | char *shm_buf; | ||||
int sender_shmid; | int sender_shmid; | ||||
int c_status; | int c_status; | ||||
pid_t wait_result; | |||||
/* | /* | ||||
* Install a SIGSYS handler so that we can exit gracefully if | * Install a SIGSYS handler so that we can exit gracefully if | ||||
* System V Shared Memory support isn't in the kernel. | * System V Shared Memory support isn't in the kernel. | ||||
*/ | */ | ||||
did_sigsys = 0; | did_sigsys = 0; | ||||
sa.sa_handler = sigsys_handler; | sa.sa_handler = sigsys_handler; | ||||
sigemptyset(&sa.sa_mask); | sigemptyset(&sa.sa_mask); | ||||
sa.sa_flags = 0; | sa.sa_flags = 0; | ||||
ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, | ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, | ||||
"sigaction SIGSYS: %d", errno); | "sigaction SIGSYS: %d", errno); | ||||
/* | |||||
* Install a SIGCHLD handler to deal with all possible exit | |||||
* conditions of the sharer. | |||||
*/ | |||||
did_sigchild = 0; | |||||
child_count = 0; | |||||
sa.sa_handler = sigchld_handler; | |||||
sigemptyset(&sa.sa_mask); | |||||
sa.sa_flags = 0; | |||||
ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, | |||||
"sigaction SIGCHLD: %d", errno); | |||||
pgsize = sysconf(_SC_PAGESIZE); | pgsize = sysconf(_SC_PAGESIZE); | ||||
shmkey = get_ftok(4160); | shmkey = get_ftok(4160); | ||||
ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed"); | ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed"); | ||||
ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize, | ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize, | ||||
IPC_CREAT | 0640)) != -1, | IPC_CREAT | 0640)) != -1, | ||||
"shmget: %d", errno); | "shmget: %d", errno); | ||||
Show All 22 Lines | ATF_TC_BODY(shm, tc) | ||||
shm_buf = shmat(sender_shmid, NULL, 0); | shm_buf = shmat(sender_shmid, NULL, 0); | ||||
ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno); | ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno); | ||||
/* | /* | ||||
* Write the test pattern into the shared memory buffer. | * Write the test pattern into the shared memory buffer. | ||||
*/ | */ | ||||
strcpy(shm_buf, m2_str); | strcpy(shm_buf, m2_str); | ||||
fflush(stdout); | |||||
switch ((child_pid = fork())) { | switch ((child_pid = fork())) { | ||||
case -1: | case -1: | ||||
atf_tc_fail("fork: %d", errno); | atf_tc_fail("fork: %d", errno); | ||||
return; | return; | ||||
case 0: | case 0: | ||||
sharer(); | sharer(); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
/* | /* | ||||
* Wait for child to finish | * Wait for child to finish | ||||
*/ | */ | ||||
sigemptyset(&sigmask); | wait_result = wait(&c_status); | ||||
(void) sigsuspend(&sigmask); | ATF_REQUIRE_EQ_MSG(wait_result, child_pid, "wait returned %d (%s)", | ||||
markj: Maybe assert that `wait_result == child_pid` just for good measure? | |||||
wait_result, wait_result == -1 ? strerror(errno) : ""); | |||||
ATF_REQUIRE_MSG(WIFEXITED(c_status), "child abnormal exit: %d (sig %d)", | |||||
c_status, WTERMSIG(c_status)); | |||||
ATF_REQUIRE_EQ_MSG(WEXITSTATUS(c_status), 0, "child status: %d", | |||||
WEXITSTATUS(c_status)); | |||||
if (did_sigchild) { | ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1, | ||||
c_status = child_status; | |||||
if (c_status < 0) | |||||
atf_tc_fail("waitpid: %d", -c_status); | |||||
else if (WIFEXITED(c_status) == 0) | |||||
atf_tc_fail("c abnormal exit: %d", c_status); | |||||
else if (WEXITSTATUS(c_status) != 0) | |||||
atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); | |||||
else { | |||||
ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, | |||||
&s_ds) != -1, | |||||
"shmctl IPC_STAT: %d", errno); | "shmctl IPC_STAT: %d", errno); | ||||
print_shmid_ds(&s_ds, 0600); | print_shmid_ds(&s_ds, 0600); | ||||
atf_tc_pass(); | |||||
} | } | ||||
} else | |||||
atf_tc_fail("sender: received unexpected signal"); | |||||
} | |||||
static void | static void | ||||
shmid_cleanup(const char *name) | shmid_cleanup(const char *name) | ||||
{ | { | ||||
int shmid; | int shmid; | ||||
/* | /* | ||||
* Remove the shared memory area if it exists. | * Remove the shared memory area if it exists. | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
sharer(void) | sharer(void) | ||||
{ | { | ||||
int shmid; | int shmid; | ||||
void *shm_buf; | void *shm_buf; | ||||
shmid = shmget(shmkey, pgsize, 0); | shmid = shmget(shmkey, pgsize, 0); | ||||
ATF_REQUIRE_MSG(shmid != -1, "receiver: shmget:%d", errno); | if (shmid == -1) | ||||
err(1, "receiver: shmget"); | |||||
shm_buf = shmat(shmid, NULL, 0); | shm_buf = shmat(shmid, NULL, 0); | ||||
ATF_REQUIRE_MSG(shm_buf != (void *) -1, "receiver: shmat: %d", errno); | if (shm_buf == (void *) -1) | ||||
err(1, "receiver: shmat"); | |||||
printf("%s\n", (const char *)shm_buf); | printf("%s\n", (const char *)shm_buf); | ||||
ATF_REQUIRE_MSG(strcmp((const char *)shm_buf, m2_str) == 0, | if (strcmp((const char *)shm_buf, m2_str) != 0) | ||||
"receiver: data isn't correct"); | errx(1, "receiver: data isn't correct"); | ||||
exit(0); | exit(0); | ||||
} | } | ||||
#ifdef SHM_REMAP | #ifdef SHM_REMAP | ||||
ATF_TC_WITH_CLEANUP(shm_remap); | ATF_TC_WITH_CLEANUP(shm_remap); | ||||
ATF_TC_HEAD(shm_remap, tc) | ATF_TC_HEAD(shm_remap, tc) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |
Maybe assert that wait_result == child_pid just for good measure?