So you read the documentation for IO::File and see:
open( FILENAME [,MODE [,PERMS]] )
open( FILENAME, IOLAYERS )
so you write:
my $rules = new IO::File('debian/rules','w', 0755);
and wonder why it hasn’t changed the permissions from 0666. Stracing
confirms it is opened 0666:
open("./debian/rules", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
A bit further reading of the documentation you discover:
If IO::File::open receives a Perl mode string (“>”, “+<“, etc.) or an
ANSI C fopen() mode string (“w”, “r+”, etc.), it uses the basic Perl
open operator (but protects any special characters).
If IO::File::open is given a numeric mode, it passes that mode and the
optional permissions value to the Perl sysopen operator. The permissions
default to 0666.
If IO::File::open is given a mode that includes the : character, it
passes all the three arguments to the three-argument open operator.
For convenience, IO::File exports the O_XXX constants from the Fcntl
module, if this module is available.
and the correct way to write this is
my $rules = new IO::File('debian/rules',O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0755)
Thank you very much perl for ignoring the permission parameter when
you feel like it.
Update: Steinar,
yes sorry, I did have 0755 rather than "0755"
originally, but changed it just to check that didn’t make a difference
and copied the wrong version. I’ve changed the post to have the right
thing.
% strace -eopen perl -MIO::File
-e 'my $rules = new IO::File("foo","w", 0755);' 2>&1 | grep foo
open("./foo", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
% strace -eopen perl -MIO::File
-e 'my $rules = new IO::File("foo","w", "0755");' 2>&1 | grep foo
open("./foo", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
Incidentally, 0755 and "0755" are different:
perl -e 'printf("%d %dn", 0755, "0755");'
493 755