O_CREAT: Creating A File#
Creating A File If It Does Not Exist (Bogus Version)#
We saw in O_WRONLY: Writing A File (Which Must Exist) that a file is not implicitly
created only because we open one, which is a good thing. Lets see how
to use the O_CREAT to make this happen.
The following program
opens the file for writing [1], declaring that is must be created if it does not exist
We pass the
O_WRONLYflag since this is our intentionWe also pass the
O_CREATflag in a bitwise-or combination
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
const char* filename = argv[1];
int fd;
const char bytes_to_write[] = "Howdy\n";
ssize_t nwritten;
fd = open(filename, O_WRONLY|O_CREAT);
if (fd == -1) {
perror("open");
return 1;
}
nwritten = write(fd, bytes_to_write, sizeof(bytes_to_write));
if (nwritten == -1) {
perror("write");
return 2;
}
close(fd);
return 0;
}
$ gcc -o example-O_CREAT-bogus example-O_CREAT-bogus.c
Bogus O_CREAT Usage: Mode Parameter Missing#
Lets see if a file that does not exist is created, and how that looks like:
$ ./example-O_CREAT-bogus /tmp/file-that-does-not-exist
$ ls -l /tmp/file-that-does-not-exist
--wxr-S---. 1 jfasch jfasch 0 May 13 18:09 /tmp/file-that-does-not-exist
- What? Permissions
-wxr-S---? This looks like if there’s something wrong.
This is a consequence of reading manual pages too sloppily
O_CREAT
...
The mode argument specifies the file mode bits to be applied
when a new file is created. If neither O_CREAT nor O_TMPFILE is
specified in flags, then mode is ignored (and can thus be speci‐
fied as 0, or simply omitted). The mode argument must be sup‐
plied if O_CREAT or O_TMPFILE is specified in flags; if it is
not supplied, some arbitrary bytes from the stack will be ap‐
plied as the file mode.
...
Creating A File If It Does Not Exist#
Fact is: if a file is created, someone needs to specify access
permissions. This is what the optional third open() parameter is
there for - mode.
int open(const char *pathname, int flags, mode_t mode);
It is common practice to specify 0666 as mode, and leave the
rest to the system. The user can specify via the umask process
attribute which permission bits to remove from the mode; see
Default Permissions: umask for how
that works, and how to specify the umask.
Here’s a fixed version of the bogus program from above:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
const char* filename = argv[1];
int fd;
const char bytes_to_write[] = "Howdy\n";
ssize_t nwritten;
fd = open(filename, O_WRONLY|O_CREAT, 0666);
if (fd == -1) {
perror("open");
return 1;
}
nwritten = write(fd, bytes_to_write, sizeof(bytes_to_write));
if (nwritten == -1) {
perror("write");
return 2;
}
close(fd);
return 0;
}
$ gcc -o example-O_CREAT example-O_CREAT.c
Footnotes