/* UDS server */ #include #include #include #include #include #include #include #include #include #include // use abstract address #define SOCKET "\0udsbench.socket" static int die(const char *msg) { if (errno) fprintf(stderr, "%s: error %d %m\n", msg, errno); else fprintf(stderr, "%s\n", msg); if (errno != ECONNRESET) exit(EXIT_FAILURE); return 0; } int main(int argc, char *argv[]) { struct sockaddr_un addr = { .sun_family = AF_UNIX, .sun_path = SOCKET, }; int sock, client1, client2 = -1, rc, len; struct pollfd pfd[2]; char buf[65536]; unsigned long cnt = 0; bool single = false; if (argc != 2) die("usage: server {single|dbus}"); if (!strcmp(argv[1], "single")) single = true; printf("running in %s mode\n", single ? "single" : "dbus"); sock = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (sock < 0) die("can't create socket"); if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) die("can't bind address"); if (listen(sock, 5) < 0) die("can't listen"); printf("waiting for client 1\n"); client1 = accept(sock, NULL, NULL); if (client1 < 0) die("accept"); if (!single) { printf("waiting for client 2\n"); client2 = accept(sock, NULL, NULL); if (client2 < 0) die("accept"); write(client2, "\01", 1); } write(client1, "\0", 1); printf("enter event loop\n"); pfd[0].fd = client1; pfd[1].fd = client2; pfd[0].events = pfd[1].events = POLLIN; for (;;) { rc = poll(pfd, single ? 1 : 2, -1); if (rc < 0) die("poll"); if (pfd[0].revents & POLLIN) { len = read(client1, buf, sizeof(buf)); if (len < 0) { die("read from client 1"); break; } if (len == 0) { printf("client 1 EOF\n"); break; } rc = write(single ? client1 : client2, buf, len); if (len != rc) { die("write to client 2"); break; } cnt++; } if (pfd[1].revents & POLLIN) { len = read(client2, buf, sizeof(buf)); if (len < 0) { die("read from client 2"); break; } if (len == 0) { printf("client 2 EOF\n"); break; } rc = write(client1, buf, len); if (len != rc) { die("write to client 1"); break; } cnt++; } } printf("passed %lu messages\n", cnt); return EXIT_SUCCESS; }