#include #include #include #include #include #include #include #include #include #define SOCKET_PATH "/tmp/otp_socket" #define CMD_ECHO 1 #define CMD_TIMER 2 struct request { int priority; int command; int value; }; void send_fd(int socket, int fd) { struct msghdr msg = {0}; char buf[CMSG_SPACE(sizeof(fd))]; memset(buf, 0, sizeof(buf)); struct iovec io = { .iov_base = (void*)"F", .iov_len = 1 }; msg.msg_iov = &io; msg.msg_iovlen = 1; msg.msg_control = buf; msg.msg_controllen = sizeof(buf); struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd)); sendmsg(socket, &msg, 0); } int main(int argc, char *argv[]) { if (argc < 4) { printf("Usage: %s \n", argv[0]); return 1; } int sock = socket(AF_UNIX, SOCK_STREAM, 0); struct sockaddr_un addr; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, SOCKET_PATH); connect(sock, (struct sockaddr*)&addr, sizeof(addr)); int efd = eventfd(0, EFD_NONBLOCK); send_fd(sock, efd); struct request req; req.priority = atoi(argv[1]); req.command = atoi(argv[2]); req.value = atoi(argv[3]); write(sock, &req, sizeof(req)); int response; read(sock, &response, sizeof(response)); printf("Sync response: %d\n", response); struct pollfd pfd = { .fd = efd, .events = POLLIN }; printf("Waiting for async notification...\n"); poll(&pfd, 1, -1); uint64_t val; read(efd, &val, sizeof(val)); printf("Async notification received!\n"); close(sock); close(efd); return 0; }