0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

birdc died during terminal resize because of unhandled EINTR

in select loop.
This commit is contained in:
Ondrej Zajicek 2008-11-21 12:59:03 +01:00
parent 44711e0ca2
commit e00115904f

View File

@ -298,11 +298,18 @@ server_read(void)
int c; int c;
byte *start, *p; byte *start, *p;
redo:
c = read(server_fd, server_read_pos, server_read_buf + sizeof(server_read_buf) - server_read_pos); c = read(server_fd, server_read_pos, server_read_buf + sizeof(server_read_buf) - server_read_pos);
if (!c) if (!c)
die("Connection closed by server."); die("Connection closed by server.");
if (c < 0) if (c < 0)
die("Server read error: %m"); {
if (errno == EINTR)
goto redo;
else
die("Server read error: %m");
}
start = server_read_buf; start = server_read_buf;
p = server_read_pos; p = server_read_pos;
server_read_pos += c; server_read_pos += c;
@ -331,6 +338,7 @@ static fd_set select_fds;
static void static void
select_loop(int mode) select_loop(int mode)
{ {
int rv;
server_reply = -1; server_reply = -1;
while (mode || server_reply < 0) while (mode || server_reply < 0)
{ {
@ -338,7 +346,16 @@ select_loop(int mode)
FD_SET(server_fd, &select_fds); FD_SET(server_fd, &select_fds);
if (mode) if (mode)
FD_SET(0, &select_fds); FD_SET(0, &select_fds);
select(server_fd+1, &select_fds, NULL, NULL, NULL);
rv = select(server_fd+1, &select_fds, NULL, NULL, NULL);
if (rv < 0)
{
if (errno == EINTR)
continue;
else
die("select: %m");
}
if (FD_ISSET(server_fd, &select_fds)) if (FD_ISSET(server_fd, &select_fds))
{ {
server_read(); server_read();
@ -351,6 +368,30 @@ select_loop(int mode)
input_reveal(); input_reveal();
} }
static void
wait_for_write(int fd)
{
while (1)
{
int rv;
fd_set set;
FD_ZERO(&set);
FD_SET(fd, &set);
rv = select(fd+1, NULL, &set, NULL, NULL);
if (rv < 0)
{
if (errno == EINTR)
continue;
else
die("select: %m");
}
if (FD_ISSET(server_fd, &set))
return;
}
}
static void static void
server_send(char *cmd) server_send(char *cmd)
{ {
@ -362,19 +403,13 @@ server_send(char *cmd)
while (l) while (l)
{ {
int cnt = write(server_fd, z, l); int cnt = write(server_fd, z, l);
if (cnt < 0) if (cnt < 0)
{ {
if (errno == -EAGAIN) if (errno == EAGAIN)
{ wait_for_write(server_fd);
fd_set set; else if (errno == EINTR)
FD_ZERO(&set); continue;
do
{
FD_SET(server_fd, &set);
select(server_fd+1, NULL, &set, NULL, NULL);
}
while (!FD_ISSET(server_fd, &set));
}
else else
die("Server write error: %m"); die("Server write error: %m");
} }