The branch, master has been updated
via 4538c269d0b366a770a5a5ebfe0c5007569edbc1 (commit)
from 446eb11cdeba97a24996cee36ba331491aba6211 (commit)
- Log -----------------------------------------------------------------
commit 4538c269d0b366a770a5a5ebfe0c5007569edbc1
Author: Nicholas Marriott <[email protected]>
Commit: Nicholas Marriott <[email protected]>
Alter how tmux handles the working directory to internally use file
descriptors
rather than strings.
- Each session still has a current working directory.
- New sessions still get their working directory from the client that
created
them or its attached session if any.
- New windows are created by default in the session working directory.
- The -c flag to new, neww, splitw allows the working directory to be
overridden.
- The -c flag to attach let's the session working directory be changed.
- The default-path option has been removed.
To get the equivalent to default-path '.', do:
bind c neww -c $PWD
To get the equivalent of default-path '', do:
bind c neww -c '#{pane_current_path}'
The equivalent of default-path '~' is left as an exercise for the reader.
This also changes the client identify protocol to be a set of messages
rather
than one as well as some other changes that should make it easier to make
backwards-compatible protocol changes in future.
---
client.c | 60 +++++++++---------------
cmd-attach-session.c | 68 +++++++++++++++++++++++----
cmd-load-buffer.c | 30 ++++++------
cmd-new-session.c | 74 ++++++++++++++++++------------
cmd-new-window.c | 41 +++++++++++++++--
cmd-queue.c | 24 ----------
cmd-save-buffer.c | 54 ++++++++++------------
cmd-split-window.c | 40 ++++++++++++++--
format.c | 3 -
options-table.c | 5 --
server-client.c | 125 +++++++++++++++++++++++++++++++++-----------------
server-fn.c | 8 ++--
session.c | 17 +++----
tmux.1 | 22 ++-------
tmux.c | 28 +----------
tmux.h | 56 ++++++----------------
window.c | 16 +++---
17 files changed, 363 insertions(+), 308 deletions(-)
diff --git a/client.c b/client.c
index 0a1c8da..6179187 100644
--- a/client.c
+++ b/client.c
@@ -53,7 +53,6 @@ int client_attached;
int client_get_lock(char *);
int client_connect(char *, int);
void client_send_identify(int);
-void client_send_environ(void);
int client_write_one(enum msgtype, int, const void *, size_t);
int client_write_server(enum msgtype, const void *, size_t);
void client_update_event(void);
@@ -261,8 +260,7 @@ client_main(int argc, char **argv, int flags)
/* Establish signal handlers. */
set_signals(client_signal);
- /* Send initial environment. */
- client_send_environ();
+ /* Send identify messages. */
client_send_identify(flags);
/* Send first command. */
@@ -320,48 +318,38 @@ client_main(int argc, char **argv, int flags)
return (client_exitval);
}
-/* Send identify message to server with the file descriptors. */
+/* Send identify messages to server. */
void
client_send_identify(int flags)
{
- struct msg_identify_data data;
- char *term;
- int fd;
+ const char *s;
+ char **ss;
+ int fd;
- data.flags = flags;
+ client_write_one(MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
- if (getcwd(data.cwd, sizeof data.cwd) == NULL)
- *data.cwd = '\0';
+ if ((s = getenv("TERM")) == NULL)
+ s = "";
+ client_write_one(MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
- term = getenv("TERM");
- if (term == NULL ||
- strlcpy(data.term, term, sizeof data.term) >= sizeof data.term)
- *data.term = '\0';
+ if ((s = ttyname(STDIN_FILENO)) == NULL)
+ s = "";
+ client_write_one(MSG_IDENTIFY_TTYNAME, -1, s, strlen(s) + 1);
+
+ if ((fd = open(".", O_RDONLY)) == -1)
+ fd = open("/", O_RDONLY);
+ client_write_one(MSG_IDENTIFY_CWD, fd, NULL, 0);
-#ifdef __CYGWIN__
- snprintf(&data.ttyname, sizeof data.ttyname, "%s",
- ttyname(STDIN_FILENO));
-#else
if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed");
-#endif
- imsg_compose(&client_ibuf,
- MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
- client_update_event();
-}
+ client_write_one(MSG_IDENTIFY_STDIN, fd, NULL, 0);
-/* Forward entire environment to server. */
-void
-client_send_environ(void)
-{
- struct msg_environ_data data;
- char **var;
+ for (ss = environ; *ss != NULL; ss++)
+ client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, strlen(*ss) +
1);
- for (var = environ; *var != NULL; var++) {
- if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
- continue;
- client_write_server(MSG_ENVIRON, &data, sizeof data);
- }
+ client_write_one(MSG_IDENTIFY_DONE, -1, NULL, 0);
+
+ client_update_event();
}
/* Helper to send one message. */
@@ -604,8 +592,6 @@ client_dispatch_wait(void *data0)
case MSG_EXITED:
imsg_free(&imsg);
return (-1);
- default:
- fatalx("unexpected message");
}
imsg_free(&imsg);
@@ -684,8 +670,6 @@ client_dispatch_attached(void)
system(data);
client_write_server(MSG_UNLOCK, NULL, 0);
break;
- default:
- fatalx("unexpected message");
}
imsg_free(&imsg);
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 7a952e5..f78a89f 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -18,7 +18,11 @@
#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include "tmux.h"
@@ -30,21 +34,25 @@ enum cmd_retval cmd_attach_session_exec(struct cmd *,
struct cmd_q *);
const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach",
- "drt:", 0, 0,
- "[-dr] " CMD_TARGET_SESSION_USAGE,
+ "c:drt:", 0, 0,
+ "[-dr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER,
NULL,
cmd_attach_session_exec
};
enum cmd_retval
-cmd_attach_session(struct cmd_q *cmdq, const char* tflag, int dflag, int rflag)
+cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
+ const char *cflag)
{
- struct session *s;
- struct client *c;
- const char *update;
- char *cause;
- u_int i;
+ struct session *s;
+ struct client *c;
+ const char *update;
+ char *cause;
+ u_int i;
+ int fd;
+ struct format_tree *ft;
+ char *cp;
if (RB_EMPTY(&sessions)) {
cmdq_error(cmdq, "no sessions");
@@ -73,6 +81,27 @@ cmd_attach_session(struct cmd_q *cmdq, const char* tflag,
int dflag, int rflag)
}
}
+ if (cflag != NULL) {
+ ft = format_create();
+ if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
+ format_client(ft, c);
+ format_session(ft, s);
+ format_winlink(ft, s, s->curw);
+ format_window_pane(ft, s->curw->window->active);
+ cp = format_expand(ft, cflag);
+ format_free(ft);
+
+ fd = open(cp, O_RDONLY|O_DIRECTORY);
+ free(cp);
+ if (fd == -1) {
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
+ close(s->cwd);
+ s->cwd = fd;
+ }
+
cmdq->client->session = s;
notify_attached_session_changed(cmdq->client);
session_update_activity(s);
@@ -85,6 +114,27 @@ cmd_attach_session(struct cmd_q *cmdq, const char* tflag,
int dflag, int rflag)
return (CMD_RETURN_ERROR);
}
+ if (cflag != NULL) {
+ ft = format_create();
+ if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
+ format_client(ft, c);
+ format_session(ft, s);
+ format_winlink(ft, s, s->curw);
+ format_window_pane(ft, s->curw->window->active);
+ cp = format_expand(ft, cflag);
+ format_free(ft);
+
+ fd = open(cp, O_RDONLY|O_DIRECTORY);
+ free(cp);
+ if (fd == -1) {
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
+ close(s->cwd);
+ s->cwd = fd;
+ }
+
if (rflag)
cmdq->client->flags |= CLIENT_READONLY;
@@ -115,5 +165,5 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_q
*cmdq)
struct args *args = self->args;
return (cmd_attach_session(cmdq, args_get(args, 't'),
- args_has(args, 'd'), args_has(args, 'r')));
+ args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c')));
}
diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c
index 82b8f57..4acbab5 100644
--- a/cmd-load-buffer.c
+++ b/cmd-load-buffer.c
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -49,11 +50,11 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client;
struct session *s;
FILE *f;
- const char *path, *newpath, *wd;
+ const char *path;
char *pdata, *new_pdata, *cause;
size_t psize;
u_int limit;
- int ch, error, buffer, *buffer_ptr;
+ int ch, error, buffer, *buffer_ptr, cwd, fd;
if (!args_has(args, 'b'))
buffer = -1;
@@ -81,20 +82,17 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_WAIT);
}
- if (c != NULL)
- wd = c->cwd;
- else if ((s = cmd_current_session(cmdq, 0)) != NULL) {
- wd = options_get_string(&s->options, "default-path");
- if (*wd == '\0')
- wd = s->cwd;
- } else
- wd = NULL;
- if (wd != NULL && *wd != '\0') {
- newpath = get_full_path(wd, path);
- if (newpath != NULL)
- path = newpath;
- }
- if ((f = fopen(path, "rb")) == NULL) {
+ if (c != NULL && c->session == NULL)
+ cwd = c->cwd;
+ else if ((s = cmd_current_session(cmdq, 0)) != NULL)
+ cwd = s->cwd;
+ else
+ cwd = AT_FDCWD;
+
+ if ((fd = openat(cwd, path, O_RDONLY)) == -1 ||
+ (f = fdopen(fd, "rb")) == NULL) {
+ if (fd != -1)
+ close(fd);
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
return (CMD_RETURN_ERROR);
}
diff --git a/cmd-new-session.c b/cmd-new-session.c
index 38c79a6..3ce2439 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -18,6 +18,8 @@
#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
@@ -47,18 +49,15 @@ enum cmd_retval
cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
- struct client *c = cmdq->client;
+ struct client *c = cmdq->client, *c0;
struct session *s, *groupwith;
struct window *w;
struct environ env;
struct termios tio, *tiop;
- struct passwd *pw;
- const char *newname, *target, *update, *base, *cwd;
- const char *errstr, *template;
+ const char *newname, *target, *update, *errstr, *template;
char *cmd, *cause, *cp;
- int detached, idx;
+ int detached, already_attached, idx, cwd, fd = -1;
u_int sx, sy;
- int already_attached;
struct format_tree *ft;
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
@@ -75,7 +74,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (session_find(newname) != NULL) {
if (args_has(args, 'A')) {
return (cmd_attach_session(cmdq, newname,
- args_has(args, 'D'), 0));
+ args_has(args, 'D'), 0, NULL));
}
cmdq_error(cmdq, "duplicate session: %s", newname);
return (CMD_RETURN_ERROR);
@@ -100,6 +99,31 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (c != NULL && c->session != NULL)
already_attached = 1;
+ /* Get the new session working directory. */
+ if (args_has(args, 'c')) {
+ ft = format_create();
+ if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
+ format_client(ft, c0);
+ cp = format_expand(ft, args_get(args, 'c'));
+ format_free(ft);
+
+ fd = open(cp, O_RDONLY|O_DIRECTORY);
+ free(cp);
+ if (fd == -1) {
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
+ cwd = fd;
+ } else if (c->session == NULL)
+ cwd = c->cwd;
+ else if ((c0 = cmd_current_client(cmdq)) != NULL)
+ cwd = c0->session->cwd;
+ else {
+ fd = open(".", O_RDONLY);
+ cwd = fd;
+ }
+
/*
* Save the termios settings, part of which is used for new windows in
* this session.
@@ -121,26 +145,10 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (server_client_open(c, NULL, &cause) != 0) {
cmdq_error(cmdq, "open terminal failed: %s", cause);
free(cause);
- return (CMD_RETURN_ERROR);
+ goto error;
}
}
- /* Get the new session working directory. */
- if (c != NULL && c->cwd != NULL)
- base = c->cwd;
- else {
- pw = getpwuid(getuid());
- if (pw->pw_dir != NULL && *pw->pw_dir != '\0')
- base = pw->pw_dir;
- else
- base = "/";
- }
- if (args_has(args, 'c'))
- cwd = args_get(args, 'c');
- else
- cwd = options_get_string(&global_s_options, "default-path");
- cwd = cmd_default_path(base, base, cwd);
-
/* Find new session size. */
if (c != NULL) {
sx = c->tty.sx;
@@ -153,14 +161,14 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
sx = strtonum(args_get(args, 'x'), 1, USHRT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(cmdq, "width %s", errstr);
- return (CMD_RETURN_ERROR);
+ goto error;
}
}
if (detached && args_has(args, 'y')) {
sy = strtonum(args_get(args, 'y'), 1, USHRT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(cmdq, "height %s", errstr);
- return (CMD_RETURN_ERROR);
+ goto error;
}
}
if (sy > 0 && options_get_number(&global_s_options, "status"))
@@ -190,7 +198,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (s == NULL) {
cmdq_error(cmdq, "create session failed: %s", cause);
free(cause);
- return (CMD_RETURN_ERROR);
+ goto error;
}
environ_free(&env);
@@ -241,8 +249,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
template = NEW_SESSION_TEMPLATE;
ft = format_create();
- if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
- format_client(ft, c);
+ if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
+ format_client(ft, c0);
format_session(ft, s);
cp = format_expand(ft, template);
@@ -254,5 +262,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (!detached)
cmdq->client_exit = 0;
+
+ if (fd != -1)
+ close(fd);
return (CMD_RETURN_NORMAL);
+
+error:
+ if (fd != -1)
+ close(fd);
+ return (CMD_RETURN_ERROR);
}
diff --git a/cmd-new-window.c b/cmd-new-window.c
index e5658b3..f6a925b 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -18,7 +18,11 @@
#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include "tmux.h"
@@ -45,9 +49,9 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct session *s;
struct winlink *wl;
struct client *c;
- const char *cmd, *cwd, *template;
+ const char *cmd, *template;
char *cause, *cp;
- int idx, last, detached;
+ int idx, last, detached, cwd, fd = -1;
struct format_tree *ft;
if (args_has(args, 'a')) {
@@ -102,7 +106,29 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
cmd = options_get_string(&s->options, "default-command");
else
cmd = args->argv[0];
- cwd = cmdq_default_path(cmdq, args_get(args, 'c'));
+
+ if (args_has(args, 'c')) {
+ ft = format_create();
+ if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
+ format_client(ft, c);
+ format_session(ft, s);
+ format_winlink(ft, s, s->curw);
+ format_window_pane(ft, s->curw->window->active);
+ cp = format_expand(ft, args_get(args, 'c'));
+ format_free(ft);
+
+ fd = open(cp, O_RDONLY|O_DIRECTORY);
+ free(cp);
+ if (fd == -1) {
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
+ cwd = fd;
+ } else if (cmdq->client->session == NULL)
+ cwd = cmdq->client->cwd;
+ else
+ cwd = s->cwd;
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
@@ -110,7 +136,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (wl == NULL) {
cmdq_error(cmdq, "create window failed: %s", cause);
free(cause);
- return (CMD_RETURN_ERROR);
+ goto error;
}
if (!detached) {
session_select(s, wl->idx);
@@ -136,5 +162,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
format_free(ft);
}
+ if (fd != -1)
+ close(fd);
return (CMD_RETURN_NORMAL);
+
+error:
+ if (fd != -1)
+ close(fd);
+ return (CMD_RETURN_ERROR);
}
diff --git a/cmd-queue.c b/cmd-queue.c
index 7feb25e..c5905bd 100644
--- a/cmd-queue.c
+++ b/cmd-queue.c
@@ -283,27 +283,3 @@ cmdq_flush(struct cmd_q *cmdq)
}
cmdq->item = NULL;
}
-
-/* Get default path using command queue. */
-const char *
-cmdq_default_path(struct cmd_q *cmdq, const char *cwd)
-{
- struct client *c = cmdq->client;
- struct session *s;
- const char *current;
-
- if ((s = cmd_current_session(cmdq, 0)) == NULL)
- return (NULL);
-
- if (cwd == NULL)
- cwd = options_get_string(&s->options, "default-path");
-
- if (c != NULL && c->session == NULL && c->cwd != NULL)
- current = c->cwd;
- else if (s->curw != NULL)
- current = osdep_get_cwd(s->curw->window->active->fd);
- else
- current = NULL;
-
- return (cmd_default_path(s->cwd, current, cwd));
-}
diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c
index c6c5401..3788fc2 100644
--- a/cmd-save-buffer.c
+++ b/cmd-save-buffer.c
@@ -20,8 +20,10 @@
#include <sys/stat.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "tmux.h"
@@ -53,17 +55,14 @@ enum cmd_retval
cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
- struct client *c;
+ struct client *c = cmdq->client;
struct session *s;
struct paste_buffer *pb;
- const char *path, *newpath, *wd;
- char *cause, *start, *end;
- size_t size, used;
- int buffer;
- mode_t mask;
+ const char *path;
+ char *cause, *start, *end, *msg;
+ size_t size, used, msglen;
+ int cwd, fd, buffer;
FILE *f;
- char *msg;
- size_t msglen;
if (!args_has(args, 'b')) {
if ((pb = paste_get_top(&global_buffers)) == NULL) {
@@ -90,7 +89,6 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
else
path = args->argv[0];
if (strcmp(path, "-") == 0) {
- c = cmdq->client;
if (c == NULL) {
cmdq_error(cmdq, "can't write to stdout");
return (CMD_RETURN_ERROR);
@@ -100,28 +98,26 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
goto do_print;
}
- c = cmdq->client;
- if (c != NULL)
- wd = c->cwd;
- else if ((s = cmd_current_session(cmdq, 0)) != NULL) {
- wd = options_get_string(&s->options, "default-path");
- if (*wd == '\0')
- wd = s->cwd;
- } else
- wd = NULL;
- if (wd != NULL && *wd != '\0') {
- newpath = get_full_path(wd, path);
- if (newpath != NULL)
- path = newpath;
- }
-
- mask = umask(S_IRWXG | S_IRWXO);
- if (args_has(self->args, 'a'))
- f = fopen(path, "ab");
+ if (c != NULL && c->session == NULL)
+ cwd = c->cwd;
+ else if ((s = cmd_current_session(cmdq, 0)) != NULL)
+ cwd = s->cwd;
else
- f = fopen(path, "wb");
- umask(mask);
+ cwd = AT_FDCWD;
+
+ f = NULL;
+ if (args_has(self->args, 'a')) {
+ fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600);
+ if (fd != -1)
+ f = fdopen(fd, "ab");
+ } else {
+ fd = openat(cwd, path, O_CREAT|O_RDWR, 0600);
+ if (fd != -1)
+ f = fdopen(fd, "wb");
+ }
if (f == NULL) {
+ if (fd != -1)
+ close(fd);
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
return (CMD_RETURN_ERROR);
}
diff --git a/cmd-split-window.c b/cmd-split-window.c
index a240325..ef1d3cb 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -18,7 +18,10 @@
#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "tmux.h"
@@ -57,16 +60,14 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window *w;
struct window_pane *wp, *new_wp = NULL;
struct environ env;
- const char *cmd, *cwd, *shell;
- char *cause, *new_cause;
+ const char *cmd, *shell, *template;
+ char *cause, *new_cause, *cp;
u_int hlimit;
- int size, percentage;
+ int size, percentage, cwd, fd = -1;
enum layout_type type;
struct layout_cell *lc;
- const char *template;
struct client *c;
struct format_tree *ft;
- char *cp;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
@@ -82,7 +83,29 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
cmd = options_get_string(&s->options, "default-command");
else
cmd = args->argv[0];
- cwd = cmdq_default_path(cmdq, args_get(args, 'c'));
+
+ if (args_has(args, 'c')) {
+ ft = format_create();
+ if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
+ format_client(ft, c);
+ format_session(ft, s);
+ format_winlink(ft, s, s->curw);
+ format_window_pane(ft, s->curw->window->active);
+ cp = format_expand(ft, args_get(args, 'c'));
+ format_free(ft);
+
+ fd = open(cp, O_RDONLY|O_DIRECTORY);
+ free(cp);
+ if (fd == -1) {
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
+ cwd = fd;
+ } else if (cmdq->client->session == NULL)
+ cwd = cmdq->client->cwd;
+ else
+ cwd = s->cwd;
type = LAYOUT_TOPBOTTOM;
if (args_has(args, 'h'))
@@ -155,6 +178,9 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
format_free(ft);
}
notify_window_layout_changed(w);
+
+ if (fd != -1)
+ close(fd);
return (CMD_RETURN_NORMAL);
error:
@@ -163,5 +189,7 @@ error:
window_remove_pane(w, new_wp);
cmdq_error(cmdq, "create pane failed: %s", cause);
free(cause);
+ if (fd != -1)
+ close(fd);
return (CMD_RETURN_ERROR);
}
diff --git a/format.c b/format.c
index ba4b95b..a7f1fde 100644
--- a/format.c
+++ b/format.c
@@ -403,7 +403,6 @@ format_client(struct format_tree *ft, struct client *c)
time_t t;
struct session *s;
- format_add(ft, "client_cwd", "%s", c->cwd);
format_add(ft, "client_height", "%u", c->tty.sy);
format_add(ft, "client_width", "%u", c->tty.sx);
if (c->tty.path != NULL)
@@ -552,8 +551,6 @@ format_window_pane(struct format_tree *ft, struct
window_pane *wp)
format_add(ft, "pane_pid", "%ld", (long) wp->pid);
if (wp->cmd != NULL)
format_add(ft, "pane_start_command", "%s", wp->cmd);
- if (wp->cwd != NULL)
- format_add(ft, "pane_start_path", "%s", wp->cwd);
if ((cwd = osdep_get_cwd(wp->fd)) != NULL)
format_add(ft, "pane_current_path", "%s", cwd);
if ((cmd = format_get_command(wp)) != NULL) {
diff --git a/options-table.c b/options-table.c
index f6a1547..5da095b 100644
--- a/options-table.c
+++ b/options-table.c
@@ -125,11 +125,6 @@ const struct options_table_entry session_options_table[] =
{
.default_str = ""
},
- { .name = "default-path",
- .type = OPTIONS_TABLE_STRING,
- .default_str = ""
- },
-
{ .name = "default-shell",
.type = OPTIONS_TABLE_STRING,
.default_str = _PATH_BSHELL
diff --git a/server-client.c b/server-client.c
index 11f1937..8a99367 100644
--- a/server-client.c
+++ b/server-client.c
@@ -41,8 +41,7 @@ int server_client_assume_paste(struct session *);
int server_client_msg_dispatch(struct client *);
void server_client_msg_command(struct client *, struct imsg *);
-void server_client_msg_identify(
- struct client *, struct msg_identify_data *, int);
+void server_client_msg_identify(struct client *, struct imsg *);
void server_client_msg_shell(struct client *);
/* Create a new client. */
@@ -151,6 +150,8 @@ server_client_lost(struct client *c)
*/
if (c->flags & CLIENT_TERMINAL)
tty_free(&c->tty);
+ free(c->ttyname);
+ free(c->term);
evbuffer_free (c->stdin_data);
evbuffer_free (c->stdout_data);
@@ -162,6 +163,7 @@ server_client_lost(struct client *c)
screen_free(&c->status);
free(c->title);
+ close(c->cwd);
evtimer_del(&c->repeat_timer);
@@ -179,7 +181,6 @@ server_client_lost(struct client *c)
free(c->prompt_string);
free(c->prompt_buffer);
- free(c->cwd);
c->cmdq->dead = 1;
cmdq_free(c->cmdq);
@@ -786,8 +787,6 @@ int
server_client_msg_dispatch(struct client *c)
{
struct imsg imsg;
- struct msg_identify_data identifydata;
- struct msg_environ_data environdata;
struct msg_stdin_data stdindata;
const char *data;
ssize_t n, datalen;
@@ -813,14 +812,14 @@ server_client_msg_dispatch(struct client *c)
log_debug("got %d from client %d", imsg.hdr.type, c->ibuf.fd);
switch (imsg.hdr.type) {
- case MSG_IDENTIFY:
- if (datalen != sizeof identifydata)
- fatalx("bad MSG_IDENTIFY size");
- memcpy(&identifydata, imsg.data, sizeof identifydata);
-#ifdef __CYGWIN__
- imsg.fd = open(identifydata.ttyname, O_RDWR|O_NOCTTY);
-#endif
- server_client_msg_identify(c, &identifydata, imsg.fd);
+ case MSG_IDENTIFY_FLAGS:
+ case MSG_IDENTIFY_TERM:
+ case MSG_IDENTIFY_TTYNAME:
+ case MSG_IDENTIFY_CWD:
+ case MSG_IDENTIFY_STDIN:
+ case MSG_IDENTIFY_ENVIRON:
+ case MSG_IDENTIFY_DONE:
+ server_client_msg_identify(c, &imsg);
break;
case MSG_COMMAND:
server_client_msg_command(c, &imsg);
@@ -878,23 +877,12 @@ server_client_msg_dispatch(struct client *c)
server_redraw_client(c);
recalculate_sizes();
break;
- case MSG_ENVIRON:
- if (datalen != sizeof environdata)
- fatalx("bad MSG_ENVIRON size");
- memcpy(&environdata, imsg.data, sizeof environdata);
-
- environdata.var[(sizeof environdata.var) - 1] = '\0';
- if (strchr(environdata.var, '=') != NULL)
- environ_put(&c->environ, environdata.var);
- break;
case MSG_SHELL:
if (datalen != 0)
fatalx("bad MSG_SHELL size");
server_client_msg_shell(c);
break;
- default:
- fatalx("unexpected message");
}
imsg_free(&imsg);
@@ -953,46 +941,99 @@ error:
/* Handle identify message. */
void
-server_client_msg_identify(
- struct client *c, struct msg_identify_data *data, int fd)
+server_client_msg_identify(struct client *c, struct imsg *imsg)
{
- c->cwd = NULL;
- data->cwd[(sizeof data->cwd) - 1] = '\0';
- if (*data->cwd != '\0')
- c->cwd = xstrdup(data->cwd);
+ const char *data;
+ size_t datalen;
+ int flags;
+
+ if (c->flags & CLIENT_IDENTIFIED)
+ fatalx("out-of-order identify message");
+
+ data = imsg->data;
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
+
+ switch (imsg->hdr.type) {
+ case MSG_IDENTIFY_FLAGS:
+ if (datalen != sizeof flags)
+ fatalx("bad MSG_IDENTIFY_FLAGS size");
+ memcpy(&flags, data, sizeof flags);
+ c->flags |= flags;
+ break;
+ case MSG_IDENTIFY_TERM:
+ if (data[datalen - 1] != '\0')
+ fatalx("bad MSG_IDENTIFY_TERM string");
+ c->term = xstrdup(data);
+ break;
+ case MSG_IDENTIFY_TTYNAME:
+ if (data[datalen - 1] != '\0')
+ fatalx("bad MSG_IDENTIFY_TTYNAME string");
+ c->ttyname = xstrdup(data);
+ break;
+ case MSG_IDENTIFY_CWD:
+ if (datalen != 0)
+ fatalx("bad MSG_IDENTIFY_CWD size");
+ c->cwd = imsg->fd;
+ break;
+ case MSG_IDENTIFY_STDIN:
+ if (datalen != 0)
+ fatalx("bad MSG_IDENTIFY_STDIN size");
+ c->fd = imsg->fd;
+ break;
+ case MSG_IDENTIFY_ENVIRON:
+ if (data[datalen - 1] != '\0')
+ fatalx("bad MSG_IDENTIFY_ENVIRON string");
+ if (strchr(data, '=') != NULL)
+ environ_put(&c->environ, data);
+ break;
+ default:
+ break;
+ }
+
+ if (imsg->hdr.type != MSG_IDENTIFY_DONE)
+ return;
+ c->flags |= CLIENT_IDENTIFIED;
- if (data->flags & CLIENT_CONTROL) {
+#ifdef __CYGWIN__
+ c->fd = open(c->ttyname, O_RDWR|O_NOCTTY);
+ c->cwd = open(".", O_RDONLY);
+#endif
+
+ if (c->flags & CLIENT_CONTROL) {
c->stdin_callback = control_callback;
+
evbuffer_free(c->stderr_data);
c->stderr_data = c->stdout_data;
- c->flags |= CLIENT_CONTROL;
- if (data->flags & CLIENT_CONTROLCONTROL)
+
+ if (c->flags & CLIENT_CONTROLCONTROL)
evbuffer_add_printf(c->stdout_data, "\033P1000p");
server_write_client(c, MSG_STDIN, NULL, 0);
c->tty.fd = -1;
c->tty.log_fd = -1;
- close(fd);
+ close(c->fd);
+ c->fd = -1;
+
return;
}
- if (fd == -1)
+ if (c->fd == -1)
return;
- if (!isatty(fd)) {
- close(fd);
+ if (!isatty(c->fd)) {
+ close(c->fd);
+ c->fd = -1;
return;
}
- data->term[(sizeof data->term) - 1] = '\0';
- tty_init(&c->tty, c, fd, data->term);
- if (data->flags & CLIENT_UTF8)
+ tty_init(&c->tty, c, c->fd, c->term);
+ if (c->flags & CLIENT_UTF8)
c->tty.flags |= TTY_UTF8;
- if (data->flags & CLIENT_256COLOURS)
+ if (c->flags & CLIENT_256COLOURS)
c->tty.term_flags |= TERM_256COLOURS;
tty_resize(&c->tty);
- if (!(data->flags & CLIENT_CONTROL))
+ if (!(c->flags & CLIENT_CONTROL))
c->flags |= CLIENT_TERMINAL;
}
diff --git a/server-fn.c b/server-fn.c
index 1b49985..4fc4eb5 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -56,8 +56,8 @@ server_write_ready(struct client *c)
}
int
-server_write_client(
- struct client *c, enum msgtype type, const void *buf, size_t len)
+server_write_client(struct client *c, enum msgtype type, const void *buf,
+ size_t len)
{
struct imsgbuf *ibuf = &c->ibuf;
int error;
@@ -73,8 +73,8 @@ server_write_client(
}
void
-server_write_session(
- struct session *s, enum msgtype type, const void *buf, size_t len)
+server_write_session(struct session *s, enum msgtype type, const void *buf,
+ size_t len)
{
struct client *c;
u_int i;
diff --git a/session.c b/session.c
index bb742d8..66a52bc 100644
--- a/session.c
+++ b/session.c
@@ -84,9 +84,8 @@ session_find_by_id(u_int id)
/* Create a new session. */
struct session *
-session_create(const char *name, const char *cmd, const char *cwd,
- struct environ *env, struct termios *tio, int idx, u_int sx, u_int sy,
- char **cause)
+session_create(const char *name, const char *cmd, int cwd, struct environ *env,
+ struct termios *tio, int idx, u_int sx, u_int sy, char **cause)
{
struct session *s;
@@ -98,7 +97,7 @@ session_create(const char *name, const char *cmd, const char
*cwd,
fatal("gettimeofday failed");
session_update_activity(s);
- s->cwd = xstrdup(cwd);
+ s->cwd = dup(cwd);
s->curw = NULL;
TAILQ_INIT(&s->lastw);
@@ -170,7 +169,7 @@ session_destroy(struct session *s)
winlink_remove(&s->windows, wl);
}
- free(s->cwd);
+ close(s->cwd);
RB_INSERT(sessions, &dead_sessions, s);
}
@@ -226,8 +225,8 @@ session_previous_session(struct session *s)
/* Create a new window on a session. */
struct winlink *
-session_new(struct session *s,
- const char *name, const char *cmd, const char *cwd, int idx, char **cause)
+session_new(struct session *s, const char *name, const char *cmd, int cwd,
+ int idx, char **cause)
{
struct window *w;
struct winlink *wl;
@@ -250,8 +249,8 @@ session_new(struct session *s,
shell = _PATH_BSHELL;
hlimit = options_get_number(&s->options, "history-limit");
- w = window_create(
- name, cmd, shell, cwd, &env, s->tio, s->sx, s->sy, hlimit, cause);
+ w = window_create(name, cmd, shell, cwd, &env, s->tio, s->sx, s->sy,
+ hlimit, cause);
if (w == NULL) {
winlink_remove(&s->windows, wl);
environ_free(&env);
diff --git a/tmux.1 b/tmux.1
index ba5fe18..07eb93f 100644
--- a/tmux.1
+++ b/tmux.1
@@ -568,6 +568,7 @@ The following commands are available to manage clients and
sessions:
.Bl -tag -width Ds
.It Xo Ic attach-session
.Op Fl dr
+.Op Fl c Ar working-directory
.Op Fl t Ar target-session
.Xc
.D1 (alias: Ic attach )
@@ -601,6 +602,10 @@ needs to select the most recently used session, it will
prefer the most
recently used
.Em unattached
session.
+.Pp
+.Fl c
+will set the session working directory (used for new windows) to
+.Ar working-directory .
.It Xo Ic detach-client
.Op Fl P
.Op Fl a
@@ -1513,13 +1518,6 @@ is not specified, the value of the
option is used.
.Fl c
specifies the working directory in which the new window is created.
-It may have an absolute path or one of the following values (or a
subdirectory):
-.Bl -column "XXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXX" -offset indent
-.It Li "Empty string" Ta "Current pane's directory"
-.It Li "~" Ta "User's home directory"
-.It Li "-" Ta "Where session was started"
-.It Li "." Ta "Where server was started"
-.El
.Pp
When the shell command completes, the window closes.
See the
@@ -2179,15 +2177,6 @@ The default is an empty string, which instructs
to create a login shell using the value of the
.Ic default-shell
option.
-.It Ic default-path Ar path
-Set the default working directory for new panes.
-If empty (the default), the working directory is determined from the process
-running in the active pane, from the command line environment or from the
-working directory where the session was created.
-Otherwise the same options are available as for the
-.Fl c
-flag to
-.Ic new-window .
.It Ic default-shell Ar path
Specify the default shell.
This is used as the login shell for new windows when the
@@ -3056,7 +3045,6 @@ The following variables are available, where appropriate:
.It Li "client_activity_string" Ta "" Ta "String time client last had activity"
.It Li "client_created" Ta "" Ta "Integer time client created"
.It Li "client_created_string" Ta "" Ta "String time client created"
-.It Li "client_cwd" Ta "" Ta "Working directory of client"
.It Li "client_height" Ta "" Ta "Height of client"
.It Li "client_last_session" Ta "" Ta "Name of the client's last session"
.It Li "client_prefix" Ta "" Ta "1 if prefix key has been pressed"
diff --git a/tmux.c b/tmux.c
index 76b09cf..a035996 100644
--- a/tmux.c
+++ b/tmux.c
@@ -127,30 +127,6 @@ areshell(const char *shell)
return (0);
}
-const char *
-get_full_path(const char *wd, const char *path)
-{
- int fd;
- static char newpath[MAXPATHLEN];
- const char *retval;
-
- fd = open(".", O_RDONLY);
- if (fd == -1)
- return (NULL);
-
- retval = NULL;
- if (chdir(wd) == 0) {
- if (realpath(path, newpath) == 0)
- retval = newpath;
- }
-
- if (fchdir(fd) != 0)
- chdir("/");
- close(fd);
-
- return (retval);
-}
-
void
parseenvironment(void)
{
@@ -249,7 +225,7 @@ int
main(int argc, char **argv)
{
struct passwd *pw;
- char *s, *path, *label, *home, **var;
+ char *s, *path, *label, *home, **var, tmp[MAXPATHLEN];
int opt, flags, quiet, keys;
#if defined(DEBUG) && defined(__OpenBSD__)
@@ -333,6 +309,8 @@ main(int argc, char **argv)
environ_init(&global_environ);
for (var = environ; *var != NULL; var++)
environ_put(&global_environ, *var);
+ if (getcwd(tmp, sizeof tmp) != NULL)
+ environ_set(&global_environ, "PWD", tmp);
options_init(&global_options, NULL);
options_table_populate_tree(server_options_table, &global_options);
diff --git a/tmux.h b/tmux.h
index 5e6de25..a76d102 100644
--- a/tmux.h
+++ b/tmux.h
@@ -52,13 +52,6 @@ extern char **environ;
#define NAME_INTERVAL 500
/*
- * Maximum sizes of strings in message data. Don't forget to bump
- * PROTOCOL_VERSION if any of these change!
- */
-#define TERMINAL_LENGTH 128 /* length of TERM environment variable */
-#define ENVIRON_LENGTH 1024 /* environment variable length */
-
-/*
* UTF-8 data size. This must be big enough to hold combined characters as well
* as single.
*/
@@ -456,9 +449,6 @@ enum msgtype {
MSG_SUSPEND,
MSG_UNLOCK,
MSG_WAKEUP,
-
- MSG_IDENTIFY = 300,
- MSG_ENVIRON
};
/*
@@ -473,21 +463,6 @@ struct msg_command_data {
int argc;
}; /* followed by packed argv */
-struct msg_identify_data {
- char cwd[MAXPATHLEN];
- char term[TERMINAL_LENGTH];
-
-#ifdef __CYGWIN__
- char ttyname[TTY_NAME_MAX];
-#endif
-
- int flags;
-};
-
-struct msg_environ_data {
- char var[ENVIRON_LENGTH];
-};
-
struct msg_stdin_data {
ssize_t size;
char data[BUFSIZ];
@@ -934,7 +909,7 @@ struct window_pane {
char *cmd;
char *shell;
- char *cwd;
+ int cwd;
pid_t pid;
char tty[TTY_NAME_MAX];
@@ -1081,7 +1056,7 @@ struct session {
u_int id;
char *name;
- char *cwd;
+ int cwd;
struct timeval creation_time;
struct timeval activity_time;
@@ -1281,6 +1256,7 @@ RB_HEAD(status_out_tree, status_out);
struct client {
struct imsgbuf ibuf;
+ int fd;
struct event event;
int retval;
@@ -1290,8 +1266,10 @@ struct client {
struct environ environ;
char *title;
- char *cwd;
+ int cwd;
+ char *term;
+ char *ttyname;
struct tty tty;
void (*stdin_callback)(struct client *, int, void *);
@@ -1524,7 +1502,6 @@ void logfile(const char *);
const char *getshell(void);
int checkshell(const char *);
int areshell(const char *);
-const char* get_full_path(const char *, const char *);
void setblocking(int, int);
__dead void shell_exec(const char *, const char *);
@@ -1760,7 +1737,6 @@ int cmd_find_index(struct cmd_q *, const
char *,
struct winlink *cmd_find_pane(struct cmd_q *, const char *, struct session **,
struct window_pane **);
char *cmd_template_replace(const char *, const char *, int);
-const char *cmd_default_path(const char *, const char *, const
char *);
extern const struct cmd_entry *cmd_table[];
extern const struct cmd_entry cmd_attach_session_entry;
extern const struct cmd_entry cmd_bind_key_entry;
@@ -1851,7 +1827,8 @@ extern const struct cmd_entry cmd_up_pane_entry;
extern const struct cmd_entry cmd_wait_for_entry;
/* cmd-attach-session.c */
-enum cmd_retval cmd_attach_session(struct cmd_q *, const char*, int,
int);
+enum cmd_retval cmd_attach_session(struct cmd_q *, const char *, int,
int,
+ const char *);
/* cmd-list.c */
struct cmd_list *cmd_list_parse(int, char **, const char *, u_int, char
**);
@@ -1869,7 +1846,6 @@ void cmdq_run(struct cmd_q *, struct
cmd_list *);
void cmdq_append(struct cmd_q *, struct cmd_list *);
int cmdq_continue(struct cmd_q *);
void cmdq_flush(struct cmd_q *);
-const char *cmdq_default_path(struct cmd_q *, const char *);
/* cmd-string.c */
int cmd_string_parse(const char *, struct cmd_list **, const char *,
@@ -2141,9 +2117,9 @@ void winlink_stack_remove(struct
winlink_stack *, struct winlink *);
int window_index(struct window *, u_int *);
struct window *window_find_by_id(u_int);
struct window *window_create1(u_int, u_int);
-struct window *window_create(const char *, const char *, const char *,
- const char *, struct environ *, struct termios *,
- u_int, u_int, u_int, char **);
+struct window *window_create(const char *, const char *, const char *, int,
+ struct environ *, struct termios *, u_int, u_int, u_int,
+ char **);
void window_destroy(struct window *);
struct window_pane *window_get_active_at(struct window *, u_int, u_int);
void window_set_active_at(struct window *, u_int, u_int);
@@ -2167,8 +2143,8 @@ struct window_pane *window_pane_create(struct window *,
u_int, u_int, u_int);
void window_pane_destroy(struct window_pane *);
void window_pane_timer_start(struct window_pane *);
int window_pane_spawn(struct window_pane *, const char *,
- const char *, const char *, struct environ *,
- struct termios *, char **);
+ const char *, int, struct environ *, struct termios *,
+ char **);
void window_pane_resize(struct window_pane *, u_int, u_int);
void window_pane_alternate_on(struct window_pane *,
struct grid_cell *, int);
@@ -2304,7 +2280,7 @@ RB_PROTOTYPE(sessions, session, entry, session_cmp);
int session_alive(struct session *);
struct session *session_find(const char *);
struct session *session_find_by_id(u_int);
-struct session *session_create(const char *, const char *, const char *,
+struct session *session_create(const char *, const char *, int,
struct environ *, struct termios *, int, u_int, u_int,
char **);
void session_destroy(struct session *);
@@ -2312,8 +2288,8 @@ int session_check_name(const char *);
void session_update_activity(struct session *);
struct session *session_next_session(struct session *);
struct session *session_previous_session(struct session *);
-struct winlink *session_new(struct session *,
- const char *, const char *, const char *, int, char **);
+struct winlink *session_new(struct session *, const char *, const char *, int,
+ int, char **);
struct winlink *session_attach(
struct session *, struct window *, int, char **);
int session_detach(struct session *, struct winlink *);
diff --git a/window.c b/window.c
index 7912bd3..9f47f44 100644
--- a/window.c
+++ b/window.c
@@ -306,7 +306,7 @@ window_create1(u_int sx, u_int sy)
struct window *
window_create(const char *name, const char *cmd, const char *shell,
- const char *cwd, struct environ *env, struct termios *tio,
+ int cwd, struct environ *env, struct termios *tio,
u_int sx, u_int sy, u_int hlimit, char **cause)
{
struct window *w;
@@ -672,7 +672,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy,
u_int hlimit)
wp->cmd = NULL;
wp->shell = NULL;
- wp->cwd = NULL;
+ wp->cwd = -1;
wp->fd = -1;
wp->event = NULL;
@@ -727,7 +727,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
- free(wp->cwd);
+ close(wp->cwd);
free(wp->shell);
free(wp->cmd);
free(wp);
@@ -735,7 +735,7 @@ window_pane_destroy(struct window_pane *wp)
int
window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
- const char *cwd, struct environ *env, struct termios *tio, char **cause)
+ int cwd, struct environ *env, struct termios *tio, char **cause)
{
struct winsize ws;
char *argv0, paneid[16];
@@ -754,9 +754,9 @@ window_pane_spawn(struct window_pane *wp, const char *cmd,
const char *shell,
free(wp->shell);
wp->shell = xstrdup(shell);
}
- if (cwd != NULL) {
- free(wp->cwd);
- wp->cwd = xstrdup(cwd);
+ if (cwd != -1) {
+ close(wp->cwd);
+ wp->cwd = dup(cwd);
}
log_debug("spawn: %s -- %s", wp->shell, wp->cmd);
@@ -771,7 +771,7 @@ window_pane_spawn(struct window_pane *wp, const char *cmd,
const char *shell,
xasprintf(cause, "%s: %s", cmd, strerror(errno));
return (-1);
case 0:
- if (chdir(wp->cwd) != 0)
+ if (fchdir(wp->cwd) != 0)
chdir("/");
if (tcgetattr(STDIN_FILENO, &tio2) != 0)
-----------------------------------------------------------------------
Summary of changes:
client.c | 60 +++++++++---------------
cmd-attach-session.c | 68 +++++++++++++++++++++++----
cmd-load-buffer.c | 30 ++++++------
cmd-new-session.c | 74 ++++++++++++++++++------------
cmd-new-window.c | 41 +++++++++++++++--
cmd-queue.c | 24 ----------
cmd-save-buffer.c | 54 ++++++++++------------
cmd-split-window.c | 40 ++++++++++++++--
format.c | 3 -
options-table.c | 5 --
server-client.c | 125 +++++++++++++++++++++++++++++++++-----------------
server-fn.c | 8 ++--
session.c | 17 +++----
tmux.1 | 22 ++-------
tmux.c | 28 +----------
tmux.h | 56 ++++++----------------
window.c | 16 +++---
17 files changed, 363 insertions(+), 308 deletions(-)
hooks/post-receive
--
tmux
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs