Merge branch 'obsd-master'

Sync from OpenBSD.
This commit is contained in:
Thomas Adam 2012-11-27 18:12:04 +00:00
commit 39631edb98
11 changed files with 142 additions and 55 deletions

11
cfg.c
View File

@ -34,9 +34,10 @@
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...); void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
char *cfg_cause; char *cfg_cause;
int cfg_finished; int cfg_finished;
struct causelist cfg_causes = ARRAY_INITIALIZER; int cfg_references;
struct causelist cfg_causes;
/* ARGSUSED */ /* ARGSUSED */
void printflike2 void printflike2
@ -89,6 +90,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
} }
n = 0; n = 0;
cfg_references++;
line = NULL; line = NULL;
retval = CMD_RETURN_NORMAL; retval = CMD_RETURN_NORMAL;
while ((buf = fgetln(f, &len))) { while ((buf = fgetln(f, &len))) {
@ -171,6 +174,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
} }
fclose(f); fclose(f);
cfg_references--;
return (retval); return (retval);
} }

View File

@ -30,13 +30,15 @@
*/ */
enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmd_ctx *); enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_run_shell_callback(struct job *);
void cmd_run_shell_free(void *); void cmd_run_shell_callback(struct job *);
void cmd_run_shell_free(void *);
void cmd_run_shell_print(struct job *, const char *);
const struct cmd_entry cmd_run_shell_entry = { const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run", "run-shell", "run",
"", 1, 1, "t:", 1, 1,
"command", CMD_TARGET_PANE_USAGE " command",
0, 0,
NULL, NULL,
NULL, NULL,
@ -46,17 +48,42 @@ const struct cmd_entry cmd_run_shell_entry = {
struct cmd_run_shell_data { struct cmd_run_shell_data {
char *cmd; char *cmd;
struct cmd_ctx ctx; struct cmd_ctx ctx;
u_int wp_id;
}; };
void
cmd_run_shell_print(struct job *job, const char *msg)
{
struct cmd_run_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx;
struct window_pane *wp;
wp = window_pane_find_by_id(cdata->wp_id);
if (wp == NULL) {
ctx->print(ctx, "%s", msg);
return;
}
if (window_pane_set_mode(wp, &window_copy_mode) == 0)
window_copy_init_for_output(wp);
if (wp->mode == &window_copy_mode)
window_copy_add(wp, "%s", msg);
}
enum cmd_retval enum cmd_retval
cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct cmd_run_shell_data *cdata; struct cmd_run_shell_data *cdata;
const char *shellcmd = args->argv[0]; const char *shellcmd = args->argv[0];
struct window_pane *wp;
if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(args->argv[0]); cdata->cmd = xstrdup(args->argv[0]);
cdata->wp_id = wp->id;
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL) if (ctx->cmdclient != NULL)
@ -87,7 +114,7 @@ cmd_run_shell_callback(struct job *job)
lines = 0; lines = 0;
do { do {
if ((line = evbuffer_readline(job->event->input)) != NULL) { if ((line = evbuffer_readline(job->event->input)) != NULL) {
ctx->print(ctx, "%s", line); cmd_run_shell_print (job, line);
lines++; lines++;
} }
} while (line != NULL); } while (line != NULL);
@ -98,7 +125,7 @@ cmd_run_shell_callback(struct job *job)
memcpy(line, EVBUFFER_DATA(job->event->input), size); memcpy(line, EVBUFFER_DATA(job->event->input), size);
line[size] = '\0'; line[size] = '\0';
ctx->print(ctx, "%s", line); cmd_run_shell_print(job, line);
lines++; lines++;
free(line); free(line);
@ -115,10 +142,10 @@ cmd_run_shell_callback(struct job *job)
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
} }
if (msg != NULL) { if (msg != NULL) {
if (lines != 0) if (lines == 0)
ctx->print(ctx, "%s", msg);
else
ctx->info(ctx, "%s", msg); ctx->info(ctx, "%s", msg);
else
cmd_run_shell_print(job, msg);
free(msg); free(msg);
} }
} }

View File

@ -42,35 +42,32 @@ enum cmd_retval
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct causelist causes;
char *cause;
struct window_pane *wp;
int retval; int retval;
u_int i; u_int i;
char *cause;
ARRAY_INIT(&causes); retval = load_cfg(args->argv[0], ctx, &cfg_causes);
retval = load_cfg(args->argv[0], ctx, &causes); /*
if (ARRAY_EMPTY(&causes)) * If the context for the cmdclient came from tmux's configuration
* file, then return the status of this command now, regardless of the
* error condition. Any errors from parsing a configuration file at
* startup will be handled for us by the server.
*/
if (cfg_references > 0 ||
(ctx->curclient == NULL && ctx->cmdclient == NULL))
return (retval); return (retval);
if (retval == 1 && !RB_EMPTY(&sessions) && ctx->cmdclient != NULL) { /*
wp = RB_MIN(sessions, &sessions)->curw->window->active; * We were called from the command-line in which case print the errors
window_pane_set_mode(wp, &window_copy_mode); * gathered here directly.
window_copy_init_for_output(wp); */
for (i = 0; i < ARRAY_LENGTH(&causes); i++) { for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&causes, i); cause = ARRAY_ITEM(&cfg_causes, i);
window_copy_add(wp, "%s", cause); ctx->print(ctx, "%s", cause);
free(cause); free(cause);
}
} else {
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
ctx->print(ctx, "%s", cause);
free(cause);
}
} }
ARRAY_FREE(&causes); ARRAY_FREE(&cfg_causes);
return (retval); return (retval);
} }

36
cmd.c
View File

@ -115,6 +115,7 @@ const struct cmd_entry *cmd_table[] = {
NULL NULL
}; };
int cmd_session_better(struct session *, struct session *, int);
struct session *cmd_choose_session_list(struct sessionslist *); struct session *cmd_choose_session_list(struct sessionslist *);
struct session *cmd_choose_session(int); struct session *cmd_choose_session(int);
struct client *cmd_choose_client(struct clients *); struct client *cmd_choose_client(struct clients *);
@ -370,6 +371,24 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached)
return (cmd_choose_session(prefer_unattached)); return (cmd_choose_session(prefer_unattached));
} }
/* Is this session better? */
int
cmd_session_better(struct session *s, struct session *best,
int prefer_unattached)
{
if (best == NULL)
return 1;
if (prefer_unattached) {
if (!(best->flags & SESSION_UNATTACHED) &&
(s->flags & SESSION_UNATTACHED))
return 1;
else if ((best->flags & SESSION_UNATTACHED) &&
!(s->flags & SESSION_UNATTACHED))
return 0;
}
return (timercmp(&s->activity_time, &best->activity_time, >));
}
/* /*
* Find the most recently used session, preferring unattached if the flag is * Find the most recently used session, preferring unattached if the flag is
* set. * set.
@ -377,21 +396,14 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached)
struct session * struct session *
cmd_choose_session(int prefer_unattached) cmd_choose_session(int prefer_unattached)
{ {
struct session *s, *sbest; struct session *s, *best;
struct timeval *tv = NULL;
sbest = NULL; best = NULL;
RB_FOREACH(s, sessions, &sessions) { RB_FOREACH(s, sessions, &sessions) {
if (tv == NULL || timercmp(&s->activity_time, tv, >) || if (cmd_session_better(s, best, prefer_unattached))
(prefer_unattached && best = s;
!(sbest->flags & SESSION_UNATTACHED) &&
(s->flags & SESSION_UNATTACHED))) {
sbest = s;
tv = &s->activity_time;
}
} }
return (best);
return (sbest);
} }
/* Find the most recently used session from a list. */ /* Find the most recently used session from a list. */

View File

@ -76,7 +76,7 @@ window_name_callback(unused int fd, unused short events, void *data)
name != NULL && name[0] == '-' && name[1] != '\0') name != NULL && name[0] == '-' && name[1] != '\0')
wname = parse_window_name(name + 1); wname = parse_window_name(name + 1);
else else
wname = parse_window_name(name); wname = parse_window_name(name);
free(name); free(name);
} }

View File

