App-Syslogd
view release on metacpan or search on metacpan
lib/App/Syslogd.pm view on Meta::CPAN
{
no autodie qw(sysopen);
sysopen($fh, $file, O_RDWR | O_APPEND | O_CREAT | $O_NOFOLLOW | $O_NONBLOCK, $LOG_MODE)
or croak($self->i18n('open_failed', { file => $file, error => "$!" }));
}
# O_NOFOLLOW cannot catch a hard link or a file someone else pre-created
# for us to fill with their reading material, so check after opening
# Safe means all three: a regular file, owned by us, one link. By De
# Morgan, "not all three" is "any one of them fails".
my @st = stat($fh);
unless(-f _ && ($st[4] == $>) && ($st[3] == 1)) {
_discard($fh);
croak($self->i18n('unsafe_file', { file => $file }));
}
# A file that already has content must be one of our logs: it must
# start with the header line. Without this a mistaken setting (as
# root, every root-owned file is "ours") would append to, and chmod,
# any file at all, /etc/passwd included. Checked before the chmod, so
# a file that is not ours to change is never changed.
is_deeply([map { $counts[$_ + 1] - $counts[$_] >= 0 ? 1 : 0 } 0 .. $#counts - 1], [(1) x $#counts], 'never decreases');
is_deeply(\@counts, [0, 1, 1, 1, 2, 2], 'and grows only for datagrams long enough');
};
# ===========================================================================
# App::Syslogd: the log file
# ===========================================================================
subtest 'M3: safe = regular && owned && one link - all eight rows, and De Morgan' => sub {
# Every combination of the three conditions. "Not regular" comes from
# /dev/null; owner and link count are faked through stat(). For each
# row the outcome must equal both "A and B and C" and its De Morgan
# form "not (not A or not B or not C)".
plan(skip_all => 'needs /dev/null') unless(-c '/dev/null');
foreach my $regular (1, 0) {
foreach my $owned (1, 0) {
foreach my $one_link (1, 0) {
my $file = $regular ? new_path() : '/dev/null';
local %FAKE_STAT = (owner => $owned ? $> : $CONFIG{someone_else}, links => $one_link ? $CONFIG{one_link} : $CONFIG{two_links});
my $accepted = eval { App::Syslogd->new(file => $file)->reopen_log(); 1 } ? 1 : 0;
my $and = ($regular && $owned && $one_link) ? 1 : 0;
( run in 0.513 second using v1.01-cache-2.11-cpan-cb04b646d8c )