mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Argv now works in main.
This commit is contained in:
parent
9ba01ad3b2
commit
ae599b6d67
7 changed files with 96 additions and 19 deletions
|
@ -31,7 +31,7 @@ namespace Maxsi
|
|||
namespace Process
|
||||
{
|
||||
DEFN_SYSCALL1_VOID(SysExit, 1, int);
|
||||
DEFN_SYSCALL3(int, SysExecute, 10, const char*, int, const char**);
|
||||
DEFN_SYSCALL4(int, SysExecVE, 10, const char*, int, char* const*, char* const*);
|
||||
DEFN_SYSCALL0_VOID(SysPrintPathFiles, 11);
|
||||
DEFN_SYSCALL0(pid_t, SysFork, 12);
|
||||
DEFN_SYSCALL0(pid_t, SysGetPID, 13);
|
||||
|
@ -42,7 +42,7 @@ namespace Maxsi
|
|||
|
||||
int Execute(const char* filepath, int argc, const char** argv)
|
||||
{
|
||||
return SysExecute(filepath, argc, argv);
|
||||
return SysExecVE(filepath, argc, (char* const*) argv, NULL);
|
||||
}
|
||||
|
||||
void PrintPathFiles()
|
||||
|
|
|
@ -33,9 +33,8 @@ _start:
|
|||
call initialize_standard_library
|
||||
|
||||
# Run main
|
||||
# TODO: Sortix should push these values to the stack itself!
|
||||
push $0x0 # argv
|
||||
push $0 # argc
|
||||
push %ebx # argv
|
||||
push %eax # argc
|
||||
call main
|
||||
|
||||
# Terminate the process with main's exit code.
|
||||
|
|
|
@ -79,7 +79,8 @@ namespace Sortix
|
|||
|
||||
Sound::Mute();
|
||||
const char* programname = "sh";
|
||||
Process::Execute(programname, regs);
|
||||
const char* const argv[] = { "sh" };
|
||||
CurrentProcess()->Execute(programname, 1, argv, regs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -244,8 +244,10 @@ namespace Sortix
|
|||
// TODO: Unmap any process memory segments.
|
||||
}
|
||||
|
||||
int Process::Execute(const char* programname, CPU::InterruptRegisters* regs)
|
||||
int Process::Execute(const char* programname, int argc, const char* const* argv, CPU::InterruptRegisters* regs)
|
||||
{
|
||||
ASSERT(CurrentProcess() == this);
|
||||
|
||||
size_t programsize = 0;
|
||||
byte* program = InitRD::Open(programname, &programsize);
|
||||
if ( !program ) { return -1; }
|
||||
|
@ -259,24 +261,75 @@ namespace Sortix
|
|||
Panic("Couldn't create the shell process");
|
||||
}
|
||||
|
||||
return Execute("sh", regs);
|
||||
const char* const SHARGV[]= { "sh" };
|
||||
return Execute("sh", 1, SHARGV, regs);
|
||||
}
|
||||
|
||||
// TODO: This may be an ugly hack!
|
||||
// TODO: Move this to x86/process.cpp.
|
||||
|
||||
// Alright, move argv onto the new stack! First figure out exactly how
|
||||
// big argv actually is.
|
||||
addr_t stackpos = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
||||
addr_t argvpos = stackpos - sizeof(char*) * argc;
|
||||
char** stackargv = (char**) argvpos;
|
||||
regs->eax = argc;
|
||||
regs->ebx = argvpos;
|
||||
|
||||
size_t argvsize = 0;
|
||||
for ( int i = 0; i < argc; i++ )
|
||||
{
|
||||
size_t len = String::Length(argv[i]) + 1;
|
||||
argvsize += len;
|
||||
char* dest = ((char*) argvpos) - argvsize;
|
||||
stackargv[i] = dest;
|
||||
Maxsi::Memory::Copy(dest, argv[i], len);
|
||||
}
|
||||
|
||||
stackpos = argvpos - argvsize;
|
||||
|
||||
regs->eip = entry;
|
||||
regs->useresp = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
||||
regs->ebp = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
||||
regs->useresp = stackpos;
|
||||
regs->ebp = stackpos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SysExecute(const char* programname)
|
||||
int SysExecVE(const char* filename, int argc, char* const argv[], char* const /*envp*/[])
|
||||
{
|
||||
// TODO: Validate that filepath is a user-space readable string!
|
||||
// TODO: Validate that all the pointer-y parameters are SAFE!
|
||||
|
||||
// This is a hacky way to set up the thread!
|
||||
return Process::Execute(programname, Syscall::InterruptRegs());
|
||||
// Make a copy of argv and filename as they are going to be destroyed
|
||||
// when the address space is reset.
|
||||
filename = String::Clone(filename);
|
||||
if ( !filename ) { return -1; /* TODO: errno */ }
|
||||
|
||||
char** newargv = new char*[argc];
|
||||
if ( !newargv ) { delete[] filename; return -1; /* TODO: errno */ }
|
||||
|
||||
for ( int i = 0; i < argc; i++ )
|
||||
{
|
||||
newargv[i] = String::Clone(argv[i]);
|
||||
if ( !newargv[i] )
|
||||
{
|
||||
while ( i ) { delete[] newargv[--i]; }
|
||||
|
||||
return -1; /* TODO: errno */
|
||||
}
|
||||
}
|
||||
|
||||
argv = newargv;
|
||||
|
||||
CPU::InterruptRegisters* regs = Syscall::InterruptRegs();
|
||||
Process* process = CurrentProcess();
|
||||
int result = process->Execute(filename, argc, argv, regs);
|
||||
Syscall::AsIs();
|
||||
|
||||
for ( int i = 0; i < argc; i++ ) { delete[] argv[i]; }
|
||||
delete[] argv;
|
||||
delete[] filename;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pid_t SysFork()
|
||||
|
@ -528,7 +581,7 @@ namespace Sortix
|
|||
|
||||
void Process::Init()
|
||||
{
|
||||
Syscall::Register(SYSCALL_EXEC, (void*) SysExecute);
|
||||
Syscall::Register(SYSCALL_EXEC, (void*) SysExecVE);
|
||||
Syscall::Register(SYSCALL_FORK, (void*) SysFork);
|
||||
Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID);
|
||||
Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID);
|
||||
|
|
|
@ -60,7 +60,6 @@ namespace Sortix
|
|||
|
||||
public:
|
||||
static void Init();
|
||||
static int Execute(const char* programname, CPU::InterruptRegisters* regs);
|
||||
|
||||
private:
|
||||
static pid_t AllocatePID();
|
||||
|
@ -90,6 +89,7 @@ namespace Sortix
|
|||
bool sigint;
|
||||
|
||||
public:
|
||||
int Execute(const char* programname, int argc, const char* const* argv, CPU::InterruptRegisters* regs);
|
||||
void ResetAddressSpace();
|
||||
|
||||
public:
|
||||
|
|
|
@ -294,7 +294,10 @@ namespace Sortix
|
|||
hacksigintpending = false;
|
||||
Log::PrintF("^C\n");
|
||||
|
||||
Process::Execute("sh", regs);
|
||||
const char* programname = "sh";
|
||||
const char* const argv[] = { "sh" };
|
||||
CurrentProcess()->Execute(programname, 1, argv, regs);
|
||||
return;
|
||||
}
|
||||
|
||||
void SigIntHack()
|
||||
|
|
|
@ -57,11 +57,32 @@ void command()
|
|||
return;
|
||||
}
|
||||
|
||||
int argc = 0;
|
||||
const char* argv[256];
|
||||
argv[argc++] = command;
|
||||
|
||||
bool lastwasspace = false;
|
||||
for ( size_t i = 0; i <= commandused; i++ )
|
||||
{
|
||||
switch ( command[i] )
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
command[i] = 0;
|
||||
lastwasspace = true;
|
||||
break;
|
||||
default:
|
||||
if ( lastwasspace ) { argv[argc++] = command + i; }
|
||||
lastwasspace = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the current process with another process image.
|
||||
Process::Execute(command, 0, NULL);
|
||||
Process::Execute(argv[0], argc, argv);
|
||||
|
||||
// This is clever. This only happens if the program didn't change.
|
||||
printf("%s: command not found\n", command);
|
||||
printf("%s: command not found\n", argv[0]);
|
||||
|
||||
exit(127);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue