probe-file returns NIL on existing file
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
On Unix, if I have a file inside a directory and I have no execute permission to that directory, the file exists, but sbcl's probe-file returns nil. Internally, it gets an access denied error from the OS and still returns nil.
You can create such a directory as follows:
```sh
mkdir /tmp/no-exec-dir
touch /tmp/no-
chmod a-x /tmp/no-exec-dir
```
Example sbcl run after setting up ("*" is the sbcl REPL):
```
* (probe-file "/tmp/no-
NIL
```
Here's a C program that sets up a directory with no execute permission and does the C equivalent of probe-file (access/faccessat in POSIX C):
```c
#define _POSIX_C_SOURCE 200809L
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int
main(void)
{
const char dir_path[] = "/tmp/no-exec-dir", file_path[] = "file";
int dir = -1, file = -1, ret;
if ((ret = mkdir(dir_path, 0777)) == -1)
goto err;
dir = open(dir_path, O_CREAT|
if (dir == -1)
goto err;
file = openat(dir, file_path, O_CREAT|
if (file == -1)
goto err;
if (fchmod(dir, 0666 /* Remove exec permission. */) == -1)
goto err;
ret = faccessat(dir, file_path, F_OK, 0);
printf("access to existing file returned %d\nerrno = %d: %s\n\n", ret,
errno, strerror(errno));
ret = faccessat(dir, file_path, F_OK, 0);
printf("access to non-existing file returned %d\nerrno = %d: %s\n",
ret, errno, strerror(errno));
return 0;
err:
fchmod(dir, 0777 /* Restore exec permission. */);
unlinkat(dir, file_path, 0);
rmdir(dir_path);
return 1;
}
```
Example run:
```console
$ ./a.out
access to existing file returned -1
errno = 13: Permission denied
access to non-existing file returned -1
errno = 13: Permission denied
```
Whether the file exists or not, the OS returns an error, and it's impossible for the program to tell the difference. sbcl's probe-file claims the file doesn't exist in such a case which might be untrue, it should raise a file-error instead.
description: | updated |
Where does it say that this should happen?