Argv now works in main.
This commit is contained in:
parent
9ba01ad3b2
commit
ae599b6d67
|
@ -31,7 +31,7 @@ namespace Maxsi
|
||||||
namespace Process
|
namespace Process
|
||||||
{
|
{
|
||||||
DEFN_SYSCALL1_VOID(SysExit, 1, int);
|
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_VOID(SysPrintPathFiles, 11);
|
||||||
DEFN_SYSCALL0(pid_t, SysFork, 12);
|
DEFN_SYSCALL0(pid_t, SysFork, 12);
|
||||||
DEFN_SYSCALL0(pid_t, SysGetPID, 13);
|
DEFN_SYSCALL0(pid_t, SysGetPID, 13);
|
||||||
|
@ -42,7 +42,7 @@ namespace Maxsi
|
||||||
|
|
||||||
int Execute(const char* filepath, int argc, const char** argv)
|
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()
|
void PrintPathFiles()
|
||||||
|
|
|
@ -33,9 +33,8 @@ _start:
|
||||||
call initialize_standard_library
|
call initialize_standard_library
|
||||||
|
|
||||||
# Run main
|
# Run main
|
||||||
# TODO: Sortix should push these values to the stack itself!
|
push %ebx # argv
|
||||||
push $0x0 # argv
|
push %eax # argc
|
||||||
push $0 # argc
|
|
||||||
call main
|
call main
|
||||||
|
|
||||||
# Terminate the process with main's exit code.
|
# Terminate the process with main's exit code.
|
||||||
|
|
|
@ -79,7 +79,8 @@ namespace Sortix
|
||||||
|
|
||||||
Sound::Mute();
|
Sound::Mute();
|
||||||
const char* programname = "sh";
|
const char* programname = "sh";
|
||||||
Process::Execute(programname, regs);
|
const char* const argv[] = { "sh" };
|
||||||
|
CurrentProcess()->Execute(programname, 1, argv, regs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,8 +244,10 @@ namespace Sortix
|
||||||
// TODO: Unmap any process memory segments.
|
// 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;
|
size_t programsize = 0;
|
||||||
byte* program = InitRD::Open(programname, &programsize);
|
byte* program = InitRD::Open(programname, &programsize);
|
||||||
if ( !program ) { return -1; }
|
if ( !program ) { return -1; }
|
||||||
|
@ -259,24 +261,75 @@ namespace Sortix
|
||||||
Panic("Couldn't create the shell process");
|
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: This may be an ugly hack!
|
||||||
// TODO: Move this to x86/process.cpp.
|
// 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->eip = entry;
|
||||||
regs->useresp = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
regs->useresp = stackpos;
|
||||||
regs->ebp = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
regs->ebp = stackpos;
|
||||||
|
|
||||||
return 0;
|
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!
|
// Make a copy of argv and filename as they are going to be destroyed
|
||||||
return Process::Execute(programname, Syscall::InterruptRegs());
|
// 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()
|
pid_t SysFork()
|
||||||
|
@ -528,7 +581,7 @@ namespace Sortix
|
||||||
|
|
||||||
void Process::Init()
|
void Process::Init()
|
||||||
{
|
{
|
||||||
Syscall::Register(SYSCALL_EXEC, (void*) SysExecute);
|
Syscall::Register(SYSCALL_EXEC, (void*) SysExecVE);
|
||||||
Syscall::Register(SYSCALL_FORK, (void*) SysFork);
|
Syscall::Register(SYSCALL_FORK, (void*) SysFork);
|
||||||
Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID);
|
Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID);
|
||||||
Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID);
|
Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID);
|
||||||
|
|
|
@ -60,7 +60,6 @@ namespace Sortix
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static int Execute(const char* programname, CPU::InterruptRegisters* regs);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static pid_t AllocatePID();
|
static pid_t AllocatePID();
|
||||||
|
@ -90,6 +89,7 @@ namespace Sortix
|
||||||
bool sigint;
|
bool sigint;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int Execute(const char* programname, int argc, const char* const* argv, CPU::InterruptRegisters* regs);
|
||||||
void ResetAddressSpace();
|
void ResetAddressSpace();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -294,7 +294,10 @@ namespace Sortix
|
||||||
hacksigintpending = false;
|
hacksigintpending = false;
|
||||||
Log::PrintF("^C\n");
|
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()
|
void SigIntHack()
|
||||||
|
|
|
@ -57,11 +57,32 @@ void command()
|
||||||
return;
|
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.
|
// 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.
|
// 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);
|
exit(127);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue