|
@@ -1,5 +1,5 @@
|
|
|
#! /usr/bin/perl -w
|
|
|
-# $Id: autoupdate.pl,v 1.34 2012/03/04 16:09:46 markus Exp $
|
|
|
+# $Id: autoupdate.pl,v 1.35 2014/09/07 07:11:10 markus Exp $
|
|
|
# Copyright (c) 2007,2008,2009
|
|
|
# Markus Hennecke <markus-hennecke@markus-hennecke.de>
|
|
|
#
|
|
@@ -24,7 +24,7 @@ use OpenBSD::PackageName;
|
|
|
use Getopt::Long;
|
|
|
use FindBin;
|
|
|
use File::Spec;
|
|
|
-use POSIX qw/uname/;
|
|
|
+use POSIX qw/uname :sys_wait_h/;
|
|
|
|
|
|
# Silence the warning that is issued because List::Util won't register
|
|
|
# $a and $b in a correct way for us
|
|
@@ -83,24 +83,47 @@ my $abort = 0;
|
|
|
# Ports that failed to build
|
|
|
my @aborted = ();
|
|
|
|
|
|
+# Hash of reaped child processes
|
|
|
+my %reaped_pids = ();
|
|
|
+
|
|
|
+
|
|
|
# This function will remove the finished forked build from the list of
|
|
|
# currently build ports.
|
|
|
sub REAPER {
|
|
|
- my $wpid = wait();
|
|
|
- my $status = $?;
|
|
|
-
|
|
|
- $abort = 1 if ($status != 0);
|
|
|
- if (exists $forked_builds{$wpid}) {
|
|
|
- $jobs--;
|
|
|
- if ($status == 0) {
|
|
|
- print STDOUT "Finished build of ";
|
|
|
+ while ((my $wpid = waitpid(-1, &WNOHANG)) > 0) {
|
|
|
+ my $status = $?;
|
|
|
+
|
|
|
+ $abort = 1 if ($status != 0);
|
|
|
+ $reaped_pids{$wpid} = $status;
|
|
|
+ }
|
|
|
+ $SIG{CHLD} = \&REAPER;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+# Remove the status codes/PIDs from the reaped_pids hash periodically
|
|
|
+sub reap {
|
|
|
+ my @pids = keys %reaped_pids;
|
|
|
+ while (scalar @pids) {
|
|
|
+ my $wpid = shift @pids;
|
|
|
+ if (exists $forked_builds{$wpid}) {
|
|
|
+ my $portname = $forked_builds{$wpid};
|
|
|
+ $jobs--;
|
|
|
+ my $status = $reaped_pids{$wpid};
|
|
|
+ if ($status == 0) {
|
|
|
+ print STDOUT 'Finished build of ';
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ print STDOUT 'Build aborted of ';
|
|
|
+ push @aborted, ($portname);
|
|
|
+ }
|
|
|
+ delete $forked_builds{$wpid};
|
|
|
+ print STDOUT $portname . "\n";
|
|
|
}
|
|
|
else {
|
|
|
- print STDOUT "Build aborted of ";
|
|
|
- push @aborted, ($forked_builds{$wpid});
|
|
|
+ print STDOUT 'No forked process recorded for '
|
|
|
+ . $wpid . "\n";
|
|
|
}
|
|
|
- print $forked_builds{$wpid} . "\n";
|
|
|
- delete $forked_builds{$wpid};
|
|
|
+ delete $reaped_pids{$wpid};
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -534,7 +557,8 @@ sub build_pkg {
|
|
|
my $pid = fork();
|
|
|
if (! defined $pid) {
|
|
|
die "Cannot fork to build $port\n";
|
|
|
- } elsif ($pid) {
|
|
|
+ }
|
|
|
+ elsif ($pid) {
|
|
|
$forked_builds{$pid} = $port;
|
|
|
$jobs++;
|
|
|
return;
|
|
@@ -819,6 +843,9 @@ $SIG{CHLD} = \&REAPER;
|
|
|
|
|
|
# Build all the packages. Packages that are still unknown to us are ignored.
|
|
|
foreach my $pkg_name (@pkg_list) {
|
|
|
+
|
|
|
+ reap();
|
|
|
+
|
|
|
# Get the package information from the info array
|
|
|
my $info = get_pkg_info($port_info, $pkg_name);
|
|
|
|
|
@@ -832,13 +859,14 @@ foreach my $pkg_name (@pkg_list) {
|
|
|
|
|
|
# XXX Here we must check if the package depends on a currently build
|
|
|
# package too.
|
|
|
- while ($jobs >= $num_jobs || can_pkg_be_build($info)) {
|
|
|
+ while (($jobs >= $num_jobs || can_pkg_be_build($info)) && !$abort) {
|
|
|
if ($wait_for_dep_notice == 0 && !can_pkg_be_build($info)) {
|
|
|
print STDOUT "Waiting for dependant package to finish "
|
|
|
. "building (" . $pkg_name . ")\n"
|
|
|
unless ($verbose < 2);
|
|
|
$wait_for_dep_notice++;
|
|
|
}
|
|
|
+ reap();
|
|
|
sleep 1;
|
|
|
}
|
|
|
|
|
@@ -847,11 +875,11 @@ foreach my $pkg_name (@pkg_list) {
|
|
|
}
|
|
|
|
|
|
# Wait for all childs to finish
|
|
|
-while (keys %forked_builds) {
|
|
|
+while (scalar (keys %forked_builds)) {
|
|
|
sleep 1;
|
|
|
}
|
|
|
|
|
|
-die "Abort requested by child" if ($abort != 0);
|
|
|
+die 'Abort requested by child' if ($abort != 0);
|
|
|
print STDOUT "Done.\n";
|
|
|
|
|
|
# Close the pipe to our log file if we were logging
|