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_sleep(int seconds);
|
||||||
BAN::ErrorOr<long> sys_nanosleep(const timespec* rqtp, timespec* rmtp);
|
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_setpwd(const char* path);
|
||||||
BAN::ErrorOr<long> sys_getpwd(char* buffer, size_t size);
|
BAN::ErrorOr<long> sys_getpwd(char* buffer, size_t size);
|
||||||
|
|
||||||
|
@ -147,7 +145,7 @@ namespace Kernel
|
||||||
static void register_process(Process*);
|
static void register_process(Process*);
|
||||||
|
|
||||||
// Load an elf file to virtual address space of the current page table
|
// 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
|
// Copy an elf file from the current page table to the processes own
|
||||||
void load_elf_to_memory(LibELF::ELF&);
|
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)
|
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);
|
auto* process = create_process(credentials, 0);
|
||||||
MUST(process->m_working_directory.push_back('/'));
|
MUST(process->m_working_directory.push_back('/'));
|
||||||
|
@ -114,7 +114,6 @@ namespace Kernel
|
||||||
elf.clear();
|
elf.clear();
|
||||||
|
|
||||||
char** argv = nullptr;
|
char** argv = nullptr;
|
||||||
char** envp = nullptr;
|
|
||||||
{
|
{
|
||||||
PageTableScope _(process->page_table());
|
PageTableScope _(process->page_table());
|
||||||
|
|
||||||
|
@ -123,18 +122,11 @@ namespace Kernel
|
||||||
memcpy(argv[0], path.data(), path.size());
|
memcpy(argv[0], path.data(), path.size());
|
||||||
argv[0][path.size()] = '\0';
|
argv[0][path.size()] = '\0';
|
||||||
argv[1] = nullptr;
|
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.argc = 1;
|
||||||
process->m_userspace_info.argv = argv;
|
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));
|
auto* thread = MUST(Thread::create_userspace(process));
|
||||||
process->add_thread(thread);
|
process->add_thread(thread);
|
||||||
|
@ -275,7 +267,7 @@ namespace Kernel
|
||||||
return 0;
|
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())
|
if (file_path.empty())
|
||||||
return BAN::Error::from_errno(ENOENT);
|
return BAN::Error::from_errno(ENOENT);
|
||||||
|
@ -283,44 +275,13 @@ namespace Kernel
|
||||||
BAN::String absolute_path;
|
BAN::String absolute_path;
|
||||||
|
|
||||||
if (file_path.front() == '/')
|
if (file_path.front() == '/')
|
||||||
{
|
|
||||||
// We have an absolute path
|
|
||||||
TRY(absolute_path.append(file_path));
|
TRY(absolute_path.append(file_path));
|
||||||
}
|
else
|
||||||
else if (file_path.front() == '.' || file_path.contains('/'))
|
|
||||||
{
|
{
|
||||||
// We have a relative path
|
|
||||||
TRY(absolute_path.append(cwd));
|
TRY(absolute_path.append(cwd));
|
||||||
TRY(absolute_path.push_back('/'));
|
TRY(absolute_path.push_back('/'));
|
||||||
TRY(absolute_path.append(file_path));
|
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));
|
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++)
|
for (int i = 0; argv && argv[i]; i++)
|
||||||
TRY(str_argv.emplace_back(argv[i]));
|
TRY(str_argv.emplace_back(argv[i]));
|
||||||
|
|
||||||
BAN::Vector<BAN::StringView> path_env;
|
|
||||||
BAN::Vector<BAN::String> str_envp;
|
BAN::Vector<BAN::String> str_envp;
|
||||||
for (int i = 0; envp && envp[i]; i++)
|
for (int i = 0; envp && envp[i]; i++)
|
||||||
{
|
|
||||||
TRY(str_envp.emplace_back(envp[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;
|
BAN::String working_directory;
|
||||||
|
|
||||||
|
@ -428,7 +384,7 @@ namespace Kernel
|
||||||
TRY(working_directory.append(m_working_directory));
|
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);
|
LockGuard lock_guard(m_lock);
|
||||||
|
|
||||||
|
@ -547,13 +503,6 @@ namespace Kernel
|
||||||
return 0;
|
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)
|
void Process::load_elf_to_memory(LibELF::ELF& elf)
|
||||||
{
|
{
|
||||||
ASSERT(elf.is_native());
|
ASSERT(elf.is_native());
|
||||||
|
|
|
@ -97,9 +97,6 @@ namespace Kernel
|
||||||
case SYS_FSTAT:
|
case SYS_FSTAT:
|
||||||
ret = Process::current().sys_fstat((int)arg1, (struct stat*)arg2);
|
ret = Process::current().sys_fstat((int)arg1, (struct stat*)arg2);
|
||||||
break;
|
break;
|
||||||
case SYS_SETENVP:
|
|
||||||
ret = Process::current().sys_setenvp((char**)arg1);
|
|
||||||
break;
|
|
||||||
case SYS_READ_DIR_ENTRIES:
|
case SYS_READ_DIR_ENTRIES:
|
||||||
ret = Process::current().sys_read_dir_entries((int)arg1, (API::DirectoryEntryList*)arg2, (size_t)arg3);
|
ret = Process::current().sys_read_dir_entries((int)arg1, (API::DirectoryEntryList*)arg2, (size_t)arg3);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -21,7 +21,6 @@ __BEGIN_DECLS
|
||||||
#define SYS_SLEEP 17
|
#define SYS_SLEEP 17
|
||||||
#define SYS_WAIT 18
|
#define SYS_WAIT 18
|
||||||
#define SYS_FSTAT 19
|
#define SYS_FSTAT 19
|
||||||
#define SYS_SETENVP 20
|
|
||||||
#define SYS_READ_DIR_ENTRIES 21
|
#define SYS_READ_DIR_ENTRIES 21
|
||||||
#define SYS_SET_UID 22
|
#define SYS_SET_UID 22
|
||||||
#define SYS_SET_GID 23
|
#define SYS_SET_GID 23
|
||||||
|
|
|
@ -124,6 +124,16 @@ int putenv(char* string)
|
||||||
return -1;
|
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;
|
int cnt = 0;
|
||||||
for (int i = 0; string[i]; i++)
|
for (int i = 0; string[i]; i++)
|
||||||
if (string[i] == '=')
|
if (string[i] == '=')
|
||||||
|
@ -151,10 +161,7 @@ int putenv(char* string)
|
||||||
|
|
||||||
char** new_envp = (char**)malloc(sizeof(char*) * (env_count + 2));
|
char** new_envp = (char**)malloc(sizeof(char*) * (env_count + 2));
|
||||||
if (new_envp == nullptr)
|
if (new_envp == nullptr)
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < env_count; i++)
|
for (int i = 0; i < env_count; i++)
|
||||||
new_envp[i] = environ[i];
|
new_envp[i] = environ[i];
|
||||||
|
@ -164,8 +171,6 @@ int putenv(char* string)
|
||||||
free(environ);
|
free(environ);
|
||||||
environ = new_envp;
|
environ = new_envp;
|
||||||
|
|
||||||
if (syscall(SYS_SETENVP, environ) == -1)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,23 @@ char** environ;
|
||||||
extern void init_malloc();
|
extern void init_malloc();
|
||||||
extern "C" void _init_libc(char** _environ)
|
extern "C" void _init_libc(char** _environ)
|
||||||
{
|
{
|
||||||
environ = _environ;
|
|
||||||
init_malloc();
|
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)
|
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((char*)arg.data()));
|
||||||
MUST(cmd_args.push_back(nullptr));
|
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();
|
pid_t pid = fork();
|
||||||
if (pid == 0)
|
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);
|
setpgid(0, pgrp);
|
||||||
}
|
}
|
||||||
|
|
||||||
execv(cmd_args.front(), cmd_args.data());
|
execv(executable_file.data(), cmd_args.data());
|
||||||
perror("execv");
|
perror("execv");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pid == -1)
|
||||||
|
ERROR_RETURN("fork", -1);
|
||||||
|
|
||||||
return pid;
|
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);
|
pid_t pid = execute_command_no_wait(args, fd_in, fd_out, 0);
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
ERROR_RETURN("fork", 1);
|
return 1;
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
if (waitpid(pid, &status, 0) == -1)
|
if (waitpid(pid, &status, 0) == -1)
|
||||||
|
|
|
@ -74,6 +74,8 @@ int main()
|
||||||
if (setuid(pwd->pw_uid) == -1)
|
if (setuid(pwd->pw_uid) == -1)
|
||||||
perror("setuid");
|
perror("setuid");
|
||||||
|
|
||||||
|
setenv("PATH", "/bin:/usr/bin", 0);
|
||||||
|
|
||||||
setenv("HOME", pwd->pw_dir, 1);
|
setenv("HOME", pwd->pw_dir, 1);
|
||||||
chdir(pwd->pw_dir);
|
chdir(pwd->pw_dir);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue