Messages in this thread |  | | From | Andrew Tridgell <> | Subject | problem with O_CREAT ? | Date | Sun, 16 Jun 1996 23:38:16 +1000 |
| |
There may be a problem with the handling of O_CREAT in linux.
I've always thought that O_CREAT should be ignored in a open() call if the file exists. I don't have the posix specs handy, so please correct me if this is wrong.
The program included below seems to show that it is not ignored in Linux (using kernel 2.0). It should print "all OK", but instead prints "2nd open failed : permission denied".
I had a look at linux/fs/open.c and the problem seems to be this but of code in do_open() which assumes that O_CREAT implies opening for writing:
if (flag & (O_TRUNC | O_CREAT)) flag |= 2;
changing it to:
if (flag & O_TRUNC) flag |= 2;
would probably "fix" the problem, but might have some nasty side effects.
Would someone with the posix specs handy like to tell me if I've misunderstood O_CREAT ?
When writing rsync I assumed O_CREAT was ignored when the file exists. I was surprised to find it didn't work :-)
Cheers, Andrew
PS: I know it's unusual to open file with O_RDONLY|O_CREAT, but it is very useful in some situations.
---------------
#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h>
char *fname = "test.tmp";
void main() { int fd;
/* create a readonly file */ unlink(fname); if ((fd=open(fname,O_RDWR|O_CREAT,0444)) == -1) { printf("first open failed : %s\n",strerror(errno)); exit(1); } close(fd);
/* try and open it for reading. This should work. Under linux 2.0 it doesn't */ if ((fd=open(fname,O_RDONLY|O_CREAT,0666)) == -1) { printf("2nd open failed : %s\n",strerror(errno)); exit(1); } close(fd);
/* it worked - clean up */ unlink(fname);
printf("all OK\n"); }
|  |