in reply to File permissions problem

Hi wdhammond,

The code you've provided isn't runnable, and doesn't show the code that actually writes to the file; it would be better if you could show us a Short, Self-Contained, Correct Example. There isn't anything obvious in the code you posted that would influence the file permissions.

Perhaps you need to check your umask, both by running the umask command from the command line, as well as checking the umask in the script via something like printf "%04o\n", umask;. If either of those show, for example, 0077, that would explain the issue.

Update:

I noticed in another post on your site that "stat" does not return a value unless "File::stat" in included.

No, stat is a builtin that should always be available. File::stat just replaces the builtin stat with a function that returns an object instead of a list of values. But in either case, stat only reads the file information, and does not modify it, so that won't be the cause of the problem.

Hope this helps,
-- Hauke D

Replies are listed 'Best First'.
Re^2: File permissions problem (updated)
by wdhammond (Novice) on Dec 15, 2016 at 21:51 UTC

    Thank you for your quick reply.

    I am not a perl programmer, but I believe the sub savefile in the code provided should be the actual code that saves the file with various switches that create backups, etc. The sub fileisreadonly is the only place I saw any reference to the file mode and when running the app I get no prompt to save as read only. The application is supposed to open a file for editing and has tools for text checking ans save the file with a program generated .bin file, the function of which is to save page number locations and other structural parts of the text. The .bin file is saved with the correct permissions while the text file is not.

    From command line:

    wayne@localhost ~]$ umask 0002

    From command line:

    [wayne@localhost ~]$ printf "%04o\n", umask; bash: printf: umask: invalid number 0000

    Regards, Wayne

      Hi Wayne,

      As far as I can tell from the code you posted, the actual code that opens the file and writes to it is probably somewhere in the SaveUTF method.

      The two examples I showed can be used to check the umask from the command line like so:

      $ umask 0022 $ perl -e 'printf "%04o\n", umask;' 0022

      Or, the best thing is probably to put the statement printf "%04o\n", umask; somewhere in your Perl script, maybe something like warn sprintf("umask is %04o\n",umask); so that it's printed to STDERR.

      Update: In your OP you wrote "I must note here that an accompanying file generated by the application saves with 0644 permissions." That makes it a little less likely to be a umask problem; perhaps the application uses sysopen with explicit perms set. But without having the code to look at these are all guesses.

      Hope this helps,
      -- Hauke D

      Update: Replaced "an explicit mode" with "explicit perms" since that's the terminology used in sysopen.

        I found this sub in another module (TextUnicode):

        # Custom file save routine to handle unicode files sub SaveUTF { my ( $w, $filename ) = @_; $filename = $w->FileName unless defined $filename; my $dir = dirname($filename); my $perms = ( stat($dir) )[2] & 07777; unless ( $perms & 0200 ) { $perms = $perms | 0200; chmod $perms, $dir or $w->BackTrace("Can not write to directory $dir: $!\n") and return; } my ( $tempfh, $tempfilename ) = tempfile( DIR => $dir ); my $status; my $count = 0; my $index = '1.0'; my $progress; my $fileend = $w->index('end -1c'); my ($lines) = $fileend =~ /^(\d+)\./; my $unicode = ::currentfileisunicode(); # No BOM please #if ($unicode) { # my $bom = "\x{FEFF}"; # utf8::encode($bom); # print $tempfh $bom; #} while ( $w->compare( $index, '<', $fileend ) ) { my $end = $w->index("$index lineend +1c"); my $line = $w->get( $index, $end ); $line =~ s/[\t \xA0]+$//; #$line = ::eol_whitespace($line); $line =~ s/\cM\cJ|\cM|\cJ/\cM\cJ/g if (OS_Win); utf8::encode($line) if $unicode; $w->BackTrace("Cannot write to temp file:$!\n") and return unless print $tempfh $line; $index = $end; if ( ( $count++ % 1000 ) == 0 ) { $progress = $w->TextUndoFileProgress( Saving => $filename, $count, $count, $lines ); } } $progress->withdraw if defined $progress; close $tempfh; if ( -e $filename ) { chmod 0777, $filename; unlink $filename; } if ( rename( $tempfilename, $filename ) ) { #$w->ResetUndo; #serves no purpose to reset undo $w->FileName($filename); return 1; } else { my $msg = "Cannot save $filename:$!. Text is in the temporary +file $tempfilename."; $w->messageBox( -icon => 'warning', -title => 'Warning', -type => 'OK', -message => $msg.(OS_Win?" (Are you using Windows Explorer + Preview?)":""), ); $w->BackTrace($msg); return 0; } }
        Regards, Wayne

        Thanks again Hauke.

        The complete application is open source and available here: https://sourceforge.net/projects/guiguts/

        I have it installed in Fedora 25 with Padre as a troubleshooting aid.

        There are a couple of other problems too, but I thought this one would be the easiest one to troubleshoot.

        Regards, Wayne
      > bash: printf: umask: invalid number 0000

      In bash, paramteres aren't separated by commas, but whitespace. Also, commands return their exit status, you need command substitution to get the output:

      printf "%04o\n" $(umask)
      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        Thank you choroba,

        Sorry about the delay in responding.

        Regards, Wayne