#!/bin/sh # -*- perl -*- # Ensure that rm gives the expected diagnostic when failing to remove a file # owned by some other user in a directory with the sticky bit set. : ${PERL=perl} : ${srcdir=.} case "$PERL" in *'missing perl') #' echo 1>&2 \ "$0: configure didn't find a usable version of Perl, so can't run this test" exit 77 ;; esac ARGV_0=$0 export ARGV_0 exec $PERL -w -- - << \EOP require 5.003; use strict; (my $ME = $ENV{ARGV_0}) =~ s|.*/||; my $verbose = $ENV{VERBOSE} && $ENV{VERBOSE} eq 'yes'; $verbose and system qw (rm --version); # Ensure that the diagnostics are in English. $ENV{LC_ALL} = 'C'; # Ensure that the effective UID is not 0. if ($> == 0) { warn "$ME: you may not run this test as root; skipping it.\n"; exit 77; } my @dir_list = qw(/tmp /var/tmp /usr/tmp); # Find a directory with the sticky bit set. my $found_dir; my $found_file; foreach my $dir (@dir_list) { if (-d $dir && -k _ && -r _ && -w _ && -x _) { $found_dir = 1; # Find a non-directory there that is owned by some other user. opendir DIR_HANDLE, $dir or die "$ME: couldn't open $dir: $!\n"; foreach my $f (readdir DIR_HANDLE) { my $target_file = "$dir/$f"; $verbose and warn "$ME: considering $target_file\n"; # Skip files owned by self, symlinks, and directories. # It's not technically necessary to skip symlinks, but it's simpler. -l $target_file || -o _ || -d _ and next; $found_file = 1; # Invoke rm on this file and ensure that we get the # expected exit code and diagnostic. my $cmd = "rm -f $target_file"; open RM, "$cmd 2>&1 |" or die "$ME: cannot execute `$cmd'\n"; my $line = ; close RM; my $status = $? >> 8; $status == 1 or die "$ME: unexpected exit status from `$cmd';\n" . " got $status, expected 1\n"; my $exp = "rm: cannot remove `$target_file':"; $line or die "$ME: no output from `$cmd';\n" . "expected something like `$exp ...'\n"; my $regex = quotemeta $exp; $line =~ /^$regex/ or die "$ME: unexpected dignostic from `$cmd';\n" . " got $line" . " expected $exp ...\n"; last; } closedir DIR_HANDLE; $found_file and last; } } if ( ! $found_dir) { warn "$ME: couldn't find a directory with the sticky bit set;" . " skipping this test\n"; exit 77; } if ( ! $found_file) { warn "$ME: couldn't find a file not owned by you\n" . " in any of the following directories:\n @dir_list\n" . "...so, skipping this test\n"; exit 77; } EOP