When calling access(2) and getting an errno == ENOENT the man page says:
ENOENT A directory component in pathname would have been accessible but
does not exist or was a dangling symbolic link.
However, in my case I was trying to create a file in /tmp/ and the directory component was accessible and exists. Could it be that ENOENT is also given when the file system has too many files in a directory? In my case, /tmp/ had grown to an enormous number of small temporary files. Can I eventually reach a limit and get this ENOENT? If so, how can I programmatically differentiate this case?
— More stripped down code added and more explaination —
Looking closer, it appears that the file exists on disk, although if that is case, why would mkstemp() give me a collision? I doubt I could I have exhausted the XXXXXX space, 36^6 = 2.1 billion!
char *fileName = new char[256];
strncpy(fileName, "/tmp/somePathXXXXXX", 255);
int fileDescriptor = mkstemp(fileName);
if (fileDescriptor == -1) {
struct stat statusFileInfo;
int result = stat(fileName, &statusFileInfo);
if (result == 0) {
mode_t mode = statusFileInfo.st_mode;
if (S_ISREG(mode)) {
// Check permission.
int result = access(fileName, W_OK);
if (result) {
// Code landed here with errno == ENOENT.
...
}
}
}
}
Please note my application’s code has worked fine for thousands of invocations, then I saw this one failure. The code above is a simplified synthesis down to the key ingredients of the failure condition.
The main meaning of ENOENT is ‘no such file or directory’. It means that the name you tried to
access()was not there.If you were trying to create the file, then maybe, perhaps, you would get ENOENT when there are ‘too many files in a directory’, but you’d be more likely to get some other error, I think – perhaps ENOSPC (no space left on the device) if there was a problem with your inode table overflowing.
The code that appeared since I wrote the first part of the answer needs correcting.
You are lucky – or maybe unlucky – that this did not cause a segmentation fault. That is categorically not the correct way to call
mkstemp()or any of the related functions. You must pass a modifiable string, and that is a string constant, and hence not modifiable. It might well be stored in read-only memory. It seems that you got away with it – but on the second invocation, you are passing a string that does not have 6 X’s in it (becausemkstemp()wrote over the X’s the first time). So, it is no wonder that the file already exists.If you’re going to play like that, you must use something equivalent to:
Now the
mkstemp()function has modifiable text to work with.