qrexec: Use pselect instead of select (#241)
Details here: http://wiki.qubes-os.org/trac/ticket/241
This commit is contained in:
parent
577dd2b076
commit
e2aeceb230
@ -532,10 +532,13 @@ int main()
|
|||||||
fd_set rdset, wrset;
|
fd_set rdset, wrset;
|
||||||
int max;
|
int max;
|
||||||
int i;
|
int i;
|
||||||
|
sigset_t chld_set;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
signal(SIGCHLD, sigchld_handler);
|
signal(SIGCHLD, sigchld_handler);
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
sigemptyset(&chld_set);
|
||||||
|
sigaddset(&chld_set, SIGCHLD);
|
||||||
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -544,7 +547,11 @@ int main()
|
|||||||
sizeof(struct server_header))
|
sizeof(struct server_header))
|
||||||
FD_ZERO(&rdset);
|
FD_ZERO(&rdset);
|
||||||
|
|
||||||
|
sigprocmask(SIG_BLOCK, &chld_set, NULL);
|
||||||
|
if (child_exited)
|
||||||
|
reap_children();
|
||||||
wait_for_vchan_or_argfd(max, &rdset, &wrset);
|
wait_for_vchan_or_argfd(max, &rdset, &wrset);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &chld_set, NULL);
|
||||||
|
|
||||||
if (FD_ISSET(passfd_socket, &rdset))
|
if (FD_ISSET(passfd_socket, &rdset))
|
||||||
handle_new_passfd();
|
handle_new_passfd();
|
||||||
@ -561,8 +568,5 @@ int main()
|
|||||||
&& client_info[i].is_blocked
|
&& client_info[i].is_blocked
|
||||||
&& FD_ISSET(client_info[i].stdin_fd, &wrset))
|
&& FD_ISSET(client_info[i].stdin_fd, &wrset))
|
||||||
flush_client_data_agent(i);
|
flush_client_data_agent(i);
|
||||||
|
|
||||||
if (child_exited)
|
|
||||||
reap_children();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -555,12 +555,15 @@ int main(int argc, char **argv)
|
|||||||
fd_set read_fdset, write_fdset;
|
fd_set read_fdset, write_fdset;
|
||||||
int i;
|
int i;
|
||||||
int max;
|
int max;
|
||||||
|
sigset_t chld_set;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf(stderr, "usage: %s domainid\n", argv[0]);
|
fprintf(stderr, "usage: %s domainid\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
init(atoi(argv[1]));
|
init(atoi(argv[1]));
|
||||||
|
sigemptyset(&chld_set);
|
||||||
|
sigaddset(&chld_set, SIGCHLD);
|
||||||
/*
|
/*
|
||||||
The main event loop. Waits for one of the following events:
|
The main event loop. Waits for one of the following events:
|
||||||
- message from client
|
- message from client
|
||||||
@ -574,7 +577,11 @@ int main(int argc, char **argv)
|
|||||||
sizeof(struct server_header))
|
sizeof(struct server_header))
|
||||||
FD_ZERO(&read_fdset); // vchan full - don't read from clients
|
FD_ZERO(&read_fdset); // vchan full - don't read from clients
|
||||||
|
|
||||||
|
sigprocmask(SIG_BLOCK, &chld_set, NULL);
|
||||||
|
if (child_exited)
|
||||||
|
reap_children();
|
||||||
wait_for_vchan_or_argfd(max, &read_fdset, &write_fdset);
|
wait_for_vchan_or_argfd(max, &read_fdset, &write_fdset);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &chld_set, NULL);
|
||||||
|
|
||||||
if (FD_ISSET(qrexec_daemon_unix_socket_fd, &read_fdset))
|
if (FD_ISSET(qrexec_daemon_unix_socket_fd, &read_fdset))
|
||||||
handle_new_client();
|
handle_new_client();
|
||||||
@ -591,8 +598,6 @@ int main(int argc, char **argv)
|
|||||||
if (clients[i].state != CLIENT_INVALID
|
if (clients[i].state != CLIENT_INVALID
|
||||||
&& FD_ISSET(i, &write_fdset))
|
&& FD_ISSET(i, &write_fdset))
|
||||||
write_buffered_data_to_client(i);
|
write_buffered_data_to_client(i);
|
||||||
if (child_exited)
|
|
||||||
reap_children();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <libvchan.h>
|
#include <libvchan.h>
|
||||||
#include <xs.h>
|
#include <xs.h>
|
||||||
#include <xenctrl.h>
|
#include <xenctrl.h>
|
||||||
@ -107,13 +108,17 @@ void slow_check_for_libvchan_is_eof(struct libvchan *ctrl)
|
|||||||
int wait_for_vchan_or_argfd_once(int max, fd_set * rdset, fd_set * wrset)
|
int wait_for_vchan_or_argfd_once(int max, fd_set * rdset, fd_set * wrset)
|
||||||
{
|
{
|
||||||
int vfd, ret;
|
int vfd, ret;
|
||||||
struct timeval tv = { 1, 100000 };
|
struct timespec tv = { 1, 100000000 };
|
||||||
|
sigset_t empty_set;
|
||||||
|
|
||||||
|
sigemptyset(&empty_set);
|
||||||
|
|
||||||
vfd = libvchan_fd_for_select(ctrl);
|
vfd = libvchan_fd_for_select(ctrl);
|
||||||
FD_SET(vfd, rdset);
|
FD_SET(vfd, rdset);
|
||||||
if (vfd > max)
|
if (vfd > max)
|
||||||
max = vfd;
|
max = vfd;
|
||||||
max++;
|
max++;
|
||||||
ret = select(max, rdset, wrset, NULL, &tv);
|
ret = pselect(max, rdset, wrset, NULL, &tv, &empty_set);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
perror("select");
|
perror("select");
|
||||||
|
Loading…
Reference in New Issue
Block a user