Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2020-05-26 14:02:15 +01:00
9 changed files with 103 additions and 38 deletions

View File

@ -404,6 +404,8 @@ client_main(struct event_base *base, int argc, char **argv, int flags, int feat)
} else if (client_exitreason != CLIENT_EXIT_NONE) } else if (client_exitreason != CLIENT_EXIT_NONE)
fprintf(stderr, "%s\n", client_exit_message()); fprintf(stderr, "%s\n", client_exit_message());
setblocking(STDIN_FILENO, 1); setblocking(STDIN_FILENO, 1);
setblocking(STDOUT_FILENO, 1);
setblocking(STDERR_FILENO, 1);
return (client_exitval); return (client_exitval);
} }
@ -431,6 +433,9 @@ client_send_identify(const char *ttynam, const char *cwd, int feat)
if ((fd = dup(STDIN_FILENO)) == -1) if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed"); fatal("dup failed");
proc_send(client_peer, MSG_IDENTIFY_STDIN, fd, NULL, 0); proc_send(client_peer, MSG_IDENTIFY_STDIN, fd, NULL, 0);
if ((fd = dup(STDOUT_FILENO)) == -1)
fatal("dup failed");
proc_send(client_peer, MSG_IDENTIFY_STDOUT, fd, NULL, 0);
pid = getpid(); pid = getpid();
proc_send(client_peer, MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid); proc_send(client_peer, MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);

View File

