IO::File->open() is broken
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) = 4A 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 %d\n", 0755, "0755");'
493 755
