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