1

I need to write c code on linux that will check if

1) a file exists and

2) if it does not exist then I need to open the file and write into the file.

Being a multi thread / multi process environment, I want to ensure that 1 and two above happen in one atomic operation

I looked at What's the best way to check if a file exists in C? (cross platform) and considered solution suggested by @Dan Lenski. So please dont mark this as duplicate without reading completely . The problem with that is the combination of O_CREAT | O_WRONLY | O_EXCL flags in an open system call as mentioned in open man page does not tolerate symbolic links. Sounds like it has problems with NFS partitions as well

We do use symbolic links in our paths ( Debatable - why but we do end up using ) so I want to do something akin Dan's suggested and cited in his code fragment reproduced below but what can tolerate a path that points to a symbolic link

#include <fcntl.h>
#include <errno.h>

fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
  /* failure */
  if (errno == EEXIST) {
    /* the file already existed */
    ...
  }
} else {
  /* now you can use the file */
}
Yogesh Devi
  • 617
  • 11
  • 30
  • Why do you need `O_EXCL`? Is an existing file not usable for you, if not, why? –  Jun 09 '17 at 07:15
  • [lstat](http://pubs.opengroup.org/onlinepubs/009695399/functions/lstat.html) is what you need, I guess. – LPs Jun 09 '17 at 07:15
  • 2
    If your intention is not to touch an existing file and just fail in this case, `O_EXCL` is good enough, why should it matter whether the file that's *in the way* is a symlink or not? –  Jun 09 '17 at 07:18
  • 1
    Regarding your edit, you can't open **and** write atomically. If this is important, you'll need e.g. a mutex. –  Jun 09 '17 at 07:22
  • Another approach would be not to use `O_EXCL` and then check whether the file is non-empty using `fstat()`. But your exact requirements still remain a bit mysterious to me. Will the other threads even touch the file? –  Jun 09 '17 at 07:33
  • What shall happen if the file already exists? What shall happen if it does not, but you don't have permission to create it? – chtz Jun 09 '17 at 07:48
  • @Felix Palmen - Other threads will do the same thing - check if the file exists - if it does not they will create it and start writing to it. If it does exist they will leave it alone assuming its being worked upon already – Yogesh Devi Jun 09 '17 at 13:02
  • @YogeshDevi Then you really should protect it with a mutex. After locking the mutex, you can just open it with `O_CREAT|O_WRONLY`, if necessary check the size with `fstat()` or just truncate it, whatever needs to be done in case there's already data in it. –  Jun 09 '17 at 13:07
  • I guess so - that I need a mutex – Yogesh Devi Jun 09 '17 at 13:09
  • Does it matter if there is a symlink? (I assume the issue is with a symlink as the final component.) If there is a link, just resolve it, and then open with `O_EXCL` to the path pointed to by the link. Even if someone changes the symlink at the same time, you should get a consistent read on it, a path it actually pointed to. – ilkkachu Jun 10 '17 at 09:35

0 Answers0