avl_init(&mounts, avl_strcmp, false, NULL);
}
+static int add_script_interp(const char *path, const char *map, int size)
+{
+ int start = 2;
+ while (start < size && map[start] != '/') {
+ start++;
+ }
+ if (start >= size) {
+ ERROR("bad script interp (%s)\n", path);
+ return -1;
+ }
+ int stop = start + 1;
+ while (stop < size && map[stop] > 0x20 && map[stop] <= 0x7e) {
+ stop++;
+ }
+ if (stop >= size || (stop-start) > PATH_MAX) {
+ ERROR("bad script interp (%s)\n", path);
+ return -1;
+ }
+ char buf[PATH_MAX];
+ strncpy(buf, map+start, stop-start);
+ return add_path_and_deps(buf, 1, -1, 0);
+}
+
int add_path_and_deps(const char *path, int readonly, int error, int lib)
{
assert(path != NULL);
if (path[0] == '/') {
if (avl_find(&mounts, path))
return 0;
- fd = open(path, O_RDONLY);
+ fd = open(path, O_RDONLY|O_CLOEXEC);
if (fd == -1)
return error;
add_mount(path, readonly, error);
struct stat s;
if (fstat(fd, &s) == -1) {
- ERROR("fstat(%s) failed: %s\n", path, strerror(errno));
+ ERROR("fstat(%s) failed: %m\n", path);
ret = error;
goto out;
}
map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map == MAP_FAILED) {
- ERROR("failed to mmap %s\n", path);
+ ERROR("failed to mmap %s: %m\n", path);
ret = -1;
goto out;
}
+ if (map[0] == '#' && map[1] == '!') {
+ ret = add_script_interp(path, map, s.st_size);
+ goto out;
+ }
+
if (map[0] == ELFMAG0 && map[1] == ELFMAG1 && map[2] == ELFMAG2 && map[3] == ELFMAG3) {
ret = elf_load_deps(path, map);
goto out;