Index: /server/common/oursrc/execsys/gitproxy.pl
===================================================================
--- /server/common/oursrc/execsys/gitproxy.pl	(revision 902)
+++ /server/common/oursrc/execsys/gitproxy.pl	(revision 903)
@@ -2,5 +2,5 @@
 #
 # gitproxy: Wrapper around git daemon for Git virtual hosting.
-# version 1.0, released 2008-10-08
+# version 1.1, released 2008-12-28
 # Copyright © 2008 Anders Kaseorg <andersk@mit.edu>
 #
@@ -23,4 +23,5 @@
 use IPC::Open2;
 use Errno qw(EINTR);
+use IO::Poll qw(POLLIN POLLOUT POLLHUP);
 
 # Receive the first message from the client, and parse out the URL.
@@ -46,33 +47,31 @@
 
 # Now start the real git daemon based on the URL.
-open2(\*IN, \*OUT, '/usr/local/sbin/ldapize.pl', "git://$host/") or die "$0: open: $!";
+my $pid = open2(\*IN, \*OUT, '/usr/local/sbin/ldapize.pl', "git://$host/") or die "$0: open: $!";
 
-# Finally, go into a select loop to transfer the remaining data
+# Finally, go into a poll loop to transfer the remaining data
 # (STDIN -> OUT, IN -> STDOUT), including the client's message to git daemon.
 my ($cbuf, $sbuf) = ($msg, '');
