#### dirent always returns NULL when opening a directory, errno is 0

Jack Bruienne

I’m testing out running some code under the EFI environment to learn about writing EFI applications. I’m trying to list files in a directory on the filesystem using the dirent API provided with LibStd in EDK II. I have successfully compiled the code and linked with all required libraries, but I keep getting an issue where opendir() is always returning NULL. When checking the value of errno, it’s still EOK anyway. Here’s the code I’m using:

struct dirent *dir;
char * path = fixpath(old_path); // converts "/path/to/dir" to "FS0:\path\to\dir"
DIR * d = opendir(path);
if (d) {
for (int i = 0; (dir = readdir(d)) != NULL; i++) {
// process file entries
}
closedir(d);
} else err(path, "Not a directory");

When this code is run, it ends up calling err() and showing a message on the screen ("FS0:\: Not a directory (0)") instead of processing the file entries in the dirent structure. Are there any known bugs with the EDK II implementation of dirent? If so, how can I rewrite my code to use native EFI calls instead of dirent?

I am using the stable201911 version of EDK II with the latest edk2-libc, and I'm compiling under macOS using a Linux cross-compilation toolchain. The built EFI application is run under QEMU x86_64 with an OVMF firmware built with the same toolchain.

Laszlo Ersek

On 01/24/20 09:52, Jack Bruienne wrote:
I’m testing out running some code under the EFI environment to learn about writing EFI applications. I’m trying to list files in a directory on the filesystem using the dirent API provided with LibStd in EDK II. I have successfully compiled the code and linked with all required libraries, but I keep getting an issue where opendir() is always returning NULL. When checking the value of errno, it’s still EOK anyway. Here’s the code I’m using:

struct dirent *dir;
char * path = fixpath(old_path); // converts "/path/to/dir" to "FS0:\path\to\dir"
DIR * d = opendir(path);
if (d) {
for (int i = 0; (dir = readdir(d)) != NULL; i++) {
// process file entries
}
closedir(d);
} else err(path, "Not a directory");

When this code is run, it ends up calling err() and showing a message on the screen ("FS0:\: Not a directory (0)") instead of processing the file entries in the dirent structure. Are there any known bugs with the EDK II implementation of dirent? If so, how can I rewrite my code to use native EFI calls instead of dirent?

I am using the stable201911 version of EDK II with the latest edk2-libc, and I'm compiling under macOS using a Linux cross-compilation toolchain. The built EFI application is run under QEMU x86_64 with an OVMF firmware built with the same toolchain.
I think the fixpath() call is superfluous and wrong. As far as I
remember, when programming against edk2-libc, edk2-libc places some
directory structure requirements on the underlying UEFI filesystem.
Therefore manual conversion of pathnames should not be necessary;
instead it is on the provider of the underlying UEFI filesystem that
needs to place files in the right spots.

Let me see... Yes, please refer to section "TARGET-SYSTEM INSTALLATION"
in "StdLib/ReadMe.txt", in the edk2-libc project (with master @
61687168fe02).

It seems that, using StdLib, you can only refer to files that are on the
same filesystem that the executable was loaded from.

Thanks
Laszlo

 1 - 2 of 2