mirror of
https://github.com/tmux/tmux.git
synced 2025-01-15 05:09:04 +00:00
Move all calls to fcntl(...O_NONBLOCK) into a function and clear the
flag on the stdio file descriptors before closing them (fixes things like "tmux ls && cat").
This commit is contained in:
parent
703160b5d6
commit
69cb1f830e
7
client.c
7
client.c
@ -54,7 +54,7 @@ client_connect(char *path, int start_server)
|
|||||||
{
|
{
|
||||||
struct sockaddr_un sa;
|
struct sockaddr_un sa;
|
||||||
size_t size;
|
size_t size;
|
||||||
int fd, mode;
|
int fd;
|
||||||
|
|
||||||
memset(&sa, 0, sizeof sa);
|
memset(&sa, 0, sizeof sa);
|
||||||
sa.sun_family = AF_UNIX;
|
sa.sun_family = AF_UNIX;
|
||||||
@ -84,10 +84,7 @@ client_connect(char *path, int start_server)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mode = fcntl(fd, F_GETFL)) == -1)
|
setblocking(fd, 0);
|
||||||
fatal("fcntl failed");
|
|
||||||
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
return (fd);
|
return (fd);
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
@ -53,7 +53,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
struct client *c;
|
struct client *c;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
char *command;
|
char *command;
|
||||||
int old_fd, pipe_fd[2], null_fd, mode;
|
int old_fd, pipe_fd[2], null_fd;
|
||||||
|
|
||||||
if ((c = cmd_find_client(ctx, NULL)) == NULL)
|
if ((c = cmd_find_client(ctx, NULL)) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -127,10 +127,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
NULL, NULL, cmd_pipe_pane_error_callback, wp);
|
NULL, NULL, cmd_pipe_pane_error_callback, wp);
|
||||||
bufferevent_enable(wp->pipe_event, EV_WRITE);
|
bufferevent_enable(wp->pipe_event, EV_WRITE);
|
||||||
|
|
||||||
if ((mode = fcntl(wp->pipe_fd, F_GETFL)) == -1)
|
setblocking(wp->pipe_fd, 0);
|
||||||
fatal("fcntl failed");
|
|
||||||
if (fcntl(wp->pipe_fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
job.c
7
job.c
@ -137,7 +137,7 @@ job_free(struct job *job)
|
|||||||
int
|
int
|
||||||
job_run(struct job *job)
|
job_run(struct job *job)
|
||||||
{
|
{
|
||||||
int nullfd, out[2], mode;
|
int nullfd, out[2];
|
||||||
|
|
||||||
if (job->fd != -1 || job->pid != -1)
|
if (job->fd != -1 || job->pid != -1)
|
||||||
return (0);
|
return (0);
|
||||||
@ -177,10 +177,7 @@ job_run(struct job *job)
|
|||||||
close(out[1]);
|
close(out[1]);
|
||||||
|
|
||||||
job->fd = out[0];
|
job->fd = out[0];
|
||||||
if ((mode = fcntl(job->fd, F_GETFL)) == -1)
|
setblocking(job->fd, 0);
|
||||||
fatal("fcntl failed");
|
|
||||||
if (fcntl(job->fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
|
|
||||||
if (job->event != NULL)
|
if (job->event != NULL)
|
||||||
bufferevent_free(job->event);
|
bufferevent_free(job->event);
|
||||||
|
@ -53,13 +53,9 @@ void
|
|||||||
server_client_create(int fd)
|
server_client_create(int fd)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct client *c;
|
||||||
int mode;
|
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
if ((mode = fcntl(fd, F_GETFL)) == -1)
|
setblocking(fd, 0);
|
||||||
fatal("fcntl failed");
|
|
||||||
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
|
|
||||||
c = xcalloc(1, sizeof *c);
|
c = xcalloc(1, sizeof *c);
|
||||||
c->references = 0;
|
c->references = 0;
|
||||||
@ -124,16 +120,22 @@ server_client_lost(struct client *c)
|
|||||||
if (c->flags & CLIENT_TERMINAL)
|
if (c->flags & CLIENT_TERMINAL)
|
||||||
tty_free(&c->tty);
|
tty_free(&c->tty);
|
||||||
|
|
||||||
if (c->stdin_fd != -1)
|
if (c->stdin_fd != -1) {
|
||||||
|
setblocking(c->stdin_fd, 1);
|
||||||
close(c->stdin_fd);
|
close(c->stdin_fd);
|
||||||
|
}
|
||||||
if (c->stdin_event != NULL)
|
if (c->stdin_event != NULL)
|
||||||
bufferevent_free(c->stdin_event);
|
bufferevent_free(c->stdin_event);
|
||||||
if (c->stdout_fd != -1)
|
if (c->stdout_fd != -1) {
|
||||||
|
setblocking(c->stdout_fd, 1);
|
||||||
close(c->stdout_fd);
|
close(c->stdout_fd);
|
||||||
|
}
|
||||||
if (c->stdout_event != NULL)
|
if (c->stdout_event != NULL)
|
||||||
bufferevent_free(c->stdout_event);
|
bufferevent_free(c->stdout_event);
|
||||||
if (c->stderr_fd != -1)
|
if (c->stderr_fd != -1) {
|
||||||
|
setblocking(c->stderr_fd, 1);
|
||||||
close(c->stderr_fd);
|
close(c->stderr_fd);
|
||||||
|
}
|
||||||
if (c->stderr_event != NULL)
|
if (c->stderr_event != NULL)
|
||||||
bufferevent_free(c->stderr_event);
|
bufferevent_free(c->stderr_event);
|
||||||
|
|
||||||
@ -632,6 +634,7 @@ server_client_in_callback(
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
bufferevent_disable(c->stdin_event, EV_READ|EV_WRITE);
|
bufferevent_disable(c->stdin_event, EV_READ|EV_WRITE);
|
||||||
|
setblocking(c->stdin_fd, 1);
|
||||||
close(c->stdin_fd);
|
close(c->stdin_fd);
|
||||||
c->stdin_fd = -1;
|
c->stdin_fd = -1;
|
||||||
|
|
||||||
@ -647,6 +650,7 @@ server_client_out_callback(
|
|||||||
struct client *c = data;
|
struct client *c = data;
|
||||||
|
|
||||||
bufferevent_disable(c->stdout_event, EV_READ|EV_WRITE);
|
bufferevent_disable(c->stdout_event, EV_READ|EV_WRITE);
|
||||||
|
setblocking(c->stdout_fd, 1);
|
||||||
close(c->stdout_fd);
|
close(c->stdout_fd);
|
||||||
c->stdout_fd = -1;
|
c->stdout_fd = -1;
|
||||||
}
|
}
|
||||||
@ -659,6 +663,7 @@ server_client_err_callback(
|
|||||||
struct client *c = data;
|
struct client *c = data;
|
||||||
|
|
||||||
bufferevent_disable(c->stderr_event, EV_READ|EV_WRITE);
|
bufferevent_disable(c->stderr_event, EV_READ|EV_WRITE);
|
||||||
|
setblocking(c->stderr_fd, 1);
|
||||||
close(c->stderr_fd);
|
close(c->stderr_fd);
|
||||||
c->stderr_fd = -1;
|
c->stderr_fd = -1;
|
||||||
}
|
}
|
||||||
@ -672,7 +677,6 @@ server_client_msg_dispatch(struct client *c)
|
|||||||
struct msg_identify_data identifydata;
|
struct msg_identify_data identifydata;
|
||||||
struct msg_environ_data environdata;
|
struct msg_environ_data environdata;
|
||||||
ssize_t n, datalen;
|
ssize_t n, datalen;
|
||||||
int mode;
|
|
||||||
|
|
||||||
if ((n = imsg_read(&c->ibuf)) == -1 || n == 0)
|
if ((n = imsg_read(&c->ibuf)) == -1 || n == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -712,9 +716,7 @@ server_client_msg_dispatch(struct client *c)
|
|||||||
NULL, NULL, server_client_in_callback, c);
|
NULL, NULL, server_client_in_callback, c);
|
||||||
if (c->stdin_event == NULL)
|
if (c->stdin_event == NULL)
|
||||||
fatalx("failed to create stdin event");
|
fatalx("failed to create stdin event");
|
||||||
|
setblocking(c->stdin_fd, 0);
|
||||||
if ((mode = fcntl(c->stdin_fd, F_GETFL)) != -1)
|
|
||||||
fcntl(c->stdin_fd, F_SETFL, mode|O_NONBLOCK);
|
|
||||||
|
|
||||||
server_client_msg_identify(c, &identifydata, imsg.fd);
|
server_client_msg_identify(c, &identifydata, imsg.fd);
|
||||||
break;
|
break;
|
||||||
@ -729,9 +731,8 @@ server_client_msg_dispatch(struct client *c)
|
|||||||
NULL, NULL, server_client_out_callback, c);
|
NULL, NULL, server_client_out_callback, c);
|
||||||
if (c->stdout_event == NULL)
|
if (c->stdout_event == NULL)
|
||||||
fatalx("failed to create stdout event");
|
fatalx("failed to create stdout event");
|
||||||
|
setblocking(c->stdout_fd, 0);
|
||||||
|
|
||||||
if ((mode = fcntl(c->stdout_fd, F_GETFL)) != -1)
|
|
||||||
fcntl(c->stdout_fd, F_SETFL, mode|O_NONBLOCK);
|
|
||||||
break;
|
break;
|
||||||
case MSG_STDERR:
|
case MSG_STDERR:
|
||||||
if (datalen != 0)
|
if (datalen != 0)
|
||||||
@ -744,9 +745,8 @@ server_client_msg_dispatch(struct client *c)
|
|||||||
NULL, NULL, server_client_err_callback, c);
|
NULL, NULL, server_client_err_callback, c);
|
||||||
if (c->stderr_event == NULL)
|
if (c->stderr_event == NULL)
|
||||||
fatalx("failed to create stderr event");
|
fatalx("failed to create stderr event");
|
||||||
|
setblocking(c->stderr_fd, 0);
|
||||||
|
|
||||||
if ((mode = fcntl(c->stderr_fd, F_GETFL)) != -1)
|
|
||||||
fcntl(c->stderr_fd, F_SETFL, mode|O_NONBLOCK);
|
|
||||||
break;
|
break;
|
||||||
case MSG_RESIZE:
|
case MSG_RESIZE:
|
||||||
if (datalen != 0)
|
if (datalen != 0)
|
||||||
|
8
server.c
8
server.c
@ -74,7 +74,7 @@ server_create_socket(void)
|
|||||||
struct sockaddr_un sa;
|
struct sockaddr_un sa;
|
||||||
size_t size;
|
size_t size;
|
||||||
mode_t mask;
|
mode_t mask;
|
||||||
int fd, mode;
|
int fd;
|
||||||
|
|
||||||
memset(&sa, 0, sizeof sa);
|
memset(&sa, 0, sizeof sa);
|
||||||
sa.sun_family = AF_UNIX;
|
sa.sun_family = AF_UNIX;
|
||||||
@ -95,11 +95,7 @@ server_create_socket(void)
|
|||||||
|
|
||||||
if (listen(fd, 16) == -1)
|
if (listen(fd, 16) == -1)
|
||||||
fatal("listen failed");
|
fatal("listen failed");
|
||||||
|
setblocking(fd, 0);
|
||||||
if ((mode = fcntl(fd, F_GETFL)) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
|
|
||||||
server_update_socket();
|
server_update_socket();
|
||||||
|
|
||||||
|
24
tmux.c
24
tmux.c
@ -194,12 +194,25 @@ makesocketpath(const char *label)
|
|||||||
return (path);
|
return (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setblocking(int fd, int state)
|
||||||
|
{
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
if ((mode = fcntl(fd, F_GETFL)) != -1) {
|
||||||
|
if (!state)
|
||||||
|
mode |= O_NONBLOCK;
|
||||||
|
else
|
||||||
|
mode &= ~O_NONBLOCK;
|
||||||
|
fcntl(fd, F_SETFL, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__dead void
|
__dead void
|
||||||
shell_exec(const char *shell, const char *shellcmd)
|
shell_exec(const char *shell, const char *shellcmd)
|
||||||
{
|
{
|
||||||
const char *shellname, *ptr;
|
const char *shellname, *ptr;
|
||||||
char *argv0;
|
char *argv0;
|
||||||
int mode;
|
|
||||||
|
|
||||||
ptr = strrchr(shell, '/');
|
ptr = strrchr(shell, '/');
|
||||||
if (ptr != NULL && *(ptr + 1) != '\0')
|
if (ptr != NULL && *(ptr + 1) != '\0')
|
||||||
@ -212,12 +225,9 @@ shell_exec(const char *shell, const char *shellcmd)
|
|||||||
xasprintf(&argv0, "%s", shellname);
|
xasprintf(&argv0, "%s", shellname);
|
||||||
setenv("SHELL", shell, 1);
|
setenv("SHELL", shell, 1);
|
||||||
|
|
||||||
if ((mode = fcntl(STDIN_FILENO, F_GETFL)) != -1)
|
setblocking(STDIN_FILENO, 1);
|
||||||
fcntl(STDIN_FILENO, F_SETFL, mode & ~O_NONBLOCK);
|
setblocking(STDOUT_FILENO, 1);
|
||||||
if ((mode = fcntl(STDOUT_FILENO, F_GETFL)) != -1)
|
setblocking(STDERR_FILENO, 1);
|
||||||
fcntl(STDOUT_FILENO, F_SETFL, mode & ~O_NONBLOCK);
|
|
||||||
if ((mode = fcntl(STDERR_FILENO, F_GETFL)) != -1)
|
|
||||||
fcntl(STDERR_FILENO, F_SETFL, mode & ~O_NONBLOCK);
|
|
||||||
closefrom(STDERR_FILENO + 1);
|
closefrom(STDERR_FILENO + 1);
|
||||||
|
|
||||||
execl(shell, argv0, "-c", shellcmd, (char *) NULL);
|
execl(shell, argv0, "-c", shellcmd, (char *) NULL);
|
||||||
|
1
tmux.h
1
tmux.h
@ -1308,6 +1308,7 @@ void logfile(const char *);
|
|||||||
const char *getshell(void);
|
const char *getshell(void);
|
||||||
int checkshell(const char *);
|
int checkshell(const char *);
|
||||||
int areshell(const char *);
|
int areshell(const char *);
|
||||||
|
void setblocking(int, int);
|
||||||
__dead void shell_exec(const char *, const char *);
|
__dead void shell_exec(const char *, const char *);
|
||||||
|
|
||||||
/* cfg.c */
|
/* cfg.c */
|
||||||
|
10
tty.c
10
tty.c
@ -165,15 +165,11 @@ void
|
|||||||
tty_start_tty(struct tty *tty)
|
tty_start_tty(struct tty *tty)
|
||||||
{
|
{
|
||||||
struct termios tio;
|
struct termios tio;
|
||||||
int mode;
|
|
||||||
|
|
||||||
if (tty->fd == -1)
|
if (tty->fd == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((mode = fcntl(tty->fd, F_GETFL)) == -1)
|
setblocking(tty->fd, 0);
|
||||||
fatal("fcntl failed");
|
|
||||||
if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
|
|
||||||
bufferevent_enable(tty->event, EV_READ|EV_WRITE);
|
bufferevent_enable(tty->event, EV_READ|EV_WRITE);
|
||||||
|
|
||||||
@ -220,7 +216,6 @@ void
|
|||||||
tty_stop_tty(struct tty *tty)
|
tty_stop_tty(struct tty *tty)
|
||||||
{
|
{
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
int mode;
|
|
||||||
|
|
||||||
if (!(tty->flags & TTY_STARTED))
|
if (!(tty->flags & TTY_STARTED))
|
||||||
return;
|
return;
|
||||||
@ -251,8 +246,7 @@ tty_stop_tty(struct tty *tty)
|
|||||||
|
|
||||||
tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
|
tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
|
||||||
|
|
||||||
if ((mode = fcntl(tty->fd, F_GETFL)) != -1)
|
setblocking(tty->fd, 1);
|
||||||
fcntl(tty->fd, F_SETFL, mode & ~O_NONBLOCK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
7
window.c
7
window.c
@ -563,7 +563,6 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
|
|||||||
const char *cwd, struct environ *env, struct termios *tio, char **cause)
|
const char *cwd, struct environ *env, struct termios *tio, char **cause)
|
||||||
{
|
{
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
int mode;
|
|
||||||
char *argv0;
|
char *argv0;
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
struct termios tio2;
|
struct termios tio2;
|
||||||
@ -637,10 +636,8 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
|
|||||||
fatal("execl failed");
|
fatal("execl failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mode = fcntl(wp->fd, F_GETFL)) == -1)
|
setblocking(wp->fd, 0);
|
||||||
fatal("fcntl failed");
|
|
||||||
if (fcntl(wp->fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
wp->event = bufferevent_new(wp->fd,
|
wp->event = bufferevent_new(wp->fd,
|
||||||
window_pane_read_callback, NULL, window_pane_error_callback, wp);
|
window_pane_read_callback, NULL, window_pane_error_callback, wp);
|
||||||
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
|
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
|
||||||
|
Loading…
Reference in New Issue
Block a user