X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=src%2FPVE%2FTools.pm;h=676647eefb375d8d1ad00e9d06ab404baab9c906;hp=6254b2e653624880ab67fd35fcb581303caa6463;hb=3982313e8d89982f109d4b4c6c1248d1b7d35512;hpb=fb3a1b2985a35eb7e2630fbe4ddd6981f81d0b98 diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm index 6254b2e..676647e 100644 --- a/src/PVE/Tools.pm +++ b/src/PVE/Tools.pm @@ -640,7 +640,7 @@ sub pipe_socket_to_command { } sub split_list { - my $listtxt = shift || ''; + my $listtxt = shift // ''; return split (/\0/, $listtxt) if $listtxt =~ m/\0/; @@ -670,7 +670,7 @@ sub template_replace { return $tmpl if !$tmpl; my $res = ''; - while ($tmpl =~ m/([^{]+)?({([^}]+)})?/g) { + while ($tmpl =~ m/([^{]+)?(\{([^}]+)\})?/g) { $res .= $1 if $1; $res .= ($data->{$3} || '-') if $2; } @@ -1384,6 +1384,11 @@ sub parse_host_and_port { return; # nothing } +sub setresuid($$$) { + my ($ruid, $euid, $suid) = @_; + return 0 == syscall(PVE::Syscall::setresuid, $ruid, $euid, $suid); +} + sub unshare($) { my ($flags) = @_; return 0 == syscall(PVE::Syscall::unshare, $flags); @@ -1399,6 +1404,11 @@ sub syncfs($) { return 0 == syscall(PVE::Syscall::syncfs, $fileno); } +sub fsync($) { + my ($fileno) = @_; + return 0 == syscall(PVE::Syscall::fsync, $fileno); +} + sub sync_mountpoint { my ($path) = @_; sysopen my $fd, $path, O_PATH or die "failed to open $path: $!\n"; @@ -1627,4 +1637,55 @@ sub get_host_arch { } } +# Devices are: [ (12 bits minor) (12 bits major) (8 bits minor) ] +sub dev_t_major($) { + my ($dev_t) = @_; + return (int($dev_t) & 0xfff00) >> 8; +} + +sub dev_t_minor($) { + my ($dev_t) = @_; + $dev_t = int($dev_t); + return (($dev_t >> 12) & 0xfff00) | ($dev_t & 0xff); +} + +# Given an array of array refs [ \[a b c], \[a b b], \[e b a] ] +# Returns the intersection of elements as a single array [a b] +sub array_intersect { + my ($arrays) = @_; + + if (!ref($arrays->[0])) { + $arrays = [ grep { ref($_) eq 'ARRAY' } @_ ]; + } + + return [] if scalar(@$arrays) == 0; + return $arrays->[0] if scalar(@$arrays) == 1; + + my $array_unique = sub { + my %seen = (); + return grep { ! $seen{ $_ }++ } @_; + }; + + # base idea is to get all unique members from the first array, then + # check the common elements with the next (uniquely made) one, only keep + # those. Repeat for every array and at the end we only have those left + # which exist in all arrays + my $return_arr = [ $array_unique->(@{$arrays->[0]}) ]; + for my $i (1 .. $#$arrays) { + my %count = (); + # $return_arr is already unique, explicit at before the loop, implicit below. + foreach my $element (@$return_arr, $array_unique->(@{$arrays->[$i]})) { + $count{$element}++; + } + $return_arr = []; + foreach my $element (keys %count) { + push @$return_arr, $element if $count{$element} > 1; + } + last if scalar(@$return_arr) == 0; # empty intersection, early exit + } + + return $return_arr; +} + + 1;