Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2015-10-31 10:01:12 +00:00
commit 17f6c3be8e
18 changed files with 136 additions and 139 deletions

View File

@ -272,8 +272,10 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL); client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL);
/* Save these before pledge(). */ /* Save these before pledge(). */
if ((cwd = getcwd(path, sizeof path)) == NULL) if ((cwd = getcwd(path, sizeof path)) == NULL) {
cwd = "/"; if ((cwd = find_home()) == NULL)
cwd = "/";
}
if ((ttynam = ttyname(STDIN_FILENO)) == NULL) if ((ttynam = ttyname(STDIN_FILENO)) == NULL)
ttynam = ""; ttynam = "";

View File

@ -51,9 +51,8 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
struct window_pane *wp = NULL; struct window_pane *wp = NULL;
const char *update; const char *update;
char *cause; char *cause;
int fd;
struct format_tree *ft; struct format_tree *ft;
char *cp; char *cwd;
if (RB_EMPTY(&sessions)) { if (RB_EMPTY(&sessions)) {
cmdq_error(cmdq, "no 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(); ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s,
NULL, NULL); NULL, NULL);
cp = format_expand(ft, cflag); cwd = format_expand(ft, cflag);
format_free(ft); format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY); if (access(cwd, X_OK) != 0) {
free(cp); free((void *)cwd);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s", cmdq_error(cmdq, "bad working directory: %s",
strerror(errno)); strerror(errno));
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
close(s->cwd); free((void *)s->cwd);
s->cwd = fd; s->cwd = cwd;
} }
if (c->session != NULL) { if (c->session != NULL) {

View File

@ -66,7 +66,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
struct winlink *wl = NULL; struct winlink *wl = NULL;
struct window_pane *wp = NULL; struct window_pane *wp = NULL;
struct format_tree *ft; struct format_tree *ft;
int cwd; const char *cwd;
if (args_has(args, 't')) { if (args_has(args, 't')) {
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); 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) else if (s != NULL)
cwd = s->cwd; cwd = s->cwd;
else else
cwd = -1; cwd = NULL;
} }
ft = format_create(); ft = format_create();

View File

@ -49,10 +49,10 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client; struct client *c = cmdq->client;
struct session *s; struct session *s;
FILE *f; FILE *f;
const char *path, *bufname; const char *path, *bufname, *cwd;
char *pdata, *new_pdata, *cause; char *pdata, *new_pdata, *cause, *file, resolved[PATH_MAX];
size_t psize; size_t psize;
int ch, error, cwd, fd; int ch, error;
bufname = NULL; bufname = NULL;
if (args_has(args, 'b')) 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) else if ((s = cmd_find_current(cmdq)) != NULL)
cwd = s->cwd; cwd = s->cwd;
else else
cwd = AT_FDCWD; cwd = ".";
if ((fd = openat(cwd, path, O_RDONLY)) == -1 || xasprintf(&file, "%s/%s", cwd, path);
(f = fdopen(fd, "rb")) == NULL) { if (realpath(file, resolved) == NULL)
if (fd != -1) f = NULL;
close(fd); else
cmdq_error(cmdq, "%s: %s", path, strerror(errno)); f = fopen(resolved, "rb");
free(file);
if (f == NULL) {
cmdq_error(cmdq, "%s: %s", resolved, strerror(errno));
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@ -97,7 +100,7 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
pdata[psize++] = ch; pdata[psize++] = ch;
} }
if (ferror(f)) { if (ferror(f)) {
cmdq_error(cmdq, "%s: read error", path); cmdq_error(cmdq, "%s: read error", resolved);
goto error; goto error;
} }
if (pdata != NULL) if (pdata != NULL)

View File