@ -685,6 +685,21 @@ const struct options_table_entry window_options_table[] = {
.default_str = "#I:#W#F" .default_str = "#I:#W#F"
}, },
{ .name = "window-status-last-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "window-status-last-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-last-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-fg", { .name = "window-status-fg",
.type = OPTIONS_TABLE_COLOUR, .type = OPTIONS_TABLE_COLOUR,
.default_num = 8 .default_num = 8

View File

@ -705,6 +705,17 @@ status_print(
gc->attr = attr; gc->attr = attr;
fmt = options_get_string(oo, "window-status-current-format"); fmt = options_get_string(oo, "window-status-current-format");
} }
if (wl == TAILQ_FIRST(&s->lastw)) {
fg = options_get_number(oo, "window-status-last-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-last-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-last-attr");
if (attr != 0)
gc->attr = attr;
}
if (wl->flags & WINLINK_BELL) { if (wl->flags & WINLINK_BELL) {
fg = options_get_number(oo, "window-status-bell-fg"); fg = options_get_number(oo, "window-status-bell-fg");

19
tmux.1
View File

@ -2827,6 +2827,15 @@ Like
.Ar window-status-format , .Ar window-status-format ,
but is the format used when the window is the current window. but is the format used when the window is the current window.
.Pp .Pp
.It Ic window-status-last-attr Ar attributes
Set status line attributes for the last active window.
.Pp
.It Ic window-status-last-bg Ar colour
Set status line background colour for the last active window.
.Pp
.It Ic window-status-last-fg Ar colour
Set status line foreground colour for the last active window.
.Pp
.It Ic window-status-fg Ar colour .It Ic window-status-fg Ar colour
Set status line foreground colour for a single window. Set status line foreground colour for a single window.
.Pp .Pp
@ -3389,12 +3398,18 @@ otherwise.
Lock each client individually by running the command specified by the Lock each client individually by running the command specified by the
.Ic lock-command .Ic lock-command
option. option.
.It Ic run-shell Ar shell-command .It Xo Ic run-shell
.Op Fl t Ar target-pane
.Ar shell-command
.Xc
.D1 (alias: Ic run ) .D1 (alias: Ic run )
Execute Execute
.Ar shell-command .Ar shell-command
in the background without creating a window. in the background without creating a window.
After it finishes, any output to stdout is displayed in copy mode. After it finishes, any output to stdout is displayed in copy mode (in the pane
specified by
.Fl t
or the current pane if omitted).
If the command doesn't return success, the exit status is also displayed. If the command doesn't return success, the exit status is also displayed.
.It Ic server-info .It Ic server-info
.D1 (alias: Ic info ) .D1 (alias: Ic info )

12
tmux.c
View File

@ -162,7 +162,7 @@ parseenvironment(void)
char * char *
makesocketpath(const char *label) makesocketpath(const char *label)
{ {
char base[MAXPATHLEN], *path, *s; char base[MAXPATHLEN], realbase[MAXPATHLEN], *path, *s;
struct stat sb; struct stat sb;
u_int uid; u_int uid;
@ -186,7 +186,10 @@ makesocketpath(const char *label)
return (NULL); return (NULL);
} }
xasprintf(&path, "%s/%s", base, label); if (realpath(base, realbase) == NULL)
strlcpy(realbase, base, sizeof realbase);
xasprintf(&path, "%s/%s", realbase, label);
return (path); return (path);
} }
@ -333,6 +336,8 @@ main(int argc, char **argv)
options_init(&global_w_options, NULL); options_init(&global_w_options, NULL);
options_table_populate_tree(window_options_table, &global_w_options); options_table_populate_tree(window_options_table, &global_w_options);
ARRAY_INIT(&cfg_causes);
/* Enable UTF-8 if the first client is on UTF-8 terminal. */ /* Enable UTF-8 if the first client is on UTF-8 terminal. */
if (flags & IDENTIFY_UTF8) { if (flags & IDENTIFY_UTF8) {
options_set_number(&global_s_options, "status-utf8", 1); options_set_number(&global_s_options, "status-utf8", 1);
@ -390,8 +395,7 @@ main(int argc, char **argv)
} }
} }
free(label); free(label);
if (realpath(path, socket_path) == NULL) strlcpy(socket_path, path, sizeof socket_path);
strlcpy(socket_path, path, sizeof socket_path);
free(path); free(path);
#ifdef HAVE_SETPROCTITLE #ifdef HAVE_SETPROCTITLE

1
tmux.h
View File

@ -1513,6 +1513,7 @@ __dead void shell_exec(const char *, const char *);
/* cfg.c */ /* cfg.c */
extern int cfg_finished; extern int cfg_finished;
extern int cfg_references;
extern struct causelist cfg_causes; extern struct causelist cfg_causes;
void printflike2 cfg_add_cause(struct causelist *, const char *, ...); void printflike2 cfg_add_cause(struct causelist *, const char *, ...);
int load_cfg(const char *, struct cmd_ctx *, struct causelist *); int load_cfg(const char *, struct cmd_ctx *, struct causelist *);

View File

@ -832,10 +832,10 @@ window_copy_mouse(
if (m->event == MOUSE_EVENT_WHEEL) { if (m->event == MOUSE_EVENT_WHEEL) {
if (m->wheel == MOUSE_WHEEL_UP) { if (m->wheel == MOUSE_WHEEL_UP) {
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
window_copy_cursor_up(wp, 0); window_copy_cursor_up(wp, 1);
} else if (m->wheel == MOUSE_WHEEL_DOWN) { } else if (m->wheel == MOUSE_WHEEL_DOWN) {
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
window_copy_cursor_down(wp, 0); window_copy_cursor_down(wp, 1);
if (data->oy == 0) if (data->oy == 0)
goto reset_mode; goto reset_mode;
} }