-my ($rin, $win, $ein) = ('', '', '');
-my ($stdout, $out, $stdin, $in) = (fileno(STDOUT), fileno(OUT), fileno(STDIN), fileno(IN));
-vec($win, $stdout, 1) = 0;
-vec($win, $out, 1) = 1;
-vec($rin, $stdin, 1) = 0;
-vec($rin, $in, 1) = 1;
-while (vec($win, $stdout, 1) or vec($win, $out, 1) or
-       vec($rin, $stdin, 1) or vec($rin, $in, 1)) {
-    my $n = select(my $rout = $rin, my $wout = $win, my $eout = $ein, undef);
+my $poll = new IO::Poll;
+$poll->mask(\*STDOUT => POLLHUP);
+$poll->mask(\*OUT => POLLOUT);
+$poll->remove(\*STDIN);
+$poll->mask(\*IN => POLLIN);
+while ($poll->handles()) {
+    my $n = $poll->poll();
     next if $n < 0 and $! == EINTR;
     $n >= 0 or die "select: $!";
-    if (vec($rout, $stdin, 1)) {
+    if ($poll->events(\*STDIN)) {
 	my $n = sysread(STDIN, $cbuf, 4096);
 	next if $n < 0 and $! == EINTR;
 	$n >= 0 or die "read: $!";
-	vec($rin, $stdin, 1) = 0;
-	vec($win, $out, 1) = 1;
-    } elsif (vec($rout, $in, 1)) {
+	$poll->remove(\*STDIN);
+	$poll->mask(\*OUT => POLLOUT);
+    } elsif ($poll->events(\*IN)) {
 	my $n = sysread(IN, $sbuf, 4096);
 	next if $n < 0 and $! == EINTR;
 	$n >= 0 or die "read: $!";
-	vec($rin, $in, 1) = 0;
-	vec($win, $stdout, 1) = 1;
-    } elsif (vec($wout, $stdout, 1) && $sbuf ne '') {
+	$poll->remove(\*IN);
+	$poll->mask(\*STDOUT => POLLOUT);
+    } elsif ($poll->events(\*STDOUT) & POLLOUT && $sbuf ne '') {
 	my $n = syswrite(STDOUT, $sbuf);
 	next if $n < 0 and $! == EINTR;
@@ -80,12 +79,13 @@
 	$sbuf = substr($sbuf, $n);
 	if ($sbuf eq '') {
-	    vec($win, $stdout, 1) = 0;
-	    vec($rin, $in, 1) = 1;
+	    $poll->mask(\*STDOUT => POLLHUP);
+	    $poll->mask(\*IN => POLLIN);
 	}
-    } elsif (vec($wout, $stdout, 1)) {
-	vec($win, $stdout, 1) = 0;
+    } elsif ($poll->events(\*STDOUT)) {
+	$poll->remove(\*STDOUT);
+	$poll->remove(\*IN);
 	close(STDOUT) or die "close: $!";
 	close(IN) or die "close: $!";
-    } elsif (vec($wout, $out, 1) && $cbuf ne '') {
+    } elsif ($poll->events(\*OUT) & POLLOUT && $cbuf ne '') {
 	my $n = syswrite(OUT, $cbuf);
 	next if $n < 0 and $! == EINTR;
@@ -93,11 +93,14 @@
 	$cbuf = substr($cbuf, $n);
 	if ($cbuf eq '') {
-	    vec($win, $out, 1) = 0;
-	    vec($rin, $stdin, 1) = 1;
+	    $poll->mask(\*OUT => POLLHUP);
+	    $poll->mask(\*STDIN => POLLIN);
 	}
-    } elsif (vec($wout, $out, 1)) {
-	vec($win, $out, 1) = 0;
+    } elsif ($poll->events(\*OUT)) {
+	$poll->remove(\*OUT);
+	$poll->remove(\*STDIN);
 	close(OUT) or die "close: $!";
 	close(STDIN) or die "close: $!";
     }
 }
+
+while (waitpid($pid, 0) == -1 && $! == EINTR) { }
Index: /server/common/oursrc/execsys/svnproxy.pl
===================================================================
--- /server/common/oursrc/execsys/svnproxy.pl	(revision 902)
+++ /server/common/oursrc/execsys/svnproxy.pl	(revision 903)
@@ -2,5 +2,5 @@
 #
 # svnproxy: Wrapper around svnserve for Subversion virtual hosting.
-# version 1.0, released 2008-08-29
+# version 1.1, released 2008-12-28
 # Copyright © 2008 Anders Kaseorg <andersk@mit.edu>
 #
@@ -23,4 +23,5 @@
 use IPC::Open2;
 use Errno qw(EINTR);
+use IO::Poll qw(POLLIN POLLOUT POLLHUP);
 
 # Read the initial greeting from a dummy svnserve process.
@@ -71,5 +72,5 @@
 
 # Now start the real svnserve based on the URL.
-open2(\*IN, \*OUT, '/usr/local/sbin/ldapize.pl', $url) or die "$0: open: $!";
+$pid = open2(\*IN, \*OUT, '/usr/local/sbin/ldapize.pl', $url) or die "$0: open: $!";
 
 # Read the greeting, expecting it to be identical to the dummy greeting.
@@ -85,28 +86,26 @@
 # (STDIN -> OUT, IN -> STDOUT), including the client's response to svnserve.
 my ($cbuf, $sbuf) = ($response, '');
-my ($rin, $win, $ein) = ('', '', '');
-my ($stdout, $out, $stdin, $in) = (fileno(STDOUT), fileno(OUT), fileno(STDIN), fileno(IN));
-vec($win, $stdout, 1) = 0;
-vec($win, $out, 1) = 1;
-vec($rin, $stdin, 1) = 0;
-vec($rin, $in, 1) = 1;
-while (vec($win, $stdout, 1) or vec($win, $out, 1) or
-       vec($rin, $stdin, 1) or vec($rin, $in, 1)) {
-    my $n = select(my $rout = $rin, my $wout = $win, my $eout = $ein, undef);
+my $poll = new IO::Poll;
+$poll->mask(\*STDOUT => POLLHUP);
+$poll->mask(\*OUT => POLLOUT);
+$poll->remove(\*STDIN);
+$poll->mask(\*IN => POLLIN);
+while ($poll->handles()) {
+    my $n = $poll->poll();
     next if $n < 0 and $! == EINTR;
     $n >= 0 or die "select: $!";
-    if (vec($rout, $stdin, 1)) {
+    if ($poll->events(\*STDIN)) {
 	my $n = sysread(STDIN, $cbuf, 4096);
 	next if $n < 0 and $! == EINTR;
 	$n >= 0 or die "read: $!";
-	vec($rin, $stdin, 1) = 0;
-	vec($win, $out, 1) = 1;
-    } elsif (vec($rout, $in, 1)) {
+	$poll->remove(\*STDIN);
+	$poll->mask(\*OUT => POLLOUT);
+    } elsif ($poll->events(\*IN)) {
 	my $n = sysread(IN, $sbuf, 4096);
 	next if $n < 0 and $! == EINTR;
 	$n >= 0 or die "read: $!";
-	vec($rin, $in, 1) = 0;
-	vec($win, $stdout, 1) = 1;
-    } elsif (vec($wout, $stdout, 1) && $sbuf ne '') {
+	$poll->remove(\*IN);
+	$poll->mask(\*STDOUT => POLLOUT);
+    } elsif ($poll->events(\*STDOUT) & POLLOUT && $sbuf ne '') {
 	my $n = syswrite(STDOUT, $sbuf);
 	next if $n < 0 and $! == EINTR;
@@ -114,12 +113,13 @@
 	$sbuf = substr($sbuf, $n);
 	if ($sbuf eq '') {
-	    vec($win, $stdout, 1) = 0;
-	    vec($rin, $in, 1) = 1;
+	    $poll->mask(\*STDOUT => POLLHUP);
+	    $poll->mask(\*IN => POLLIN);
 	}
-    } elsif (vec($wout, $stdout, 1)) {
-	vec($win, $stdout, 1) = 0;
+    } elsif ($poll->events(\*STDOUT)) {
+	$poll->remove(\*STDOUT);
+	$poll->remove(\*IN);
 	close(STDOUT) or die "close: $!";
 	close(IN) or die "close: $!";
-    } elsif (vec($wout, $out, 1) && $cbuf ne '') {
+    } elsif ($poll->events(\*OUT) & POLLOUT && $cbuf ne '') {
 	my $n = syswrite(OUT, $cbuf);
 	next if $n < 0 and $! == EINTR;
@@ -127,11 +127,14 @@
 	$cbuf = substr($cbuf, $n);
 	if ($cbuf eq '') {
-	    vec($win, $out, 1) = 0;
-	    vec($rin, $stdin, 1) = 1;
+	    $poll->mask(\*OUT => POLLHUP);
+	    $poll->mask(\*STDIN => POLLIN);
 	}
-    } elsif (vec($wout, $out, 1)) {
-	vec($win, $out, 1) = 0;
+    } elsif ($poll->events(\*OUT)) {
+	$poll->remove(\*OUT);
+	$poll->remove(\*STDIN);
 	close(OUT) or die "close: $!";
 	close(STDIN) or die "close: $!";
     }
 }
+
+while (waitpid($pid, 0) == -1 && $! == EINTR) { }
