]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/Tools.pm
various perl critic fixes
[pve-common.git] / src / PVE / Tools.pm
index cacfc89f9b6b31e01a9ca354fbe54b019fca70ea..d933503d164a8a2d4abbf51c9c64f627b30fc519 100644 (file)
@@ -302,7 +302,7 @@ sub safe_read_from {
     my ($fh, $max, $oneline, $filename) = @_;
 
     # pmxcfs file size limit
-    $max = 512*1024 if !$max;
+    $max = 1024 * 1024 if !$max;
 
     my $subject = defined($filename) ? "file '$filename'" : 'input';
 
@@ -1022,6 +1022,7 @@ sub run_fork_with_timeout {
     warn $@ if $@;
     $pipe_out->close();
     kill('KILL', $child);
+    # FIXME: hangs if $child doesn't exits?! (D state)
     waitpid($child, 0);
 
     alarm $prev_alarm;
@@ -1210,8 +1211,7 @@ sub decode_text {
     return Encode::decode("utf8", uri_unescape($data));
 }
 
-# depreciated - do not use!
-# we now decode all parameters by default
+# NOTE: deprecated - do not use! we now decode all parameters by default
 sub decode_utf8_parameters {
     my ($param) = @_;
 
@@ -1265,54 +1265,76 @@ sub split_args {
     return $str ? [ Text::ParseWords::shellwords($str) ] : [];
 }
 
-sub dump_logfile {
-    my ($filename, $start, $limit, $filter) = @_;
+sub dump_logfile_by_filehandle {
+    my ($fh, $filter, $state) = @_;
 
-    my $lines = [];
-    my $count = 0;
-
-    my $fh = IO::File->new($filename, "r");
-    if (!$fh) {
-       $count++;
-       push @$lines, { n => $count, t => "unable to open file - $!"};
-       return ($count, $lines);
-    }
-
-    $start = 0 if !$start;
-    $limit = 50 if !$limit;
+    my $count = ($state->{count} //= 0);
+    my $lines = ($state->{lines} //= []);
+    my $start = ($state->{start} //= 0);
+    my $limit = ($state->{limit} //= 50);
+    my $final = ($state->{final} //= 1);
+    my $read_until_end = ($state->{read_until_end} //= $limit == 0);
 
     my $line;
-
     if ($filter) {
        # duplicate code, so that we do not slow down normal path
        while (defined($line = <$fh>)) {
-           next if $line !~ m/$filter/;
+           if (ref($filter) eq 'CODE') {
+               next if !$filter->($line);
+           } else {
+               next if $line !~ m/$filter/;
+           }
            next if $count++ < $start;
-           next if $limit <= 0;
+           if (!$read_until_end) {
+               next if $limit <= 0;
+               $limit--;
+           }
            chomp $line;
            push @$lines, { n => $count, t => $line};
-           $limit--;
        }
     } else {
        while (defined($line = <$fh>)) {
            next if $count++ < $start;
-           next if $limit <= 0;
+           if (!$read_until_end) {
+               next if $limit <= 0;
+               $limit--;
+           }
            chomp $line;
            push @$lines, { n => $count, t => $line};
-           $limit--;
        }
     }
 
-    close($fh);
-
     # HACK: ExtJS store.guaranteeRange() does not like empty array
     # so we add a line
-    if (!$count) {
+    if (!$count && $final) {
        $count++;
        push @$lines, { n => $count, t => "no content"};
     }
 
-    return ($count, $lines);
+    $state->{count} = $count;
+    $state->{limit} = $limit;
+}
+
+sub dump_logfile {
+    my ($filename, $start, $limit, $filter) = @_;
+
+    my $fh = IO::File->new($filename, "r");
+    if (!$fh) {
+       return (1, { n => 1, t => "unable to open file - $!"});
+    }
+
+    my %state = (
+       'count' => 0,
+       'lines' => [],
+       'start' => $start,
+       'limit' => $limit,
+    );
+
+    dump_logfile_by_filehandle($fh, $filter, \%state);
+
+    close($fh);
+
+    return ($state{'count'}, $state{'lines'});
 }
 
 sub dump_journal {
@@ -1468,32 +1490,39 @@ sub parse_host_and_port {
 
 sub setresuid($$$) {
     my ($ruid, $euid, $suid) = @_;
-    return 0 == syscall(PVE::Syscall::setresuid, $ruid, $euid, $suid);
+    return 0 == syscall(PVE::Syscall::setresuid, int($ruid), int($euid), int($suid));
 }
 
 sub unshare($) {
     my ($flags) = @_;
-    return 0 == syscall(PVE::Syscall::unshare, $flags);
+    return 0 == syscall(PVE::Syscall::unshare, int($flags));
 }
 
 sub setns($$) {
     my ($fileno, $nstype) = @_;
-    return 0 == syscall(PVE::Syscall::setns, $fileno, $nstype);
+    return 0 == syscall(PVE::Syscall::setns, int($fileno), int($nstype));
 }
 
 sub syncfs($) {
     my ($fileno) = @_;
-    return 0 == syscall(PVE::Syscall::syncfs, $fileno);
+    return 0 == syscall(PVE::Syscall::syncfs, int($fileno));
 }
 
 sub fsync($) {
     my ($fileno) = @_;
-    return 0 == syscall(PVE::Syscall::fsync, $fileno);
+    return 0 == syscall(PVE::Syscall::fsync, int($fileno));
 }
 
 sub renameat2($$$$$) {
     my ($olddirfd, $oldpath, $newdirfd, $newpath, $flags) = @_;
-    return 0 == syscall(PVE::Syscall::renameat2, $olddirfd, $oldpath, $newdirfd, $newpath, $flags);
+    return 0 == syscall(
+       PVE::Syscall::renameat2,
+       int($olddirfd),
+       $oldpath,
+       int($newdirfd),
+       $newpath,
+       int($flags),
+    );
 }
 
 sub sync_mountpoint {
@@ -1652,7 +1681,11 @@ sub validate_ssh_public_keys {
 
 sub openat($$$;$) {
     my ($dirfd, $pathname, $flags, $mode) = @_;
-    my $fd = syscall(PVE::Syscall::openat, $dirfd, $pathname, $flags, $mode//0);
+    $dirfd = int($dirfd);
+    $flags = int($flags);
+    $mode = int($mode // 0);
+
+    my $fd = syscall(PVE::Syscall::openat, $dirfd, $pathname, $flags, $mode);
     return undef if $fd < 0;
     # sysopen() doesn't deal with numeric file descriptors apparently
     # so we need to convert to a mode string for IO::Handle->new_from_fd
@@ -1667,12 +1700,19 @@ sub openat($$$;$) {
 
 sub mkdirat($$$) {
     my ($dirfd, $name, $mode) = @_;
-    return syscall(PVE::Syscall::mkdirat, $dirfd, $name, $mode) == 0;
+    return syscall(PVE::Syscall::mkdirat, int($dirfd), $name, int($mode)) == 0;
 }
 
 sub fchownat($$$$$) {
     my ($dirfd, $pathname, $owner, $group, $flags) = @_;
-    return syscall(PVE::Syscall::fchownat, $dirfd, $pathname, $owner, $group, $flags) == 0;
+    return syscall(
+       PVE::Syscall::fchownat,
+       int($dirfd),
+       $pathname,
+       int($owner),
+       int($group),
+       int($flags),
+    ) == 0;
 }
 
 my $salt_starter = time();
@@ -1802,9 +1842,9 @@ sub open_tree($$$) {
     my ($dfd, $pathname, $flags) = @_;
     return PVE::Syscall::file_handle_result(syscall(
        &PVE::Syscall::open_tree,
-       $dfd,
+       int($dfd),
        $pathname,
-       $flags,
+       int($flags),
     ));
 }
 
@@ -1812,26 +1852,26 @@ sub move_mount($$$$$) {
     my ($from_dirfd, $from_pathname, $to_dirfd, $to_pathname, $flags) = @_;
     return 0 == syscall(
        &PVE::Syscall::move_mount,
-       $from_dirfd,
+       int($from_dirfd),
        $from_pathname,
-       $to_dirfd,
+       int($to_dirfd),
        $to_pathname,
-       $flags,
+       int($flags),
     );
 }
 
 sub fsopen($$) {
     my ($fsname, $flags) = @_;
-    return PVE::Syscall::file_handle_result(syscall(&PVE::Syscall::fsopen, $fsname, $flags));
+    return PVE::Syscall::file_handle_result(syscall(&PVE::Syscall::fsopen, $fsname, int($flags)));
 }
 
 sub fsmount($$$) {
     my ($fd, $flags, $mount_attrs) = @_;
     return PVE::Syscall::file_handle_result(syscall(
        &PVE::Syscall::fsmount,
-       $fd,
-       $flags,
-       $mount_attrs,
+       int($fd),
+       int($flags),
+       int($mount_attrs),
     ));
 }
 
@@ -1839,15 +1879,22 @@ sub fspick($$$) {
     my ($dirfd, $pathname, $flags) = @_;
     return PVE::Syscall::file_handle_result(syscall(
        &PVE::Syscall::fspick,
-       $dirfd,
+       int($dirfd),
        $pathname,
-       $flags,
+       int($flags),
     ));
 }
 
 sub fsconfig($$$$$) {
     my ($fd, $command, $key, $value, $aux) = @_;
-    return 0 == syscall(&PVE::Syscall::fsconfig, $fd, $command, $key, $value, $aux);
+    return 0 == syscall(
+       &PVE::Syscall::fsconfig,
+       int($fd),
+       int($command),
+       $key,
+       $value,
+       int($aux),
+    );
 }
 
 # "raw" mount, old api, not for generic use (as it does not invoke any helpers).
@@ -1859,13 +1906,13 @@ sub mount($$$$$) {
        $source,
        $target,
        $filesystemtype,
-       $mountflags,
+       int($mountflags),
        $data,
     );
 }
 
 # size is optional and defaults to 256, note that xattr limits are FS specific and that xattrs can
-# get arbitrary long. NOTE: $! is set to ENOBUFS if the xattr is longer than the buffer size used.
+# get arbitrary long. pass `0` for $size in array context to get the actual size of a value
 sub getxattr($$;$) {
     my ($path_or_handle, $name, $size) = @_;
     $size //= 256;
@@ -1873,16 +1920,14 @@ sub getxattr($$;$) {
 
     my $xattr_size = -1; # the actual size of the xattr, can be zero
     if (defined(my $fd = fileno($path_or_handle))) {
-       $xattr_size = syscall(&PVE::Syscall::fgetxattr, $fd, $name, $buf, $size);
+       $xattr_size = syscall(&PVE::Syscall::fgetxattr, $fd, $name, $buf, int($size));
     } else {
-       $xattr_size = syscall(&PVE::Syscall::getxattr, $path_or_handle, $name, $buf, $size);
+       $xattr_size = syscall(&PVE::Syscall::getxattr, $path_or_handle, $name, $buf, int($size));
     }
     if ($xattr_size < 0) {
-       warn "$xattr_size <0 - $!";
        return undef;
-    } elsif ($xattr_size > $size) {
-       $! = POSIX::ENOBUFS;
     }
+    $buf = substr($buf, 0, $xattr_size);
     return wantarray ? ($buf, $xattr_size) : $buf;
 }
 
@@ -1892,9 +1937,23 @@ sub setxattr($$$;$) {
     my $size = length($value); # NOTE: seems to get correct length also for wide-characters in text..
 
     if (defined(my $fd = fileno($path_or_handle))) {
-       return 0 == syscall(&PVE::Syscall::fsetxattr, $fd, $name, $value, $size, $flags // 0);
+       return 0 == syscall(
+           &PVE::Syscall::fsetxattr,
+           $fd,
+           $name,
+           $value,
+           int($size),
+           int($flags // 0),
+       );
     } else {
-       return 0 == syscall(&PVE::Syscall::setxattr, $path_or_handle, $name, $value, $size, $flags // 0);
+       return 0 == syscall(
+           &PVE::Syscall::setxattr,
+           $path_or_handle,
+           $name,
+           $value,
+           int($size),
+           int($flags // 0),
+       );
     }
 }