Introduction
Introduction Statistics Contact Development Disclaimer Help
lchat: exclude filter from input tail pipe - lchat - A line oriented chat front…
git clone git://git.suckless.org/lchat
Log
Files
Refs
README
---
commit e5371dc7ca278ac80852f30b699ae3f0ae8627bf
parent 5d78aec7398254c86ce90cb53d750af437f12a75
Author: Jan Klemkow <[email protected]>
Date: Wed, 22 Feb 2017 21:08:33 +0100
lchat: exclude filter from input tail pipe
This avoids a conflict between .bellmatch and .filter.
Both programs get the same raw input from tail now.
Diffstat:
M lchat.c | 83 ++++++++++++++++++++++++++++-…
1 file changed, 77 insertions(+), 6 deletions(-)
---
diff --git a/lchat.c b/lchat.c
@@ -119,6 +119,45 @@ line_output(struct slackline *sl, char *file)
}
static void
+fork_filter(int *read, int *write)
+{
+ int fds_read[2]; /* .filter -> lchat */
+ int fds_write[2]; /* lchat -> .filter */
+
+ if (pipe(fds_read) == -1)
+ err(EXIT_FAILURE, "pipe");
+ if (pipe(fds_write) == -1)
+ err(EXIT_FAILURE, "pipe");
+
+ switch (fork()) {
+ case -1:
+ err(EXIT_FAILURE, "fork of .filter");
+ case 0: /* child */
+ if (dup2(fds_read[1], STDOUT_FILENO) == -1)
+ err(EXIT_FAILURE, "dup2");
+ if (dup2(fds_write[0], STDIN_FILENO) == -1)
+ err(EXIT_FAILURE, "dup2");
+
+ if (close(fds_read[0]) == -1)
+ err(EXIT_FAILURE, "close");
+ if (close(fds_write[1]) == -1)
+ err(EXIT_FAILURE, "close");
+
+ execl("./.filter", "./.filter", NULL);
+ err(EXIT_FAILURE, "exec of .filter");
+ }
+
+ /* parent */
+ if (close(fds_read[1]) == -1)
+ err(EXIT_FAILURE, "close");
+ if (close(fds_write[0]) == -1)
+ err(EXIT_FAILURE, "close");
+
+ *read = fds_read[0];
+ *write = fds_write[1];
+}
+
+static void
usage(void)
{
fprintf(stderr, "lchat [-aeh] [-n lines] [-p prompt] [-t title] [-i in…
@@ -129,11 +168,13 @@ usage(void)
int
main(int argc, char *argv[])
{
- struct pollfd pfd[2];
+ struct pollfd pfd[3];
struct termios term;
struct slackline *sl = sl_init();
int fd = STDIN_FILENO;
int read_fd = 6;
+ int read_filter = -1;
+ int backend_sink = STDOUT_FILENO;
char c;
int ch;
bool empty_line = false;
@@ -260,27 +301,35 @@ main(int argc, char *argv[])
snprintf(tail_cmd, sizeof tail_cmd, "exec tail -n %zd -f %s",
history_len, out_file);
- if (access(".filter", X_OK) == 0)
- strlcat(tail_cmd, " | ./.filter", sizeof tail_cmd);
-
if ((fh = popen(tail_cmd, "r")) == NULL)
err(EXIT_FAILURE, "unable to open pipe to tail");
read_fd = fileno(fh);
}
+ int nfds = 2;
+
pfd[0].fd = fd;
pfd[0].events = POLLIN;
pfd[1].fd = read_fd;
pfd[1].events = POLLIN;
+ if (access(".filter", X_OK) == 0) {
+ fork_filter(&read_filter, &backend_sink);
+
+ pfd[2].fd = read_filter;
+ pfd[2].events = POLLIN;
+
+ nfds = 3;
+ }
+
/* print initial prompt */
fputs(prompt, stdout);
for (;;) {
errno = 0;
- if (poll(pfd, 2, INFTIM) == -1 && errno != EINTR)
+ if (poll(pfd, nfds, INFTIM) == -1 && errno != EINTR)
err(EXIT_FAILURE, "poll");
/* moves cursor back after linewrap */
@@ -338,7 +387,7 @@ main(int argc, char *argv[])
errx(EXIT_FAILURE, "backend exited");
if (n == -1)
err(EXIT_FAILURE, "read");
- if (write(STDOUT_FILENO, buf, n) == -1)
+ if (write(backend_sink, buf, n) == -1)
err(EXIT_FAILURE, "write");
/* terminate the input buffer with NUL */
@@ -348,6 +397,28 @@ main(int argc, char *argv[])
if (bell_flag && bell_match(buf, bell_file))
putchar('\a');
}
+
+ /* handel optional .filter i/o */
+ if (nfds > 2) {
+ /* handle .filter error and its broken pipe */
+ if (pfd[2].revents & POLLHUP)
+ break;
+ if (pfd[2].revents & POLLERR ||
+ pfd[2].revents & POLLNVAL)
+ errx(EXIT_FAILURE, ".filter error");
+
+ /* handle .filter output */
+ if (pfd[2].revents & POLLIN) {
+ char buf[BUFSIZ];
+ ssize_t n = read(pfd[2].fd, buf, sizeof buf);
+ if (n == 0)
+ errx(EXIT_FAILURE, ".filter exited");
+ if (n == -1)
+ err(EXIT_FAILURE, "read");
+ if (write(STDOUT_FILENO, buf, n) == -1)
+ err(EXIT_FAILURE, "write");
+ }
+ }
out:
/* show current input line */
fputs(prompt, stdout);
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.