C++/Advanced File IO in C / Unix Environment
Expert: Ralph McArdell - 8/28/2006
QuestionHi Ralph,
I saw a previous post of yours in which you posted a very helpful link (
http://experts.about.com/q/C-1040/file-permissions-C-2.htm). Thank you for that. I do have a question though as follows:
I would like to create a directory in my C++ program, and have permissions of 777, where everyone can read/right/execute anything and everything.
To do this, i am using the mkdir() function (man -s 2 mkdir). It has been a VERY confusing search to figure out how the heck to set permissions with mkdir(). From what I've been able to figure out, the command:
mkdir(filename,0777);
*should* produce a directory that has 777 permissions. The '0' tells C++ its an octal number, the 1st 7 is for my permissions, the 2nd 7 is the permission of the group, and the 3rd 7 is for others. However, when i execute this in my code, i get a directory seen by ls -l:
drwxr-xr-x
I can't seem to get write permissions on the directory. I was previously writing a string "mkdir mydir; chmod 777 mydir;" and using the system() command to call the unix commands, but i want to avoid the shell commands. However, the shell commands actually did what i wanted and created read/write/exec. Any thoughts on what is going wrong? This program will be used by various users across different computers, etc so i want everyone to have no problems accessing the directory.
AnswerAs I stated in the answer you refer to in your question this is not a C++ question but a UNIX/Linux programming question. Also as I stated in that article I am not an expert in the area of OS access control and permissions. You might do better asking a UNIX/Linux programming expert.
However I am good at reading function descriptions. I Googled for the man page for mkdir and note that the description of the mode parameter is as follows:
"The file permission bits of the new directory
shall be initialized from mode.
These file permission bits of the mode argument
shall be modified by the process' file creation
mask."
From:
http://www.opengroup.org/onlinepubs/000095399/functions/mkdir.html
I have separated the two sentences to emphasise the second one which I think you may have overlooked. That is you can set what permissions you like for the new directory, but they cannot exceed those given by the process' file creation mask. The what? I hear you say.
Each process gets a file creation mask. This mask specifies those permissions your processes will have _disabled_ when creating files and directories and the like. I stress that permission bits set in the file creation mask prevent your process creating files having that permission, so if you set world write in the file creation mask then no files or directories created by your process will be created with write access to all others - even if this permission is specified in the mode argument. You can read a bit more about this topic in the "Assigning File Permissions" section of the page at (Warning! Long URL, parts may have wrapped over more than 1 line):
http://www.informatik.uni-hamburg.de/RZ/software/gnu/libraries/libc_9.html#SEC16...
(and probably other places that have GNU library information online).
You use the umask command or function to set a process' file creation mask, see:
http://www.opengroup.org/onlinepubs/000095399/functions/umask.html
for a description of the umask function which, by the way, is listed under the mkdir man page "See Also" section. Typically the umask command is executed when you login and all other processes you create inherit the file creation mask value.
An alternative is to use the chmod function to set the permissions on your new directory after you have created it (following the form of your commands executed via the system function) as chmod does not use the file creation mask:
http://www.opengroup.org/onlinepubs/000095399/functions/chmod.html
Finally rather than using magic numbers like 0777 you might like to use the symbolic names for the file modes bitwise ORed together. See:
http://www.opengroup.org/onlinepubs/007908799/xsh/sysstat.h.html
Under the "File mode bits:" line.
Oh, and pay attention to error returns and errno.
As I have said before, you are as able as I am to look up and read these things. As this is not my primary area of expertise I had to search for and read the pages I refer to here to put together this answer for you. It took very little time to locate these articles and considerably more time to write up the answer for you. So please make use of the various sources of information you have available to you - man and info and other help on your system, books, magazine articles and of course most usefully the Internet and Google or other search engine. Doing so in this case could have saved you many hours waiting for my reply.