Find the file mode from the umask ? simple ?
août 30th, 2007 by Prune
This has always been a mess for sysadmins. Even good onces always get fooled by UNIX file rights and umask calculation.
The base is simple :
take 777 and substract the umask. If umask is 022, you’ll get a file permission of 755, which mean rwx-rwx-rwx.
Remember that 7 is 0111 in binary, so the rights are only triggered if a 1 is set.
First number is the “setUID bit”, second the read, then the write, and the execute right.
But how to do this in C++ ?
I had to change the source code of Rotter as the file mode mask was hard coded in the source file rotter.c
Rotter is a little and handy application that connect to Jack Audio and dump some inputs into a file (mp3 or wave depending on your compile settings). It have the ability to generate one file per hour, spread in multiple directories.
The hardcoded mask was 755, which is right for many applications, but not for me. I will have some users, with a different UID than rotter, writing some files within the same per day directory.
I so had to change the hardcoded mask to use the “umask” C function instead. Easy. But getting the file mode from the mask wan’t that easy
I finaly got something working, and here the result.
This is just the modified function in rotter.c :
static int mkdir_p( const char* dir ) { int result = 0; if (directory_exists( dir )) { return 0; } // added by prune // get the umask value (by stting it to 0) then set it back mode_t mask = umask (0); umask (mask); // Compute the right mode mode_t DIR_MODE = ((0777) ^ mask); if (mkdir(dir, DIR_MODE) < 0) { if (errno == ENOENT) { // ENOENT (a parent directory doesn't exist) char* parent = strdup( dir ); int i; // Create parent directories recursively for(i=strlen(parent); i>0; i--) { if (parent[i]=='/') { parent[i]=0; result = mkdir_p( parent ); break; } } free(parent); // Try again to create the directory if (result==0) { result = mkdir(dir, DIR_MODE); } } else { result = -1; } } return result; }