static int fuse_access(const char* path, int mask) { PRINTD("##access\n"); return _ERR(_kern_access(path, mask)); }
/*! Tests if there is an executable file at the provided path. It will also test if the file has a valid ELF header or is a shell script. Even if the runtime loader does not need to be able to deal with both types, the caller will give scripts a proper treatment. */ status_t test_executable(const char *name, char *invoker) { char path[B_PATH_NAME_LENGTH]; char buffer[B_FILE_NAME_LENGTH]; // must be large enough to hold the ELF header status_t status; ssize_t length; int fd; if (name == NULL) return B_BAD_VALUE; strlcpy(path, name, sizeof(path)); fd = open_executable(path, B_APP_IMAGE, NULL, NULL, NULL); if (fd < B_OK) return fd; // see if it's executable at all status = _kern_access(-1, path, X_OK, false); if (status != B_OK) goto out; // read and verify the ELF header length = _kern_read(fd, 0, buffer, sizeof(buffer)); if (length < 0) { status = length; goto out; } status = elf_verify_header(buffer, length); if (status == B_NOT_AN_EXECUTABLE) { // test for shell scripts if (!strncmp(buffer, "#!", 2)) { char *end; buffer[min_c((size_t)length, sizeof(buffer) - 1)] = '\0'; end = strchr(buffer, '\n'); if (end == NULL) { status = E2BIG; goto out; } else end[0] = '\0'; if (invoker) strcpy(invoker, buffer + 2); status = B_OK; } } else if (status == B_OK) { elf_ehdr *elfHeader = (elf_ehdr *)buffer; if (elfHeader->e_entry == 0) { // we don't like to open shared libraries status = B_NOT_AN_EXECUTABLE; } else if (invoker) invoker[0] = '\0'; } out: _kern_close(fd); return status; }