summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2015-10-31 08:13:59 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2015-10-31 08:13:59 +0000
commit7e717b7c0bef4ea6f45816300dc8583a6e824290 (patch)
tree8e69b8b95496ce2a63ea8730df19d85dba84c775 /usr.bin
parent902466cba774a7c9c6d5cdd965302db1e4c04b0a (diff)
Because pledge(2) does not allow us to pass directory file descriptors
around, we can't use file descriptors for the working directory because we will be unable to pass it to a privileged process to tell it where to read or write files or spawn children. So move tmux back to using strings for the current working directory. We try to check it exists with access() when it is set but ultimately fall back to ~ if it fails at time of use (or / if that fails too).
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/tmux/client.c8
-rw-r--r--usr.bin/tmux/cmd-attach-session.c16
-rw-r--r--usr.bin/tmux/cmd-if-shell.c6
-rw-r--r--usr.bin/tmux/cmd-load-buffer.c25
-rw-r--r--usr.bin/tmux/cmd-new-session.c41
-rw-r--r--usr.bin/tmux/cmd-new-window.c34
-rw-r--r--usr.bin/tmux/cmd-respawn-pane.c4
-rw-r--r--usr.bin/tmux/cmd-respawn-window.c4
-rw-r--r--usr.bin/tmux/cmd-run-shell.c6
-rw-r--r--usr.bin/tmux/cmd-save-buffer.c37
-rw-r--r--usr.bin/tmux/cmd-split-window.c35
-rw-r--r--usr.bin/tmux/format.c4
-rw-r--r--usr.bin/tmux/job.c11
-rw-r--r--usr.bin/tmux/server-client.c16
-rw-r--r--usr.bin/tmux/session.c12
-rw-r--r--usr.bin/tmux/tmux.h22
-rw-r--r--usr.bin/tmux/window-copy.c4
-rw-r--r--usr.bin/tmux/window.c26
18 files changed, 154 insertions, 157 deletions
diff --git a/usr.bin/tmux/client.c b/usr.bin/tmux/client.c
index 2376206d7d8..75028301486 100644
--- a/usr.bin/tmux/client.c
+++ b/usr.bin/tmux/client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: client.c,v 1.101 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: client.c,v 1.102 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -273,8 +273,10 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL);
/* Save these before pledge(). */
- if ((cwd = getcwd(path, sizeof path)) == NULL)
- cwd = "/";
+ if ((cwd = getcwd(path, sizeof path)) == NULL) {
+ if ((cwd = find_home()) == NULL)
+ cwd = "/";
+ }
if ((ttynam = ttyname(STDIN_FILENO)) == NULL)
ttynam = "";
diff --git a/usr.bin/tmux/cmd-attach-session.c b/usr.bin/tmux/cmd-attach-session.c
index 94e337686ad..093c2b7e649 100644
--- a/usr.bin/tmux/cmd-attach-session.c
+++ b/usr.bin/tmux/cmd-attach-session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-attach-session.c,v 1.45 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: cmd-attach-session.c,v 1.46 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -51,9 +51,8 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
struct window_pane *wp = NULL;
const char *update;
char *cause;
- int fd;
struct format_tree *ft;
- char *cp;
+ char *cwd;
if (RB_EMPTY(&sessions)) {
cmdq_error(cmdq, "no sessions");
@@ -97,18 +96,17 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s,
NULL, NULL);
- cp = format_expand(ft, cflag);
+ cwd = format_expand(ft, cflag);
format_free(ft);
- fd = open(cp, O_RDONLY|O_DIRECTORY);
- free(cp);
- if (fd == -1) {
+ if (access(cwd, X_OK) != 0) {
+ free((void *)cwd);
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
- close(s->cwd);
- s->cwd = fd;
+ free((void *)s->cwd);
+ s->cwd = cwd;
}
if (c->session != NULL) {
diff --git a/usr.bin/tmux/cmd-if-shell.c b/usr.bin/tmux/cmd-if-shell.c
index fdac5bd188e..2154afafce6 100644
--- a/usr.bin/tmux/cmd-if-shell.c
+++ b/usr.bin/tmux/cmd-if-shell.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-if-shell.c,v 1.33 2015/09/16 22:24:54 nicm Exp $ */
+/* $OpenBSD: cmd-if-shell.c,v 1.34 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -66,7 +66,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
struct winlink *wl = NULL;
struct window_pane *wp = NULL;
struct format_tree *ft;
- int cwd;
+ const char *cwd;
if (args_has(args, 't')) {
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
@@ -83,7 +83,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
else if (s != NULL)
cwd = s->cwd;
else
- cwd = -1;
+ cwd = NULL;
}
ft = format_create();
diff --git a/usr.bin/tmux/cmd-load-buffer.c b/usr.bin/tmux/cmd-load-buffer.c
index f8b56c4a4e0..39637013bfe 100644
--- a/usr.bin/tmux/cmd-load-buffer.c
+++ b/usr.bin/tmux/cmd-load-buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-load-buffer.c,v 1.34 2015/06/05 18:06:30 nicm Exp $ */
+/* $OpenBSD: cmd-load-buffer.c,v 1.35 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -49,10 +49,10 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client;
struct session *s;
FILE *f;
- const char *path, *bufname;
- char *pdata, *new_pdata, *cause;
+ const char *path, *bufname, *cwd;
+ char *pdata, *new_pdata, *cause, *file, resolved[PATH_MAX];
size_t psize;
- int ch, error, cwd, fd;
+ int ch, error;
bufname = NULL;
if (args_has(args, 'b'))
@@ -75,13 +75,16 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
else if ((s = cmd_find_current(cmdq)) != NULL)
cwd = s->cwd;
else
- cwd = AT_FDCWD;
+ cwd = ".";
- 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));
+ xasprintf(&file, "%s/%s", cwd, path);
+ if (realpath(file, resolved) == NULL)
+ f = NULL;
+ else
+ f = fopen(resolved, "rb");
+ free(file);
+ if (f == NULL) {
+ cmdq_error(cmdq, "%s: %s", resolved, strerror(errno));
return (CMD_RETURN_ERROR);
}
@@ -97,7 +100,7 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
pdata[psize++] = ch;
}
if (ferror(f)) {
- cmdq_error(cmdq, "%s: read error", path);
+ cmdq_error(cmdq, "%s: read error", resolved);
goto error;
}
if (pdata != NULL)
diff --git a/usr.bin/tmux/cmd-new-session.c b/usr.bin/tmux/cmd-new-session.c
index 9b194cc8e2a..6ca91bd404e 100644
--- a/usr.bin/tmux/cmd-new-session.c
+++ b/usr.bin/tmux/cmd-new-session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-new-session.c,v 1.75 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: cmd-new-session.c,v 1.76 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,10 +63,9 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
struct environ *env;
struct termios tio, *tiop;
const char *newname, *target, *update, *errstr, *template;
- const char *path;
+ const char *path, *cwd, *to_free;
char **argv, *cmd, *cause, *cp;
- int detached, already_attached, idx, cwd, fd = -1;
- int argc;
+ int detached, already_attached, idx, argc;
u_int sx, sy;
struct format_tree *ft;
struct environ_entry *envent;
@@ -118,32 +117,26 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
already_attached = 1;
/* Get the new session working directory. */
+ to_free = NULL;
if (args_has(args, 'c')) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL,
NULL);
- cp = format_expand(ft, args_get(args, 'c'));
+ to_free = cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft);
- if (cp != NULL && *cp != '\0') {
- 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);
- }
- } else
- free(cp);
- cwd = fd;
+ if (access(cwd, X_OK) != 0) {
+ free((void *)cwd);
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
} else if (c != NULL && c->session == NULL)
cwd = c->cwd;
else if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
cwd = c0->session->cwd;
- else {
- fd = open(".", O_RDONLY);
- cwd = fd;
- }
+ else
+ cwd = ".";
/*
* If this is a new client, check for nesting and save the termios
@@ -311,12 +304,12 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (!detached)
cmdq->client_exit = 0;
- if (fd != -1)
- close(fd);
+ if (to_free != NULL)
+ free((void *)to_free);
return (CMD_RETURN_NORMAL);
error:
- if (fd != -1)
- close(fd);
+ if (to_free != NULL)
+ free((void *)to_free);
return (CMD_RETURN_ERROR);
}
diff --git a/usr.bin/tmux/cmd-new-window.c b/usr.bin/tmux/cmd-new-window.c
index 2553330c045..5762ba95473 100644
--- a/usr.bin/tmux/cmd-new-window.c
+++ b/usr.bin/tmux/cmd-new-window.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-new-window.c,v 1.49 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: cmd-new-window.c,v 1.50 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -49,9 +49,9 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct args *args = self->args;
struct session *s;
struct winlink *wl;
- const char *cmd, *path, *template;
+ const char *cmd, *path, *template, *cwd, *to_free;
char **argv, *cause, *cp;
- int argc, idx, detached, cwd, fd = -1;
+ int argc, idx, detached;
struct format_tree *ft;
struct environ_entry *envent;
@@ -92,24 +92,20 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (envent != NULL)
path = envent->value;
+ to_free = NULL;
if (args_has(args, 'c')) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
- cp = format_expand(ft, args_get(args, 'c'));
+ cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft);
- if (cp != NULL && *cp != '\0') {
- 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);
- }
- } else
- free(cp);
- cwd = fd;
+ if (access(cwd, X_OK) != 0) {
+ free((void *)cwd);
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else
@@ -165,12 +161,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
format_free(ft);
}
- if (fd != -1)
- close(fd);
+ if (to_free != NULL)
+ free((void *)to_free);
return (CMD_RETURN_NORMAL);
error:
- if (fd != -1)
- close(fd);
+ if (to_free != NULL)
+ free((void *)to_free);
return (CMD_RETURN_ERROR);
}
diff --git a/usr.bin/tmux/cmd-respawn-pane.c b/usr.bin/tmux/cmd-respawn-pane.c
index 365cf2a6e8b..fc601724668 100644
--- a/usr.bin/tmux/cmd-respawn-pane.c
+++ b/usr.bin/tmux/cmd-respawn-pane.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-respawn-pane.c,v 1.15 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: cmd-respawn-pane.c,v 1.16 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -81,7 +81,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
if (envent != NULL)
path = envent->value;
- if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, env,
+ if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env,
s->tio, &cause) != 0) {
cmdq_error(cmdq, "respawn pane failed: %s", cause);
free(cause);
diff --git a/usr.bin/tmux/cmd-respawn-window.c b/usr.bin/tmux/cmd-respawn-window.c
index 5e897d79ea3..d41e3657045 100644
--- a/usr.bin/tmux/cmd-respawn-window.c
+++ b/usr.bin/tmux/cmd-respawn-window.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-respawn-window.c,v 1.24 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: cmd-respawn-window.c,v 1.25 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -84,7 +84,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (envent != NULL)
path = envent->value;
- if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, env,
+ if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env,
s->tio, &cause) != 0) {
cmdq_error(cmdq, "respawn window failed: %s", cause);
free(cause);
diff --git a/usr.bin/tmux/cmd-run-shell.c b/usr.bin/tmux/cmd-run-shell.c
index 32ee362a8d1..b163a98bc49 100644
--- a/usr.bin/tmux/cmd-run-shell.c
+++ b/usr.bin/tmux/cmd-run-shell.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-run-shell.c,v 1.29 2015/09/16 22:24:54 nicm Exp $ */
+/* $OpenBSD: cmd-run-shell.c,v 1.30 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -80,7 +80,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
struct winlink *wl = NULL;
struct window_pane *wp = NULL;
struct format_tree *ft;
- int cwd;
+ const char *cwd;
if (args_has(args, 't')) {
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
@@ -97,7 +97,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
else if (s != NULL)
cwd = s->cwd;
else
- cwd = -1;
+ cwd = NULL;
}
ft = format_create();
diff --git a/usr.bin/tmux/cmd-save-buffer.c b/usr.bin/tmux/cmd-save-buffer.c
index 4dc46a65285..b85a16bdb63 100644
--- a/usr.bin/tmux/cmd-save-buffer.c
+++ b/usr.bin/tmux/cmd-save-buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-save-buffer.c,v 1.30 2015/08/29 09:36:46 nicm Exp $ */
+/* $OpenBSD: cmd-save-buffer.c,v 1.31 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -57,10 +57,10 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client;
struct session *s;
struct paste_buffer *pb;
- const char *path, *bufname, *bufdata, *start, *end;
- char *msg;
+ const char *path, *bufname, *bufdata, *start, *end, *cwd;
+ const char *flags;
+ char *msg, *file, resolved[PATH_MAX];
size_t size, used, msglen, bufsize;
- int cwd, fd;
FILE *f;
if (!args_has(args, 'b')) {
@@ -97,26 +97,25 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
else if ((s = cmd_find_current(cmdq)) != NULL)
cwd = s->cwd;
else
- cwd = AT_FDCWD;
+ cwd = ".";
- 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|O_TRUNC, 0600);
- if (fd != -1)
- f = fdopen(fd, "wb");
- }
+ flags = "wb";
+ if (args_has(self->args, 'a'))
+ flags = "ab";
+
+ xasprintf(&file, "%s/%s", cwd, path);
+ if (realpath(file, resolved) == NULL)
+ f = NULL;
+ else
+ f = fopen(resolved, flags);
+ free(file);
if (f == NULL) {
- if (fd != -1)
- close(fd);
- cmdq_error(cmdq, "%s: %s", path, strerror(errno));
+ cmdq_error(cmdq, "%s: %s", resolved, strerror(errno));
return (CMD_RETURN_ERROR);
}
+
if (fwrite(bufdata, 1, bufsize, f) != bufsize) {
- cmdq_error(cmdq, "%s: fwrite error", path);
+ cmdq_error(cmdq, "%s: write error", resolved);
fclose(f);
return (CMD_RETURN_ERROR);
}
diff --git a/usr.bin/tmux/cmd-split-window.c b/usr.bin/tmux/cmd-split-window.c
index 45b6d81b8f8..074e8dbefa3 100644
--- a/usr.bin/tmux/cmd-split-window.c
+++ b/usr.bin/tmux/cmd-split-window.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-split-window.c,v 1.60 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: cmd-split-window.c,v 1.61 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -53,10 +53,10 @@ 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, *path, *shell, *template;
+ const char *cmd, *path, *shell, *template, *cwd, *to_free;
char **argv, *cause, *new_cause, *cp;
u_int hlimit;
- int argc, size, percentage, cwd, fd = -1;
+ int argc, size, percentage;
enum layout_type type;
struct layout_cell *lc;
struct format_tree *ft;
@@ -86,24 +86,20 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
argv = args->argv;
}
+ to_free = NULL;
if (args_has(args, 'c')) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
- cp = format_expand(ft, args_get(args, 'c'));
+ to_free = cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft);
- if (cp != NULL && *cp != '\0') {
- 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);
- }
- } else
- free(cp);
- cwd = fd;
+ if (access(cwd, X_OK) != 0) {
+ free((void *)cwd);
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else
@@ -188,8 +184,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
notify_window_layout_changed(w);
- if (fd != -1)
- close(fd);
+ if (to_free != NULL)
+ free((void *)to_free);
return (CMD_RETURN_NORMAL);
error:
@@ -200,7 +196,8 @@ error:
}
cmdq_error(cmdq, "create pane failed: %s", cause);
free(cause);
- if (fd != -1)
- close(fd);
+
+ if (to_free != NULL)
+ free((void *)to_free);
return (CMD_RETURN_ERROR);
}
diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c
index f1f21015579..50f3c0da3dc 100644
--- a/usr.bin/tmux/format.c
+++ b/usr.bin/tmux/format.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: format.c,v 1.91 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.92 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -239,7 +239,7 @@ format_job_get(struct format_tree *ft, const char *cmd)
t = time(NULL);
if (fj->job == NULL && ((ft->flags & FORMAT_FORCE) || fj->last != t)) {
- fj->job = job_run(fj->cmd, NULL, -1, format_job_callback,
+ fj->job = job_run(fj->cmd, NULL, NULL, format_job_callback,
NULL, fj);
if (fj->job == NULL) {
free(fj->out);
diff --git a/usr.bin/tmux/job.c b/usr.bin/tmux/job.c
index 8358f8e301c..ade884d008d 100644
--- a/usr.bin/tmux/job.c
+++ b/usr.bin/tmux/job.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: job.c,v 1.37 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: job.c,v 1.38 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -41,13 +41,14 @@ struct joblist all_jobs = LIST_HEAD_INITIALIZER(all_jobs);
/* Start a job running, if it isn't already. */
struct job *
-job_run(const char *cmd, struct session *s, int cwd,
+job_run(const char *cmd, struct session *s, const char *cwd,
void (*callbackfn)(struct job *), void (*freefn)(void *), void *data)
{
struct job *job;
struct environ *env;
pid_t pid;
int nullfd, out[2];
+ const char *home;
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0)
return (NULL);
@@ -67,8 +68,10 @@ job_run(const char *cmd, struct session *s, int cwd,
case 0: /* child */
clear_signals(1);
- if (cwd != -1 && fchdir(cwd) != 0)
- chdir("/");
+ if (cwd == NULL || chdir(cwd) != 0) {
+ if ((home = find_home()) == NULL || chdir(home) != 0)
+ chdir("/");
+ }
environ_push(env);
environ_free(env);
diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c
index 76ff5e04da2..25d214fb2d7 100644
--- a/usr.bin/tmux/server-client.c
+++ b/usr.bin/tmux/server-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-client.c,v 1.164 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.165 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -98,7 +98,7 @@ server_client_create(int fd)
c->environ = environ_create();
c->fd = -1;
- c->cwd = -1;
+ c->cwd = NULL;
c->cmdq = cmdq_new(c);
c->cmdq->client_exit = 1;
@@ -194,7 +194,7 @@ server_client_lost(struct client *c)
screen_free(&c->status);
free(c->title);
- close(c->cwd);
+ free((void *)c->cwd);
evtimer_del(&c->repeat_timer);
@@ -1099,7 +1099,7 @@ error:
void
server_client_dispatch_identify(struct client *c, struct imsg *imsg)
{
- const char *data;
+ const char *data, *home;
size_t datalen;
int flags;
@@ -1132,8 +1132,12 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
case MSG_IDENTIFY_CWD:
if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_CWD string");
- if ((c->cwd = open(data, O_RDONLY)) == -1)
- c->cwd = open("/", O_RDONLY);
+ if (access(data, X_OK) == 0)
+ c->cwd = xstrdup(data);
+ else if ((home = find_home()) != NULL)
+ c->cwd = xstrdup(home);
+ else
+ c->cwd = xstrdup("/");
log_debug("client %p IDENTIFY_CWD %s", c, data);
break;
case MSG_IDENTIFY_STDIN:
diff --git a/usr.bin/tmux/session.c b/usr.bin/tmux/session.c
index 822f2dbaa5e..a912183cc7f 100644
--- a/usr.bin/tmux/session.c
+++ b/usr.bin/tmux/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.57 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: session.c,v 1.58 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -104,8 +104,8 @@ session_find_by_id(u_int id)
/* Create a new session. */
struct session *
session_create(const char *name, int argc, char **argv, const char *path,
- int cwd, struct environ *env, struct termios *tio, int idx, u_int sx,
- u_int sy, char **cause)
+ const char *cwd, struct environ *env, struct termios *tio, int idx,
+ u_int sx, u_int sy, char **cause)
{
struct session *s;
struct winlink *wl;
@@ -114,7 +114,7 @@ session_create(const char *name, int argc, char **argv, const char *path,
s->references = 1;
s->flags = 0;
- s->cwd = dup(cwd);
+ s->cwd = xstrdup(cwd);
s->curw = NULL;
TAILQ_INIT(&s->lastw);
@@ -224,7 +224,7 @@ session_destroy(struct session *s)
winlink_remove(&s->windows, wl);
}
- close(s->cwd);
+ free((void *)s->cwd);
session_unref(s);
}
@@ -315,7 +315,7 @@ session_previous_session(struct session *s)
/* Create a new window on a session. */
struct winlink *
session_new(struct session *s, const char *name, int argc, char **argv,
- const char *path, int cwd, int idx, char **cause)
+ const char *path, const char *cwd, int idx, char **cause)
{
struct window *w;
struct winlink *wl;
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 1c29aa49dbe..ce8ae8f097e 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.568 2015/10/28 09:51:55 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.569 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -829,7 +829,7 @@ struct window_pane {
int argc;
char **argv;
char *shell;
- int cwd;
+ const char *cwd;
pid_t pid;
char tty[TTY_NAME_MAX];
@@ -976,7 +976,7 @@ struct session {
u_int id;
char *name;
- int cwd;
+ const char *cwd;
struct timeval creation_time;
struct timeval last_attached_time;
@@ -1181,7 +1181,7 @@ struct client {
struct environ *environ;
char *title;
- int cwd;
+ const char *cwd;
char *term;
char *ttyname;
@@ -1536,7 +1536,7 @@ int options_table_find(const char *, const struct options_table_entry **,
/* job.c */
extern struct joblist all_jobs;
-struct job *job_run(const char *, struct session *, int,
+struct job *job_run(const char *, struct session *, const char *,
void (*)(struct job *), void (*)(void *), void *);
void job_free(struct job *);
void job_died(struct job *, int);
@@ -1982,8 +1982,8 @@ struct window *window_find_by_id(u_int);
void window_update_activity(struct window *);
struct window *window_create1(u_int, u_int);
struct window *window_create(const char *, int, char **, const char *,
- const char *, int, struct environ *, struct termios *,
- u_int, u_int, u_int, char **);
+ const char *, const char *, 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);
struct window_pane *window_find_string(struct window *, const char *);
@@ -2010,7 +2010,7 @@ struct window_pane *window_pane_find_by_id(u_int);
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
void window_pane_destroy(struct window_pane *);
int window_pane_spawn(struct window_pane *, int, char **,
- const char *, const char *, int, struct environ *,
+ const char *, const char *, const char *, struct environ *,
struct termios *, char **);
void window_pane_resize(struct window_pane *, u_int, u_int);
void window_pane_alternate_on(struct window_pane *,
@@ -2144,8 +2144,8 @@ struct session *session_find(const char *);
struct session *session_find_by_id_str(const char *);
struct session *session_find_by_id(u_int);
struct session *session_create(const char *, int, char **, const char *,
- int, struct environ *, struct termios *, int, u_int,
- u_int, char **);
+ const char *, struct environ *, struct termios *, int,
+ u_int, u_int, char **);
void session_destroy(struct session *);
void session_unref(struct session *);
int session_check_name(const char *);
@@ -2153,7 +2153,7 @@ void session_update_activity(struct session *, struct timeval *);
struct session *session_next_session(struct session *);
struct session *session_previous_session(struct session *);
struct winlink *session_new(struct session *, const char *, int, char **,
- const char *, int, int, char **);
+ const char *, const char *, int, char **);
struct winlink *session_attach(struct session *, struct window *, int,
char **);
int session_detach(struct session *, struct winlink *);
diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c
index 01e6e1f96b7..afcccecb850 100644
--- a/usr.bin/tmux/window-copy.c
+++ b/usr.bin/tmux/window-copy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-copy.c,v 1.136 2015/10/27 15:58:43 nicm Exp $ */
+/* $OpenBSD: window-copy.c,v 1.137 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1488,7 +1488,7 @@ window_copy_copy_pipe(struct window_pane *wp, struct session *sess,
format_defaults(ft, NULL, sess, NULL, wp);
expanded = format_expand(ft, arg);
- job = job_run(expanded, sess, -1, NULL, NULL, NULL);
+ job = job_run(expanded, sess, NULL, NULL, NULL, NULL);
bufferevent_write(job->event, buf, len);
free(expanded);
diff --git a/usr.bin/tmux/window.c b/usr.bin/tmux/window.c
index 9bef3b69678..d53ef86d9cd 100644
--- a/usr.bin/tmux/window.c
+++ b/usr.bin/tmux/window.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: window.c,v 1.146 2015/10/27 15:58:43 nicm Exp $ */
+/* $OpenBSD: window.c,v 1.147 2015/10/31 08:13:58 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -316,8 +316,8 @@ window_create1(u_int sx, u_int sy)
struct window *
window_create(const char *name, int argc, char **argv, const char *path,
- const char *shell, int cwd, struct environ *env, struct termios *tio,
- u_int sx, u_int sy, u_int hlimit, char **cause)
+ const char *shell, const char *cwd, struct environ *env,
+ struct termios *tio, u_int sx, u_int sy, u_int hlimit, char **cause)
{
struct window *w;
struct window_pane *wp;
@@ -736,7 +736,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->argc = 0;
wp->argv = NULL;
wp->shell = NULL;
- wp->cwd = -1;
+ wp->cwd = NULL;
wp->fd = -1;
wp->event = NULL;
@@ -796,7 +796,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
- close(wp->cwd);
+ free((void *)wp->cwd);
free(wp->shell);
cmd_free_argv(wp->argc, wp->argv);
free(wp);
@@ -804,12 +804,12 @@ window_pane_destroy(struct window_pane *wp)
int
window_pane_spawn(struct window_pane *wp, int argc, char **argv,
- const char *path, const char *shell, int cwd, struct environ *env,
+ const char *path, const char *shell, const char *cwd, struct environ *env,
struct termios *tio, char **cause)
{
struct winsize ws;
char *argv0, *cmd, **argvp, paneid[16];
- const char *ptr, *first;
+ const char *ptr, *first, *home;
struct termios tio2;
int i;
@@ -826,9 +826,9 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv,
free(wp->shell);
wp->shell = xstrdup(shell);
}
- if (cwd != -1) {
- close(wp->cwd);
- wp->cwd = dup(cwd);
+ if (cwd != NULL) {
+ free((void *)wp->cwd);
+ wp->cwd = xstrdup(cwd);
}
cmd = cmd_stringify_argv(wp->argc, wp->argv);
@@ -847,8 +847,10 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv,
free(cmd);
return (-1);
case 0:
- if (fchdir(wp->cwd) != 0)
- chdir("/");
+ if (chdir(wp->cwd) != 0) {
+ if ((home = find_home()) == NULL || chdir(home) != 0)
+ chdir("/");
+ }
if (tcgetattr(STDIN_FILENO, &tio2) != 0)
fatal("tcgetattr failed");