#############################################################################*/
#include <ctype.h>
+#include <dirent.h>
#include <errno.h>
-#include <fts.h>
+#include <fcntl.h>
#include <linux/limits.h>
#include <stddef.h>
#include <stdio.h>
return pakfire_arch_is_compatible(native_arch, name);
}
-static char* find_interpreter(const char* path, const char* magic) {
- FILE* f = fopen(path, "r");
+static char* find_interpreter(DIR* dir, const char* path, const char* magic) {
+ FILE* f = NULL;
+ int fd = -1;
+
+ // Open the file
+ fd = openat(dirfd(dir), path, O_CLOEXEC);
+ if (fd < 0)
+ return NULL;
+
+ // Re-open the file as file handle
+ f = fdopen(fd, "r");
if (!f)
return NULL;
}
char* pakfire_arch_find_interpreter(const char* name) {
+ char* interpreter = NULL;
+ DIR* dir = NULL;
+ struct dirent* entry = NULL;
+
+ // Check inputs
if (!name) {
errno = EINVAL;
return NULL;
// If the host supports this architecture natively,
// we do not need to search for the interpreter
if (pakfire_arch_supported_by_host(name))
- return NULL;
+ goto ERROR;
const struct pakfire_arch* arch = pakfire_arch_find(name);
if (!arch)
- return NULL;
-
- char* interpreter = NULL;
-
- char* paths[] = {
- "/proc/sys/fs/binfmt_misc", NULL,
- };
+ goto ERROR;
- FTS* f = fts_open(paths, FTS_NOCHDIR|FTS_NOSTAT, NULL);
- if (!f)
+ // Open /proc/sys/fs/binfmt_misc
+ dir = opendir("/proc/sys/fs/binfmt_misc");
+ if (!dir)
goto ERROR;
for (;;) {
- FTSENT* fent = fts_read(f);
- if (!fent)
+ entry = readdir(dir);
+ if (!entry)
break;
- // Only handle files
- if (!(fent->fts_info & FTS_F))
- continue;
-
- interpreter = find_interpreter(fent->fts_path, arch->magic);
+ // Check if the file matches
+ interpreter = find_interpreter(dir, entry->d_name, arch->magic);
// End search if we have found a match
if (interpreter)
}
ERROR:
- if (f)
- fts_close(f);
+ if (dir)
+ closedir(dir);
return interpreter;
}