2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 18:07:57 +00:00
criu/test/unix-callback/unix-server.c
Andrey Vagin 1e4b8c8c23 tests: check callback-s for dumping and restoring sockets (v2)
Here are client, server programs and two libraries for dumping client
sockets and syslog socket.

The client can ask server to save a value and then request it later.
We suppose that after dumping and restoring the client will get
the same value.

So the dump callback requests the value and save it in a file.
The restore callback creates a new socket and ask server to save the
value from the file.

v2: open a syslog socket

Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2013-12-20 15:28:53 +04:00

105 lines
2.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <linux/un.h>
struct ticket
{
struct ticket *next;
int val;
int id;
};
struct ticket *tickets;
#define SK_NAME "/tmp/criu.unix.callback.test"
int main()
{
int sk, ret, id;
char buf[4096];
struct ticket *t;
struct sockaddr_un addr;
socklen_t addr_len;
struct stat st;
unlink(SK_NAME);
sk = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sk < 0) {
perror("socket");
return -1;
}
addr.sun_family = AF_UNIX;
addr_len = snprintf(addr.sun_path, UNIX_PATH_MAX, SK_NAME);
addr_len += sizeof(addr.sun_family);
if (bind(sk, (struct sockaddr *) &addr, addr_len) < 0) {
perror("bind");
return 1;
}
fstat(sk, &st);
while (1) {
addr_len = sizeof(struct sockaddr_un);
ret = recvfrom(sk, buf, sizeof(buf), 0, (struct sockaddr *) &addr, &addr_len);
if (ret == 0)
return 0;
if (ret < 0) {
perror("recvfrom");
return 1;
}
id = 0;
switch (buf[0]) {
case 'l':
ret = sprintf(buf, "%ld", st.st_ino);
if (sendto(sk, buf, ret + 1, 0, (struct sockaddr *) &addr, addr_len) < 0) {
perror("sendto");
return -1;
}
break;
case 't': /* ticket */
t = malloc(sizeof(struct ticket));
if (t == 0) {
perror("Can't allocate memory");
return 1;
}
t->val = atoi(buf + 1);
t->next = tickets;
t->id = atoi(addr.sun_path +strlen(SK_NAME));
printf("t: id %d val %d\n", t->id, t->val);
tickets = t;
break;
case 'd': /* dump */
id = atoi(buf + 1);
case 'r': /* request */
if (!id)
id = atoi(addr.sun_path + strlen(SK_NAME));
for (t = tickets; t; t = t->next)
if (t->id == id)
break;
if (t == NULL)
return 1;
printf("r: id %d val %d\n", id, t->val);
ret = sprintf(buf, "%d", t->val);
if (sendto(sk, buf, ret + 1, 0, (struct sockaddr *) &addr, addr_len) < 0) {
perror("sendto");
return 1;
}
break;
default:
return -1;
}
}
return 0;
}