static void test_listen_bound(void) { struct sockaddr_un sun; char path[PATH_MAX]; int s; snprintf(path, sizeof(path), "/tmp/lds.XXXXXXXXX"); if (mktemp(path) == NULL) FAILERR("mktemp"); s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); if (s < 0) FAILERR("socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_LOCAL; sun.sun_len = sizeof(sun); strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); if (bind(s, (struct sockaddr *)&sun, sizeof(sun)) < 0) FAILERR("bind"); if (listen(s, -1)) { (void)unlink(path); FAILERR("bind"); } close(s); (void)unlink(path); }
static void test_connect_send(struct sockaddr_un *sun) { ssize_t ssize; char ch; int s; ANN(); NEW_SOCKET(s); if (connect(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) FAILERR("connect"); ssize = send(s, &ch, sizeof(ch), 0); if (ssize < 0) FAILERR("send"); if (ssize != sizeof(ch)) FAILERRX("send wrong size"); (void)close(s); OK(); }
static void test_socketpair(void) { int sv[2]; if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv) < 0) FAILERR("socketpair"); (void)close(sv[0]); (void)close(sv[1]); }
static void test_socket(void) { int s; s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); if (s < 0) FAILERR("socket"); (void)close(s); }
static void test_connect_shutdown_send(struct sockaddr_un *sun) { ssize_t ssize; char ch; int s; ANN(); NEW_SOCKET(s); if (connect(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) FAILERR("connect"); if (shutdown(s, SHUT_RDWR) < 0) FAILERR("shutdown SHUT_RDWR"); ssize = send(s, &ch, sizeof(ch), 0); if (ssize >= 0) FAILERRX("send"); if (errno != EPIPE) FAILERR("send unexpected error"); (void)close(s); OK(); }
static void test_connect(struct sockaddr_un *sun) { int s; ANN(); NEW_SOCKET(s); if (connect(s, (struct sockaddr *)sun, sizeof(*sun)) < 0) FAILERR("connect"); (void)close(s); OK(); }
static void test_listen_unbound(void) { int s; s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); if (s < 0) FAILERR("socket"); if (listen(s, -1) == 0) FAILERRX("listen"); (void)close(s); }
static void test_sendto(struct sockaddr_un *sun) { ssize_t ssize; char ch; int s; ANN(); NEW_SOCKET(s); ssize = sendto(s, &ch, sizeof(ch), 0, (struct sockaddr *)sun, sizeof(*sun)); if (ssize < 0) FAILERR("sendto"); (void)close(s); OK(); }
int main(int argc, char *argv[]) { struct sockaddr_un sun; char path[PATH_MAX]; pid_t pid_client, pid_server; int i, s_listen; snprintf(path, sizeof(path), "/tmp/lds_exercise.XXXXXXXXX"); if (mktemp(path) == NULL) FAILERR("mktemp"); s_listen = socket(PF_LOCAL, SOCK_SEQPACKET, 0); if (s_listen < 0) { (void)unlink(path); FAILERR("socket"); } i = SEQPACKET_RCVBUF; if (setsockopt(s_listen, SOL_SOCKET, SO_RCVBUF, &i, sizeof(i)) < 0) { (void)unlink(path); FAILERR("setsockopt SO_RCVBUF"); } i = SEQPACKET_SNDBUF; if (setsockopt(s_listen, SOL_SOCKET, SO_SNDBUF, &i, sizeof(i)) < 0) { (void)unlink(path); FAILERR("setsockopt SO_SNDBUF"); } i = 1; if (setsockopt(s_listen, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof(i)) < 0) { (void)unlink(path); FAILERR("setsockopt SO_NOSIGPIPE"); } bzero(&sun, sizeof(sun)); sun.sun_len = sizeof(sun); sun.sun_family = AF_LOCAL; strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); if (bind(s_listen, (struct sockaddr *)&sun, sizeof(sun)) < 0) { (void)unlink(path); FAILERR("bind"); } if (listen(s_listen, -1) < 0) { (void)unlink(path); FAILERR("listen"); } pid_server = fork(); if (pid_server < 0) { (void)unlink(path); FAILERR("fork"); } if (pid_server == 0) { server(s_listen); return (0); } pid_client = fork(); if (pid_client < 0) { (void)kill(pid_server, SIGKILL); (void)unlink(path); FAILERR("fork"); } if (pid_client == 0) { client(&sun); return (0); } /* * When the client is done, kill the server and clean up. */ (void)waitpid(pid_client, NULL, 0); (void)kill(pid_server, SIGKILL); (void)unlink(path); return (0); }