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);
/* 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 = "";

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;
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) {

View File

@ -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();

View File

@ -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)

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -56,10 +56,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')) {
@ -96,26 +96,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);
}

View File

@ -52,10 +52,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;
@ -85,24 +85,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
@ -187,8 +183,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:
@ -199,7 +195,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);
}

View File

@ -241,7 +241,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);

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. */
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);
@ -66,8 +67,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);

View File

@ -96,7 +96,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;
@ -192,7 +192,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);
@ -1107,7 +1107,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;
@ -1140,8 +1140,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:

View File

@ -103,8 +103,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;
@ -113,7 +113,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);
@ -223,7 +223,7 @@ session_destroy(struct session *s)
winlink_remove(&s->windows, wl);
}
close(s->cwd);
free((void *)s->cwd);
session_unref(s);
}
@ -314,7 +314,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;

20
tmux.h
View File

@ -832,7 +832,7 @@ struct window_pane {
int argc;
char **argv;
char *shell;
int cwd;
const char *cwd;
pid_t pid;
char tty[TTY_NAME_MAX];
@ -979,7 +979,7 @@ struct session {
u_int id;
char *name;
int cwd;
const char *cwd;
struct timeval creation_time;
struct timeval last_attached_time;
@ -1184,7 +1184,7 @@ struct client {
struct environ *environ;
char *title;
int cwd;
const char *cwd;
char *term;
char *ttyname;
@ -1539,7 +1539,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);
@ -1985,8 +1985,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 *);
@ -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);
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 *,
@ -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(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 *);
@ -2156,7 +2156,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 *);

View File

@ -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);

View File

@ -315,8 +315,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;
@ -735,7 +735,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;
@ -798,7 +798,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);
@ -806,12 +806,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;
#ifdef HAVE_UTEMPTER
char s[32];
@ -831,9 +831,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);
@ -852,8 +852,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");