blind-from-named.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-from-named.c (2249B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include "common.h" | |
3 | |
4 USAGE("[-t decisecs] [-a] ([-f fd] path [command ...] | path)") | |
5 | |
6 static int | |
7 erecv_fd(int sock) | |
8 { | |
9 int fd; | |
10 char buf[1]; | |
11 struct iovec iov; | |
12 struct msghdr msg; | |
13 struct cmsghdr *cmsg; | |
14 char cms[CMSG_SPACE(sizeof(fd))]; | |
15 | |
16 iov.iov_base = buf; | |
17 iov.iov_len = 1; | |
18 | |
19 memset(&msg, 0, sizeof(msg)); | |
20 msg.msg_name = 0; | |
21 msg.msg_namelen = 0; | |
22 msg.msg_iov = &iov; | |
23 msg.msg_iovlen = 1; | |
24 | |
25 msg.msg_control = (caddr_t)cms; | |
26 msg.msg_controllen = sizeof(cms); | |
27 | |
28 switch (recvmsg(sock, &msg, 0)) { | |
29 case -1: | |
30 eprintf("recvmsg:"); | |
31 case 0: | |
32 eprintf("recvmsg: connection closed by peer"); | |
33 default: | |
34 break; | |
35 } | |
36 | |
37 cmsg = CMSG_FIRSTHDR(&msg); | |
38 memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd)); | |
39 return fd; | |
40 } | |
41 | |
42 int | |
43 main(int argc, char *argv[]) | |
44 { | |
45 char buf[BUFSIZ]; | |
46 struct sockaddr_un addr; | |
47 int abstract = 0; | |
48 int filedes = -1; | |
49 int tries = 11; | |
50 int sockfd, fd; | |
51 size_t n; | |
52 | |
53 ARGBEGIN { | |
54 case 'a': | |
55 abstract = 1; | |
56 break; | |
57 case 'f': | |
58 filedes = etoi_flag('f', UARGF(), 0, INT_MAX); | |
59 break; | |
60 case 't': | |
61 tries = etoi_flag('t', UARGF(), 0, INT_MAX - 1) + 1; | |
62 break; | |
63 default: | |
64 usage(); | |
65 } ARGEND; | |
66 if (argc < 1 || (filedes >= 0 && argc == 1)) | |
67 usage(); | |
68 if (filedes < 0) | |
69 filedes = STDIN_FILENO; | |
70 | |
71 memset(&addr, 0, sizeof(addr)); | |
72 addr.sun_family = AF_UNIX; | |
73 if (strlen(argv[0]) + (size_t)(1 + abstract) > sizeof(addr.sun_p… | |
74 errno = ENAMETOOLONG; | |
75 eprintf("%s:", argv[0]); | |
76 } | |
77 strcpy(addr.sun_path + abstract, argv[0]); | |
78 argv++, argc--; | |
79 | |
80 sockfd = socket(PF_UNIX, SOCK_SEQPACKET, 0); | |
81 if (sockfd < 0) | |
82 eprintf("socket PF_UNIX SOCK_SEQPACKET:"); | |
83 | |
84 retry: | |
85 if ((connect(sockfd, (const struct sockaddr *)&addr, (size_t)siz… | |
86 if (--tries) { | |
87 usleep((useconds_t)100000L); | |
88 goto retry; | |
89 } else { | |
90 eprintf("bind %s%s%s:", | |
91 abstract ? "<abstract:" : "", | |
92 addr.sun_path + abstract, | |
93 abstract ? ">" : ""); | |
94 } | |
95 } | |
96 | |
97 fd = erecv_fd(sockfd); | |
98 close(sockfd); | |
99 | |
100 if (argc) { | |
101 if (fd != filedes) { | |
102 if (dup2(fd, filedes) < 0) | |
103 eprintf("dup2 %i %i:", fd, filedes); | |
104 close(fd); | |
105 } | |
106 execvp(argv[0], argv); | |
107 eprintf("execvp %s:", argv[0]); | |
108 } | |
109 | |
110 while ((n = eread(fd, buf, sizeof(buf), "<received file>"))) | |
111 ewriteall(STDOUT_FILENO, buf, n, "<stdout>"); | |
112 return 0; | |
113 } |