Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: [Cygwin] Setting and getting file permissions as octal numbers

by kcott (Archbishop)
on Sep 03, 2022 at 19:13 UTC ( [id://11146667]=note: print w/replies, xml ) Need Help??


in reply to [Cygwin] Setting and getting file permissions as octal numbers

G'day Rob,

I tested the following using Cygwin version 3.3.5 running on Win10 (both fully updated less than two days ago).

$ uname -a CYGWIN_NT-10.0-19044 titan 3.3.5-341.x86_64 2022-05-13 12:27 UTC x86_6 +4 Cygwin

I don't have any old versions of Perl available; however, I don't think there's any code here that wouldn't run on Perl 5.8 (happy to be corrected on that as I can't test it myself).

Some basic notes on Perl code (you probably know most of this; possibly useful for other readers):

  • stat gets the mode; & 07777 masks off the file type leaving just the perm value (e.g. get 0644 instead of 0100644).
  • sprintf provides the octal format you wanted.
  • chmod changes permissions using an octal number (stored in %perms).
  • I've recently taken to using the "system PROGRAM LIST" form of system for security reasons. However, for a long time, I've been using 'use autodie ':all';. Unfortunately, these two don't play well together; CORE::system fixes this; see "autodie: system/exec" for details.
    • As a side note, IPC::System::Simple has some useful functions to avoid using system directly in code.

Here's perm_tasks.pl:

#!/usr/bin/env perl use strict; use warnings; use autodie ':all'; use constant { OLD => 0, NEW => 1, }; print "OS: $^O; Perl: $^V\n"; my @filenames = 'a' .. 'd'; my %perms = ( a => [0644, 0644], b => [0644, 0755], c => [0644, 0440], d => [0644, 07644], ); print "\n*** Initial permissions (visual check):\n"; list_perms(@filenames); print "\n*** Initial permissions (program check):\n"; check_perms(\@filenames, \%perms, OLD); change_perms(\@filenames, \%perms, NEW); print "\n*** Modified permissions (visual check):\n"; list_perms(@filenames); print "\n*** Modified permissions (program check):\n"; check_perms(\@filenames, \%perms, NEW); change_perms(\@filenames, \%perms, OLD); print "\n*** Restored permissions (visual check):\n"; list_perms(@filenames); print "\n*** Restored permissions (program check):\n"; check_perms(\@filenames, \%perms, OLD); sub list_perms { my (@files) = @_; my @cmd_list = (ls => '-l', @files); CORE::system {$cmd_list[0]} @cmd_list; return; } sub check_perms { my ($files, $perms, $oldnew) = @_; for my $file (@$files) { my $perm = (stat $file)[2] & 07777; my $expected = sprintf('%#5o', $perms->{$file}[$oldnew]); print "File: '$file'; Perm: ", sprintf('%#5o', $perm), '; Check: ', ( $perm == $perms->{$file}[$oldnew] ? 'OK' : "WRONG (expected: $expected)" ), "\n"; } return; } sub change_perms { my ($files, $perms, $oldnew) = @_; for my $file (@$files) { chmod $perms->{$file}[$oldnew], $file; } return; }

I initially created the four files manually (e.g. >a); they all started with 0644 (rw-r--r--) according to my 0022 umask. I then programmatically altered three of those; 'd' being quite exotic with 07644 (rwSr-Sr-T). I then restored all to their original values; 'a' hadn't changed and restoring it (basically a no-op) was not a problem.

Output:

$ ./perm_tasks.pl OS: cygwin; Perl: v5.36.0 *** Initial permissions (visual check): -rw-r--r-- 1 ken None 0 Sep 4 02:07 a -rw-r--r-- 1 ken None 0 Sep 4 02:07 b -rw-r--r-- 1 ken None 0 Sep 4 02:07 c -rw-r--r-- 1 ken None 0 Sep 4 02:16 d *** Initial permissions (program check): File: 'a'; Perm: 0644; Check: OK File: 'b'; Perm: 0644; Check: OK File: 'c'; Perm: 0644; Check: OK File: 'd'; Perm: 0644; Check: OK *** Modified permissions (visual check): -rw-r--r-- 1 ken None 0 Sep 4 02:07 a -rwxr-xr-x 1 ken None 0 Sep 4 02:07 b -r--r----- 1 ken None 0 Sep 4 02:07 c -rwSr-Sr-T 1 ken None 0 Sep 4 02:16 d *** Modified permissions (program check): File: 'a'; Perm: 0644; Check: OK File: 'b'; Perm: 0755; Check: OK File: 'c'; Perm: 0440; Check: OK File: 'd'; Perm: 07644; Check: OK *** Restored permissions (visual check): -rw-r--r-- 1 ken None 0 Sep 4 02:07 a -rw-r--r-- 1 ken None 0 Sep 4 02:07 b -rw-r--r-- 1 ken None 0 Sep 4 02:07 c -rw-r--r-- 1 ken None 0 Sep 4 02:16 d *** Restored permissions (program check): File: 'a'; Perm: 0644; Check: OK File: 'b'; Perm: 0644; Check: OK File: 'c'; Perm: 0644; Check: OK File: 'd'; Perm: 0644; Check: OK
"On Cygwin, I find that sometimes the file permissions change when I (programmatically) make alterations to a text file."

I do find that execute permissions are automatically set for new files from a non-cygwin source copied to somewhere under /cygdrive/c/cygwin64 (e.g. saving a PNG created by Gimp which I run under Win10; downloading a PDF from the internet; copying a DOCX from $work, and so on). Files that I create myself (under /cygdrive/c/cygwin64) do not get execute permissions.

I've not encountered the scenario you describe; although, I've probably not done a lot of that (beyond appending to a logfile and such like). I'd be happy to check or test if that would be useful.

Update (correction): In the penultimate paragraph, I had /cygdrive/ in two places. Those should have been, and I've now changed them to, /cygdrive/c/cygwin64. By way of clarification for those unfamiliar with Cygwin:

Cygwin MSWin ============================= ==================== /cygdrive/c C:\ /cygdrive/d D:\ /cygdrive/c/Users/ken C:\Users\ken /cygdrive/c/cygwin64 C:\cygwin64 / C:\cygwin64 /cygdrive/c/cygwin64/home/ken C:\cygwin64\home\ken /home/ken C:\cygwin64\home\ken

— Ken

Replies are listed 'Best First'.
Re^2: [Cygwin] Setting and getting file permissions as octal numbers
by syphilis (Archbishop) on Sep 04, 2022 at 03:45 UTC
    I do find that execute permissions are automatically set for new files from a non-cygwin source copied to somewhere under /cygdrive/

    That's the type of problem I'm trying to avoid - the programmatic alterations are being made on a copy of the original file and then moved back.
    Prior to reading your post, I had not realized that it was the move rather than the "programmatic alterations" that was the source of the trouble.

    I'm finding that even copying a file (using the Windows clipboard) from /home/me/someplace to /home/me/elsewhere will set the execution bits on the copy.
    It's probably a case of just avoiding moving the file, by editing the file in place. (That seems to work ok, but I'll still be setting the perms to their original value anyway.)

    A rarer case is that I have also had execution bits mysteriously vanish. I haven't really found out how that happens, so I'll be guarding against that, too.

    Should I also be paying attention to the perms settings of the files that make up my perl module source distros on CPAN ?
    Those files inside the source tarballs all originate from a Cygwin environment, and the ones that I have just checked have their execution bits set.
    Should I be concerned about that ? (No-one has ever complained about the perms settings of the files in my perl modules.)

    Cheers,
    Rob

      Firstly, see the update to my post. Hopefully, the originally incorrect /cygdrive/ (now changed to /cygdrive/c/cygwin64) didn't mislead you; my apologies if it did.

      It seems our mode of operating differs somewhat; for instance, I don't believe I've ever used Windows clipboard to copy a file. I rarely use File Explorer for anything; ironically, the most common use is to update Cygwin (for the current 3.3.5 version: C:\Users\ken\local\opt\cygwin\3_3_5\setup-x86_64.exe). I use a Cygwin CLI to create files: "cp old new", "vim new" and "> new" would be the most common for individual files; "module-starter --module=New::Module" creates a directory structure for a new module — none of these creates files with inappropriate permissions.

      I checked through all of my (Perl v5.36) @INC directories. The core modules were installed using perlbrew; all CPAN modules were installed using the cpan utility (two exceptions; "cpan: Terminal does not support AddHistory." has details); all personal modules were installed with a standard "make install". All *.pm files had 444 permissions (except for one black sheep, Tcl.pm, which had 555 — I've no idea what happened there).

      I found an old Strawberry Perl v5.26.3 installation; I don't recall details of setting this up. All *.pm files in lib and vendor/lib had 444 permissions with owner ken; all in site/lib had 555 with owner Administrators.

      That's about all the info I could think of that was relevant. I'm happy to share more if you think it will be useful; just ask. Bear in mind how our different ways of working may affect outcomes.

      "No-one has ever complained about the perms settings of the files in my perl modules."

      I'm really no expert in this area; take the following as (potentially ill-informed) opinion. If no one has ever complained, there's probably no urgency to "fix" what's not broken. I see you have "25 distributions uploaded to CPAN". Perhaps change the permissions in one distro as a test; look at working on the others as updates are made.

      — Ken

        Perhaps change the permissions in one distro as a test;look at working on the others as updates are made

        Yes - I think that's the approach to take.
        Thanks for the feedback.

        Cheers,
        Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11146667]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2024-04-25 06:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found