s6-ipcserver-socketbinder.c (1757B)
1 /* ISC license. */ 2 3 #include <skalibs/nonposix.h> 4 #include <sys/stat.h> 5 #include <sys/socket.h> 6 #include <unistd.h> 7 #include <fcntl.h> 8 9 #include <skalibs/types.h> 10 #include <skalibs/sgetopt.h> 11 #include <skalibs/strerr.h> 12 #include <skalibs/socket.h> 13 #include <skalibs/exec.h> 14 15 #define USAGE "s6-ipcserver-socketbinder [ -d | -D ] [ -b backlog ] [ -M | -m ] [ -a perms ] [ -B ] path prog..." 16 #define dieusage() strerr_dieusage(100, USAGE) 17 18 int main (int argc, char const *const *argv) 19 { 20 unsigned int backlog = SOMAXCONN ; 21 int flagreuse = 1 ; 22 int flagdgram = 0 ; 23 unsigned int flags = O_NONBLOCK ; 24 unsigned int perms = 0777 ; 25 PROG = "s6-ipcserver-socketbinder" ; 26 { 27 subgetopt l = SUBGETOPT_ZERO ; 28 for (;;) 29 { 30 int opt = subgetopt_r(argc, argv, "DdMmBb:a:", &l) ; 31 if (opt == -1) break ; 32 switch (opt) 33 { 34 case 'D' : flagreuse = 0 ; break ; 35 case 'd' : flagreuse = 1 ; break ; 36 case 'M' : flagdgram = 0 ; break ; 37 case 'm' : flagdgram = 1 ; break ; 38 case 'B' : flags = 0 ; break ; 39 case 'b' : if (!uint0_scan(l.arg, &backlog)) dieusage() ; break ; 40 case 'a' : if (!uint0_oscan(l.arg, &perms)) dieusage() ; break ; 41 default : dieusage() ; 42 } 43 } 44 argc -= l.ind ; argv += l.ind ; 45 } 46 if (argc < 2) dieusage() ; 47 close(0) ; 48 if (flagdgram ? ipc_datagram_internal(flags) : ipc_stream_internal(flags)) 49 strerr_diefu1sys(111, "create socket") ; 50 51 { 52 mode_t m = umask(~perms & 0777) ; 53 if ((flagreuse ? ipc_bind_reuse(0, argv[0]) : ipc_bind(0, argv[0])) < 0) 54 strerr_diefu2sys(111, "bind to ", argv[0]) ; 55 umask(m) ; 56 } 57 if (backlog && ipc_listen(0, backlog) < 0) 58 strerr_diefu2sys(111, "listen to ", argv[0]) ; 59 60 xexec(argv+1) ; 61 }