summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client.c6
-rw-r--r--cmd-attach-session.c14
-rw-r--r--cmd-if-shell.c4
-rw-r--r--cmd-load-buffer.c23
-rw-r--r--cmd-new-session.c39
-rw-r--r--cmd-new-window.c32
-rw-r--r--cmd-respawn-pane.c2
-rw-r--r--cmd-respawn-window.c2
-rw-r--r--cmd-run-shell.c4
-rw-r--r--cmd-save-buffer.c35
-rw-r--r--cmd-split-window.c33
-rw-r--r--format.c2
-rw-r--r--job.c9
-rw-r--r--server-client.c14
-rw-r--r--session.c10
-rw-r--r--tmux.h20
-rw-r--r--window-copy.c2
-rw-r--r--window.c24
18 files changed, 136 insertions, 139 deletions
diff --git a/client.c b/client.c
index 97382f63..008bd631 100644
--- a/client.c
+++ b/client.c
@@ -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/cmd-attach-session.c b/cmd-attach-session.c
index c570358c..b339b890 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -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/cmd-if-shell.c b/cmd-if-shell.c
index 0271fdea..a9c84261 100644
--- a/cmd-if-shell.c
+++ b/cmd-if-shell.c
@@ -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/cmd-load-buffer.c b/cmd-load-buffer.c
index 897807d0..c55e6c11 100644
--- a/cmd-load-buffer.c
+++ b/cmd-load-buffer.c
@@ -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/cmd-new-session.c b/cmd-new-session.c
index 7b637bc6..90bb2e0e 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -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/cmd-new-window.c b/cmd-new-window.c
index 70e70c68..a5085fff 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -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/cmd-respawn-pane.c b/cmd-respawn-pane.c
index 864b45b8..a50b9d06 100644
--- a/cmd-respawn-pane.c
+++ b/cmd-respawn-pane.c
@@ -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/cmd-respawn-window.c b/cmd-respawn-window.c
index 8d8332b1..93af1b68 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -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/cmd-run-shell.c b/cmd-run-shell.c
index 17ac0f76..def3ef01 100644
--- a/cmd-run-shell.c
+++ b/cmd-run-shell.c
@@ -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/cmd-save-buffer.c b/cmd-save-buffer.c
index 5916cd4d..dca2c8ef 100644
--- a/cmd-save-buffer.c
+++ b/cmd-save-buffer.c
@@ -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/cmd-split-window.c b/cmd-split-window.c
index 75b8eeb6..6adb19a8 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -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/format.c b/format.c
index 0d9fbc7f..847ba08a 100644
--- a/format.c
+++ b/format.c
@@ -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/job.c b/job.c
index 8492fb52..0aee7b05 100644
--- a/job.c
+++ b/job.c
@@ -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/server-client.c b/server-client.c
index 7ae74c09..264e5e4a 100644
--- a/server-client.c
+++ b/server-client.c
@@ -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/session.c b/session.c
index 217b5272..cbaadcee 100644
--- a/session.c
+++ b/session.c
@@ -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/tmux.h b/tmux.h
index 9a55a1b1..f26f1c8c 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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/window-copy.c b/window-copy.c
index 3ba27c80..c5c053bf 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -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/window.c b/window.c
index baaaa0f8..49408297 100644
--- a/window.c
+++ b/window.c
@@ -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");