Kernel/LibC: remove PATH resoltion from kernel
I have no idea why I had made PATH environment variable parsing to be part of the kernel. Now the shell does the parsing and environment syscall is no longer needed.
This commit is contained in:
parent
fe2dca16f0
commit
fc953df281
|
@ -71,8 +71,6 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> sys_sleep(int seconds);
|
||||
BAN::ErrorOr<long> sys_nanosleep(const timespec* rqtp, timespec* rmtp);
|
||||
|
||||
BAN::ErrorOr<long> sys_setenvp(char** envp);
|
||||
|
||||
BAN::ErrorOr<long> sys_setpwd(const char* path);
|
||||
BAN::ErrorOr<long> sys_getpwd(char* buffer, size_t size);
|
||||
|
||||
|
@ -147,7 +145,7 @@ namespace Kernel
|
|||
static void register_process(Process*);
|
||||
|
||||
// Load an elf file to virtual address space of the current page table
|
||||
static BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> load_elf_for_exec(const Credentials&, BAN::StringView file_path, const BAN::String& cwd, const BAN::Vector<BAN::StringView>& path_env);
|
||||
static BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> load_elf_for_exec(const Credentials&, BAN::StringView file_path, const BAN::String& cwd);
|
||||
|
||||
// Copy an elf file from the current page table to the processes own
|
||||
void load_elf_to_memory(LibELF::ELF&);
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<Process*> Process::create_userspace(const Credentials& credentials, BAN::StringView path)
|
||||
{
|
||||
auto elf = TRY(load_elf_for_exec(credentials, path, "/"sv, {}));
|
||||
auto elf = TRY(load_elf_for_exec(credentials, path, "/"sv));
|
||||
|
||||
auto* process = create_process(credentials, 0);
|
||||
MUST(process->m_working_directory.push_back('/'));
|
||||
|
@ -114,7 +114,6 @@ namespace Kernel
|
|||
elf.clear();
|
||||
|
||||
char** argv = nullptr;
|
||||
char** envp = nullptr;
|
||||
{
|
||||
PageTableScope _(process->page_table());
|
||||
|
||||
|
@ -123,18 +122,11 @@ namespace Kernel
|
|||
memcpy(argv[0], path.data(), path.size());
|
||||
argv[0][path.size()] = '\0';
|
||||
argv[1] = nullptr;
|
||||
|
||||
BAN::StringView env1 = "PATH=/bin:/usr/bin"sv;
|
||||
envp = (char**)MUST(process->sys_alloc(sizeof(char**) * 2));
|
||||
envp[0] = (char*)MUST(process->sys_alloc(env1.size() + 1));
|
||||
memcpy(envp[0], env1.data(), env1.size());
|
||||
envp[0][env1.size()] = '\0';
|
||||
envp[1] = nullptr;
|
||||
}
|
||||
|
||||
process->m_userspace_info.argc = 1;
|
||||
process->m_userspace_info.argv = argv;
|
||||
process->m_userspace_info.envp = envp;
|
||||
process->m_userspace_info.envp = nullptr;
|
||||
|
||||
auto* thread = MUST(Thread::create_userspace(process));
|
||||
process->add_thread(thread);
|
||||
|
@ -275,7 +267,7 @@ namespace Kernel
|
|||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> Process::load_elf_for_exec(const Credentials& credentials, BAN::StringView file_path, const BAN::String& cwd, const BAN::Vector<BAN::StringView>& path_env)
|
||||
BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> Process::load_elf_for_exec(const Credentials& credentials, BAN::StringView file_path, const BAN::String& cwd)
|
||||
{
|
||||
if (file_path.empty())
|
||||
return BAN::Error::from_errno(ENOENT);
|
||||
|
@ -283,44 +275,13 @@ namespace Kernel
|
|||
BAN::String absolute_path;
|
||||
|
||||
if (file_path.front() == '/')
|
||||
{
|
||||
// We have an absolute path
|
||||
TRY(absolute_path.append(file_path));
|
||||
}
|
||||
else if (file_path.front() == '.' || file_path.contains('/'))
|
||||
else
|
||||
{
|
||||
// We have a relative path
|
||||
TRY(absolute_path.append(cwd));
|
||||
TRY(absolute_path.push_back('/'));
|
||||
TRY(absolute_path.append(file_path));
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have neither relative or absolute path,
|
||||
// search from PATH environment
|
||||
for (auto path_part : path_env)
|
||||
{
|
||||
if (path_part.empty())
|
||||
continue;
|
||||
|
||||
if (path_part.front() != '/')
|
||||
{
|
||||
TRY(absolute_path.append(cwd));
|
||||
TRY(absolute_path.push_back('/'));
|
||||
}
|
||||
TRY(absolute_path.append(path_part));
|
||||
TRY(absolute_path.push_back('/'));
|
||||
TRY(absolute_path.append(file_path));
|
||||
|
||||
if (!VirtualFileSystem::get().file_from_absolute_path(credentials, absolute_path, O_EXEC).is_error())
|
||||
break;
|
||||
|
||||
absolute_path.clear();
|
||||
}
|
||||
|
||||
if (absolute_path.empty())
|
||||
return BAN::Error::from_errno(ENOENT);
|
||||
}
|
||||
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(credentials, absolute_path, O_EXEC));
|
||||
|
||||
|
@ -412,14 +373,9 @@ namespace Kernel
|
|||
for (int i = 0; argv && argv[i]; i++)
|
||||
TRY(str_argv.emplace_back(argv[i]));
|
||||
|
||||
BAN::Vector<BAN::StringView> path_env;
|
||||
BAN::Vector<BAN::String> str_envp;
|
||||
for (int i = 0; envp && envp[i]; i++)
|
||||
{
|
||||
TRY(str_envp.emplace_back(envp[i]));
|
||||
if (strncmp(envp[i], "PATH=", 5) == 0)
|
||||
path_env = TRY(BAN::StringView(envp[i]).substring(5).split(':'));
|
||||
}
|
||||
|
||||
BAN::String working_directory;
|
||||
|
||||
|
@ -428,7 +384,7 @@ namespace Kernel
|
|||
TRY(working_directory.append(m_working_directory));
|
||||
}
|
||||
|
||||
auto elf = TRY(load_elf_for_exec(m_credentials, path, working_directory, path_env));
|
||||
auto elf = TRY(load_elf_for_exec(m_credentials, path, working_directory));
|
||||
|
||||
LockGuard lock_guard(m_lock);
|
||||
|
||||
|
@ -547,13 +503,6 @@ namespace Kernel
|
|||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_setenvp(char** envp)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
m_userspace_info.envp = envp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Process::load_elf_to_memory(LibELF::ELF& elf)
|
||||
{
|
||||
ASSERT(elf.is_native());
|
||||
|
|
|
@ -97,9 +97,6 @@ namespace Kernel
|
|||
case SYS_FSTAT:
|
||||
ret = Process::current().sys_fstat((int)arg1, (struct stat*)arg2);
|
||||
break;
|
||||
case SYS_SETENVP:
|
||||
ret = Process::current().sys_setenvp((char**)arg1);
|
||||
break;
|
||||
case SYS_READ_DIR_ENTRIES:
|
||||
ret = Process::current().sys_read_dir_entries((int)arg1, (API::DirectoryEntryList*)arg2, (size_t)arg3);
|
||||
break;
|
||||
|
|
|
@ -21,7 +21,6 @@ __BEGIN_DECLS
|
|||
#define SYS_SLEEP 17
|
||||
#define SYS_WAIT 18
|
||||
#define SYS_FSTAT 19
|
||||
#define SYS_SETENVP 20
|
||||
#define SYS_READ_DIR_ENTRIES 21
|
||||
#define SYS_SET_UID 22
|
||||
#define SYS_SET_GID 23
|
||||
|
|
|
@ -124,6 +124,16 @@ int putenv(char* string)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!environ)
|
||||
{
|
||||
environ = (char**)malloc(sizeof(char*) * 2);
|
||||
if (!environ)
|
||||
return -1;
|
||||
environ[0] = string;
|
||||
environ[1] = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cnt = 0;
|
||||
for (int i = 0; string[i]; i++)
|
||||
if (string[i] == '=')
|
||||
|
@ -151,10 +161,7 @@ int putenv(char* string)
|
|||
|
||||
char** new_envp = (char**)malloc(sizeof(char*) * (env_count + 2));
|
||||
if (new_envp == nullptr)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < env_count; i++)
|
||||
new_envp[i] = environ[i];
|
||||
|
@ -164,8 +171,6 @@ int putenv(char* string)
|
|||
free(environ);
|
||||
environ = new_envp;
|
||||
|
||||
if (syscall(SYS_SETENVP, environ) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,23 @@ char** environ;
|
|||
extern void init_malloc();
|
||||
extern "C" void _init_libc(char** _environ)
|
||||
{
|
||||
environ = _environ;
|
||||
init_malloc();
|
||||
|
||||
if (!_environ)
|
||||
return;
|
||||
|
||||
size_t env_count = 0;
|
||||
while (_environ[env_count])
|
||||
env_count++;
|
||||
|
||||
environ = (char**)malloc(sizeof(char*) * env_count + 1);
|
||||
for (size_t i = 0; i < env_count; i++)
|
||||
{
|
||||
size_t bytes = strlen(_environ[i]) + 1;
|
||||
environ[i] = (char*)malloc(bytes);
|
||||
memcpy(environ[i], _environ[i], bytes);
|
||||
}
|
||||
environ[env_count] = nullptr;
|
||||
}
|
||||
|
||||
void _exit(int status)
|
||||
|
|
|
@ -437,6 +437,40 @@ pid_t execute_command_no_wait(BAN::Vector<BAN::String>& args, int fd_in, int fd_
|
|||
MUST(cmd_args.push_back((char*)arg.data()));
|
||||
MUST(cmd_args.push_back(nullptr));
|
||||
|
||||
// do PATH resolution
|
||||
BAN::String executable_file;
|
||||
if (!args.front().empty() && args.front().front() != '.' && args.front().front() != '/')
|
||||
{
|
||||
char* path_env_cstr = getenv("PATH");
|
||||
if (path_env_cstr)
|
||||
{
|
||||
auto path_env_list = MUST(BAN::StringView(path_env_cstr).split(':'));
|
||||
for (auto path_env : path_env_list)
|
||||
{
|
||||
BAN::String test_file = path_env;
|
||||
MUST(test_file.push_back('/'));
|
||||
MUST(test_file.append(args.front()));
|
||||
|
||||
struct stat st;
|
||||
if (stat(test_file.data(), &st) == 0)
|
||||
{
|
||||
executable_file = BAN::move(test_file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (executable_file.empty())
|
||||
{
|
||||
fprintf(stderr, "command not found: %s\n", args.front().data());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
executable_file = args.front();
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
|
@ -477,11 +511,14 @@ pid_t execute_command_no_wait(BAN::Vector<BAN::String>& args, int fd_in, int fd_
|
|||
setpgid(0, pgrp);
|
||||
}
|
||||
|
||||
execv(cmd_args.front(), cmd_args.data());
|
||||
execv(executable_file.data(), cmd_args.data());
|
||||
perror("execv");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pid == -1)
|
||||
ERROR_RETURN("fork", -1);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
@ -489,7 +526,7 @@ int execute_command(BAN::Vector<BAN::String>& args, int fd_in, int fd_out)
|
|||
{
|
||||
pid_t pid = execute_command_no_wait(args, fd_in, fd_out, 0);
|
||||
if (pid == -1)
|
||||
ERROR_RETURN("fork", 1);
|
||||
return 1;
|
||||
|
||||
int status;
|
||||
if (waitpid(pid, &status, 0) == -1)
|
||||
|
|
|
@ -74,6 +74,8 @@ int main()
|
|||
if (setuid(pwd->pw_uid) == -1)
|
||||
perror("setuid");
|
||||
|
||||
setenv("PATH", "/bin:/usr/bin", 0);
|
||||
|
||||
setenv("HOME", pwd->pw_dir, 1);
|
||||
chdir(pwd->pw_dir);
|
||||
|
||||
|
|
Loading…
Reference in New Issue