@ -80,6 +80,10 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (args_has(args, 'n')) {
window_set_name(w, args_get(args, 'n'));
options_set_number(w->options, "automatic-rename", 0);
}
server_unlink_window(src_s, wl); server_unlink_window(src_s, wl);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@ -129,7 +129,10 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'm') || args_has(args, 'M')) { if (args_has(args, 'm') || args_has(args, 'M')) {
if (args_has(args, 'm') && !window_pane_visible(wp)) if (args_has(args, 'm') && !window_pane_visible(wp))
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
lastwp = marked_pane.wp; if (server_check_marked())
lastwp = marked_pane.wp;
else
lastwp = NULL;
if (args_has(args, 'M') || server_is_marked(s, wl, wp)) if (args_has(args, 'M') || server_is_marked(s, wl, wp))
server_clear_marked(); server_clear_marked();

View File

@ -23,10 +23,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
/* Control offsets. */ /* Control client offset. */
struct control_offset { struct control_offset {
u_int pane; u_int pane;
@ -34,13 +35,16 @@ struct control_offset {
int flags; int flags;
#define CONTROL_OFFSET_OFF 0x1 #define CONTROL_OFFSET_OFF 0x1
RB_ENTRY(control_offset) entry; RB_ENTRY(control_offset) entry;
}; };
RB_HEAD(control_offsets, control_offset); RB_HEAD(control_offsets, control_offset);
/* Control state. */ /* Control client state. */
struct control_state { struct control_state {
struct control_offsets offsets; struct control_offsets offsets;
struct bufferevent *read_event;
struct bufferevent *write_event;
}; };
/* Compare client offsets. */ /* Compare client offsets. */
@ -146,18 +150,24 @@ control_set_pane_off(struct client *c, struct window_pane *wp)
void void
control_write(struct client *c, const char *fmt, ...) control_write(struct client *c, const char *fmt, ...)
{ {
va_list ap; struct control_state *cs = c->control_state;
va_list ap;
char *s;
va_start(ap, fmt); va_start(ap, fmt);
file_vprint(c, fmt, ap); xvasprintf(&s, fmt, ap);
file_print(c, "\n");
va_end(ap); va_end(ap);
bufferevent_write(cs->write_event, s, strlen(s));
bufferevent_write(cs->write_event, "\n", 1);
free(s);
} }
/* Write output from a pane. */ /* Write output from a pane. */
void void
control_write_output(struct client *c, struct window_pane *wp) control_write_output(struct client *c, struct window_pane *wp)
{ {
struct control_state *cs = c->control_state;
struct control_offset *co; struct control_offset *co;
struct evbuffer *message; struct evbuffer *message;
u_char *new_data; u_char *new_data;
@ -165,11 +175,6 @@ control_write_output(struct client *c, struct window_pane *wp)
if (c->flags & CLIENT_CONTROL_NOOUTPUT) if (c->flags & CLIENT_CONTROL_NOOUTPUT)
return; return;
/*
* Only write input if the window pane is linked to a window belonging
* to the client's session.
*/
if (winlink_find_by_window(&c->session->windows, wp->window) == NULL) if (winlink_find_by_window(&c->session->windows, wp->window) == NULL)
return; return;
@ -193,15 +198,15 @@ control_write_output(struct client *c, struct window_pane *wp)
else else
evbuffer_add_printf(message, "%c", new_data[i]); evbuffer_add_printf(message, "%c", new_data[i]);
} }
evbuffer_add(message, "", 1); evbuffer_add(message, "\n", 1);
control_write(c, "%s", EVBUFFER_DATA(message)); bufferevent_write_buffer(cs->write_event, message);
evbuffer_free(message); evbuffer_free(message);
window_pane_update_used_data(wp, &co->offset, new_size, 1); window_pane_update_used_data(wp, &co->offset, new_size, 1);
} }
/* Control error callback. */ /* Control client error callback. */
static enum cmd_retval static enum cmd_retval
control_error(struct cmdq_item *item, void *data) control_error(struct cmdq_item *item, void *data)
{ {
@ -216,18 +221,27 @@ control_error(struct cmdq_item *item, void *data)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
/* Control input callback. Read lines and fire commands. */ /* Control client error callback. */
static void static void
control_callback(__unused struct client *c, __unused const char *path, control_error_callback(__unused struct bufferevent *bufev,
int read_error, int closed, struct evbuffer *buffer, __unused void *data) __unused short what, void *data)
{ {
struct client *c = data;
c->flags |= CLIENT_EXIT;
}
/* Control client input callback. Read lines and fire commands. */
static void
control_read_callback(__unused struct bufferevent *bufev, void *data)
{
struct client *c = data;
struct control_state *cs = c->control_state;
struct evbuffer *buffer = cs->read_event->input;
char *line, *error; char *line, *error;
struct cmdq_state *state; struct cmdq_state *state;
enum cmd_parse_status status; enum cmd_parse_status status;
if (closed || read_error != 0)
c->flags |= CLIENT_EXIT;
for (;;) { for (;;) {
line = evbuffer_readln(buffer, NULL, EVBUFFER_EOL_LF); line = evbuffer_readln(buffer, NULL, EVBUFFER_EOL_LF);
if (line == NULL) if (line == NULL)
@ -255,13 +269,30 @@ control_start(struct client *c)
{ {
struct control_state *cs; struct control_state *cs;
if (c->flags & CLIENT_CONTROLCONTROL) {
close(c->out_fd);
c->out_fd = -1;
} else
setblocking(c->out_fd, 0);
setblocking(c->fd, 0);
cs = c->control_state = xcalloc(1, sizeof *cs); cs = c->control_state = xcalloc(1, sizeof *cs);
RB_INIT(&cs->offsets); RB_INIT(&cs->offsets);
file_read(c, "-", control_callback, c); cs->read_event = bufferevent_new(c->fd, control_read_callback, NULL,
control_error_callback, c);
bufferevent_enable(cs->read_event, EV_READ);
if (c->flags & CLIENT_CONTROLCONTROL) if (c->flags & CLIENT_CONTROLCONTROL)
file_print(c, "\033P1000p"); cs->write_event = cs->read_event;
else {
cs->write_event = bufferevent_new(c->out_fd, NULL, NULL,
control_error_callback, c);
}
bufferevent_enable(cs->write_event, EV_WRITE);
if (c->flags & CLIENT_CONTROLCONTROL)
control_write(c, "\033P1000p");
} }
/* Stop control mode. */ /* Stop control mode. */
@ -270,6 +301,10 @@ control_stop(struct client *c)
{ {
struct control_state *cs = c->control_state; struct control_state *cs = c->control_state;
if (~c->flags & CLIENT_CONTROLCONTROL)
bufferevent_free(cs->write_event);
bufferevent_free(cs->read_event);
control_free_offsets(c); control_free_offsets(c);
free(cs); free(cs);
} }

8
file.c
View File

@ -239,7 +239,9 @@ file_write(struct client *c, const char *path, int flags, const void *bdata,
cf->path = xstrdup("-"); cf->path = xstrdup("-");
fd = STDOUT_FILENO; fd = STDOUT_FILENO;
if (c == NULL || c->flags & CLIENT_ATTACHED) { if (c == NULL ||
(c->flags & CLIENT_ATTACHED) ||
(c->flags & CLIENT_CONTROL)) {
cf->error = EBADF; cf->error = EBADF;
goto done; goto done;
} }
@ -308,7 +310,9 @@ file_read(struct client *c, const char *path, client_file_cb cb, void *cbdata)
cf->path = xstrdup("-"); cf->path = xstrdup("-");
fd = STDIN_FILENO; fd = STDIN_FILENO;
if (c == NULL || c->flags & CLIENT_ATTACHED) { if (c == NULL ||
(c->flags & CLIENT_ATTACHED) ||
(c->flags & CLIENT_CONTROL)) {
cf->error = EBADF; cf->error = EBADF;
goto done; goto done;
} }

1
grid.c
View File

@ -496,7 +496,6 @@ grid_get_cell1(struct grid_line *gl, u_int px, struct grid_cell *gc)
gc->fg = gee->fg; gc->fg = gee->fg;
gc->bg = gee->bg; gc->bg = gee->bg;
gc->us = gee->us; gc->us = gee->us;
log_debug("!!! %x", gc->flags);
utf8_to_data(gee->data, &gc->data); utf8_to_data(gee->data, &gc->data);
} }
return; return;

View File

@ -221,7 +221,7 @@ server_client_create(int fd)
c->environ = environ_create(); c->environ = environ_create();
c->fd = -1; c->fd = -1;
c->cwd = NULL; c->out_fd = -1;
c->queue = cmdq_new(); c->queue = cmdq_new();
RB_INIT(&c->windows); RB_INIT(&c->windows);
@ -336,6 +336,8 @@ server_client_lost(struct client *c)
proc_remove_peer(c->peer); proc_remove_peer(c->peer);
c->peer = NULL; c->peer = NULL;
if (c->out_fd != -1)
close(c->out_fd);
if (c->fd != -1) { if (c->fd != -1) {
close(c->fd); close(c->fd);
c->fd = -1; c->fd = -1;
@ -1571,10 +1573,9 @@ server_client_check_pane_buffer(struct window_pane *wp)
out: out:
/* /*
* If there is data remaining, and there are no clients able to consume * If there is data remaining, and there are no clients able to consume
* it, do not read any more. This is true when 1) there are attached * it, do not read any more. This is true when there are attached
* clients 2) all the clients are control clients 3) all of them have * clients, all of which are control clients which are not able to
* either the OFF flag set, or are otherwise not able to accept any * accept any more data.
* more data for this pane.
*/ */
if (off) if (off)
bufferevent_disable(wp->event, EV_READ); bufferevent_disable(wp->event, EV_READ);
@ -1967,6 +1968,7 @@ server_client_dispatch(struct imsg *imsg, void *arg)
case MSG_IDENTIFY_TTYNAME: case MSG_IDENTIFY_TTYNAME:
case MSG_IDENTIFY_CWD: case MSG_IDENTIFY_CWD:
case MSG_IDENTIFY_STDIN: case MSG_IDENTIFY_STDIN:
case MSG_IDENTIFY_STDOUT:
case MSG_IDENTIFY_ENVIRON: case MSG_IDENTIFY_ENVIRON:
case MSG_IDENTIFY_CLIENTPID: case MSG_IDENTIFY_CLIENTPID:
case MSG_IDENTIFY_DONE: case MSG_IDENTIFY_DONE:
@ -2177,6 +2179,12 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
c->fd = imsg->fd; c->fd = imsg->fd;
log_debug("client %p IDENTIFY_STDIN %d", c, imsg->fd); log_debug("client %p IDENTIFY_STDIN %d", c, imsg->fd);
break; break;
case MSG_IDENTIFY_STDOUT:
if (datalen != 0)
fatalx("bad MSG_IDENTIFY_STDOUT size");
c->out_fd = imsg->fd;
log_debug("client %p IDENTIFY_STDOUT %d", c, imsg->fd);
break;
case MSG_IDENTIFY_ENVIRON: case MSG_IDENTIFY_ENVIRON:
if (datalen == 0 || data[datalen - 1] != '\0') if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_ENVIRON string"); fatalx("bad MSG_IDENTIFY_ENVIRON string");
@ -2209,11 +2217,9 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
c->fd = open(c->ttyname, O_RDWR|O_NOCTTY); c->fd = open(c->ttyname, O_RDWR|O_NOCTTY);
#endif #endif
if (c->flags & CLIENT_CONTROL) { if (c->flags & CLIENT_CONTROL)
close(c->fd);
c->fd = -1;
control_start(c); control_start(c);
} else if (c->fd != -1) { else if (c->fd != -1) {
if (tty_init(&c->tty, c) != 0) { if (tty_init(&c->tty, c) != 0) {
close(c->fd); close(c->fd);
c->fd = -1; c->fd = -1;
@ -2221,6 +2227,8 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
tty_resize(&c->tty); tty_resize(&c->tty);
c->flags |= CLIENT_TERMINAL; c->flags |= CLIENT_TERMINAL;
} }
close(c->out_fd);
c->out_fd = -1;
} }
/* /*
@ -2337,7 +2345,8 @@ void
server_client_set_flags(struct client *c, const char *flags) server_client_set_flags(struct client *c, const char *flags)
{ {
char *s, *copy, *next; char *s, *copy, *next;
int flag, not; uint64_t flag;
int not;
s = copy = xstrdup (flags); s = copy = xstrdup (flags);
while ((next = strsep(&s, ",")) != NULL) { while ((next = strsep(&s, ",")) != NULL) {

View File

@ -1275,7 +1275,10 @@ process_key:
append_key: append_key:
if (key <= 0x1f || key >= KEYC_BASE) if (key <= 0x1f || key >= KEYC_BASE)
return (0); return (0);
utf8_to_data(key, &tmp); if (key <= 0x7f)
utf8_set(&tmp, key);
else
utf8_to_data(key, &tmp);
c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 2, c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 2,
sizeof *c->prompt_buffer); sizeof *c->prompt_buffer);

3
tmux.h
View File

@ -500,6 +500,7 @@ enum msgtype {
MSG_IDENTIFY_CLIENTPID, MSG_IDENTIFY_CLIENTPID,
MSG_IDENTIFY_CWD, MSG_IDENTIFY_CWD,
MSG_IDENTIFY_FEATURES, MSG_IDENTIFY_FEATURES,
MSG_IDENTIFY_STDOUT,
MSG_COMMAND = 200, MSG_COMMAND = 200,
MSG_DETACH, MSG_DETACH,
@ -969,6 +970,7 @@ struct window_pane {
int fd; int fd;
struct bufferevent *event; struct bufferevent *event;
struct window_pane_offset offset; struct window_pane_offset offset;
size_t base_offset; size_t base_offset;
@ -1583,6 +1585,7 @@ struct client {
pid_t pid; pid_t pid;
int fd; int fd;
int out_fd;
struct event event; struct event event;
int retval; int retval;