#include #include #include #include #include #include #include #include struct ticket { struct ticket *next; int val; int id; }; struct ticket *tickets; #define SK_NAME "/tmp/criu.unix.callback.test" int main(void) { 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; }