Reputation: 560
If you look at this code block below by taking into consideration the last parameter "0", Does write line work properly ?
filename = argv[1];
string = "Example string";
if (stat(argv[1], &buf) != 0)
{
fd = open(filename, O_WRONLY | O_CREAT, 0);
if (fd < 0)
{
perror(filename);
exit(1);
}
write(fd, string, strlen(string));
close(fd);
}
else
{
print("%s file exists\n", filename);
}
Upvotes: 2
Views: 6421
Reputation: 20392
Interesting question. POSIX says:
The argument following the oflag argument does not affect whether the file is open for reading, writing, or for both.
Which means that since you're handling the error return from open
, if you reach the write
line the behavior is well defined.
To expand a bit why this works. On most filesystems on unix-like systems, the meta-data related to a file should not affect already open file descriptors. You can for example remove a file that you have opened. This is in fact done quite commonly with temporary files, so that you don't need to remember to delete them on exit. The same applies to permissions or even ownership of the file. In fact, you can chroot
while holding a file open and you can still write to it without actually being able to see it. You can even use file descriptor passing to give an open file descriptor to another process that wouldn't be allowed to open that file. This is quite commonly used for privilege separation. The permissions you had when creating a file descriptor are valid regardless of the changes to permissions later. So your question is a very interesting edge case because it asks if the filesystem permissions of the file are set before or after we create a file descriptor for it and POSIX seems to be clear on that.
I can only think of two exceptions to that right now. First is when someone forcibly remounts a filesystem to read-only in that case the kernel will go through horrifying gymnastics to invalidate your file descriptor which will make all its operations fail. Second one is AFS where your permissions are actually checked when you close the file (or, when the last user of the file on your local system closes it which sends it to the server), which leads to hilarious problems where your time-limited access tokens were valid when you opened a file but aren't valid any longer when you close it. This is also why close
returns errors (but that's another rant).
This is why I mentioned error handling above. Even though POSIX says that it should not have an effect, I could see AFS or certain other file systems refusing to open such a file.
Upvotes: 2
Reputation: 70263
From the manpage:
mode
specifies the permissions to use in case a new file is created. This argument must be supplied whenO_CREAT
is specified in flags; ifO_CREAT
is not specified, thenmode
is ignored. The effective permissions are modified by the process's umask in the usual way: The permissions of the created file are (mode & ~umask
). Note that this mode applies only to future accesses of the newly created file; theopen()
call that creates a read-only file may well return a read/write file descriptor.The following symbolic constants are provided for mode:
S_IRWXU 00700 user (file owner) has read, write and execute permission S_IRUSR 00400 user has read permission S_IWUSR 00200 user has write permission S_IXUSR 00100 user has execute permission S_IRWXG 00070 group has read, write and execute permission S_IRGRP 00040 group has read permission S_IWGRP 00020 group has write permission S_IXGRP 00010 group has execute permission S_IRWXO 00007 others have read, write and execute permission S_IROTH 00004 others have read permission S_IWOTH 00002 others have write permission S_IXOTH 00001 others have execute permission
So, specifying a mode
of zero, you will create a file with the permissions of 0 & ~umask
, i.e. a file without any permissions.
What exactly the filesystem makes of this is not in the domain of the open()
or write()
functions.
Upvotes: 2
Reputation: 53006
It is valid,
This is from open(2)
Linux manual pages
The mode argument specifies the file mode bits be applied when a new file is created. This argument must be supplied when
O_CREAT
orO_TMPFILE
is specified in flags; if neitherO_CREAT
norO_TMPFILE
is specified, then mode is ignored. The effective mode is modified by the process's umask in the usual way: in the absence of a default ACL, the mode of the created file is (mode & ~umask). Note that this mode applies only to future accesses of the newly created file; the open() call that creates a read-only file may well return a read/write file descriptor.
In theory then, your access to the file will be valid until you call close()
as I understand the part I highlighted in the above excerpt.
Upvotes: 2