dvtm

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

commit 2de6c7d664f35e48e2e2dd5fcc12312bc6d5e947
parent f6d6c4a61e42d14343ca2bb2998189c6890126fb
Author: Marc Andre Tanner <mat@brain-dump.org>
Date:   Fri, 22 Mar 2013 15:07:36 +0100

Implement MOD+C

which creates a new window but sets its working directory to the one
of the selected window. The implementation currently relies on the
/proc/$pid/cwd symlink and assumes a realpath(3) implementation
conforming to POSIX.1-2008 (i.e. the second argument can be NULL
in which case a big enough buffer is allocated).

Signed-off-by: Marc Andre Tanner <mat@brain-dump.org>

Diffstat:
config.def.h | 3++-
dvtm.c | 22+++++++++++++++++-----
vt.c | 4+++-
vt.h | 2+-
4 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -47,9 +47,10 @@ static Layout layouts[] = { #define MOD CTRL('g') -/* you can at most specifiy MAX_ARGS (2) number of arguments */ +/* you can at most specifiy MAX_ARGS (3) number of arguments */ static Key keys[] = { { MOD, 'c', { create, { NULL } } }, + { MOD, 'C', { create, { NULL, NULL, "$CWD" } } }, { MOD, 'x', { killclient, { NULL } } }, { MOD, 'j', { focusnext, { NULL } } }, { MOD, 'u', { focusnextnm, { NULL } } }, diff --git a/dvtm.c b/dvtm.c @@ -89,13 +89,13 @@ typedef struct { #endif #define CTRL_ALT(k) ((k) + (129 - 'a')) -#define MAX_ARGS 2 +#define MAX_ARGS 3 typedef struct { void (*cmd)(const char *args[]); /* needed to avoid an error about initialization * of nested flexible array members */ - const char *args[MAX_ARGS + 1]; + const char *args[MAX_ARGS]; } Action; typedef struct { @@ -705,6 +705,14 @@ cleanup() { unlink(cmdfifo.file); } +static char *getcwd_by_pid(Client *c) { + if (!c) + return NULL; + char buf[32]; + snprintf(buf, sizeof buf, "/proc/%d/cwd", c->pid); + return realpath(buf, NULL); +} + /* commands for use by keybindings */ static void create(const char *args[]) { @@ -714,7 +722,7 @@ create(const char *args[]) { const char *cmd = (args && args[0]) ? args[0] : shell; const char *pargs[] = { "/bin/sh", "-c", cmd, NULL }; c->id = ++cmdfifo.id; - char buf[8]; + char buf[8], *cwd = NULL; snprintf(buf, sizeof buf, "%d", c->id); const char *env[] = { "DVTM", VERSION, @@ -738,7 +746,11 @@ create(const char *args[]) { strncpy(c->title, args[1], sizeof(c->title) - 1); c->title[sizeof(c->title) - 1] = '\0'; } - c->pid = vt_forkpty(c->term, "/bin/sh", pargs, env, &c->pty); + if (args && args[2]) + cwd = !strcmp(args[2], "$CWD") ? getcwd_by_pid(sel) : (char*)args[2]; + c->pid = vt_forkpty(c->term, "/bin/sh", pargs, cwd, env, &c->pty); + if (args && args[2] && !strcmp(args[2], "$CWD")) + free(cwd); vt_set_data(c->term, c); vt_set_event_handler(c->term, term_event_handler); c->w = screen.w; @@ -1108,7 +1120,7 @@ handle_cmdfifo() { bool quote = false; int argc = 0; /* XXX: initializer assumes MAX_ARGS == 2 use a initialization loop? */ - const char *args[MAX_ARGS] = { NULL, NULL}, *arg; + const char *args[MAX_ARGS] = { NULL, NULL, NULL}, *arg; /* if arguments were specified in config.h ignore the one given via * the named pipe and thus skip everything until we find a new line */ diff --git a/vt.c b/vt.c @@ -1565,7 +1565,7 @@ void vt_togglebell(Vt *t) t->bell = !t->bell; } -pid_t vt_forkpty(Vt *t, const char *p, const char *argv[], const char *env[], int *pty) +pid_t vt_forkpty(Vt *t, const char *p, const char *argv[], const char *cwd, const char *env[], int *pty) { struct winsize ws; pid_t pid; @@ -1593,6 +1593,8 @@ pid_t vt_forkpty(Vt *t, const char *p, const char *argv[], const char *env[], in envp += 2; } setenv("TERM", vt_term, 1); + if (cwd) + chdir(cwd); execv(p, (char *const *)argv); fprintf(stderr, "\nexecv() failed.\nCommand: '%s'\n", argv[0]); exit(1); diff --git a/vt.h b/vt.h @@ -72,7 +72,7 @@ void vt_set_default_colors(Vt *, unsigned attrs, short fg, short bg); Vt *vt_create(int rows, int cols, int scroll_buf_sz); void vt_resize(Vt *, int rows, int cols); void vt_destroy(Vt *); -pid_t vt_forkpty(Vt *, const char *, const char *argv[], const char *envp[], int *pty); +pid_t vt_forkpty(Vt *, const char *, const char *argv[], const char *cwd, const char *envp[], int *pty); int vt_getpty(Vt *); unsigned vt_cursor(Vt *t);