You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
1.7 KiB
96 lines
1.7 KiB
7 months ago
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||
|
/*
|
||
|
* Copyright (c) International Business Machines Corp., 2002
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Check that if a child has a "broken pipe", this information
|
||
|
* is transmitted to the waiting parent.
|
||
|
*/
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <sys/wait.h>
|
||
|
#include "tst_test.h"
|
||
|
|
||
|
#define SIZE 5
|
||
|
|
||
|
static int fd[2];
|
||
|
static char rdbuf[SIZE];
|
||
|
static char wrbuf[SIZE];
|
||
|
|
||
|
static void do_child(void)
|
||
|
{
|
||
|
SAFE_SIGNAL(SIGPIPE, SIG_DFL);
|
||
|
SAFE_CLOSE(fd[0]);
|
||
|
SAFE_WRITE(1, fd[1], wrbuf, SIZE);
|
||
|
|
||
|
TST_CHECKPOINT_WAIT(0);
|
||
|
|
||
|
SAFE_WRITE(1, fd[1], wrbuf, SIZE);
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
static void verify_pipe(void)
|
||
|
{
|
||
|
int status;
|
||
|
int sig = 0;
|
||
|
pid_t pid;
|
||
|
|
||
|
memset(wrbuf, 'a', SIZE);
|
||
|
|
||
|
#ifdef UCLINUX
|
||
|
maybe_run_child(&do_child, "dd", &fd[0], &fd[1]);
|
||
|
#endif
|
||
|
|
||
|
TEST(pipe(fd));
|
||
|
if (TST_RET == -1) {
|
||
|
tst_res(TFAIL|TERRNO, "pipe() failed");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
pid = SAFE_FORK();
|
||
|
if (pid == 0) {
|
||
|
#ifdef UCLINUX
|
||
|
if (self_exec(av[0], "dd", fd[0], fd[1]) < 0)
|
||
|
tst_brk(TBROK, "self_exec failed");
|
||
|
#else
|
||
|
do_child();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
memset(rdbuf, 0, SIZE);
|
||
|
SAFE_CLOSE(fd[1]);
|
||
|
SAFE_READ(1, fd[0], rdbuf, SIZE);
|
||
|
|
||
|
if (memcmp(wrbuf, rdbuf, SIZE) != 0) {
|
||
|
tst_res(TFAIL, "pipe read data and pipe "
|
||
|
"write data didn't match");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SAFE_CLOSE(fd[0]);
|
||
|
TST_CHECKPOINT_WAKE(0);
|
||
|
SAFE_WAIT(&status);
|
||
|
|
||
|
if (!WIFSIGNALED(status)) {
|
||
|
tst_res(TFAIL, "Child wasn't killed by signal");
|
||
|
} else {
|
||
|
sig = WTERMSIG(status);
|
||
|
if (sig != SIGPIPE) {
|
||
|
tst_res(TFAIL, "Child killed by %s expected SIGPIPE",
|
||
|
tst_strsig(sig));
|
||
|
} else {
|
||
|
tst_res(TPASS, "Child killed by SIGPIPE");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static struct tst_test test = {
|
||
|
.forks_child = 1,
|
||
|
.needs_checkpoints = 1,
|
||
|
.test_all = verify_pipe,
|
||
|
};
|