mirror of
https://github.com/tmux/tmux.git
synced 2026-07-14 13:10:39 +00:00
Merge branch 'obsd-master'
This commit is contained in:
27
client.c
27
client.c
@@ -239,9 +239,8 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
|
||||
pid_t ppid;
|
||||
enum msgtype msg;
|
||||
struct termios tio, saved_tio;
|
||||
size_t size, linesize = 0;
|
||||
ssize_t linelen;
|
||||
char *line = NULL, **caps = NULL, *cause;
|
||||
size_t size;
|
||||
char **caps = NULL, *cause;
|
||||
u_int ncaps = 0;
|
||||
struct args_value *values;
|
||||
|
||||
@@ -407,11 +406,6 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
|
||||
client_exec(client_execshell, client_execcmd);
|
||||
}
|
||||
|
||||
/* Restore streams to blocking. */
|
||||
setblocking(STDIN_FILENO, 1);
|
||||
setblocking(STDOUT_FILENO, 1);
|
||||
setblocking(STDERR_FILENO, 1);
|
||||
|
||||
/* Print the exit message, if any, and exit. */
|
||||
if (client_attached) {
|
||||
if (client_exitreason != CLIENT_EXIT_NONE)
|
||||
@@ -426,15 +420,8 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
|
||||
else
|
||||
printf("%%exit\n");
|
||||
fflush(stdout);
|
||||
if (client_flags & CLIENT_CONTROL_WAITEXIT) {
|
||||
setvbuf(stdin, NULL, _IOLBF, 0);
|
||||
for (;;) {
|
||||
linelen = getline(&line, &linesize, stdin);
|
||||
if (linelen <= 1)
|
||||
break;
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
if (client_flags & CLIENT_CONTROL_WAITEXIT)
|
||||
control_wait_exit(STDIN_FILENO);
|
||||
if (client_flags & CLIENT_CONTROLCONTROL) {
|
||||
printf("\033\\");
|
||||
fflush(stdout);
|
||||
@@ -442,6 +429,12 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
|
||||
}
|
||||
} else if (client_exitreason != CLIENT_EXIT_NONE)
|
||||
fprintf(stderr, "%s\n", client_exit_message());
|
||||
|
||||
/* Restore the streams to blocking. */
|
||||
setblocking(STDIN_FILENO, 1);
|
||||
setblocking(STDOUT_FILENO, 1);
|
||||
setblocking(STDERR_FILENO, 1);
|
||||
|
||||
return (client_exitval);
|
||||
}
|
||||
|
||||
|
||||
50
control.c
50
control.c
@@ -19,6 +19,9 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <event.h>
|
||||
#include <poll.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@@ -485,6 +488,53 @@ control_all_done(struct client *c)
|
||||
return (EVBUFFER_LENGTH(cs->write_event->output) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the terminal to send an empty line or close, used by a control
|
||||
* client after printing %exit so a wrapping terminal (such as iTerm2) can
|
||||
* finish reading.
|
||||
*/
|
||||
void
|
||||
control_wait_exit(int fd)
|
||||
{
|
||||
struct pollfd pfd;
|
||||
struct evbuffer *evb;
|
||||
char *line;
|
||||
int n;
|
||||
|
||||
evb = evbuffer_new();
|
||||
if (evb == NULL)
|
||||
fatalx("out of memory");
|
||||
|
||||
for (;;) {
|
||||
line = evbuffer_readln(evb, NULL, EVBUFFER_EOL_LF);
|
||||
if (line != NULL) {
|
||||
if (*line == '\0') { /* empty line, stop */
|
||||
free(line);
|
||||
break;
|
||||
}
|
||||
free(line);
|
||||
continue; /* drain buffered lines first */
|
||||
}
|
||||
|
||||
memset(&pfd, 0, sizeof pfd);
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLIN;
|
||||
if (poll(&pfd, 1, INFTIM) == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
n = evbuffer_read(evb, fd, -1);
|
||||
if (n == 0)
|
||||
break;
|
||||
if (n == -1 && errno != EAGAIN && errno != EINTR)
|
||||
break;
|
||||
}
|
||||
|
||||
evbuffer_free(evb);
|
||||
}
|
||||
|
||||
/* Flush all blocks until output. */
|
||||
static void
|
||||
control_flush_all_blocks(struct client *c)
|
||||
|
||||
1
tmux.h
1
tmux.h
@@ -3967,6 +3967,7 @@ void control_discard(struct client *);
|
||||
void control_start(struct client *);
|
||||
void control_ready(struct client *);
|
||||
void control_stop(struct client *);
|
||||
void control_wait_exit(int);
|
||||
void control_set_pane_on(struct client *, struct window_pane *);
|
||||
void control_set_pane_off(struct client *, struct window_pane *);
|
||||
void control_continue_pane(struct client *, struct window_pane *);
|
||||
|
||||
Reference in New Issue
Block a user