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_WRONLY
flag since this is our intentionWe also pass the
O_CREAT
flag 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