1 /* $OpenBSD: accept.c,v 1.6 2021/12/13 16:56:49 deraadt Exp $ */ 2 /* 3 * Written by Artur Grabowski <art@openbsd.org>, 2002 Public Domain. 4 */ 5 #include <sys/socket.h> 6 #include <sys/time.h> 7 #include <sys/wait.h> 8 #include <sys/un.h> 9 10 #include <stdlib.h> 11 #include <stdio.h> 12 #include <unistd.h> 13 #include <fcntl.h> 14 #include <err.h> 15 #include <signal.h> 16 #include <string.h> 17 18 #define SOCK_NAME "test-sock" 19 20 int child(void); 21 22 int 23 main(int argc, char *argv[]) 24 { 25 int listensock, sock; 26 struct sockaddr_un sun, csun; 27 int csunlen; 28 int fd, lastfd; 29 int status; 30 int ischild = 0; 31 32 /* 33 * Create the listen socket. 34 */ 35 if ((listensock = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) 36 err(1, "socket"); 37 38 unlink(SOCK_NAME); 39 memset(&sun, 0, sizeof(sun)); 40 sun.sun_family = AF_LOCAL; 41 strlcpy(sun.sun_path, SOCK_NAME, sizeof sun.sun_path); 42 43 44 if (bind(listensock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 45 err(1, "bind"); 46 47 if (listen(listensock, 1) == -1) 48 err(1, "listen"); 49 50 switch (fork()) { 51 case -1: 52 err(1, "fork"); 53 case 0: 54 return child(); 55 } 56 57 while ((fd = open("/dev/null", O_RDONLY)) >= 0) 58 lastfd = fd; 59 60 switch (fork()) { 61 case -1: 62 err(1, "fork"); 63 case 0: 64 ischild = 1; 65 close(lastfd); /* Close one fd so that accept can succeed */ 66 sleep(2); /* sleep a bit so that we're the second to accept */ 67 } 68 69 sock = accept(listensock, (struct sockaddr *)&csun, &csunlen); 70 71 if (!ischild && sock >= 0) 72 errx(1, "accept succeeded in parent"); 73 if (ischild && sock < 0) 74 err(1, "accept failed in child"); 75 76 while (!ischild && wait4(-1, &status, 0, NULL) > 0) 77 ; 78 79 return (0); 80 } 81 82 int 83 child() 84 { 85 int i, fd, sock; 86 struct sockaddr_un sun; 87 88 /* 89 * Create socket and connect to the receiver. 90 */ 91 if ((sock = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) 92 errx(1, "child socket"); 93 94 (void) memset(&sun, 0, sizeof(sun)); 95 sun.sun_family = AF_LOCAL; 96 (void) strlcpy(sun.sun_path, SOCK_NAME, sizeof sun.sun_path); 97 98 if (connect(sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) 99 err(1, "child connect"); 100 101 return (0); 102 } 103