diff --git a/CHANGES b/CHANGES index 2e68b029..9d9c8651 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ 10 January 2009 +* If a window is created from the command line, tmux will now use the same + current working directory for the new process. A new default-path option to + sets the working directory for processes created from keys or interactively + from the prompt. * New mode to display a large clock. Entered with clock-mode command (bound to C-b t by default); two window options: clock-mode-colour and clock-mode-style (12 or 24). This will probably be used as the basis for window locking. @@ -841,7 +845,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.188 2009-01-10 19:35:39 nicm Exp $ +$Id: CHANGES,v 1.189 2009-01-10 19:37:35 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB diff --git a/TODO b/TODO index a7dde8c4..2d825c0a 100644 --- a/TODO +++ b/TODO @@ -59,6 +59,7 @@ data). maybe too slow though? - use a better termcap internally instead of screen, perhaps xterm - tty.c is a bit ugly +- document default-path - document xterm-keys - document server-info - document window options changes diff --git a/client.c b/client.c index 4ae5fc1a..4e012a1b 100644 --- a/client.c +++ b/client.c @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.35 2008-09-09 22:16:36 nicm Exp $ */ +/* $Id: client.c,v 1.36 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -99,6 +99,8 @@ retry: data.sx = ws.ws_col; data.sy = ws.ws_row; *data.tty = '\0'; + if (getcwd(data.cwd, sizeof data.cwd) == NULL) + *data.cwd = '\0'; if ((name = ttyname(STDIN_FILENO)) == NULL) fatal("ttyname failed"); diff --git a/cmd-new-session.c b/cmd-new-session.c index 32bb94b4..711e0776 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-session.c,v 1.32 2008-12-10 20:25:41 nicm Exp $ */ +/* $Id: cmd-new-session.c,v 1.33 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -113,7 +113,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) struct cmd_new_session_data *data = self->data; struct client *c = ctx->cmdclient; struct session *s; - char *cmd, *cause; + char *cmd, *cwd, *cause; u_int sx, sy; if (ctx->curclient != NULL) @@ -138,6 +138,10 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) cmd = data->cmd; if (cmd == NULL) cmd = options_get_string(&global_options, "default-command"); + if (c == NULL || c->cwd == NULL) + cwd = options_get_string(&global_options, "default-path"); + else + cwd = c->cwd; sx = 80; sy = 25; @@ -160,8 +164,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) } - if ((s = session_create(data->newname, cmd, sx, sy)) == NULL) - fatalx("session_create failed"); + if ((s = session_create(data->newname, cmd, cwd, sx, sy)) == NULL) + fatalx("session_create failed"); if (data->winname != NULL) { xfree(s->curw->window->name); s->curw->window->name = xstrdup(data->winname); diff --git a/cmd-new-window.c b/cmd-new-window.c index f730e3ac..2dad77e8 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-window.c,v 1.26 2008-12-10 20:25:41 nicm Exp $ */ +/* $Id: cmd-new-window.c,v 1.27 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -115,7 +115,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx) struct cmd_new_window_data *data = self->data; struct session *s; struct winlink *wl; - char *cmd; + char *cmd, *cwd; int idx; if (data == NULL) @@ -137,8 +137,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd = data->cmd; if (cmd == NULL) cmd = options_get_string(&s->options, "default-command"); + if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL) + cwd = options_get_string(&global_options, "default-path"); + else + cwd = ctx->cmdclient->cwd; - wl = session_new(s, data->name, cmd, idx); + wl = session_new(s, data->name, cmd, cwd, idx); if (wl == NULL) { ctx->error(ctx, "command failed: %s", cmd); return; diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c index 37040715..20002c3e 100644 --- a/cmd-respawn-window.c +++ b/cmd-respawn-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-respawn-window.c,v 1.5 2008-09-10 19:15:04 nicm Exp $ */ +/* $Id: cmd-respawn-window.c,v 1.6 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -47,7 +47,9 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx) struct cmd_target_data *data = self->data; struct winlink *wl; struct session *s; - const char *env[] = { NULL /* TMUX= */, "TERM=screen", NULL }; + const char *env[] = { + NULL /* TMUX= */, "TERM=screen", NULL + }; char buf[256]; u_int i; @@ -64,7 +66,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx) xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i); env[0] = buf; - if (window_spawn(wl->window, data->arg, env) != 0) { + if (window_spawn(wl->window, data->arg, wl->window->cwd, env) != 0) { ctx->error(ctx, "respawn failed: %s:%d", s->name, wl->idx); return; } diff --git a/cmd-set-option.c b/cmd-set-option.c index 5f8b32d7..55d1a7cf 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -1,4 +1,4 @@ -/* $Id: cmd-set-option.c,v 1.49 2009-01-10 01:51:21 nicm Exp $ */ +/* $Id: cmd-set-option.c,v 1.50 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -49,6 +49,7 @@ const struct set_option_entry set_option_table[NSETOPTION] = { { "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list }, { "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "default-command", SET_OPTION_STRING, 0, 0, NULL }, + { "default-path", SET_OPTION_STRING, 0, 0, NULL }, { "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "history-limit", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "message-bg", SET_OPTION_COLOUR, 0, 0, NULL }, diff --git a/server-msg.c b/server-msg.c index 555e21ae..2f1fc681 100644 --- a/server-msg.c +++ b/server-msg.c @@ -1,4 +1,4 @@ -/* $Id: server-msg.c,v 1.54 2009-01-07 22:57:03 nicm Exp $ */ +/* $Id: server-msg.c,v 1.55 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -183,6 +183,10 @@ server_msg_fn_identify(struct hdr *hdr, struct client *c) c->sx = data.sx; c->sy = data.sy; + c->cwd = NULL; + if (*data.cwd != '\0') + c->cwd = xstrdup(data.cwd); + data.tty[(sizeof data.tty) - 1] = '\0'; tty_init(&c->tty, data.tty, xstrdup(term)); if (data.flags & IDENTIFY_UTF8) diff --git a/server.c b/server.c index f0651f07..078183b3 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.92 2009-01-10 19:35:40 nicm Exp $ */ +/* $Id: server.c,v 1.93 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -101,7 +101,7 @@ server_start(const char *path) * Must daemonise before loading configuration as the PID changes so * $TMUX would be wrong for sessions created in the config file. */ - if (daemon(1, 1) != 0) + if (daemon(0, 1) != 0) fatal("daemon failed"); ARRAY_INIT(&windows); @@ -590,6 +590,9 @@ server_lost_client(struct client *c) xfree(ARRAY_ITEM(&c->prompt_hdata, i)); ARRAY_FREE(&c->prompt_hdata); + if (c->cwd != NULL) + xfree(c->cwd); + close(c->fd); buffer_destroy(c->in); buffer_destroy(c->out); diff --git a/session.c b/session.c index 9d1e1acf..bc8c6126 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $Id: session.c,v 1.48 2009-01-10 14:43:43 nicm Exp $ */ +/* $Id: session.c,v 1.49 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -109,7 +109,8 @@ session_find(const char *name) /* Create a new session. */ struct session * -session_create(const char *name, const char *cmd, u_int sx, u_int sy) +session_create( + const char *name, const char *cmd, const char *cwd, u_int sx, u_int sy) { struct session *s; u_int i; @@ -141,7 +142,7 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy) s->name = xstrdup(name); else xasprintf(&s->name, "%u", i); - if (session_new(s, NULL, cmd, -1) == NULL) { + if (session_new(s, NULL, cmd, cwd, -1) == NULL) { session_destroy(s); return (NULL); } @@ -192,7 +193,8 @@ session_index(struct session *s, u_int *i) /* Create a new window on a session. */ struct winlink * -session_new(struct session *s, const char *name, const char *cmd, int idx) +session_new(struct session *s, + const char *name, const char *cmd, const char *cwd, int idx) { struct window *w; const char *env[] = { NULL /* TMUX= */, "TERM=screen", NULL }; @@ -205,7 +207,8 @@ session_new(struct session *s, const char *name, const char *cmd, int idx) env[0] = buf; hlimit = options_get_number(&s->options, "history-limit"); - if ((w = window_create(name, cmd, env, s->sx, s->sy, hlimit)) == NULL) + w = window_create(name, cmd, cwd, env, s->sx, s->sy, hlimit); + if (w == NULL) return (NULL); return (session_attach(s, w, idx)); diff --git a/tmux.c b/tmux.c index ada0bb4a..64d50743 100644 --- a/tmux.c +++ b/tmux.c @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.90 2009-01-10 19:35:40 nicm Exp $ */ +/* $Id: tmux.c,v 1.91 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -178,7 +178,7 @@ main(int argc, char **argv) const char *shell; struct passwd *pw; char *path, *cause, *home; - char rpath[MAXPATHLEN]; + char rpath[MAXPATHLEN], cwd[MAXPATHLEN]; int n, opt, flags; flags = 0; @@ -305,6 +305,12 @@ main(int argc, char **argv) &global_options, "default-command", "exec %s", shell); + if (getcwd(cwd, sizeof cwd) == NULL) { + log_warn("getcwd"); + exit(1); + } + options_set_string(&global_options, "default-path", "%s", cwd); + if (argc == 0) { cmd = xmalloc(sizeof *cmd); cmd->entry = &cmd_new_session_entry; diff --git a/tmux.h b/tmux.h index d5541bfe..cfd4973b 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.218 2009-01-10 19:35:40 nicm Exp $ */ +/* $Id: tmux.h,v 1.219 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -387,6 +387,8 @@ struct msg_identify_data { char tty[TTY_NAME_MAX]; int version; + char cwd[MAXPATHLEN]; + #define IDENTIFY_UTF8 0x1 #define IDENTIFY_256COLOURS 0x2 #define IDENTIFY_HASDEFAULTS 0x4 @@ -591,6 +593,7 @@ struct window_mode { struct window { char *name; char *cmd; + char *cwd; int fd; struct buffer *in; @@ -728,6 +731,7 @@ struct client { struct buffer *out; char *title; + char *cwd; struct tty tty; struct timeval status_timer; @@ -866,7 +870,7 @@ struct set_option_entry { }; extern const struct set_option_entry set_option_table[]; extern const struct set_option_entry set_window_option_table[]; -#define NSETOPTION 17 +#define NSETOPTION 18 #define NSETWINDOWOPTION 12 /* Edit keys. */ @@ -1342,9 +1346,10 @@ struct winlink *winlink_next(struct winlinks *, struct winlink *); struct winlink *winlink_previous(struct winlinks *, struct winlink *); void winlink_stack_push(struct winlink_stack *, struct winlink *); void winlink_stack_remove(struct winlink_stack *, struct winlink *); -struct window *window_create(const char *, +struct window *window_create(const char *, const char *, const char *, const char **, u_int, u_int, u_int); -int window_spawn(struct window *, const char *, const char **); +int window_spawn(struct window *, + const char *, const char *, const char **); void window_destroy(struct window *); int window_resize(struct window *, u_int, u_int); int window_set_mode(struct window *, const struct window_mode *); @@ -1373,10 +1378,12 @@ void session_alert_cancel(struct session *, struct winlink *); int session_alert_has(struct session *, struct winlink *, int); int session_alert_has_window(struct session *, struct window *, int); struct session *session_find(const char *); -struct session *session_create(const char *, const char *, u_int, u_int); +struct session *session_create( + const char *, const char *, const char *, u_int, u_int); void session_destroy(struct session *); int session_index(struct session *, u_int *); -struct winlink *session_new(struct session *, const char *, const char *, int); +struct winlink *session_new(struct session *, + const char *, const char *, const char *, int); struct winlink *session_attach(struct session *, struct window *, int); int session_detach(struct session *, struct winlink *); int session_has(struct session *, struct window *); diff --git a/window.c b/window.c index 48de0da9..8d4bd496 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.53 2009-01-10 14:43:43 nicm Exp $ */ +/* $Id: window.c,v 1.54 2009-01-10 19:37:35 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -204,14 +204,15 @@ winlink_stack_remove(struct winlink_stack *stack, struct winlink *wl) } struct window * -window_create(const char *name, - const char *cmd, const char **envp, u_int sx, u_int sy, u_int hlimit) +window_create(const char *name, const char *cmd, + const char *cwd, const char **envp, u_int sx, u_int sy, u_int hlimit) { struct window *w; char *ptr, *copy; w = xmalloc(sizeof *w); w->cmd = NULL; + w->cwd = NULL; w->fd = -1; w->in = buffer_create(BUFSIZ); @@ -252,7 +253,7 @@ window_create(const char *name, ARRAY_ADD(&windows, w); w->references = 0; - if (window_spawn(w, cmd, envp) != 0) { + if (window_spawn(w, cmd, cwd, envp) != 0) { window_destroy(w); return (NULL); } @@ -260,7 +261,8 @@ window_create(const char *name, } int -window_spawn(struct window *w, const char *cmd, const char **envp) +window_spawn( + struct window *w, const char *cmd, const char *cwd, const char **envp) { struct winsize ws; int mode; @@ -268,11 +270,10 @@ window_spawn(struct window *w, const char *cmd, const char **envp) if (w->fd != -1) close(w->fd); - if (cmd != NULL) { - if (w->cmd != NULL) - xfree(w->cmd); - w->cmd = xstrdup(cmd); - } + if (w->cmd != NULL) + xfree(w->cmd); + w->cmd = xstrdup(cmd); + w->cwd = xstrdup(cwd); memset(&ws, 0, sizeof ws); ws.ws_col = screen_size_x(&w->base); @@ -282,12 +283,14 @@ window_spawn(struct window *w, const char *cmd, const char **envp) case -1: return (1); case 0: + if (chdir(cwd) != 0) + chdir("/"); for (envq = envp; *envq != NULL; envq++) { if (putenv(*envq) != 0) fatal("putenv failed"); } sigreset(); - log_debug("new child: cmd=%s; pid=%ld", w->cmd, (long) getpid()); + log_debug("new child: cmd=%s pid=%ld", w->cmd, (long) getpid()); log_close(); execl(_PATH_BSHELL, "sh", "-c", w->cmd, (char *) NULL); @@ -327,6 +330,8 @@ window_destroy(struct window *w) buffer_destroy(w->in); buffer_destroy(w->out); + if (w->cwd != NULL) + xfree(w->cwd); if (w->cmd != NULL) xfree(w->cmd); xfree(w->name);