mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:47:44 +00:00
Kernel: Pass process arguments directly on the stack.
Get rid of the convoluted get_arguments and get_environment syscalls. This patch also adds a simple /bin/env that just prints its environment.
This commit is contained in:
parent
e969419202
commit
6d3e12899b
9 changed files with 59 additions and 66 deletions
|
@ -223,9 +223,6 @@ Process* Process::fork(RegisterDump& regs)
|
||||||
dbgprintf("fork: child=%p\n", child);
|
dbgprintf("fork: child=%p\n", child);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
child->m_initial_arguments = m_initial_arguments;
|
|
||||||
child->m_initial_environment = m_initial_environment;
|
|
||||||
|
|
||||||
for (auto& region : m_regions) {
|
for (auto& region : m_regions) {
|
||||||
#ifdef FORK_DEBUG
|
#ifdef FORK_DEBUG
|
||||||
dbgprintf("fork: cloning Region{%p} \"%s\" L%x\n", region.ptr(), region->name.characters(), region->laddr().get());
|
dbgprintf("fork: cloning Region{%p} \"%s\" L%x\n", region.ptr(), region->name.characters(), region->laddr().get());
|
||||||
|
@ -426,8 +423,46 @@ void Process::make_userspace_stack(Vector<String> arguments, Vector<String> envi
|
||||||
m_stack_top3 = region->laddr().offset(default_userspace_stack_size).get();
|
m_stack_top3 = region->laddr().offset(default_userspace_stack_size).get();
|
||||||
m_tss.esp = m_stack_top3;
|
m_tss.esp = m_stack_top3;
|
||||||
|
|
||||||
m_initial_arguments = move(arguments);
|
char* stack_base = (char*)region->laddr().get();
|
||||||
m_initial_environment = move(environment);
|
int argc = arguments.size();
|
||||||
|
char** argv = (char**)stack_base;
|
||||||
|
char** env = argv + arguments.size() + 1;
|
||||||
|
char* bufptr = stack_base + (sizeof(char*) * (arguments.size() + 1)) + (sizeof(char*) * (environment.size() + 1));
|
||||||
|
|
||||||
|
size_t total_blob_size = 0;
|
||||||
|
for (auto& a : arguments)
|
||||||
|
total_blob_size += a.length() + 1;
|
||||||
|
for (auto& e : environment)
|
||||||
|
total_blob_size += e.length() + 1;
|
||||||
|
|
||||||
|
size_t total_meta_size = sizeof(char*) * (arguments.size() + 1) + sizeof(char*) * (environment.size() + 1);
|
||||||
|
|
||||||
|
// FIXME: It would be better if this didn't make us panic.
|
||||||
|
ASSERT((total_blob_size + total_meta_size) < default_userspace_stack_size);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < arguments.size(); ++i) {
|
||||||
|
argv[i] = bufptr;
|
||||||
|
memcpy(bufptr, arguments[i].characters(), arguments[i].length());
|
||||||
|
bufptr += arguments[i].length();
|
||||||
|
*(bufptr++) = '\0';
|
||||||
|
printf("argv[%u] = %p (%s)\n", i, argv[i], argv[i]);
|
||||||
|
}
|
||||||
|
argv[arguments.size()] = nullptr;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < environment.size(); ++i) {
|
||||||
|
env[i] = bufptr;
|
||||||
|
memcpy(bufptr, environment[i].characters(), environment[i].length());
|
||||||
|
bufptr += environment[i].length();
|
||||||
|
*(bufptr++) = '\0';
|
||||||
|
printf("env[%u] = %p (%s)\n", i, env[i], env[i]);
|
||||||
|
}
|
||||||
|
env[environment.size()] = nullptr;
|
||||||
|
|
||||||
|
// NOTE: The stack needs to be 16-byte aligned.
|
||||||
|
push_value_on_stack((dword)env);
|
||||||
|
push_value_on_stack((dword)argv);
|
||||||
|
push_value_on_stack((dword)argc);
|
||||||
|
push_value_on_stack(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::exec(String path, Vector<String> arguments, Vector<String> environment)
|
int Process::exec(String path, Vector<String> arguments, Vector<String> environment)
|
||||||
|
@ -529,45 +564,6 @@ Process* Process::create_user_process(const String& path, uid_t uid, gid_t gid,
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$get_environment(char*** environ)
|
|
||||||
{
|
|
||||||
auto* region = allocate_region(LinearAddress(), PAGE_SIZE, "environ");
|
|
||||||
if (!region)
|
|
||||||
return -ENOMEM;
|
|
||||||
MM.map_region(*this, *region);
|
|
||||||
char* envpage = (char*)region->laddr().get();
|
|
||||||
*environ = (char**)envpage;
|
|
||||||
char* bufptr = envpage + (sizeof(char*) * (m_initial_environment.size() + 1));
|
|
||||||
for (size_t i = 0; i < m_initial_environment.size(); ++i) {
|
|
||||||
(*environ)[i] = bufptr;
|
|
||||||
memcpy(bufptr, m_initial_environment[i].characters(), m_initial_environment[i].length());
|
|
||||||
bufptr += m_initial_environment[i].length();
|
|
||||||
*(bufptr++) = '\0';
|
|
||||||
}
|
|
||||||
(*environ)[m_initial_environment.size()] = nullptr;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Process::sys$get_arguments(int* argc, char*** argv)
|
|
||||||
{
|
|
||||||
auto* region = allocate_region(LinearAddress(), PAGE_SIZE, "argv");
|
|
||||||
if (!region)
|
|
||||||
return -ENOMEM;
|
|
||||||
MM.map_region(*this, *region);
|
|
||||||
char* argpage = (char*)region->laddr().get();
|
|
||||||
*argc = m_initial_arguments.size();
|
|
||||||
*argv = (char**)argpage;
|
|
||||||
char* bufptr = argpage + (sizeof(char*) * (m_initial_arguments.size() + 1));
|
|
||||||
for (size_t i = 0; i < m_initial_arguments.size(); ++i) {
|
|
||||||
(*argv)[i] = bufptr;
|
|
||||||
memcpy(bufptr, m_initial_arguments[i].characters(), m_initial_arguments[i].length());
|
|
||||||
bufptr += m_initial_arguments[i].length();
|
|
||||||
*(bufptr++) = '\0';
|
|
||||||
}
|
|
||||||
(*argv)[m_initial_arguments.size()] = nullptr;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Process* Process::create_kernel_process(String&& name, void (*e)())
|
Process* Process::create_kernel_process(String&& name, void (*e)())
|
||||||
{
|
{
|
||||||
auto* process = new Process(move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0);
|
auto* process = new Process(move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0);
|
||||||
|
|
|
@ -183,8 +183,6 @@ public:
|
||||||
int sys$usleep(useconds_t usec);
|
int sys$usleep(useconds_t usec);
|
||||||
int sys$gettimeofday(timeval*);
|
int sys$gettimeofday(timeval*);
|
||||||
int sys$gethostname(char* name, size_t length);
|
int sys$gethostname(char* name, size_t length);
|
||||||
int sys$get_arguments(int* argc, char*** argv);
|
|
||||||
int sys$get_environment(char*** environ);
|
|
||||||
int sys$uname(utsname*);
|
int sys$uname(utsname*);
|
||||||
int sys$readlink(const char*, char*, size_t);
|
int sys$readlink(const char*, char*, size_t);
|
||||||
int sys$ttyname_r(int fd, char*, size_t);
|
int sys$ttyname_r(int fd, char*, size_t);
|
||||||
|
@ -386,8 +384,6 @@ private:
|
||||||
|
|
||||||
static void notify_waiters(pid_t waitee, int exit_status, int signal);
|
static void notify_waiters(pid_t waitee, int exit_status, int signal);
|
||||||
|
|
||||||
Vector<String> m_initial_arguments;
|
|
||||||
Vector<String> m_initial_environment;
|
|
||||||
HashTable<gid_t> m_gids;
|
HashTable<gid_t> m_gids;
|
||||||
|
|
||||||
Region* m_signal_stack_user_region { nullptr };
|
Region* m_signal_stack_user_region { nullptr };
|
||||||
|
|
|
@ -111,10 +111,6 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
|
||||||
current->sys$exit((int)arg1);
|
current->sys$exit((int)arg1);
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
return 0;
|
return 0;
|
||||||
case Syscall::SC_get_arguments:
|
|
||||||
return current->sys$get_arguments((int*)arg1, (char***)arg2);
|
|
||||||
case Syscall::SC_get_environment:
|
|
||||||
return current->sys$get_environment((char***)arg1);
|
|
||||||
case Syscall::SC_chdir:
|
case Syscall::SC_chdir:
|
||||||
return current->sys$chdir((const char*)arg1);
|
return current->sys$chdir((const char*)arg1);
|
||||||
case Syscall::SC_uname:
|
case Syscall::SC_uname:
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
__ENUMERATE_SYSCALL(getcwd) \
|
__ENUMERATE_SYSCALL(getcwd) \
|
||||||
__ENUMERATE_SYSCALL(gettimeofday) \
|
__ENUMERATE_SYSCALL(gettimeofday) \
|
||||||
__ENUMERATE_SYSCALL(gethostname) \
|
__ENUMERATE_SYSCALL(gethostname) \
|
||||||
__ENUMERATE_SYSCALL(get_arguments) \
|
|
||||||
__ENUMERATE_SYSCALL(chdir) \
|
__ENUMERATE_SYSCALL(chdir) \
|
||||||
__ENUMERATE_SYSCALL(uname) \
|
__ENUMERATE_SYSCALL(uname) \
|
||||||
__ENUMERATE_SYSCALL(set_mmap_name) \
|
__ENUMERATE_SYSCALL(set_mmap_name) \
|
||||||
|
@ -31,7 +30,6 @@
|
||||||
__ENUMERATE_SYSCALL(write) \
|
__ENUMERATE_SYSCALL(write) \
|
||||||
__ENUMERATE_SYSCALL(ttyname_r) \
|
__ENUMERATE_SYSCALL(ttyname_r) \
|
||||||
__ENUMERATE_SYSCALL(stat) \
|
__ENUMERATE_SYSCALL(stat) \
|
||||||
__ENUMERATE_SYSCALL(get_environment) \
|
|
||||||
__ENUMERATE_SYSCALL(getsid) \
|
__ENUMERATE_SYSCALL(getsid) \
|
||||||
__ENUMERATE_SYSCALL(setsid) \
|
__ENUMERATE_SYSCALL(setsid) \
|
||||||
__ENUMERATE_SYSCALL(getpgid) \
|
__ENUMERATE_SYSCALL(getpgid) \
|
||||||
|
|
|
@ -69,6 +69,7 @@ cp -v ../Userland/top mnt/bin/top
|
||||||
cp -v ../Userland/ln mnt/bin/ln
|
cp -v ../Userland/ln mnt/bin/ln
|
||||||
cp -v ../Userland/df mnt/bin/df
|
cp -v ../Userland/df mnt/bin/df
|
||||||
cp -v ../Userland/su mnt/bin/su
|
cp -v ../Userland/su mnt/bin/su
|
||||||
|
cp -v ../Userland/env mnt/bin/env
|
||||||
chmod 4755 mnt/bin/su
|
chmod 4755 mnt/bin/su
|
||||||
cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal
|
cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal
|
||||||
cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor
|
cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor
|
||||||
|
|
|
@ -13,28 +13,19 @@ char** environ;
|
||||||
void __malloc_init();
|
void __malloc_init();
|
||||||
void __stdio_init();
|
void __stdio_init();
|
||||||
|
|
||||||
int _start()
|
int _start(int argc, char** argv, char** env)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
environ = env;
|
||||||
|
|
||||||
__stdio_init();
|
__stdio_init();
|
||||||
__malloc_init();
|
__malloc_init();
|
||||||
|
|
||||||
int status = 254;
|
int status = main(argc, argv);
|
||||||
int argc;
|
|
||||||
char** argv;
|
|
||||||
int rc = syscall(SC_get_arguments, &argc, &argv);
|
|
||||||
if (rc < 0)
|
|
||||||
goto epilogue;
|
|
||||||
rc = syscall(SC_get_environment, &environ);
|
|
||||||
if (rc < 0)
|
|
||||||
goto epilogue;
|
|
||||||
status = main(argc, argv);
|
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
epilogue:
|
|
||||||
syscall(SC_exit, status);
|
syscall(SC_exit, status);
|
||||||
|
|
||||||
// Birger's birthday <3
|
// Birger's birthday <3
|
||||||
|
|
1
Userland/.gitignore
vendored
1
Userland/.gitignore
vendored
|
@ -34,3 +34,4 @@ pape
|
||||||
ln
|
ln
|
||||||
df
|
df
|
||||||
su
|
su
|
||||||
|
env
|
||||||
|
|
|
@ -30,6 +30,7 @@ OBJS = \
|
||||||
df.o \
|
df.o \
|
||||||
ln.o \
|
ln.o \
|
||||||
su.o \
|
su.o \
|
||||||
|
env.o \
|
||||||
rm.o
|
rm.o
|
||||||
|
|
||||||
APPS = \
|
APPS = \
|
||||||
|
@ -65,6 +66,7 @@ APPS = \
|
||||||
ln \
|
ln \
|
||||||
df \
|
df \
|
||||||
su \
|
su \
|
||||||
|
env \
|
||||||
rm
|
rm
|
||||||
|
|
||||||
ARCH_FLAGS =
|
ARCH_FLAGS =
|
||||||
|
@ -184,6 +186,9 @@ df: df.o
|
||||||
su: su.o
|
su: su.o
|
||||||
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
|
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
|
||||||
|
|
||||||
|
env: env.o
|
||||||
|
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
|
||||||
|
|
||||||
.cpp.o:
|
.cpp.o:
|
||||||
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
|
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
|
9
Userland/env.cpp
Normal file
9
Userland/env.cpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; environ[i]; ++i)
|
||||||
|
printf("%s\n", environ[i]);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue