mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-23 18:19:39 +00:00
The TEST_STRING "Hello World!" has 13 bytes size. Therefore the 10 bytes used for the buffer size are not sufficient. Fix this and use sizeof() to be on the safe side. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
206 lines
3.3 KiB
C
206 lines
3.3 KiB
C
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sched.h>
|
|
#include <signal.h>
|
|
#include <sys/wait.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "zdtmtst.h"
|
|
|
|
const char *test_doc = "Check a shared file descriptor table.";
|
|
const char *test_author = "Andrew Vagin <avagin@openvz.org>";
|
|
|
|
char *filename;
|
|
TEST_OPTION(filename, string, "file name", 1);
|
|
|
|
#define STACK_SIZE 4096
|
|
#define TEST_FD 128
|
|
#define TEST_STRING "Hello World!"
|
|
|
|
#define CHILDREN 4
|
|
static int fork_pfd[2];
|
|
|
|
static void forked()
|
|
{
|
|
char c = 0;
|
|
|
|
if (write(fork_pfd[1], &c, 1) != 1) {
|
|
pr_perror("Unable to send a signal to the parent");
|
|
exit(5);
|
|
}
|
|
}
|
|
|
|
static void wait_children()
|
|
{
|
|
int i;
|
|
char c;
|
|
|
|
for (i = 0; i < CHILDREN; i++) {
|
|
if (read(fork_pfd[0], &c, 1) != 1) {
|
|
pr_perror("Unable to read a signal from a child");
|
|
exit(5);
|
|
}
|
|
}
|
|
}
|
|
|
|
static pid_t clone_child(int (*fn)(void *), int flags)
|
|
{
|
|
char stack[STACK_SIZE] __stack_aligned__;
|
|
pid_t pid;
|
|
|
|
pid = clone(fn, stack + STACK_SIZE,
|
|
flags | SIGCHLD, NULL);
|
|
if (pid == -1) {
|
|
pr_perror("Unable to clone a new process");
|
|
return -1;
|
|
}
|
|
|
|
return pid;
|
|
}
|
|
|
|
static int child2(void *_arg)
|
|
{
|
|
char buf[sizeof(TEST_STRING)];
|
|
|
|
forked();
|
|
test_waitsig();
|
|
|
|
if (read(TEST_FD, buf, sizeof(TEST_STRING)) != sizeof(TEST_STRING)) {
|
|
pr_perror("Unable to read from %d", TEST_FD);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int child3(void *_arg)
|
|
{
|
|
forked();
|
|
test_waitsig();
|
|
|
|
if (close(TEST_FD) != -1) {
|
|
fail("%d is exist\n", TEST_FD);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int child(void *_arg)
|
|
{
|
|
char buf[sizeof(TEST_STRING)];
|
|
pid_t pid, pid2;
|
|
int status;
|
|
|
|
pid = clone_child(child2, CLONE_FILES);
|
|
if (pid < 0)
|
|
return 1;
|
|
|
|
pid2 = clone_child(child3, 0);
|
|
if (pid < 0)
|
|
return 1;
|
|
|
|
forked();
|
|
test_waitsig();
|
|
|
|
kill(pid2, SIGTERM);
|
|
kill(pid, SIGTERM);
|
|
waitpid(pid2, &status, 0);
|
|
|
|
if (status) {
|
|
fail("The child3 returned %d\n", status);
|
|
return 1;
|
|
}
|
|
|
|
waitpid(pid, &status, 0);
|
|
|
|
if (status) {
|
|
fail("The child2 returned %d\n", status);
|
|
return 1;
|
|
}
|
|
|
|
if (read(TEST_FD, buf, sizeof(TEST_STRING)) != sizeof(TEST_STRING)) {
|
|
pr_perror("Unable to read from %d", TEST_FD);
|
|
return 1;
|
|
}
|
|
|
|
if (close(TEST_FD) == -1) {
|
|
pr_perror("Unable to close(%d)", TEST_FD);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char ** argv)
|
|
{
|
|
int status;
|
|
pid_t pid, pid2;
|
|
int fd, i;
|
|
|
|
test_init(argc, argv);
|
|
|
|
if (pipe(fork_pfd)) {
|
|
pr_perror("pipe");
|
|
return 1;
|
|
}
|
|
|
|
pid = clone_child(child, CLONE_FILES);
|
|
if (pid < 0)
|
|
return 1;
|
|
|
|
pid2 = clone_child(child2, CLONE_FILES);
|
|
if (pid2 < 0)
|
|
return 1;
|
|
|
|
wait_children();
|
|
|
|
test_daemon();
|
|
test_waitsig();
|
|
|
|
fd = open(filename, O_RDWR | O_CREAT, 0666);
|
|
if (fd == -1) {
|
|
pr_perror("Can't open /dev/zero");
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < 3; i++)
|
|
if (write(fd, TEST_STRING, sizeof(TEST_STRING)) != sizeof(TEST_STRING)) {
|
|
pr_perror("Unable to write a test string");
|
|
return -1;
|
|
}
|
|
|
|
fd = dup2(fd, TEST_FD);
|
|
if (fd == -1) {
|
|
pr_perror("Can't dup fd %d to %d", fd, TEST_FD);
|
|
return -1;
|
|
}
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
|
|
|
kill(pid2, SIGTERM);
|
|
waitpid(pid2, &status, 0);
|
|
kill(pid, SIGTERM);
|
|
|
|
if (status) {
|
|
fail("The child returned %d\n", status);
|
|
return 1;
|
|
}
|
|
|
|
waitpid(pid, &status, 0);
|
|
if (status) {
|
|
fail("The child returned %d\n", status);
|
|
return 1;
|
|
}
|
|
|
|
if (close(TEST_FD) == 0) {
|
|
fail("%d was not closed\n", TEST_FD);
|
|
return 1;
|
|
}
|
|
|
|
pass();
|
|
|
|
return 0;
|
|
}
|