@ -63,10 +63,9 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
struct environ *env; struct environ *env;
struct termios tio, *tiop; struct termios tio, *tiop;
const char *newname, *target, *update, *errstr, *template; const char *newname, *target, *update, *errstr, *template;
const char *path; const char *path, *cwd, *to_free;
char **argv, *cmd, *cause, *cp; char **argv, *cmd, *cause, *cp;
int detached, already_attached, idx, cwd, fd = -1; int detached, already_attached, idx, argc;
int argc;
u_int sx, sy; u_int sx, sy;
struct format_tree *ft; struct format_tree *ft;
struct environ_entry *envent; struct environ_entry *envent;
@ -118,32 +117,26 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
already_attached = 1; already_attached = 1;
/* Get the new session working directory. */ /* Get the new session working directory. */
to_free = NULL;
if (args_has(args, 'c')) { if (args_has(args, 'c')) {
ft = format_create(); ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL, format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL,
NULL); NULL);
cp = format_expand(ft, args_get(args, 'c')); to_free = cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft); format_free(ft);
if (cp != NULL && *cp != '\0') { if (access(cwd, X_OK) != 0) {
fd = open(cp, O_RDONLY|O_DIRECTORY); free((void *)cwd);
free(cp); cmdq_error(cmdq, "bad working directory: %s",
if (fd == -1) { strerror(errno));
cmdq_error(cmdq, "bad working directory: %s", return (CMD_RETURN_ERROR);
strerror(errno)); }
return (CMD_RETURN_ERROR);
}
} else
free(cp);
cwd = fd;
} else if (c != NULL && c->session == NULL) } else if (c != NULL && c->session == NULL)
cwd = c->cwd; cwd = c->cwd;
else if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL) else if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
cwd = c0->session->cwd; cwd = c0->session->cwd;
else { else
fd = open(".", O_RDONLY); cwd = ".";
cwd = fd;
}
/* /*
* If this is a new client, check for nesting and save the termios * 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) if (!detached)
cmdq->client_exit = 0; cmdq->client_exit = 0;
if (fd != -1) if (to_free != NULL)
close(fd); free((void *)to_free);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
error: error:
if (fd != -1) if (to_free != NULL)
close(fd); free((void *)to_free);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@ -49,9 +49,9 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct args *args = self->args; struct args *args = self->args;
struct session *s; struct session *s;
struct winlink *wl; struct winlink *wl;
const char *cmd, *path, *template; const char *cmd, *path, *template, *cwd, *to_free;
char **argv, *cause, *cp; char **argv, *cause, *cp;
int argc, idx, detached, cwd, fd = -1; int argc, idx, detached;
struct format_tree *ft; struct format_tree *ft;
struct environ_entry *envent; struct environ_entry *envent;
@ -92,24 +92,20 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (envent != NULL) if (envent != NULL)
path = envent->value; path = envent->value;
to_free = NULL;
if (args_has(args, 'c')) { if (args_has(args, 'c')) {
ft = format_create(); ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL, format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL); NULL);
cp = format_expand(ft, args_get(args, 'c')); cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft); format_free(ft);
if (cp != NULL && *cp != '\0') { if (access(cwd, X_OK) != 0) {
fd = open(cp, O_RDONLY|O_DIRECTORY); free((void *)cwd);
free(cp); cmdq_error(cmdq, "bad working directory: %s",
if (fd == -1) { strerror(errno));
cmdq_error(cmdq, "bad working directory: %s", return (CMD_RETURN_ERROR);
strerror(errno)); }
return (CMD_RETURN_ERROR);
}
} else
free(cp);
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL) } else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd; cwd = cmdq->client->cwd;
else else
@ -165,12 +161,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
format_free(ft); format_free(ft);
} }
if (fd != -1) if (to_free != NULL)
close(fd); free((void *)to_free);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
error: error:
if (fd != -1) if (to_free != NULL)
close(fd); free((void *)to_free);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@ -81,7 +81,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
if (envent != NULL) if (envent != NULL)
path = envent->value; 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) { s->tio, &cause) != 0) {
cmdq_error(cmdq, "respawn pane failed: %s", cause); cmdq_error(cmdq, "respawn pane failed: %s", cause);
free(cause); free(cause);

View File

@ -84,7 +84,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (envent != NULL) if (envent != NULL)
path = envent->value; 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) { s->tio, &cause) != 0) {
cmdq_error(cmdq, "respawn window failed: %s", cause); cmdq_error(cmdq, "respawn window failed: %s", cause);
free(cause); free(cause);

View File

@ -80,7 +80,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
struct winlink *wl = NULL; struct winlink *wl = NULL;
struct window_pane *wp = NULL; struct window_pane *wp = NULL;
struct format_tree *ft; struct format_tree *ft;
int cwd; const char *cwd;
if (args_has(args, 't')) { if (args_has(args, 't')) {
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); 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) else if (s != NULL)
cwd = s->cwd; cwd = s->cwd;
else else
cwd = -1; cwd = NULL;
} }
ft = format_create(); ft = format_create();

View File

@ -56,10 +56,10 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client; struct client *c = cmdq->client;
struct session *s; struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
const char *path, *bufname, *bufdata, *start, *end; const char *path, *bufname, *bufdata, *start, *end, *cwd;
char *msg; const char *flags;
char *msg, *file, resolved[PATH_MAX];
size_t size, used, msglen, bufsize; size_t size, used, msglen, bufsize;
int cwd, fd;
FILE *f; FILE *f;
if (!args_has(args, 'b')) { if (!args_has(args, 'b')) {
@ -96,26 +96,25 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
else if ((s = cmd_find_current(cmdq)) != NULL) else if ((s = cmd_find_current(cmdq)) != NULL)
cwd = s->cwd; cwd = s->cwd;
else else
cwd = AT_FDCWD; cwd = ".";
f = NULL; flags = "wb";
if (args_has(self->args, 'a')) { if (args_has(self->args, 'a'))
fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600); flags = "ab";
if (fd != -1)
f = fdopen(fd, "ab"); xasprintf(&file, "%s/%s", cwd, path);
} else { if (realpath(file, resolved) == NULL)
fd = openat(cwd, path, O_CREAT|O_RDWR|O_TRUNC, 0600); f = NULL;
if (fd != -1) else
f = fdopen(fd, "wb"); f = fopen(resolved, flags);
} free(file);
if (f == NULL) { if (f == NULL) {
if (fd != -1) cmdq_error(cmdq, "%s: %s", resolved, strerror(errno));
close(fd);
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (fwrite(bufdata, 1, bufsize, f) != bufsize) { if (fwrite(bufdata, 1, bufsize, f) != bufsize) {
cmdq_error(cmdq, "%s: fwrite error", path); cmdq_error(cmdq, "%s: write error", resolved);
fclose(f); fclose(f);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@ -52,10 +52,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window *w; struct window *w;
struct window_pane *wp, *new_wp = NULL; struct window_pane *wp, *new_wp = NULL;
struct environ *env; struct environ *env;
const char *cmd, *path, *shell, *template; const char *cmd, *path, *shell, *template, *cwd, *to_free;
char **argv, *cause, *new_cause, *cp; char **argv, *cause, *new_cause, *cp;
u_int hlimit; u_int hlimit;
int argc, size, percentage, cwd, fd = -1; int argc, size, percentage;
enum layout_type type; enum layout_type type;
struct layout_cell *lc; struct layout_cell *lc;
struct format_tree *ft; struct format_tree *ft;
@ -85,24 +85,20 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
argv = args->argv; argv = args->argv;
} }
to_free = NULL;
if (args_has(args, 'c')) { if (args_has(args, 'c')) {
ft = format_create(); ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL, format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL); NULL);
cp = format_expand(ft, args_get(args, 'c')); to_free = cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft); format_free(ft);
if (cp != NULL && *cp != '\0') { if (access(cwd, X_OK) != 0) {
fd = open(cp, O_RDONLY|O_DIRECTORY); free((void *)cwd);
free(cp); cmdq_error(cmdq, "bad working directory: %s",
if (fd == -1) { strerror(errno));
cmdq_error(cmdq, "bad working directory: %s", return (CMD_RETURN_ERROR);
strerror(errno)); }
return (CMD_RETURN_ERROR);
}
} else
free(cp);
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL) } else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd; cwd = cmdq->client->cwd;
else else
@ -187,8 +183,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
} }
notify_window_layout_changed(w); notify_window_layout_changed(w);
if (fd != -1) if (to_free != NULL)
close(fd); free((void *)to_free);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
error: error:
@ -199,7 +195,8 @@ error:
} }
cmdq_error(cmdq, "create pane failed: %s", cause); cmdq_error(cmdq, "create pane failed: %s", cause);
free(cause); free(cause);
if (fd != -1)
close(fd); if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@ -241,7 +241,7 @@ format_job_get(struct format_tree *ft, const char *cmd)
t = time(NULL); t = time(NULL);
if (fj->job == NULL && ((ft->flags & FORMAT_FORCE) || fj->last != t)) { 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); NULL, fj);
if (fj->job == NULL) { if (fj->job == NULL) {
free(fj->out); free(fj->out);

9
job.c
View File

@ -40,13 +40,14 @@ struct joblist all_jobs = LIST_HEAD_INITIALIZER(all_jobs);
/* Start a job running, if it isn't already. */ /* Start a job running, if it isn't already. */
struct job * 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) void (*callbackfn)(struct job *), void (*freefn)(void *), void *data)
{ {
struct job *job; struct job *job;
struct environ *env; struct environ *env;
pid_t pid; pid_t pid;
int nullfd, out[2]; int nullfd, out[2];
const char *home;
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0) if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0)
return (NULL); return (NULL);
@ -66,8 +67,10 @@ job_run(const char *cmd, struct session *s, int cwd,
case 0: /* child */ case 0: /* child */
clear_signals(1); clear_signals(1);
if (cwd != -1 && fchdir(cwd) != 0) if (cwd == NULL || chdir(cwd) != 0) {
chdir("/"); if ((home = find_home()) == NULL || chdir(home) != 0)
chdir("/");
}
environ_push(env); environ_push(env);
environ_free(env); environ_free(env);

View File

@ -96,7 +96,7 @@ server_client_create(int fd)
c->environ = environ_create(); c->environ = environ_create();
c->fd = -1; c->fd = -1;
c->cwd = -1; c->cwd = NULL;
c->cmdq = cmdq_new(c); c->cmdq = cmdq_new(c);
c->cmdq->client_exit = 1; c->cmdq->client_exit = 1;
@ -192,7 +192,7 @@ server_client_lost(struct client *c)
screen_free(&c->status); screen_free(&c->status);
free(c->title); free(c->title);
close(c->cwd); free((void *)c->cwd);
evtimer_del(&c->repeat_timer); evtimer_del(&c->repeat_timer);
@ -1107,7 +1107,7 @@ error:
void void
server_client_dispatch_identify(struct client *c, struct imsg *imsg) server_client_dispatch_identify(struct client *c, struct imsg *imsg)
{ {
const char *data; const char *data, *home;
size_t datalen; size_t datalen;
int flags; int flags;
@ -1140,8 +1140,12 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
case MSG_IDENTIFY_CWD: case MSG_IDENTIFY_CWD:
if (datalen == 0 || data[datalen - 1] != '\0') if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_CWD string"); fatalx("bad MSG_IDENTIFY_CWD string");
if ((c->cwd = open(data, O_RDONLY)) == -1) if (access(data, X_OK) == 0)
c->cwd = open("/", O_RDONLY); 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); log_debug("client %p IDENTIFY_CWD %s", c, data);
break; break;
case MSG_IDENTIFY_STDIN: case MSG_IDENTIFY_STDIN:

View File

@ -103,8 +103,8 @@ session_find_by_id(u_int id)
/* Create a new session. */ /* Create a new session. */
struct session * struct session *
session_create(const char *name, int argc, char **argv, const char *path, 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, const char *cwd, struct environ *env, struct termios *tio, int idx,
u_int sy, char **cause) u_int sx, u_int sy, char **cause)
{ {
struct session *s; struct session *s;
struct winlink *wl; struct winlink *wl;
@ -113,7 +113,7 @@ session_create(const char *name, int argc, char **argv, const char *path,
s->references = 1; s->references = 1;
s->flags = 0; s->flags = 0;
s->cwd = dup(cwd); s->cwd = xstrdup(cwd);
s->curw = NULL; s->curw = NULL;
TAILQ_INIT(&s->lastw); TAILQ_INIT(&s->lastw);
@ -223,7 +223,7 @@ session_destroy(struct session *s)
winlink_remove(&s->windows, wl); winlink_remove(&s->windows, wl);
} }
close(s->cwd); free((void *)s->cwd);
session_unref(s); session_unref(s);
} }
@ -314,7 +314,7 @@ session_previous_session(struct session *s)
/* Create a new window on a session. */ /* Create a new window on a session. */
struct winlink * struct winlink *
session_new(struct session *s, const char *name, int argc, char **argv, 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 window *w;
struct winlink *wl; struct winlink *wl;

20
tmux.h
View File

@ -832,7 +832,7 @@ struct window_pane {
int argc; int argc;
char **argv; char **argv;
char *shell; char *shell;
int cwd; const char *cwd;
pid_t pid; pid_t pid;
char tty[TTY_NAME_MAX]; char tty[TTY_NAME_MAX];
@ -979,7 +979,7 @@ struct session {
u_int id; u_int id;
char *name; char *name;
int cwd; const char *cwd;
struct timeval creation_time; struct timeval creation_time;
struct timeval last_attached_time; struct timeval last_attached_time;
@ -1184,7 +1184,7 @@ struct client {
struct environ *environ; struct environ *environ;
char *title; char *title;
int cwd; const char *cwd;
char *term; char *term;
char *ttyname; char *ttyname;
@ -1539,7 +1539,7 @@ int options_table_find(const char *, const struct options_table_entry **,
/* job.c */ /* job.c */
extern struct joblist all_jobs; 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 (*)(struct job *), void (*)(void *), void *);
void job_free(struct job *); void job_free(struct job *);
void job_died(struct job *, int); void job_died(struct job *, int);
@ -1985,8 +1985,8 @@ struct window *window_find_by_id(u_int);
void window_update_activity(struct window *); void window_update_activity(struct window *);
struct window *window_create1(u_int, u_int); struct window *window_create1(u_int, u_int);
struct window *window_create(const char *, int, char **, const char *, struct window *window_create(const char *, int, char **, const char *,
const char *, int, struct environ *, struct termios *, const char *, const char *, struct environ *,
u_int, u_int, u_int, char **); struct termios *, u_int, u_int, u_int, char **);
void window_destroy(struct window *); void window_destroy(struct window *);
struct window_pane *window_get_active_at(struct window *, u_int, u_int); struct window_pane *window_get_active_at(struct window *, u_int, u_int);
struct window_pane *window_find_string(struct window *, const char *); struct window_pane *window_find_string(struct window *, const char *);
@ -2013,7 +2013,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); struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
void window_pane_destroy(struct window_pane *); void window_pane_destroy(struct window_pane *);
int window_pane_spawn(struct window_pane *, int, char **, 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 **); struct termios *, char **);
void window_pane_resize(struct window_pane *, u_int, u_int); void window_pane_resize(struct window_pane *, u_int, u_int);
void window_pane_alternate_on(struct window_pane *, void window_pane_alternate_on(struct window_pane *,
@ -2147,8 +2147,8 @@ struct session *session_find(const char *);
struct session *session_find_by_id_str(const char *); struct session *session_find_by_id_str(const char *);
struct session *session_find_by_id(u_int); struct session *session_find_by_id(u_int);
struct session *session_create(const char *, int, char **, const char *, struct session *session_create(const char *, int, char **, const char *,
int, struct environ *, struct termios *, int, u_int, const char *, struct environ *, struct termios *, int,
u_int, char **); u_int, u_int, char **);
void session_destroy(struct session *); void session_destroy(struct session *);
void session_unref(struct session *); void session_unref(struct session *);
int session_check_name(const char *); int session_check_name(const char *);
@ -2156,7 +2156,7 @@ void session_update_activity(struct session *, struct timeval *);
struct session *session_next_session(struct session *); struct session *session_next_session(struct session *);
struct session *session_previous_session(struct session *); struct session *session_previous_session(struct session *);
struct winlink *session_new(struct session *, const char *, int, char **, 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, struct winlink *session_attach(struct session *, struct window *, int,
char **); char **);
int session_detach(struct session *, struct winlink *); int session_detach(struct session *, struct winlink *);

View File

@ -1488,7 +1488,7 @@ window_copy_copy_pipe(struct window_pane *wp, struct session *sess,
format_defaults(ft, NULL, sess, NULL, wp); format_defaults(ft, NULL, sess, NULL, wp);
expanded = format_expand(ft, arg); 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); bufferevent_write(job->event, buf, len);
free(expanded); free(expanded);

View File

@ -315,8 +315,8 @@ window_create1(u_int sx, u_int sy)
struct window * struct window *
window_create(const char *name, int argc, char **argv, const char *path, window_create(const char *name, int argc, char **argv, const char *path,
const char *shell, int cwd, struct environ *env, struct termios *tio, const char *shell, const char *cwd, struct environ *env,
u_int sx, u_int sy, u_int hlimit, char **cause) struct termios *tio, u_int sx, u_int sy, u_int hlimit, char **cause)
{ {
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
@ -735,7 +735,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->argc = 0; wp->argc = 0;
wp->argv = NULL; wp->argv = NULL;
wp->shell = NULL; wp->shell = NULL;
wp->cwd = -1; wp->cwd = NULL;
wp->fd = -1; wp->fd = -1;
wp->event = NULL; wp->event = NULL;
@ -798,7 +798,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp); RB_REMOVE(window_pane_tree, &all_window_panes, wp);
close(wp->cwd); free((void *)wp->cwd);
free(wp->shell); free(wp->shell);
cmd_free_argv(wp->argc, wp->argv); cmd_free_argv(wp->argc, wp->argv);
free(wp); free(wp);
@ -806,12 +806,12 @@ window_pane_destroy(struct window_pane *wp)
int int
window_pane_spawn(struct window_pane *wp, int argc, char **argv, 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 termios *tio, char **cause)
{ {
struct winsize ws; struct winsize ws;
char *argv0, *cmd, **argvp, paneid[16]; char *argv0, *cmd, **argvp, paneid[16];
const char *ptr, *first; const char *ptr, *first, *home;
struct termios tio2; struct termios tio2;
#ifdef HAVE_UTEMPTER #ifdef HAVE_UTEMPTER
char s[32]; char s[32];
@ -831,9 +831,9 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv,
free(wp->shell); free(wp->shell);
wp->shell = xstrdup(shell); wp->shell = xstrdup(shell);
} }
if (cwd != -1) { if (cwd != NULL) {
close(wp->cwd); free((void *)wp->cwd);
wp->cwd = dup(cwd); wp->cwd = xstrdup(cwd);
} }
cmd = cmd_stringify_argv(wp->argc, wp->argv); cmd = cmd_stringify_argv(wp->argc, wp->argv);
@ -852,8 +852,10 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv,
free(cmd); free(cmd);
return (-1); return (-1);
case 0: case 0:
if (fchdir(wp->cwd) != 0) if (chdir(wp->cwd) != 0) {
chdir("/"); if ((home = find_home()) == NULL || chdir(home) != 0)
chdir("/");
}
if (tcgetattr(STDIN_FILENO, &tio2) != 0) if (tcgetattr(STDIN_FILENO, &tio2) != 0)
fatal("tcgetattr failed"); fatal("tcgetattr failed");