mirror of
https://github.com/tmux/tmux.git
synced 2026-10-12 13:44:44 +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;
|
pid_t ppid;
|
||||||
enum msgtype msg;
|
enum msgtype msg;
|
||||||
struct termios tio, saved_tio;
|
struct termios tio, saved_tio;
|
||||||
size_t size, linesize = 0;
|
size_t size;
|
||||||
ssize_t linelen;
|
char **caps = NULL, *cause;
|
||||||
char *line = NULL, **caps = NULL, *cause;
|
|
||||||
u_int ncaps = 0;
|
u_int ncaps = 0;
|
||||||
struct args_value *values;
|
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);
|
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. */
|
/* Print the exit message, if any, and exit. */
|
||||||
if (client_attached) {
|
if (client_attached) {
|
||||||
if (client_exitreason != CLIENT_EXIT_NONE)
|
if (client_exitreason != CLIENT_EXIT_NONE)
|
||||||
@@ -426,15 +420,8 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
|
|||||||
else
|
else
|
||||||
printf("%%exit\n");
|
printf("%%exit\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if (client_flags & CLIENT_CONTROL_WAITEXIT) {
|
if (client_flags & CLIENT_CONTROL_WAITEXIT)
|
||||||
setvbuf(stdin, NULL, _IOLBF, 0);
|
control_wait_exit(STDIN_FILENO);
|
||||||
for (;;) {
|
|
||||||
linelen = getline(&line, &linesize, stdin);
|
|
||||||
if (linelen <= 1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
if (client_flags & CLIENT_CONTROLCONTROL) {
|
if (client_flags & CLIENT_CONTROLCONTROL) {
|
||||||
printf("\033\\");
|
printf("\033\\");
|
||||||
fflush(stdout);
|
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)
|
} else if (client_exitreason != CLIENT_EXIT_NONE)
|
||||||
fprintf(stderr, "%s\n", client_exit_message());
|
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);
|
return (client_exitval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
50
control.c
50
control.c
@@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <event.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -485,6 +488,53 @@ control_all_done(struct client *c)
|
|||||||
return (EVBUFFER_LENGTH(cs->write_event->output) == 0);
|
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. */
|
/* Flush all blocks until output. */
|
||||||
static void
|
static void
|
||||||
control_flush_all_blocks(struct client *c)
|
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_start(struct client *);
|
||||||
void control_ready(struct client *);
|
void control_ready(struct client *);
|
||||||
void control_stop(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_on(struct client *, struct window_pane *);
|
||||||
void control_set_pane_off(struct client *, struct window_pane *);
|
void control_set_pane_off(struct client *, struct window_pane *);
|
||||||
void control_continue_pane(struct client *, struct window_pane *);
|
void control_continue_pane(struct client *, struct window_pane *);
|
||||||
|
|||||||
Reference in New Issue
Block a user