2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-29 05:18:00 +00:00
criu/test/zdtm/static/fifo_upon_unix_socket00.c
Adrian Reber 93dd984ca0 Run 'make indent' on all C files
Acked-by: Mike Rapoport <rppt@linux.ibm.com>
Signed-off-by: Adrian Reber <areber@redhat.com>
2021-09-03 10:31:00 -07:00

168 lines
2.9 KiB
C

#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include "zdtmtst.h"
const char *test_doc = "Check that fifo upon ghost socket configuration is restored";
const char *test_author = "Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>";
char *filename;
TEST_OPTION(filename, string, "socket name", 1);
#ifndef FIFO_UPON_UNIX01
static int fill_sock_name(struct sockaddr_un *name, const char *filename)
{
char *cwd;
cwd = get_current_dir_name();
if (strlen(filename) + strlen(cwd) + 1 >= sizeof(name->sun_path)) {
pr_err("Name %s/%s is too long for socket\n", cwd, filename);
return -1;
}
name->sun_family = AF_LOCAL;
ssprintf(name->sun_path, "%s/%s", cwd, filename);
return 0;
}
#else
static int fill_sock_name(struct sockaddr_un *name, const char *filename)
{
if (strlen(filename) + 1 >= sizeof(name->sun_path)) {
pr_err("Name %s is too long for socket\n", filename);
return -1;
}
name->sun_family = AF_LOCAL;
ssprintf(name->sun_path, "%s", filename);
return 0;
}
#endif
static int sk_alloc_bind(int type, struct sockaddr_un *addr)
{
int sk;
sk = socket(PF_UNIX, type, 0);
if (sk < 0) {
pr_perror("socket");
return -1;
}
if (addr && bind(sk, (const struct sockaddr *)addr, sizeof(*addr))) {
pr_perror("bind %s", addr->sun_path);
close(sk);
return -1;
}
return sk;
}
static int sk_alloc_connect(int type, struct sockaddr_un *addr)
{
int sk;
sk = socket(PF_UNIX, type, 0);
if (sk < 0) {
pr_perror("socket");
return -1;
}
if (connect(sk, (const struct sockaddr *)addr, sizeof(*addr))) {
pr_perror("connect %s", addr->sun_path);
close(sk);
return -1;
}
return sk;
}
static int check_fd(int fdin, int fdout)
{
int ret;
char c = 0;
ret = write(fdin, &c, 1);
if (ret != 1)
goto err;
ret = read(fdout, &c, 1);
if (ret != 1)
goto err;
return 0;
err:
pr_perror("broken fd pair %d %d", fdin, fdout);
return -1;
}
int main(int argc, char **argv)
{
int sk1, sk2, fd1, err;
struct sockaddr_un addr;
test_init(argc, argv);
unlink(filename);
if (fill_sock_name(&addr, filename))
return 1;
sk1 = sk_alloc_bind(SOCK_DGRAM, &addr);
if (sk1 < 0) {
pr_perror("Can't create sk");
return 1;
}
sk2 = sk_alloc_connect(SOCK_DGRAM, &addr);
if (sk2 < 0) {
pr_perror("Can't connect to sk");
return 1;
}
if (unlink(filename) < 0) {
fail("can't unlink %s", filename);
return 1;
}
if (mkfifo(filename, 0666)) {
pr_perror("can't make fifo \"%s\"", filename);
return 1;
}
fd1 = open(filename, O_RDWR);
if (fd1 < 0) {
pr_perror("can't open %s", filename);
return 1;
}
#ifdef FIFO_UPON_UNIX01
chdir("/");
#endif
test_daemon();
test_waitsig();
unlink(filename);
err = check_fd(sk2, sk1) || check_fd(fd1, fd1);
if (err)
fail();
else
pass();
close(sk1);
close(sk2);
close(fd1);
return 0;
}