qrexec: Use pselect instead of select (#241)

Details here: http://wiki.qubes-os.org/trac/ticket/241
This commit is contained in:
Marek Marczykowski 2011-09-01 14:50:38 +02:00
parent 577dd2b076
commit e2aeceb230
3 changed files with 21 additions and 7 deletions

View File

@ -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();
} }
} }

View File

@ -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();
} }
} }

View File

@ -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");