开发者

Need help in understanding a statement in Perl which use File::stat

开发者 https://www.devze.com 2023-02-04 11:08 出处:网络
In the below code, what does statement \"$retMode & 0777\" and \"$retMode & 006\" mean? use File::stat;

In the below code, what does statement "$retMode & 0777" and "$retMode & 006" mean?

 use File::stat;  

 my $fpath = "/home/xyz/abc.sh" ;  
 my $info ;  
 my $retMode ;  
 my $property = "File_Permission";  

 $info=stat($fpath) ;  
 if($info){  
     $retMode = $info->mode; # This field contain file mode info  
     $retMode = $retMode & 0777;  
     if(($retMode & 006)) {  
        printf "$property|%03o|$fpath\n",$re开发者_开发百科tMode;  
     }  
 }


$retMode & 0777 means that you take the value of return mode (which is file permissions + file type) and Bitwise-And it with an octal-representation number of 777 (e.g. decimal 511, e.g. binary 111111111).

What this does technically is removes any bits from an integer above the 9th bit, so if the mode binary representation was >9 bits, it would, after this operation, leave only the last 9 bits, representing the main permissions (read/write/execute for other/group/user).

Why? Because (as perldoc stat shows), mode() returned from stat:

"contains both the file type and its permissions, you should mask off the file type portion and (s)printf using a "%o" if you want to see the real permissions".

In other words, it DOES contain data above 9th bit, but only last 9 bits represent permissions data which is what the code above is after. To be more precise, the last 12 digits represent permissions (so the code should instead be doing & 07777) but bits 10-12 represent special permission bits unrelated to user/group/other read/write/execute perms (e.g. setuid, is_directory).


$retMode & 006 has similar mechanics, but different purpose. 006 octal is 110 in binary so it basically takes the mode bit vector and leaves only bits in 2/3 positions. Since the result is used in a boolean context, it will merely check whether the resulting # is non-zero, meaning if ONE of those 2 bits was set to 1.

Please note that & 006 is actually BAD coding style since it is not obvious which bits are which perms (as I tried to subtly hint at by not explaining what bits 2/3 mean in the paragraph above). Instead you should import symbolic mode constants (S_IF* ) and functions (S_IS* ) from the Fcntl module:

use Fcntl ':mode';
$retMode = $retMode & 0777; # Ignoring setuid and directory bits
$other_read_or_write = $retMode & (S_IWOTH || S_IROTH); 
                                  # Bits 2/3 - Other read/write
if ($other_read_or_write) {
    printf "$property|%03o|$fpath\n",$retMode; 
}


In POSIX environments a file's mode is a set of bits that describe the read,write, and execute permissions for the file's owner, the file's group, and everyone else.

See http://www.tuxfiles.org/linuxhelp/filepermissions.html or google "linux file permissions" for a complete overview.

In this case

if(($retMode & 006)) {
      printf "$property|%03o|$fpath\n",$retMode;
}

the code inside the conditional will only run if you have either write or read permission on the file.


They are bit operations Perl bitwise and.

$retMode & 0777 clears all bits above the bottom 9 bits of $retMode.

$retMode & 006 tests two of the bottom 3 bits and returns true (a number other than 0) if these bits correspond to the numbers 2, 3, 4, 5, 6, 7

In pictures (where x is 1 or 0 and is unchanged going from the top line to the bottom line):

$RetMode & 0777:

$RetMode:   xxxxxxxxxxxxxxxxxx
0777        000000000111111111
Result:     000000000xxxxxxxxx

$RetMode & 006:

$RetMode:   000000000xxxxxxxxx
0777        000000000000000110
Result:     000000000000000xx0

As graviton posted, you are testing the permissions on the file.

0

精彩评论

暂无评论...
验证码 换一张
取 消