criu/test/zdtm/static/fdt_shared.c
Dmitry Safonov df81b884d4 test: add printf-attribute to test_msg
...and fix misprints that weren't caught before.

I guess, I never fixed that much (possible) bugs by one commit, heh.

Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-09-06 18:58:12 +03:00

207 lines
3.3 KiB
C

#define _GNU_SOURCE /* See feature_test_macros(7) */
#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[10];
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[10];
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;
}