summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCurtis McEnroe2018-09-10 19:18:26 -0400
committerCurtis McEnroe2018-09-10 19:18:26 -0400
commit86e80edfcd3ba660dea1ce337467a10e2e878b18 (patch)
treed32d05f2cb51c08d963ffe3d2f4b4caf84ad12cb
parentc9968aadb959aeee1e999880089a9b6d923a6f26 (diff)
Add /man command
-rw-r--r--chat.h3
-rw-r--r--chatte.13
-rw-r--r--event.c75
-rw-r--r--input.c8
-rw-r--r--url.c3
5 files changed, 61 insertions, 31 deletions
diff --git a/chat.h b/chat.h
index 6c95ab6..2ee80db 100644
--- a/chat.h
+++ b/chat.h
@@ -37,7 +37,8 @@ void selfNick(const char *nick);
void selfUser(const char *user);
void selfJoin(const char *join);
-void eventSpawn(char *const argv[]);
+void eventWait(char *const argv[]);
+void eventPipe(char *const argv[]);
void eventLoop(int ui, int irc);
struct Tag {
diff --git a/chatte.1 b/chatte.1
index e3dbbb6..4dce17b 100644
--- a/chatte.1
+++ b/chatte.1
@@ -100,6 +100,9 @@ are renumbered.
.It Ic /join Ar chan
Join a channel.
.
+.It Ic /man
+View this manual.
+.
.It Ic /me Ar action
Send a CTCP
.Ql ACTION
diff --git a/event.c b/event.c
index 4771aac..cad170f 100644
--- a/event.c
+++ b/event.c
@@ -27,18 +27,26 @@
#include "chat.h"
-static union {
- struct {
- struct pollfd ui;
- struct pollfd irc;
- struct pollfd pipe;
- };
- struct pollfd fds[3];
-} fds;
+static struct {
+ bool wait;
+ bool pipe;
+ int fd;
+} spawn;
+
+void eventWait(char *const argv[]) {
+ uiHide();
+ pid_t pid = fork();
+ if (pid < 0) err(EX_OSERR, "fork");
+ if (!pid) {
+ execvp(argv[0], argv);
+ err(EX_CONFIG, "%s", argv[0]);
+ }
+ spawn.wait = true;
+}
-void eventSpawn(char *const argv[]) {
- if (fds.pipe.events) {
- uiLog(TagStatus, UIHot, L"eventSpawn: existing pipe");
+void eventPipe(char *const argv[]) {
+ if (spawn.pipe) {
+ uiLog(TagStatus, UIHot, L"event: existing pipe");
return;
}
@@ -60,21 +68,21 @@ void eventSpawn(char *const argv[]) {
}
close(rw[1]);
- fds.pipe.fd = rw[0];
- fds.pipe.events = POLLIN;
+ spawn.fd = rw[0];
+ spawn.pipe = true;
}
static void pipeRead(void) {
char buf[256];
- ssize_t len = read(fds.pipe.fd, buf, sizeof(buf) - 1);
+ ssize_t len = read(spawn.fd, buf, sizeof(buf) - 1);
if (len < 0) err(EX_IOERR, "read");
if (len) {
buf[len] = '\0';
len = strcspn(buf, "\n");
- uiFmt(TagStatus, UIHot, "eventSpawn: %.*s", (int)len, buf);
+ uiFmt(TagStatus, UIHot, "event: %.*s", (int)len, buf);
} else {
- close(fds.pipe.fd);
- memset(&fds.pipe, 0, sizeof(fds.pipe));
+ close(spawn.fd);
+ spawn.pipe = false;
}
}
@@ -84,10 +92,11 @@ static void sigchld(int sig) {
pid_t pid = wait(&status);
if (pid < 0) err(EX_OSERR, "wait");
if (WIFEXITED(status) && WEXITSTATUS(status)) {
- uiFmt(TagStatus, UIHot, "eventSpawn: exit %d", WEXITSTATUS(status));
+ uiFmt(TagStatus, UIHot, "event: exit %d", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
- uiFmt(TagStatus, UIHot, "eventSpawn: singal %d", WTERMSIG(status));
+ uiFmt(TagStatus, UIHot, "event: signal %d", WTERMSIG(status));
}
+ spawn.wait = false;
}
static void sigint(int sig) {
@@ -101,23 +110,31 @@ void eventLoop(int ui, int irc) {
signal(SIGINT, sigint);
signal(SIGCHLD, sigchld);
- fds.ui.fd = ui;
- fds.irc.fd = irc;
- fds.ui.events = POLLIN;
- fds.irc.events = POLLIN;
-
+ struct pollfd fds[3] = {
+ { irc, POLLIN, 0 },
+ { ui, POLLIN, 0 },
+ { -1, POLLIN, 0 },
+ };
for (;;) {
- uiDraw();
+ nfds_t nfds = 2;
+ if (spawn.wait) nfds = 1;
+ if (spawn.pipe) {
+ fds[2].fd = spawn.fd;
+ nfds = 3;
+ }
- int ready = poll(fds.fds, (fds.pipe.events ? 3 : 2), -1);
+ int ready = poll(fds, nfds, -1);
if (ready < 0) {
if (errno != EINTR) err(EX_IOERR, "poll");
uiRead();
+ uiDraw();
continue;
}
- if (fds.ui.revents) uiRead();
- if (fds.irc.revents) ircRead();
- if (fds.pipe.revents) pipeRead();
+ if (fds[0].revents) ircRead();
+ if (nfds > 1 && fds[1].revents) uiRead();
+ if (nfds > 2 && fds[2].revents) pipeRead();
+
+ if (nfds > 1) uiDraw();
}
}
diff --git a/input.c b/input.c
index 0d8e491..6e95b11 100644
--- a/input.c
+++ b/input.c
@@ -135,12 +135,20 @@ static void inputClose(struct Tag tag, char *params) {
tabRemove(TagNone, tag.name);
}
+static void inputMan(struct Tag tag, char *params) {
+ (void)tag;
+ (void)params;
+ char *argv[] = { "man", "1", "chatte", NULL };
+ eventWait(argv);
+}
+
static const struct {
const char *command;
Handler handler;
} Commands[] = {
{ "/close", inputClose },
{ "/join", inputJoin },
+ { "/man", inputMan },
{ "/me", inputMe },
{ "/names", inputWho },
{ "/nick", inputNick },
diff --git a/url.c b/url.c
index 49bea65..902128a 100644
--- a/url.c
+++ b/url.c
@@ -82,5 +82,6 @@ void urlOpen(struct Tag tag, size_t at, size_t to) {
if (tagIndex >= at && tagIndex < to) argv[argc++] = entry.url;
tagIndex++;
}
- if (argc > 1) eventSpawn(argv);
+ argv[argc] = NULL;
+ if (argc > 1) eventPipe(argv);
}