forked from josch/mmdebstrap
coverage.sh: test with perlcritic
This commit is contained in:
parent
4ba82a41cf
commit
f867384c20
2 changed files with 252 additions and 191 deletions
|
@ -12,6 +12,13 @@ if [ "$ret" -ne 0 ]; then
|
||||||
fi
|
fi
|
||||||
rm mmdebstrap.tdy
|
rm mmdebstrap.tdy
|
||||||
|
|
||||||
|
if [ $(wc -L < mmdebstrap) -gt 79 ]; then
|
||||||
|
echo "exceeded maximum line length of 79 characters" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
perlcritic --severity 4 --verbose 8 mmdebstrap
|
||||||
|
|
||||||
mirrordir="./shared/cache/debian"
|
mirrordir="./shared/cache/debian"
|
||||||
|
|
||||||
if [ ! -e "$mirrordir" ]; then
|
if [ ! -e "$mirrordir" ]; then
|
||||||
|
|
436
mmdebstrap
436
mmdebstrap
|
@ -33,7 +33,7 @@ use File::Path qw(make_path remove_tree);
|
||||||
use File::Temp qw(tempfile tempdir);
|
use File::Temp qw(tempfile tempdir);
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
use Cwd qw(abs_path);
|
use Cwd qw(abs_path);
|
||||||
require "syscall.ph";
|
require "syscall.ph"; ## no critic (Modules::RequireBarewordIncludes)
|
||||||
use Fcntl qw(S_IFCHR S_IFBLK FD_CLOEXEC F_GETFD F_SETFD);
|
use Fcntl qw(S_IFCHR S_IFBLK FD_CLOEXEC F_GETFD F_SETFD);
|
||||||
use List::Util qw(any none);
|
use List::Util qw(any none);
|
||||||
use POSIX qw(SIGINT SIGHUP SIGPIPE SIGTERM SIG_BLOCK SIG_UNBLOCK);
|
use POSIX qw(SIGINT SIGHUP SIGPIPE SIGTERM SIG_BLOCK SIG_UNBLOCK);
|
||||||
|
@ -41,15 +41,21 @@ use Carp;
|
||||||
use Term::ANSIColor;
|
use Term::ANSIColor;
|
||||||
use Socket;
|
use Socket;
|
||||||
|
|
||||||
|
## no critic (InputOutput::RequireBriefOpen)
|
||||||
|
|
||||||
# from sched.h
|
# from sched.h
|
||||||
use constant {
|
# use typeglob constants because "use constant" has several drawback as
|
||||||
CLONE_NEWNS => 0x20000,
|
# explained in the documentation for the Readonly CPAN module
|
||||||
CLONE_NEWUTS => 0x4000000,
|
*CLONE_NEWNS = \0x20000;
|
||||||
CLONE_NEWIPC => 0x8000000,
|
*CLONE_NEWUTS = \0x4000000;
|
||||||
CLONE_NEWUSER => 0x10000000,
|
*CLONE_NEWIPC = \0x8000000;
|
||||||
CLONE_NEWPID => 0x20000000,
|
*CLONE_NEWUSER = \0x10000000;
|
||||||
CLONE_NEWNET => 0x40000000,
|
*CLONE_NEWPID = \0x20000000;
|
||||||
};
|
*CLONE_NEWNET = \0x40000000;
|
||||||
|
our (
|
||||||
|
$CLONE_NEWNS, $CLONE_NEWUTS, $CLONE_NEWIPC,
|
||||||
|
$CLONE_NEWUSER, $CLONE_NEWPID, $CLONE_NEWNET
|
||||||
|
);
|
||||||
|
|
||||||
# type codes:
|
# type codes:
|
||||||
# 0 -> normal file
|
# 0 -> normal file
|
||||||
|
@ -60,21 +66,21 @@ use constant {
|
||||||
# 5 -> directory
|
# 5 -> directory
|
||||||
my @devfiles = (
|
my @devfiles = (
|
||||||
# filename mode type link target major minor
|
# filename mode type link target major minor
|
||||||
["./dev/", 0755, 5, '', undef, undef],
|
["./dev/", oct(755), 5, '', undef, undef],
|
||||||
["./dev/console", 0666, 3, '', 5, 1],
|
["./dev/console", oct(666), 3, '', 5, 1],
|
||||||
["./dev/fd", 0777, 2, '/proc/self/fd', undef, undef],
|
["./dev/fd", oct(777), 2, '/proc/self/fd', undef, undef],
|
||||||
["./dev/full", 0666, 3, '', 1, 7],
|
["./dev/full", oct(666), 3, '', 1, 7],
|
||||||
["./dev/null", 0666, 3, '', 1, 3],
|
["./dev/null", oct(666), 3, '', 1, 3],
|
||||||
["./dev/ptmx", 0666, 3, '', 5, 2],
|
["./dev/ptmx", oct(666), 3, '', 5, 2],
|
||||||
["./dev/pts/", 0755, 5, '', undef, undef],
|
["./dev/pts/", oct(755), 5, '', undef, undef],
|
||||||
["./dev/random", 0666, 3, '', 1, 8],
|
["./dev/random", oct(666), 3, '', 1, 8],
|
||||||
["./dev/shm/", 0755, 5, '', undef, undef],
|
["./dev/shm/", oct(755), 5, '', undef, undef],
|
||||||
["./dev/stderr", 0777, 2, '/proc/self/fd/2', undef, undef],
|
["./dev/stderr", oct(777), 2, '/proc/self/fd/2', undef, undef],
|
||||||
["./dev/stdin", 0777, 2, '/proc/self/fd/0', undef, undef],
|
["./dev/stdin", oct(777), 2, '/proc/self/fd/0', undef, undef],
|
||||||
["./dev/stdout", 0777, 2, '/proc/self/fd/1', undef, undef],
|
["./dev/stdout", oct(777), 2, '/proc/self/fd/1', undef, undef],
|
||||||
["./dev/tty", 0666, 3, '', 5, 0],
|
["./dev/tty", oct(666), 3, '', 5, 0],
|
||||||
["./dev/urandom", 0666, 3, '', 1, 9],
|
["./dev/urandom", oct(666), 3, '', 1, 9],
|
||||||
["./dev/zero", 0666, 3, '', 1, 5],
|
["./dev/zero", oct(666), 3, '', 1, 5],
|
||||||
);
|
);
|
||||||
|
|
||||||
# verbosity levels:
|
# verbosity levels:
|
||||||
|
@ -84,7 +90,7 @@ my @devfiles = (
|
||||||
# 3 -> debug output
|
# 3 -> debug output
|
||||||
my $verbosity_level = 1;
|
my $verbosity_level = 1;
|
||||||
|
|
||||||
my $is_covering = !!(eval 'Devel::Cover::get_coverage()');
|
my $is_covering = !!(eval { Devel::Cover::get_coverage() });
|
||||||
|
|
||||||
sub debug {
|
sub debug {
|
||||||
if ($verbosity_level < 3) {
|
if ($verbosity_level < 3) {
|
||||||
|
@ -93,10 +99,11 @@ sub debug {
|
||||||
my $msg = shift;
|
my $msg = shift;
|
||||||
my ($package, $filename, $line) = caller;
|
my ($package, $filename, $line) = caller;
|
||||||
$msg = "D: $PID $line $msg";
|
$msg = "D: $PID $line $msg";
|
||||||
if (-t STDERR) {
|
if (-t STDERR) { ## no critic (InputOutput::ProhibitInteractiveTest)
|
||||||
$msg = colored($msg, 'clear');
|
$msg = colored($msg, 'clear');
|
||||||
}
|
}
|
||||||
print STDERR "$msg\n";
|
print STDERR "$msg\n";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub info {
|
sub info {
|
||||||
|
@ -109,10 +116,11 @@ sub info {
|
||||||
$msg = "$PID $line $msg";
|
$msg = "$PID $line $msg";
|
||||||
}
|
}
|
||||||
$msg = "I: $msg";
|
$msg = "I: $msg";
|
||||||
if (-t STDERR) {
|
if (-t STDERR) { ## no critic (InputOutput::ProhibitInteractiveTest)
|
||||||
$msg = colored($msg, 'green');
|
$msg = colored($msg, 'green');
|
||||||
}
|
}
|
||||||
print STDERR "$msg\n";
|
print STDERR "$msg\n";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub warning {
|
sub warning {
|
||||||
|
@ -121,10 +129,11 @@ sub warning {
|
||||||
}
|
}
|
||||||
my $msg = shift;
|
my $msg = shift;
|
||||||
$msg = "W: $msg";
|
$msg = "W: $msg";
|
||||||
if (-t STDERR) {
|
if (-t STDERR) { ## no critic (InputOutput::ProhibitInteractiveTest)
|
||||||
$msg = colored($msg, 'bold yellow');
|
$msg = colored($msg, 'bold yellow');
|
||||||
}
|
}
|
||||||
print STDERR "$msg\n";
|
print STDERR "$msg\n";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub error {
|
sub error {
|
||||||
|
@ -136,11 +145,11 @@ sub error {
|
||||||
# are stripping here
|
# are stripping here
|
||||||
chomp(my $msg = shift);
|
chomp(my $msg = shift);
|
||||||
$msg = "E: $msg";
|
$msg = "E: $msg";
|
||||||
if (-t STDERR) {
|
if (-t STDERR) { ## no critic (InputOutput::ProhibitInteractiveTest)
|
||||||
$msg = colored($msg, 'bold red');
|
$msg = colored($msg, 'bold red');
|
||||||
}
|
}
|
||||||
if ($verbosity_level == 3) {
|
if ($verbosity_level == 3) {
|
||||||
croak $msg; # produces a backtrace
|
croak $msg; # produces a backtrace
|
||||||
} else {
|
} else {
|
||||||
die "$msg\n";
|
die "$msg\n";
|
||||||
}
|
}
|
||||||
|
@ -148,7 +157,7 @@ sub error {
|
||||||
|
|
||||||
# check whether a directory is mounted by comparing the device number of the
|
# check whether a directory is mounted by comparing the device number of the
|
||||||
# directory itself with its parent
|
# directory itself with its parent
|
||||||
sub is_mountpoint($) {
|
sub is_mountpoint {
|
||||||
my $dir = shift;
|
my $dir = shift;
|
||||||
if (!-e $dir) {
|
if (!-e $dir) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -169,12 +178,12 @@ sub is_mountpoint($) {
|
||||||
# tar cannot figure out the decompression program when receiving data on
|
# tar cannot figure out the decompression program when receiving data on
|
||||||
# standard input, thus we do it ourselves. This is copied from tar's
|
# standard input, thus we do it ourselves. This is copied from tar's
|
||||||
# src/suffix.c
|
# src/suffix.c
|
||||||
sub get_tar_compressor($) {
|
sub get_tar_compressor {
|
||||||
my $filename = shift;
|
my $filename = shift;
|
||||||
if ($filename eq '-') {
|
if ($filename eq '-') {
|
||||||
return undef;
|
return;
|
||||||
} elsif ($filename =~ /\.tar$/) {
|
} elsif ($filename =~ /\.tar$/) {
|
||||||
return undef;
|
return;
|
||||||
} elsif ($filename =~ /\.(gz|tgz|taz)$/) {
|
} elsif ($filename =~ /\.(gz|tgz|taz)$/) {
|
||||||
return ['gzip'];
|
return ['gzip'];
|
||||||
} elsif ($filename =~ /\.(Z|taZ)$/) {
|
} elsif ($filename =~ /\.(Z|taZ)$/) {
|
||||||
|
@ -194,10 +203,10 @@ sub get_tar_compressor($) {
|
||||||
} elsif ($filename =~ /\.zst$/) {
|
} elsif ($filename =~ /\.zst$/) {
|
||||||
return ['zstd'];
|
return ['zstd'];
|
||||||
}
|
}
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub test_unshare($) {
|
sub test_unshare {
|
||||||
my $verbose = shift;
|
my $verbose = shift;
|
||||||
if ($EFFECTIVE_USER_ID == 0) {
|
if ($EFFECTIVE_USER_ID == 0) {
|
||||||
my $msg = "cannot use unshare mode when executing as root";
|
my $msg = "cannot use unshare mode when executing as root";
|
||||||
|
@ -210,12 +219,12 @@ sub test_unshare($) {
|
||||||
}
|
}
|
||||||
# arguments to syscalls have to be stored in their own variable or
|
# arguments to syscalls have to be stored in their own variable or
|
||||||
# otherwise we will get "Modification of a read-only value attempted"
|
# otherwise we will get "Modification of a read-only value attempted"
|
||||||
my $unshare_flags = CLONE_NEWUSER;
|
my $unshare_flags = $CLONE_NEWUSER;
|
||||||
# we spawn a new per process because if unshare succeeds, we would
|
# we spawn a new per process because if unshare succeeds, we would
|
||||||
# otherwise have unshared the mmdebstrap process itself which we don't want
|
# otherwise have unshared the mmdebstrap process itself which we don't want
|
||||||
my $pid = fork() // error "fork() failed: $!";
|
my $pid = fork() // error "fork() failed: $!";
|
||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
my $ret = syscall &SYS_unshare, $unshare_flags;
|
my $ret = syscall(&SYS_unshare, $unshare_flags);
|
||||||
if ($ret == 0) {
|
if ($ret == 0) {
|
||||||
exit 0;
|
exit 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -371,16 +380,16 @@ sub read_subuid_subgid() {
|
||||||
# This is because when unsharing the PID namespace, we need a PID 1 to be kept
|
# This is because when unsharing the PID namespace, we need a PID 1 to be kept
|
||||||
# alive or otherwise any child processes cannot fork() anymore themselves. So
|
# alive or otherwise any child processes cannot fork() anymore themselves. So
|
||||||
# we keep F as PID 1 and finally call exec() in G.
|
# we keep F as PID 1 and finally call exec() in G.
|
||||||
sub get_unshare_cmd(&$) {
|
sub get_unshare_cmd {
|
||||||
my $cmd = shift;
|
my $cmd = shift;
|
||||||
my $idmap = shift;
|
my $idmap = shift;
|
||||||
|
|
||||||
my $unshare_flags
|
my $unshare_flags
|
||||||
= CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUTS
|
= $CLONE_NEWUSER | $CLONE_NEWNS | $CLONE_NEWPID | $CLONE_NEWUTS
|
||||||
| CLONE_NEWIPC;
|
| $CLONE_NEWIPC;
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
$unshare_flags |= CLONE_NEWNET;
|
$unshare_flags |= $CLONE_NEWNET;
|
||||||
}
|
}
|
||||||
|
|
||||||
# fork a new process and let the child get unshare()ed
|
# fork a new process and let the child get unshare()ed
|
||||||
|
@ -522,7 +531,7 @@ sub get_unshare_cmd(&$) {
|
||||||
return $gcpid;
|
return $gcpid;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub havemknod($) {
|
sub havemknod {
|
||||||
my $root = shift;
|
my $root = shift;
|
||||||
my $havemknod = 0;
|
my $havemknod = 0;
|
||||||
if (-e "$root/test-dev-null") {
|
if (-e "$root/test-dev-null") {
|
||||||
|
@ -561,7 +570,7 @@ sub print_progress {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
my $perc = shift;
|
my $perc = shift;
|
||||||
if (!-t STDERR) {
|
if (!-t STDERR) { ## no critic (InputOutput::ProhibitInteractiveTest)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($perc eq "done") {
|
if ($perc eq "done") {
|
||||||
|
@ -580,6 +589,7 @@ sub print_progress {
|
||||||
$bar .= ' ' x ($width - $num_x - 1);
|
$bar .= ' ' x ($width - $num_x - 1);
|
||||||
}
|
}
|
||||||
printf STDERR "%6.2f [%s]\r", $perc, $bar;
|
printf STDERR "%6.2f [%s]\r", $perc, $bar;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run_progress {
|
sub run_progress {
|
||||||
|
@ -599,10 +609,10 @@ sub run_progress {
|
||||||
|
|
||||||
if ($pid1 == 0) {
|
if ($pid1 == 0) {
|
||||||
# child: default signal handlers
|
# child: default signal handlers
|
||||||
$SIG{'INT'} = 'DEFAULT';
|
local $SIG{'INT'} = 'DEFAULT';
|
||||||
$SIG{'HUP'} = 'DEFAULT';
|
local $SIG{'HUP'} = 'DEFAULT';
|
||||||
$SIG{'PIPE'} = 'DEFAULT';
|
local $SIG{'PIPE'} = 'DEFAULT';
|
||||||
$SIG{'TERM'} = 'DEFAULT';
|
local $SIG{'TERM'} = 'DEFAULT';
|
||||||
|
|
||||||
# unblock all delayed signals (and possibly handle them)
|
# unblock all delayed signals (and possibly handle them)
|
||||||
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
||||||
|
@ -625,7 +635,7 @@ sub run_progress {
|
||||||
if (defined $chdir) {
|
if (defined $chdir) {
|
||||||
chdir $chdir or error "failed chdir() to $chdir: $!";
|
chdir $chdir or error "failed chdir() to $chdir: $!";
|
||||||
}
|
}
|
||||||
eval 'Devel::Cover::set_coverage("none")' if $is_covering;
|
eval { Devel::Cover::set_coverage("none") } if $is_covering;
|
||||||
exec { $execargs[0] } @execargs
|
exec { $execargs[0] } @execargs
|
||||||
or error 'cannot exec() ' . (join ' ', @execargs);
|
or error 'cannot exec() ' . (join ' ', @execargs);
|
||||||
}
|
}
|
||||||
|
@ -637,22 +647,22 @@ sub run_progress {
|
||||||
my $pid2 = fork() // error "failed to fork(): $!";
|
my $pid2 = fork() // error "failed to fork(): $!";
|
||||||
if ($pid2 == 0) {
|
if ($pid2 == 0) {
|
||||||
# child: default signal handlers
|
# child: default signal handlers
|
||||||
$SIG{'INT'} = 'IGNORE';
|
local $SIG{'INT'} = 'IGNORE';
|
||||||
$SIG{'HUP'} = 'IGNORE';
|
local $SIG{'HUP'} = 'IGNORE';
|
||||||
$SIG{'PIPE'} = 'IGNORE';
|
local $SIG{'PIPE'} = 'IGNORE';
|
||||||
$SIG{'TERM'} = 'IGNORE';
|
local $SIG{'TERM'} = 'IGNORE';
|
||||||
|
|
||||||
# unblock all delayed signals (and possibly handle them)
|
# unblock all delayed signals (and possibly handle them)
|
||||||
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
||||||
or error "Can't unblock signals: $!";
|
or error "Can't unblock signals: $!";
|
||||||
|
|
||||||
print_progress 0.0;
|
print_progress(0.0);
|
||||||
while (my $line = <$rfh>) {
|
while (my $line = <$rfh>) {
|
||||||
my $output = $line_handler->($line);
|
my $output = $line_handler->($line);
|
||||||
next unless $output;
|
next unless $output;
|
||||||
print_progress $output;
|
print_progress($output);
|
||||||
}
|
}
|
||||||
print_progress "done";
|
print_progress("done");
|
||||||
|
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
|
@ -702,6 +712,7 @@ sub run_progress {
|
||||||
}
|
}
|
||||||
error((join ' ', $get_exec->('<$fd>')) . ' failed');
|
error((join ' ', $get_exec->('<$fd>')) . ' failed');
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run_dpkg_progress {
|
sub run_dpkg_progress {
|
||||||
|
@ -721,6 +732,7 @@ sub run_dpkg_progress {
|
||||||
return $num / $total * 100;
|
return $num / $total * 100;
|
||||||
};
|
};
|
||||||
run_progress $get_exec, $line_handler, $line_has_error;
|
run_progress $get_exec, $line_handler, $line_has_error;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run_apt_progress {
|
sub run_apt_progress {
|
||||||
|
@ -755,9 +767,10 @@ sub run_apt_progress {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
run_progress $get_exec, $line_handler, $line_has_error, $options->{CHDIR};
|
run_progress $get_exec, $line_handler, $line_has_error, $options->{CHDIR};
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run_chroot(&$) {
|
sub run_chroot {
|
||||||
my $cmd = shift;
|
my $cmd = shift;
|
||||||
my $options = shift;
|
my $options = shift;
|
||||||
|
|
||||||
|
@ -1044,9 +1057,10 @@ sub run_chroot(&$) {
|
||||||
if ($error) {
|
if ($error) {
|
||||||
error "run_chroot failed: $error";
|
error "run_chroot failed: $error";
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run_hooks($$) {
|
sub run_hooks {
|
||||||
my $name = shift;
|
my $name = shift;
|
||||||
my $options = shift;
|
my $options = shift;
|
||||||
|
|
||||||
|
@ -1123,9 +1137,9 @@ sub run_hooks($$) {
|
||||||
# exist yet)
|
# exist yet)
|
||||||
&{$runner}();
|
&{$runner}();
|
||||||
} else {
|
} else {
|
||||||
run_chroot \&$runner, $options;
|
run_chroot(\&$runner, $options);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub setup {
|
sub setup {
|
||||||
|
@ -1417,7 +1431,10 @@ sub setup {
|
||||||
# line arguments because configuration settings like Dir::Etc have already
|
# line arguments because configuration settings like Dir::Etc have already
|
||||||
# been evaluated at the time that apt takes its command line arguments
|
# been evaluated at the time that apt takes its command line arguments
|
||||||
# into account.
|
# into account.
|
||||||
$ENV{"APT_CONFIG"} = "$tmpfile";
|
{
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
|
$ENV{"APT_CONFIG"} = "$tmpfile";
|
||||||
|
}
|
||||||
|
|
||||||
# when apt-get update is run by the root user, then apt will attempt to
|
# when apt-get update is run by the root user, then apt will attempt to
|
||||||
# drop privileges to the _apt user. This will fail if the _apt user does
|
# drop privileges to the _apt user. This will fail if the _apt user does
|
||||||
|
@ -1440,8 +1457,10 @@ sub setup {
|
||||||
|
|
||||||
# setting PATH for chroot, ldconfig, start-stop-daemon...
|
# setting PATH for chroot, ldconfig, start-stop-daemon...
|
||||||
if (defined $ENV{PATH} && $ENV{PATH} ne "") {
|
if (defined $ENV{PATH} && $ENV{PATH} ne "") {
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{PATH} = "$ENV{PATH}:/usr/sbin:/usr/bin:/sbin:/bin";
|
$ENV{PATH} = "$ENV{PATH}:/usr/sbin:/usr/bin:/sbin:/bin";
|
||||||
} else {
|
} else {
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{PATH} = "/usr/sbin:/usr/bin:/sbin:/bin";
|
$ENV{PATH} = "/usr/sbin:/usr/bin:/sbin:/bin";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1692,7 +1711,7 @@ sub setup {
|
||||||
if ($pid1 == 0) {
|
if ($pid1 == 0) {
|
||||||
open(STDOUT, '>&', $wfh) or error "cannot open STDOUT: $!";
|
open(STDOUT, '>&', $wfh) or error "cannot open STDOUT: $!";
|
||||||
debug("running dpkg-deb --fsys-tarfile $options->{root}/$deb");
|
debug("running dpkg-deb --fsys-tarfile $options->{root}/$deb");
|
||||||
eval 'Devel::Cover::set_coverage("none")' if $is_covering;
|
eval { Devel::Cover::set_coverage("none") } if $is_covering;
|
||||||
exec 'dpkg-deb', '--fsys-tarfile', "$options->{root}/$deb";
|
exec 'dpkg-deb', '--fsys-tarfile', "$options->{root}/$deb";
|
||||||
}
|
}
|
||||||
my $pid2 = fork() // error "fork() failed: $!";
|
my $pid2 = fork() // error "fork() failed: $!";
|
||||||
|
@ -1700,7 +1719,7 @@ sub setup {
|
||||||
open(STDIN, '<&', $rfh) or error "cannot open STDIN: $!";
|
open(STDIN, '<&', $rfh) or error "cannot open STDIN: $!";
|
||||||
debug( "running tar -C $options->{root}"
|
debug( "running tar -C $options->{root}"
|
||||||
. " --keep-directory-symlink --extract --file -");
|
. " --keep-directory-symlink --extract --file -");
|
||||||
eval 'Devel::Cover::set_coverage("none")' if $is_covering;
|
eval { Devel::Cover::set_coverage("none") } if $is_covering;
|
||||||
exec 'tar', '-C', $options->{root},
|
exec 'tar', '-C', $options->{root},
|
||||||
'--keep-directory-symlink', '--extract', '--file', '-';
|
'--keep-directory-symlink', '--extract', '--file', '-';
|
||||||
}
|
}
|
||||||
|
@ -1730,8 +1749,10 @@ sub setup {
|
||||||
# where it has to look for shared libraries
|
# where it has to look for shared libraries
|
||||||
if (defined $ENV{QEMU_LD_PREFIX}
|
if (defined $ENV{QEMU_LD_PREFIX}
|
||||||
&& $ENV{QEMU_LD_PREFIX} ne "") {
|
&& $ENV{QEMU_LD_PREFIX} ne "") {
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{QEMU_LD_PREFIX} = "$ENV{QEMU_LD_PREFIX}:$options->{root}";
|
$ENV{QEMU_LD_PREFIX} = "$ENV{QEMU_LD_PREFIX}:$options->{root}";
|
||||||
} else {
|
} else {
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{QEMU_LD_PREFIX} = $options->{root};
|
$ENV{QEMU_LD_PREFIX} = $options->{root};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1798,18 +1819,24 @@ sub setup {
|
||||||
push @fakechrootsubst, split /:/,
|
push @fakechrootsubst, split /:/,
|
||||||
$ENV{FAKECHROOT_CMD_SUBST};
|
$ENV{FAKECHROOT_CMD_SUBST};
|
||||||
}
|
}
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{FAKECHROOT_CMD_SUBST} = join ':', @fakechrootsubst;
|
$ENV{FAKECHROOT_CMD_SUBST} = join ':', @fakechrootsubst;
|
||||||
}
|
}
|
||||||
if (defined $ENV{FAKECHROOT_EXCLUDE_PATH}
|
if (defined $ENV{FAKECHROOT_EXCLUDE_PATH}
|
||||||
&& $ENV{FAKECHROOT_EXCLUDE_PATH} ne "") {
|
&& $ENV{FAKECHROOT_EXCLUDE_PATH} ne "") {
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{FAKECHROOT_EXCLUDE_PATH}
|
$ENV{FAKECHROOT_EXCLUDE_PATH}
|
||||||
= "$ENV{FAKECHROOT_EXCLUDE_PATH}:/dev:/proc:/sys";
|
= "$ENV{FAKECHROOT_EXCLUDE_PATH}:/dev:/proc:/sys";
|
||||||
} else {
|
} else {
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{FAKECHROOT_EXCLUDE_PATH} = '/dev:/proc:/sys';
|
$ENV{FAKECHROOT_EXCLUDE_PATH} = '/dev:/proc:/sys';
|
||||||
}
|
}
|
||||||
# workaround for long unix socket path if FAKECHROOT_BASE
|
# workaround for long unix socket path if FAKECHROOT_BASE
|
||||||
# exceeds the limit of 108 bytes
|
# exceeds the limit of 108 bytes
|
||||||
$ENV{FAKECHROOT_AF_UNIX_PATH} = "/tmp";
|
{
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
|
$ENV{FAKECHROOT_AF_UNIX_PATH} = "/tmp";
|
||||||
|
}
|
||||||
{
|
{
|
||||||
my @ldsoconf = ('/etc/ld.so.conf');
|
my @ldsoconf = ('/etc/ld.so.conf');
|
||||||
opendir(my $dh, '/etc/ld.so.conf.d')
|
opendir(my $dh, '/etc/ld.so.conf.d')
|
||||||
|
@ -1839,6 +1866,7 @@ sub setup {
|
||||||
}
|
}
|
||||||
close $fh;
|
close $fh;
|
||||||
}
|
}
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{LD_LIBRARY_PATH} = join ':', @ldlibpath;
|
$ENV{LD_LIBRARY_PATH} = join ':', @ldlibpath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1869,15 +1897,6 @@ sub setup {
|
||||||
if ($options->{mode} eq 'proot') {
|
if ($options->{mode} eq 'proot') {
|
||||||
push @chrootcmd, "--qemu=qemu-$options->{qemu}";
|
push @chrootcmd, "--qemu=qemu-$options->{qemu}";
|
||||||
} elsif ($options->{mode} eq 'fakechroot') {
|
} elsif ($options->{mode} eq 'fakechroot') {
|
||||||
# The binfmt support on the outside is used, so qemu needs
|
|
||||||
# to know where it has to look for shared libraries
|
|
||||||
if (defined $ENV{QEMU_LD_PREFIX}
|
|
||||||
&& $ENV{QEMU_LD_PREFIX} ne "") {
|
|
||||||
$ENV{QEMU_LD_PREFIX}
|
|
||||||
= "$ENV{QEMU_LD_PREFIX}:$options->{root}";
|
|
||||||
} else {
|
|
||||||
$ENV{QEMU_LD_PREFIX} = $options->{root};
|
|
||||||
}
|
|
||||||
# Make sure that the fakeroot and fakechroot shared
|
# Make sure that the fakeroot and fakechroot shared
|
||||||
# libraries exist for the right architecture
|
# libraries exist for the right architecture
|
||||||
open my $fh, '-|', 'dpkg-architecture', '-a',
|
open my $fh, '-|', 'dpkg-architecture', '-a',
|
||||||
|
@ -1887,7 +1906,7 @@ sub setup {
|
||||||
my $deb_host_multiarch = do { local $/; <$fh> }
|
my $deb_host_multiarch = do { local $/; <$fh> }
|
||||||
);
|
);
|
||||||
close $fh;
|
close $fh;
|
||||||
if ($? != 0 or !$deb_host_multiarch) {
|
if (($? != 0) or (!$deb_host_multiarch)) {
|
||||||
error "dpkg-architecture failed: $?";
|
error "dpkg-architecture failed: $?";
|
||||||
}
|
}
|
||||||
my $fakechrootdir
|
my $fakechrootdir
|
||||||
|
@ -1904,10 +1923,24 @@ sub setup {
|
||||||
. " Install libfakeroot:$options->{nativearch}"
|
. " Install libfakeroot:$options->{nativearch}"
|
||||||
. " outside the chroot";
|
. " outside the chroot";
|
||||||
}
|
}
|
||||||
|
# The rest of this block sets environment variables, so we
|
||||||
|
# have to add the "no critic" statement to stop perlcritic
|
||||||
|
# from complaining about setting global variables
|
||||||
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
# fakechroot only fills LD_LIBRARY_PATH with the
|
# fakechroot only fills LD_LIBRARY_PATH with the
|
||||||
# directories of the host's architecture. We append the
|
# directories of the host's architecture. We append the
|
||||||
# directories of the chroot architecture.
|
# directories of the chroot architecture.
|
||||||
$ENV{LD_LIBRARY_PATH} .= ":$fakechrootdir:$fakerootdir";
|
$ENV{LD_LIBRARY_PATH}
|
||||||
|
= "$ENV{LD_LIBRARY_PATH}:$fakechrootdir:$fakerootdir";
|
||||||
|
# The binfmt support on the outside is used, so qemu needs
|
||||||
|
# to know where it has to look for shared libraries
|
||||||
|
if (defined $ENV{QEMU_LD_PREFIX}
|
||||||
|
&& $ENV{QEMU_LD_PREFIX} ne "") {
|
||||||
|
$ENV{QEMU_LD_PREFIX}
|
||||||
|
= "$ENV{QEMU_LD_PREFIX}:$options->{root}";
|
||||||
|
} else {
|
||||||
|
$ENV{QEMU_LD_PREFIX} = $options->{root};
|
||||||
|
}
|
||||||
} elsif (any { $_ eq $options->{mode} } ('root', 'unshare')) {
|
} elsif (any { $_ eq $options->{mode} } ('root', 'unshare')) {
|
||||||
# other modes require a static qemu-user binary
|
# other modes require a static qemu-user binary
|
||||||
my $qemubin = "/usr/bin/qemu-$options->{qemu}-static";
|
my $qemubin = "/usr/bin/qemu-$options->{qemu}-static";
|
||||||
|
@ -1968,17 +2001,19 @@ sub setup {
|
||||||
# into account and thus doesn't install them in the right order
|
# into account and thus doesn't install them in the right order
|
||||||
# And the --predep-package option is broken: #539133
|
# And the --predep-package option is broken: #539133
|
||||||
info "installing packages...";
|
info "installing packages...";
|
||||||
run_chroot {
|
run_chroot(
|
||||||
run_dpkg_progress({
|
sub {
|
||||||
ARGV => [
|
run_dpkg_progress({
|
||||||
@chrootcmd, 'env',
|
ARGV => [
|
||||||
'--unset=TMPDIR', 'dpkg',
|
@chrootcmd, 'env',
|
||||||
'--install', '--force-depends'
|
'--unset=TMPDIR', 'dpkg',
|
||||||
],
|
'--install', '--force-depends'
|
||||||
PKGS => \@essential_pkgs,
|
],
|
||||||
});
|
PKGS => \@essential_pkgs,
|
||||||
}
|
});
|
||||||
$options;
|
},
|
||||||
|
$options
|
||||||
|
);
|
||||||
|
|
||||||
# if the path-excluded option was added to the dpkg config,
|
# if the path-excluded option was added to the dpkg config,
|
||||||
# reinstall all packages
|
# reinstall all packages
|
||||||
|
@ -1986,7 +2021,7 @@ sub setup {
|
||||||
open(my $fh, '<',
|
open(my $fh, '<',
|
||||||
"$options->{root}/etc/dpkg/dpkg.cfg.d/99mmdebstrap")
|
"$options->{root}/etc/dpkg/dpkg.cfg.d/99mmdebstrap")
|
||||||
or error "cannot open /etc/dpkg/dpkg.cfg.d/99mmdebstrap: $!";
|
or error "cannot open /etc/dpkg/dpkg.cfg.d/99mmdebstrap: $!";
|
||||||
my $num_matches = grep /^path-exclude=/, <$fh>;
|
my $num_matches = grep { /^path-exclude=/ } <$fh>;
|
||||||
close $fh;
|
close $fh;
|
||||||
if ($num_matches > 0) {
|
if ($num_matches > 0) {
|
||||||
# without --skip-same-version, dpkg will install the given
|
# without --skip-same-version, dpkg will install the given
|
||||||
|
@ -2107,19 +2142,22 @@ sub setup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run_chroot {
|
run_chroot(
|
||||||
info "installing remaining packages inside the chroot...";
|
sub {
|
||||||
run_apt_progress({
|
info
|
||||||
ARGV => [
|
"installing remaining packages inside the chroot...";
|
||||||
@chrootcmd, 'env',
|
run_apt_progress({
|
||||||
'--unset=APT_CONFIG', '--unset=TMPDIR',
|
ARGV => [
|
||||||
'apt-get', '--yes',
|
@chrootcmd, 'env',
|
||||||
'install'
|
'--unset=APT_CONFIG', '--unset=TMPDIR',
|
||||||
],
|
'apt-get', '--yes',
|
||||||
PKGS => [@pkgs_to_install],
|
'install'
|
||||||
});
|
],
|
||||||
}
|
PKGS => [@pkgs_to_install],
|
||||||
$options;
|
});
|
||||||
|
},
|
||||||
|
$options
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2192,6 +2230,7 @@ sub setup {
|
||||||
}
|
}
|
||||||
closedir($dh);
|
closedir($dh);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# messages from process inside unshared namespace to the outside
|
# messages from process inside unshared namespace to the outside
|
||||||
|
@ -2209,6 +2248,7 @@ sub checkokthx {
|
||||||
my ($len, $msg) = unpack("nA5", $buf);
|
my ($len, $msg) = unpack("nA5", $buf);
|
||||||
if ($msg ne "okthx") { error "expected okthx but got: $msg"; }
|
if ($msg ne "okthx") { error "expected okthx but got: $msg"; }
|
||||||
if ($len != 0) { error "expected no payload but got $len bytes"; }
|
if ($len != 0) { error "expected no payload but got $len bytes"; }
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub main() {
|
sub main() {
|
||||||
|
@ -2467,11 +2507,14 @@ sub main() {
|
||||||
$mtime = $ENV{SOURCE_DATE_EPOCH} + 0;
|
$mtime = $ENV{SOURCE_DATE_EPOCH} + 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ENV{DEBIAN_FRONTEND} = 'noninteractive';
|
{
|
||||||
$ENV{DEBCONF_NONINTERACTIVE_SEEN} = 'true';
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
||||||
$ENV{LC_ALL} = 'C.UTF-8';
|
$ENV{DEBIAN_FRONTEND} = 'noninteractive';
|
||||||
$ENV{LANGUAGE} = 'C.UTF-8';
|
$ENV{DEBCONF_NONINTERACTIVE_SEEN} = 'true';
|
||||||
$ENV{LANG} = 'C.UTF-8';
|
$ENV{LC_ALL} = 'C.UTF-8';
|
||||||
|
$ENV{LANGUAGE} = 'C.UTF-8';
|
||||||
|
$ENV{LANG} = 'C.UTF-8';
|
||||||
|
}
|
||||||
|
|
||||||
# copy ARGV because getopt modifies it
|
# copy ARGV because getopt modifies it
|
||||||
my @ARGVORIG = @ARGV;
|
my @ARGVORIG = @ARGV;
|
||||||
|
@ -2596,7 +2639,7 @@ sub main() {
|
||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
# with the FAKECHROOT_DETECT environment variable set, any program
|
# with the FAKECHROOT_DETECT environment variable set, any program
|
||||||
# execution will be replaced with the output "fakeroot [version]"
|
# execution will be replaced with the output "fakeroot [version]"
|
||||||
$ENV{FAKECHROOT_DETECT} = 0;
|
local $ENV{FAKECHROOT_DETECT} = 0;
|
||||||
exec 'echo', 'If fakechroot is running, this will not be printed';
|
exec 'echo', 'If fakechroot is running, this will not be printed';
|
||||||
}
|
}
|
||||||
my $content = do { local $/; <$rfh> };
|
my $content = do { local $/; <$rfh> };
|
||||||
|
@ -2752,8 +2795,9 @@ sub main() {
|
||||||
my $pid = open my $fh, '-|' // error "failed to fork(): $!";
|
my $pid = open my $fh, '-|' // error "failed to fork(): $!";
|
||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
{
|
{
|
||||||
no warnings
|
## no critic (TestingAndDebugging::ProhibitNoWarnings)
|
||||||
; # don't print a warning if the following fails
|
# don't print a warning if the following fails
|
||||||
|
no warnings;
|
||||||
exec 'arch-test', $options->{nativearch};
|
exec 'arch-test', $options->{nativearch};
|
||||||
}
|
}
|
||||||
# if exec didn't work (for example because the arch-test
|
# if exec didn't work (for example because the arch-test
|
||||||
|
@ -2775,8 +2819,9 @@ sub main() {
|
||||||
my $pid = open my $fh, '-|' // error "failed to fork(): $!";
|
my $pid = open my $fh, '-|' // error "failed to fork(): $!";
|
||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
{
|
{
|
||||||
no warnings
|
## no critic (TestingAndDebugging::ProhibitNoWarnings)
|
||||||
; # don't print a warning if the following fails
|
# don't print a warning if the following fails
|
||||||
|
no warnings;
|
||||||
exec 'arch-test', '-n', $options->{nativearch};
|
exec 'arch-test', '-n', $options->{nativearch};
|
||||||
}
|
}
|
||||||
# if exec didn't work (for example because the arch-test
|
# if exec didn't work (for example because the arch-test
|
||||||
|
@ -2807,7 +2852,7 @@ sub main() {
|
||||||
{
|
{
|
||||||
open my $fh, '<', '/proc/filesystems'
|
open my $fh, '<', '/proc/filesystems'
|
||||||
or error "failed to open /proc/filesystems: $!";
|
or error "failed to open /proc/filesystems: $!";
|
||||||
unless (grep /^nodev\tbinfmt_misc$/, (<$fh>)) {
|
unless (grep { /^nodev\tbinfmt_misc$/ } (<$fh>)) {
|
||||||
warning "binfmt_misc not found in /proc/filesystems --"
|
warning "binfmt_misc not found in /proc/filesystems --"
|
||||||
. " is the module loaded?";
|
. " is the module loaded?";
|
||||||
}
|
}
|
||||||
|
@ -2817,9 +2862,11 @@ sub main() {
|
||||||
open my $fh, '<', '/proc/mounts'
|
open my $fh, '<', '/proc/mounts'
|
||||||
or error "failed to open /proc/mounts: $!";
|
or error "failed to open /proc/mounts: $!";
|
||||||
unless (
|
unless (
|
||||||
grep
|
grep {
|
||||||
/^binfmt_misc \/proc\/sys\/fs\/binfmt_misc binfmt_misc/,
|
/^binfmt_misc
|
||||||
(<$fh>)
|
\/proc\/sys\/fs\/binfmt_misc
|
||||||
|
binfmt_misc/x
|
||||||
|
} (<$fh>)
|
||||||
) {
|
) {
|
||||||
warning "binfmt_misc not found in /proc/mounts -- not"
|
warning "binfmt_misc not found in /proc/mounts -- not"
|
||||||
. " mounted?";
|
. " mounted?";
|
||||||
|
@ -2890,7 +2937,7 @@ sub main() {
|
||||||
# If no suite was specified, then the whole sources.list has to
|
# If no suite was specified, then the whole sources.list has to
|
||||||
# come from standard input
|
# come from standard input
|
||||||
info "Reading sources.list from standard input...";
|
info "Reading sources.list from standard input...";
|
||||||
$sourceslist = do { local $/; <STDIN> };
|
$sourceslist = do { local $/; <> };
|
||||||
} else {
|
} else {
|
||||||
my @components = ();
|
my @components = ();
|
||||||
foreach my $comp (@{ $options->{components} }) {
|
foreach my $comp (@{ $options->{components} }) {
|
||||||
|
@ -3050,7 +3097,7 @@ sub main() {
|
||||||
for my $arg (@ARGV) {
|
for my $arg (@ARGV) {
|
||||||
if ($arg eq '-') {
|
if ($arg eq '-') {
|
||||||
info "Reading sources.list from standard input...";
|
info "Reading sources.list from standard input...";
|
||||||
$sourceslist .= do { local $/; <STDIN> };
|
$sourceslist .= do { local $/; <> };
|
||||||
} elsif ($arg =~ /^deb(-src)? /) {
|
} elsif ($arg =~ /^deb(-src)? /) {
|
||||||
$sourceslist .= "$arg\n";
|
$sourceslist .= "$arg\n";
|
||||||
} elsif ($arg =~ /:\/\//) {
|
} elsif ($arg =~ /:\/\//) {
|
||||||
|
@ -3284,12 +3331,13 @@ sub main() {
|
||||||
|
|
||||||
my $outer_gid = $REAL_GROUP_ID + 0;
|
my $outer_gid = $REAL_GROUP_ID + 0;
|
||||||
|
|
||||||
my $pid = get_unshare_cmd { chown 1, 1, $options->{root} }
|
my $pid = get_unshare_cmd(
|
||||||
[
|
sub { chown 1, 1, $options->{root} },
|
||||||
['u', '0', $REAL_USER_ID, '1'],
|
[
|
||||||
['g', '0', $outer_gid, '1'],
|
['u', '0', $REAL_USER_ID, '1'],
|
||||||
['u', '1', $idmap[0][2], '1'],
|
['g', '0', $outer_gid, '1'],
|
||||||
['g', '1', $idmap[1][2], '1']];
|
['u', '1', $idmap[0][2], '1'],
|
||||||
|
['g', '1', $idmap[1][2], '1']]);
|
||||||
waitpid $pid, 0;
|
waitpid $pid, 0;
|
||||||
$? == 0 or error "chown failed";
|
$? == 0 or error "chown failed";
|
||||||
}
|
}
|
||||||
|
@ -3297,10 +3345,12 @@ sub main() {
|
||||||
# figure out whether we have mknod
|
# figure out whether we have mknod
|
||||||
$options->{havemknod} = 0;
|
$options->{havemknod} = 0;
|
||||||
if ($options->{mode} eq 'unshare') {
|
if ($options->{mode} eq 'unshare') {
|
||||||
my $pid = get_unshare_cmd {
|
my $pid = get_unshare_cmd(
|
||||||
$options->{havemknod} = havemknod($options->{root});
|
sub {
|
||||||
}
|
$options->{havemknod} = havemknod($options->{root});
|
||||||
\@idmap;
|
},
|
||||||
|
\@idmap
|
||||||
|
);
|
||||||
waitpid $pid, 0;
|
waitpid $pid, 0;
|
||||||
$? == 0 or error "havemknod failed";
|
$? == 0 or error "havemknod failed";
|
||||||
} elsif (
|
} elsif (
|
||||||
|
@ -3366,60 +3416,62 @@ sub main() {
|
||||||
or error "socketpair failed: $!";
|
or error "socketpair failed: $!";
|
||||||
$options->{hooksock} = $childsock;
|
$options->{hooksock} = $childsock;
|
||||||
if ($options->{mode} eq 'unshare') {
|
if ($options->{mode} eq 'unshare') {
|
||||||
$pid = get_unshare_cmd {
|
$pid = get_unshare_cmd(
|
||||||
# child
|
sub {
|
||||||
$SIG{'INT'} = 'DEFAULT';
|
# child
|
||||||
$SIG{'HUP'} = 'DEFAULT';
|
local $SIG{'INT'} = 'DEFAULT';
|
||||||
$SIG{'PIPE'} = 'DEFAULT';
|
local $SIG{'HUP'} = 'DEFAULT';
|
||||||
$SIG{'TERM'} = 'DEFAULT';
|
local $SIG{'PIPE'} = 'DEFAULT';
|
||||||
|
local $SIG{'TERM'} = 'DEFAULT';
|
||||||
|
|
||||||
# unblock all delayed signals (and possibly handle them)
|
# unblock all delayed signals (and possibly handle them)
|
||||||
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
||||||
or error "Can't unblock signals: $!";
|
or error "Can't unblock signals: $!";
|
||||||
|
|
||||||
close $rfh;
|
close $rfh;
|
||||||
close $parentsock;
|
close $parentsock;
|
||||||
open(STDOUT, '>&', STDERR) or error "cannot open STDOUT: $!";
|
open(STDOUT, '>&', STDERR) or error "cannot open STDOUT: $!";
|
||||||
|
|
||||||
setup($options);
|
setup($options);
|
||||||
|
|
||||||
print $childsock (pack('n', 0) . 'adios');
|
print $childsock (pack('n', 0) . 'adios');
|
||||||
$childsock->flush();
|
$childsock->flush();
|
||||||
|
|
||||||
close $childsock;
|
close $childsock;
|
||||||
|
|
||||||
if ($options->{maketar} or $options->{makesqfs}) {
|
if ($options->{maketar} or $options->{makesqfs}) {
|
||||||
info "creating tarball...";
|
info "creating tarball...";
|
||||||
|
|
||||||
# redirect tar output to the writing end of the pipe so that
|
# redirect tar output to the writing end of the pipe so
|
||||||
# the parent process can capture the output
|
# that the parent process can capture the output
|
||||||
open(STDOUT, '>&', $wfh) or error "cannot open STDOUT: $!";
|
open(STDOUT, '>&', $wfh) or error "cannot open STDOUT: $!";
|
||||||
|
|
||||||
# Add ./dev as the first entries of the tar file.
|
# Add ./dev as the first entries of the tar file.
|
||||||
# We cannot add them after calling tar, because there is no way
|
# We cannot add them after calling tar, because there is no
|
||||||
# to prevent tar from writing NULL entries at the end.
|
# way to prevent tar from writing NULL entries at the end.
|
||||||
print $devtar;
|
print $devtar;
|
||||||
|
|
||||||
# pack everything except ./dev
|
# pack everything except ./dev
|
||||||
0 == system('tar', @taropts, '-C', $options->{root}, '.')
|
0 == system('tar', @taropts, '-C', $options->{root}, '.')
|
||||||
or error "tar failed: $?";
|
or error "tar failed: $?";
|
||||||
|
|
||||||
info "done";
|
info "done";
|
||||||
}
|
}
|
||||||
|
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
},
|
||||||
\@idmap;
|
\@idmap
|
||||||
|
);
|
||||||
} elsif (
|
} elsif (
|
||||||
any { $_ eq $options->{mode} }
|
any { $_ eq $options->{mode} }
|
||||||
('root', 'fakechroot', 'proot', 'chrootless')
|
('root', 'fakechroot', 'proot', 'chrootless')
|
||||||
) {
|
) {
|
||||||
$pid = fork() // error "fork() failed: $!";
|
$pid = fork() // error "fork() failed: $!";
|
||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
$SIG{'INT'} = 'DEFAULT';
|
local $SIG{'INT'} = 'DEFAULT';
|
||||||
$SIG{'HUP'} = 'DEFAULT';
|
local $SIG{'HUP'} = 'DEFAULT';
|
||||||
$SIG{'PIPE'} = 'DEFAULT';
|
local $SIG{'PIPE'} = 'DEFAULT';
|
||||||
$SIG{'TERM'} = 'DEFAULT';
|
local $SIG{'TERM'} = 'DEFAULT';
|
||||||
|
|
||||||
# unblock all delayed signals (and possibly handle them)
|
# unblock all delayed signals (and possibly handle them)
|
||||||
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
||||||
|
@ -3503,10 +3555,10 @@ sub main() {
|
||||||
info "main() received signal $got_signal: waiting for $waiting_for...";
|
info "main() received signal $got_signal: waiting for $waiting_for...";
|
||||||
};
|
};
|
||||||
|
|
||||||
$SIG{'INT'} = $ignore;
|
local $SIG{'INT'} = $ignore;
|
||||||
$SIG{'HUP'} = $ignore;
|
local $SIG{'HUP'} = $ignore;
|
||||||
$SIG{'PIPE'} = $ignore;
|
local $SIG{'PIPE'} = $ignore;
|
||||||
$SIG{'TERM'} = $ignore;
|
local $SIG{'TERM'} = $ignore;
|
||||||
|
|
||||||
# unblock all delayed signals (and possibly handle them)
|
# unblock all delayed signals (and possibly handle them)
|
||||||
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
|
||||||
|
@ -3880,10 +3932,10 @@ sub main() {
|
||||||
my $cpid = fork() // error "fork() failed: $!";
|
my $cpid = fork() // error "fork() failed: $!";
|
||||||
if ($cpid == 0) {
|
if ($cpid == 0) {
|
||||||
# child: default signal handlers
|
# child: default signal handlers
|
||||||
$SIG{'INT'} = 'DEFAULT';
|
local $SIG{'INT'} = 'DEFAULT';
|
||||||
$SIG{'HUP'} = 'DEFAULT';
|
local $SIG{'HUP'} = 'DEFAULT';
|
||||||
$SIG{'PIPE'} = 'DEFAULT';
|
local $SIG{'PIPE'} = 'DEFAULT';
|
||||||
$SIG{'TERM'} = 'DEFAULT';
|
local $SIG{'TERM'} = 'DEFAULT';
|
||||||
|
|
||||||
# unblock all delayed signals (and possibly handle
|
# unblock all delayed signals (and possibly handle
|
||||||
# them)
|
# them)
|
||||||
|
@ -3900,7 +3952,7 @@ sub main() {
|
||||||
}
|
}
|
||||||
open(STDIN, '<&', $rfh)
|
open(STDIN, '<&', $rfh)
|
||||||
or error "cannot open file handle for reading: $!";
|
or error "cannot open file handle for reading: $!";
|
||||||
eval 'Devel::Cover::set_coverage("none")'
|
eval { Devel::Cover::set_coverage("none") }
|
||||||
if $is_covering;
|
if $is_covering;
|
||||||
exec { $argv[0] } @argv
|
exec { $argv[0] } @argv
|
||||||
or
|
or
|
||||||
|
@ -3943,27 +3995,29 @@ sub main() {
|
||||||
# the unshared namespace, so we remove it here.
|
# the unshared namespace, so we remove it here.
|
||||||
# Since this is still inside the unshared namespace, there is
|
# Since this is still inside the unshared namespace, there is
|
||||||
# no risk of removing anything important.
|
# no risk of removing anything important.
|
||||||
$pid = get_unshare_cmd {
|
$pid = get_unshare_cmd(
|
||||||
# File::Path will produce the error "cannot stat initial
|
sub {
|
||||||
# working directory" if the working directory cannot be
|
# File::Path will produce the error "cannot stat initial
|
||||||
# accessed by the unprivileged unshared user. Thus, we first
|
# working directory" if the working directory cannot be
|
||||||
# navigate to the parent of the root directory.
|
# accessed by the unprivileged unshared user. Thus, we
|
||||||
chdir "$options->{root}/.."
|
# first navigate to the parent of the root directory.
|
||||||
or error "unable to chdir() to parent directory of"
|
chdir "$options->{root}/.."
|
||||||
. " $options->{root}: $!";
|
or error "unable to chdir() to parent directory of"
|
||||||
remove_tree($options->{root}, { error => \my $err });
|
. " $options->{root}: $!";
|
||||||
if (@$err) {
|
remove_tree($options->{root}, { error => \my $err });
|
||||||
for my $diag (@$err) {
|
if (@$err) {
|
||||||
my ($file, $message) = %$diag;
|
for my $diag (@$err) {
|
||||||
if ($file eq '') {
|
my ($file, $message) = %$diag;
|
||||||
warning "general error: $message";
|
if ($file eq '') {
|
||||||
} else {
|
warning "general error: $message";
|
||||||
warning "problem unlinking $file: $message";
|
} else {
|
||||||
|
warning "problem unlinking $file: $message";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
\@idmap
|
||||||
\@idmap;
|
);
|
||||||
waitpid $pid, 0;
|
waitpid $pid, 0;
|
||||||
$? == 0 or error "remove_tree failed";
|
$? == 0 or error "remove_tree failed";
|
||||||
} elsif (
|
} elsif (
|
||||||
|
|
Loading…
Reference in a new issue