Version: 1.5.9.0
SDK Version: 1.4.2
Frequency: Consistently
Severity: High
Bug description:
C function stat doesn’t work on directories (it works correctly on files)
Repro steps:
In a WASM standalone module, if I do “stat” on any dir of my package I get error 29:
struct stat st;
auto result = stat("./modules", &st);
if (result == -1) {
int error_code = errno;
printf(" FAILURE: stat() returned -1.\n");
printf(" Error Code (errno): %d\n", error_code);
printf(" Error Message: %s\n", strerror(error_code));
}
else {
printf(" SUCCESS: stat() returned 0.\n");
}
result is always -1 with errno 29
1 Like
Hi @MaxHype
I have just checked the code and indeed we never implemented the WASI function “path_filestat_get” for file descriptors targeting directories.
We’ll see if we can add this in the future but I have to say this rather low priority at this stage.
Best regards,
Eric / Asobo
1 Like
Ok thank you @EPellissier,
in the meantime I’ve found a workaround using opendir function (that instead uses “__wasilibc_nocwd_opendirat” and “__wasi_path_open”)
another low priority similar issue is with fseek and negative offsets:
auto f = fopen("./file.dat", "rb");
auto result = fseek(f, -2, SEEK_END);
if (result == -1)
{
fprintf(stderr, "Failed to seek in file ./file.dat: %s\n", strerror(errno));
fclose(f);
return;
}
result is always -1 with errno 29
the workaround is avoiding negative offset using SEEK_SET with absolute position from the start calculated using file size
1 Like
@EPellissier unfortunately I still haven’t found a reliable way to check if a directory exist.
I noticed that opendir never returns NULL even if the directory is not existent:
DIR* dir = opendir("./modules");
if (dir) {
fprintf(stdout, "Directory ./modules opened successfully.\n");
closedir(dir);
}
else {
fprintf(stderr, "Failed to open directory ./modules: %s\n", strerror(errno));
return;
}
dir = opendir("./notexist");
if (dir) {
fprintf(stdout, "Directory ./notexist opened successfully.\n");
closedir(dir);
}
else {
fprintf(stderr, "Failed to open directory ./notexist: %s\n", strerror(errno));
return;
}
In the example /modules is opened successfully, but also /notexist is opened successfully (wrongly)
Moreover, no luck also trying with access function:
auto acc = access("./modules", F_OK); // Check if the directory exists
if (acc == 0) {
fprintf(stdout, "Access Directory ./modules exists.\n");
}
else {
fprintf(stderr, "Access Directory ./modules does not exist: %s %d\n", strerror(errno), errno); //EIO
return;
}
this last returns always -1 with errno 29