dvtm

dynamic virtual terminal manager - with my changes
git clone https://pi.duncano.de/git/dvtm.git
Log | Files | Refs | README | LICENSE

commit daf2b7867d986d778c2442b526f46e4d59e2c682
parent 09ca83b21fc84fdc84c322d631020d1cdf7abdfe
Author: Marc Andre Tanner <mat@brain-dump.org>
Date:   Sat, 14 Jun 2008 18:50:32 +0200

Implement a command mechanism over a named pipe

This adds a new command line argument -c which takes a filename of a
named pipe if the pipe doesn't exists it is created. Commands which
should be recognized can be defined in config.h.

This feature is only enabled if CONFIG_CMDFIFO is defined.

Diffstat:
cmdfifo.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
config.h | 6++++++
config.mk | 1+
dvtm.c | 45++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 131 insertions(+), 3 deletions(-)

diff --git a/cmdfifo.c b/cmdfifo.c @@ -0,0 +1,82 @@ +int cmdfd = -1; +const char *cmdpath = NULL; + +Cmd * +get_cmd_by_name(const char *name) { + for (int i = 0; i < countof(commands); i++) { + if (!strcmp(name, commands[i].name)) + return &commands[i]; + } + return NULL; +} + +void +handle_cmdfifo() { + int r; + char *p, *s, cmdbuf[512]; + Cmd *cmd; + switch (r = read(cmdfd, cmdbuf, sizeof cmdbuf - 1)) { + case -1: + case 0: + cmdfd = -1; + break; + default: + cmdbuf[r] = '\0'; + /* find the command name */ + for (p = cmdbuf; *p == ' '; p++); + for (s = p; *p != ' ' && *p != '\n'; p++); + *p++ = '\0'; + if ((cmd = get_cmd_by_name(s)) != NULL) { + bool quote = false; + int argc = 0; + const char *args[MAX_ARGS], *arg = p; + if (cmd->action.args[0]) { + cmd->action.cmd(cmd->action.args); + break; + } + for (; *p; p++) { + switch (*p) { + case '\\': + /* remove the escape character '\\' move every + * following character to the left by one position + */ + switch (*(++p)) { + case '\\': + case '\'': + case '\"': { + char *t = p; + for (;;) { + *(t - 1) = *t; + if (*t++ == '\0') + break; + } + } + } + break; + case '\'': + case '\"': + quote = !quote; + break; + case ' ': + if (!quote) { + case '\n': + /* remove trailing quote */ + if (*(p - 1) == '\'' || *(p - 1) == '\"') + *(p - 1) = '\0'; + *p++ = '\0'; + /* remove leading quote */ + if (*arg == '\'' || *arg == '\"') + arg++; + + args[argc++] = arg; + while (*p == ' ') + p++; + arg = p; + } + break; + } + } + cmd->action.cmd(args); + } + } +} diff --git a/config.h b/config.h @@ -125,6 +125,12 @@ Button buttons[] = { }; #endif /* HANDLE_MOUSE */ +#ifdef CONFIG_CMDFIFO +Cmd commands[] = { + { "create", { create, { NULL } } }, +}; +#endif /* CONFIG_CMDFIFO */ + /* gets executed when dvtm is started */ Action actions[] = { { create, { NULL } }, diff --git a/config.mk b/config.mk @@ -15,6 +15,7 @@ LDFLAGS += -L/usr/lib -L/usr/local/lib ${LIBS} # Mouse handling CFLAGS += -DHANDLE_MOUSE +CFLAGS += -DCONFIG_CMDFIFO DEBUG_CFLAGS = ${CFLAGS} -UNDEBUG -O0 -g -ggdb -Wall diff --git a/dvtm.c b/dvtm.c @@ -79,6 +79,13 @@ typedef struct { } Button; #endif /* HANDLE_MOUSE */ +#ifdef CONFIG_CMDFIFO +typedef struct { + const char *name; + Action action; +} Cmd; +#endif + enum { BarTop, BarBot, BarOff }; #define COLOR(fg, bg) madtty_color_pair(fg, bg) @@ -142,6 +149,10 @@ bool need_screen_resize = true; int width, height; bool running = true; +#ifdef CONFIG_CMDFIFO +# include "cmdfifo.c" +#endif + void eprint(const char *errstr, ...) { va_list ap; @@ -869,8 +880,7 @@ resize_screen() { void startup(const char *args[]) { - int i; - for (i = 0; i < countof(actions); i++) + for (int i = 0; i < countof(actions); i++) actions[i].cmd(actions[i].args); } @@ -901,6 +911,12 @@ cleanup() { endwin(); if (statusfd > 0) close(statusfd); +#ifdef CONFIG_CMDFIFO + if (cmdfd > 0) + close(cmdfd); + if (cmdpath) + unlink(cmdpath); +#endif } void @@ -912,7 +928,11 @@ quit(const char *args[]) { void usage() { cleanup(); - eprint("usage: dvtm [-v] [-m mod] [-s status-fifo] [-c cmd-fifo] [cmd...]\n"); + eprint("usage: dvtm [-v] [-m mod] [-s status-fifo] " +#ifdef CONFIG_CMDFIFO + "[-c cmd-fifo] " +#endif + "[cmd...]\n"); exit(EXIT_FAILURE); } @@ -967,6 +987,14 @@ parse_args(int argc, char *argv[]) { statusfd = open_or_create_fifo(argv[arg]); updatebarpos(); break; +#ifdef CONFIG_CMDFIFO + case 'c': + if (++arg >= argc) + usage(); + cmdfd = open_or_create_fifo(argv[arg]); + cmdpath = argv[arg]; + break; +#endif default: usage(); } @@ -980,6 +1008,7 @@ main(int argc, char *argv[]) { setup(); startup(NULL); } + while (running) { Client *c, *t; int r, nfds = 0; @@ -991,6 +1020,12 @@ main(int argc, char *argv[]) { FD_ZERO(&rd); FD_SET(STDIN_FILENO, &rd); +#ifdef CONFIG_CMDFIFO + if (cmdfd != -1) { + FD_SET(cmdfd, &rd); + nfds = cmdfd; + } +#endif if (statusfd != -1) { FD_SET(statusfd, &rd); nfds = max(nfds, statusfd); @@ -1063,6 +1098,10 @@ main(int argc, char *argv[]) { continue; } +#ifdef CONFIG_CMDFIFO + if (cmdfd != -1 && FD_ISSET(cmdfd, &rd)) + handle_cmdfifo(); +#endif if (statusfd != -1 && FD_ISSET(statusfd, &rd)) { char *p; switch (r = read(statusfd, stext, sizeof stext - 1)) {