Re: Determine if open(2) created or opened (again)
From: Juha Laiho (Juha.Laiho_at_iki.fi)
Date: 05/23/04
- Next message: Kieran Simkin: "Re: Retrieving block size of a filesystem"
- Previous message: luc wastiaux: "Re: readline() with select() on STDIN"
- In reply to: Michael B Allen: "Determine if open(2) created or opened (again)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sun, 23 May 2004 10:52:02 GMT
Michael B Allen <mba2000@ioplex.com> said:
>Some time ago I asked if there was a way to open a file and know if it
>was actually created or if it was just opened. Someone posted a fairly
>reasonable answer but strangely I can't find it in google groups.
Hmm.. that's an answer I'd like to see, as I think this is not possible.
>Anyway, I've implemented what I recall about the answer but perhaps
>someone confirm or provide a better solution? I've tested this to some
>extent and it appears to work correctly.
Hm. At least this causes a resource leak in form of file descriptors
(it doesn't return the fd returned by open(), so the file cannot be
closed, or accessed in any way). So, instead of returning '0' from this
function, you must store and return the real return value from the
call to "open".
In practice the code might work for most cases, but still it contains
the exact race condition that makes this functionality impossible.
Consider another piece of code that runs concurrently with this
one, and somehow manages to keep synchronous with this code.
First iteration of the while loop ("OC" = opencre; "X" = "other" code):
X: make sure file does not exist
OC: goes through the first "if" struture within the while loop
X: creates file
OC: goes through the second "if" structure within the while loop
... and continue similarly through the remaining iterations through
the while loop, thus falling off to the "errno=EACCESS".
You can reduce the possibility of this race condition in practical
situations by increasing the "max" value, but the theoretical race
condition will always remain, because there is no atomic way to
open/create a file and return whether the file was created or merely
opened.
>int
>opencre(const char *pathname, int flags, mode_t mode, int *cre)
>{
> int max = 3; /* maximum attempts to open */
>
> if ((flags & O_CREAT) == 0) { /* bypass special procedure */
> if (open(pathname, flags, mode) == -1) {
> return -1;
> }
> *cre = 0;
> return 0;
> }
> while (max--) {
> /* fail if not exists */
> if (open(pathname, flags & ~(O_CREAT | O_EXCL)) != -1) {
> *cre = 0;
> return 0;
> } else if (errno != ENOENT) {
> return -1;
> }
> /* fail if exits */
> if (open(pathname, flags | O_EXCL, mode) != -1) {
> *cre = 1;
> return 0;
> } else if (errno != EEXIST) {
> return -1;
> }
> }
>
> errno = EACCES;
> return -1;
>}
--
Wolf a.k.a. Juha Laiho Espoo, Finland
(GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
"...cancel my subscription to the resurrection!" (Jim Morrison)
- Next message: Kieran Simkin: "Re: Retrieving block size of a filesystem"
- Previous message: luc wastiaux: "Re: readline() with select() on STDIN"
- In reply to: Michael B Allen: "Determine if open(2) created or opened (again)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|