Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a directory with the 'right' permissions using Perl's mkdir?

I need help with this program. As a part of my project I need to create a directory. I was using the system function to do this, but later was told that Perl has a builtin called mkdir.

I'm on Ubuntu 10.04. The problem is mkdir does not seem to work as needed.

It creates the directory but the permissions are different. Here is my function that creates the directory:

sub createDir {
       my ($dir,$perm) = @_;
       unless(-d $dir) {
               mkdir $dir,$perm or die "$!";
       }
}

and I call it in many parts of my program as:

createDir('.today','0755');

the directory .today gets created but the problem is with permissions, it does not have the 0755 permission.

What am I doing wrong?

My Perl details are:

$perl -v

This is perl, v5.8.8 built for x86_64-linux-thread-multi
like image 962
user491976 Avatar asked Oct 30 '10 06:10

user491976


3 Answers

You are passing the permission as a string. mkdir expects it to be numeric. But an octal number inside a string is interpreted as a decimal. So '0755' is being interpreted as decimal 755 and is being used by mkdir.

To fix this you can call the subroutine passing it numeric permission:

createDir('.today',0755);

Alternatively you can use make use of the oct function to convert the octal string into a numeric value.

Subroutine call remains the same:

createDir('.today','0755');

but its definition changes to use the oct function as:

mkdir $dir,oct($perm) or die "$!";
like image 180
codaddict Avatar answered Oct 01 '22 00:10

codaddict


After you fix codeaddict's string versus number issue and note tchrist's umask issue you should call chmod on the new directory after creating it if you need specific permissions.

I usually call mkdir without the mask and then chmod the directory to the permissions I want.

Check these from the shell:

$ perldoc -f mkdir
$ perldoc -f chmod
$ perldoc -f unmask

You can also set the umask to zero before calling mkdir, you'd need to do it this way if you need to create the directory with the correct permissions atomically. Something like this is probably what you're looking for:

sub createDir {
        my ($dir, $perm) = @_;
        if(!-d $dir) {
                my $old = umask(0);
                mkdir($dir, $perm) or die "$!";
                umask($old);
        }
        else {
                chmod($dir, $perm);
        }
}
like image 45
mu is too short Avatar answered Sep 30 '22 23:09

mu is too short


The second argument to mkdir is not the creation mode. It is a mask which will be &ed with ~umask to determine the creation mode. If you specify an argument of 0755 and your umask is 027, then 0755 &~ 0027 == 0750. Make sure to keep everything in octal, not decimal.

There are also constants for these things available via use POSIX qw[ :sys_stat_h ], such as S_IRWXU, S_IWGRP, and S_ISVTX, but those may be more trouble than they're worth.

like image 24
tchrist Avatar answered Oct 01 '22 01:10

tchrist