vi: use ren_noeol() in vc_replace()
[neatvi.git] / cmd.c
blob1eb3e4207967cdba5a338d185f3a8e91f137b738
1 #include <poll.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/wait.h>
7 #include "vi.h"
9 static int cmd_make(char **argv, int *ifd, int *ofd)
11 int pid;
12 int pipefds0[2];
13 int pipefds1[2];
14 if (ifd)
15 pipe(pipefds0);
16 if (ofd)
17 pipe(pipefds1);
18 if (!(pid = fork())) {
19 if (ifd) { /* setting up stdin */
20 close(0);
21 dup(pipefds0[0]);
22 close(pipefds0[1]);
23 close(pipefds0[0]);
25 if (ofd) { /* setting up stdout */
26 close(1);
27 dup(pipefds1[1]);
28 close(pipefds1[0]);
29 close(pipefds1[1]);
31 execvp(argv[0], argv);
32 exit(1);
34 if (ifd)
35 close(pipefds0[0]);
36 if (ofd)
37 close(pipefds1[1]);
38 if (pid < 0) {
39 if (ifd)
40 close(pipefds0[1]);
41 if (ofd)
42 close(pipefds1[0]);
43 return -1;
45 if (ifd)
46 *ifd = pipefds0[1];
47 if (ofd)
48 *ofd = pipefds1[0];
49 return pid;
52 char *cmd_pipe(char *cmd, char *s)
54 char *argv[] = {"/bin/sh", "-c", cmd, NULL};
55 struct pollfd fds[2];
56 struct sbuf *sb;
57 char buf[512];
58 int ifd = 0, ofd = 0;
59 int slen = strlen(s);
60 int nw = 0;
61 int pid = cmd_make(argv, &ifd, &ofd);
62 if (pid <= 0)
63 return NULL;
64 sb = sbuf_make();
65 fds[0].fd = ofd;
66 fds[0].events = POLLIN;
67 fds[1].fd = ifd;
68 fds[1].events = POLLOUT;
69 while ((fds[0].fd >= 0 || fds[1].fd >= 0) && poll(fds, 3, 200) >= 0) {
70 if (fds[0].revents & POLLIN) {
71 int ret = read(fds[0].fd, buf, sizeof(buf));
72 if (ret > 0)
73 sbuf_mem(sb, buf, ret);
74 if (ret < 0)
75 close(fds[0].fd);
76 } else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
77 fds[0].fd = -1;
79 if (fds[1].revents & POLLOUT) {
80 int ret = write(fds[1].fd, s + nw, slen - nw);
81 if (ret > 0)
82 nw += ret;
83 if (ret <= 0 || nw == slen)
84 close(fds[1].fd);
85 } else if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) {
86 fds[1].fd = -1;
89 waitpid(pid, NULL, 0);
90 return sbuf_done(sb);