mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:27:43 +00:00
Add a simplified waitpid() so that sh can wait on spawned commands.
This commit is contained in:
parent
018da1be11
commit
3253a23b91
8 changed files with 42 additions and 7 deletions
|
@ -88,6 +88,8 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3)
|
||||||
return current->sys$getgid();
|
return current->sys$getgid();
|
||||||
case Syscall::PosixGetpid:
|
case Syscall::PosixGetpid:
|
||||||
return current->sys$getpid();
|
return current->sys$getpid();
|
||||||
|
case Syscall::PosixWaitpid:
|
||||||
|
return current->sys$waitpid((pid_t)arg1);
|
||||||
case Syscall::PosixExit:
|
case Syscall::PosixExit:
|
||||||
cli();
|
cli();
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
|
|
@ -23,6 +23,7 @@ enum Function {
|
||||||
PosixExit = 0x1991,
|
PosixExit = 0x1991,
|
||||||
PosixGetgid = 0x1992,
|
PosixGetgid = 0x1992,
|
||||||
PosixGetpid = 0x1993,
|
PosixGetpid = 0x1993,
|
||||||
|
PosixWaitpid = 0x1994,
|
||||||
};
|
};
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#include "MemoryManager.h"
|
#include "MemoryManager.h"
|
||||||
|
|
||||||
//#define DEBUG_IO
|
//#define DEBUG_IO
|
||||||
|
//#define TASK_DEBUG
|
||||||
|
|
||||||
|
static const DWORD defaultStackSize = 16384;
|
||||||
|
|
||||||
Task* current;
|
Task* current;
|
||||||
Task* s_kernelTask;
|
Task* s_kernelTask;
|
||||||
|
@ -169,7 +172,9 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid)
|
||||||
|
|
||||||
s_tasks->prepend(t);
|
s_tasks->prepend(t);
|
||||||
system.nprocess++;
|
system.nprocess++;
|
||||||
|
#ifdef TASK_DEBUG
|
||||||
kprintf("Task %u (%s) spawned @ %p\n", t->pid(), t->name().characters(), t->m_tss.eip);
|
kprintf("Task %u (%s) spawned @ %p\n", t->pid(), t->name().characters(), t->m_tss.eip);
|
||||||
|
#endif
|
||||||
sti();
|
sti();
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
|
@ -206,9 +211,6 @@ Task::Task(String&& name, uid_t uid, gid_t gid)
|
||||||
|
|
||||||
m_tss.cr3 = MemoryManager::the().pageDirectoryBase().get();
|
m_tss.cr3 = MemoryManager::the().pageDirectoryBase().get();
|
||||||
|
|
||||||
// NOTE: Each task gets 16KB of stack.
|
|
||||||
static const DWORD defaultStackSize = 16384;
|
|
||||||
|
|
||||||
auto* region = allocateRegion(defaultStackSize, "stack");
|
auto* region = allocateRegion(defaultStackSize, "stack");
|
||||||
ASSERT(region);
|
ASSERT(region);
|
||||||
m_stackTop = region->linearAddress.offset(defaultStackSize).get() & 0xfffffff8;
|
m_stackTop = region->linearAddress.offset(defaultStackSize).get() & 0xfffffff8;
|
||||||
|
@ -287,9 +289,6 @@ Task::Task(void (*e)(), const char* n, IPC::Handle h, RingLevel ring)
|
||||||
m_tss.eip = codeRegion->linearAddress.get();
|
m_tss.eip = codeRegion->linearAddress.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Each task gets 16KB of stack.
|
|
||||||
static const DWORD defaultStackSize = 16384;
|
|
||||||
|
|
||||||
if (isRing0()) {
|
if (isRing0()) {
|
||||||
// FIXME: This memory is leaked.
|
// FIXME: This memory is leaked.
|
||||||
// But uh, there's also no kernel task termination, so I guess it's not technically leaked...
|
// But uh, there's also no kernel task termination, so I guess it's not technically leaked...
|
||||||
|
@ -327,8 +326,9 @@ Task::Task(void (*e)(), const char* n, IPC::Handle h, RingLevel ring)
|
||||||
s_tasks->prepend(this);
|
s_tasks->prepend(this);
|
||||||
|
|
||||||
system.nprocess++;
|
system.nprocess++;
|
||||||
|
#ifdef TASK_DEBUG
|
||||||
kprintf("Task %u (%s) spawned @ %p\n", m_pid, m_name.characters(), m_tss.eip);
|
kprintf("Task %u (%s) spawned @ %p\n", m_pid, m_name.characters(), m_tss.eip);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Task::~Task()
|
Task::~Task()
|
||||||
|
@ -359,7 +359,9 @@ void Task::dumpRegions()
|
||||||
void Task::sys$exit(int status)
|
void Task::sys$exit(int status)
|
||||||
{
|
{
|
||||||
cli();
|
cli();
|
||||||
|
#ifdef TASK_DEBUG
|
||||||
kprintf("sys$exit: %s(%u) exit with status %d\n", name().characters(), pid(), status);
|
kprintf("sys$exit: %s(%u) exit with status %d\n", name().characters(), pid(), status);
|
||||||
|
#endif
|
||||||
|
|
||||||
setState(Exiting);
|
setState(Exiting);
|
||||||
|
|
||||||
|
@ -473,6 +475,13 @@ bool scheduleNewTask()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (task->state() == Task::BlockedWait) {
|
||||||
|
if (!Task::fromPID(task->waitee())) {
|
||||||
|
task->unblock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* prevHead = s_tasks->head();
|
auto* prevHead = s_tasks->head();
|
||||||
|
@ -693,6 +702,16 @@ pid_t Task::sys$getpid()
|
||||||
return m_pid;
|
return m_pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid_t Task::sys$waitpid(pid_t waitee)
|
||||||
|
{
|
||||||
|
if (!Task::fromPID(waitee))
|
||||||
|
return -1;
|
||||||
|
m_waitee = waitee;
|
||||||
|
block(BlockedWait);
|
||||||
|
yield();
|
||||||
|
return m_waitee;
|
||||||
|
}
|
||||||
|
|
||||||
bool Task::acceptsMessageFrom(Task& peer)
|
bool Task::acceptsMessageFrom(Task& peer)
|
||||||
{
|
{
|
||||||
return !ipc.msg.isValid() && (ipc.src == IPC::Handle::Any || ipc.src == peer.handle());
|
return !ipc.msg.isValid() && (ipc.src == IPC::Handle::Any || ipc.src == peer.handle());
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
Terminated = 6,
|
Terminated = 6,
|
||||||
Crashing = 7,
|
Crashing = 7,
|
||||||
Exiting = 8,
|
Exiting = 8,
|
||||||
|
BlockedWait = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RingLevel {
|
enum RingLevel {
|
||||||
|
@ -97,6 +98,7 @@ public:
|
||||||
void sys$sleep(DWORD ticks);
|
void sys$sleep(DWORD ticks);
|
||||||
void sys$exit(int status);
|
void sys$exit(int status);
|
||||||
int sys$spawn(const char* path);
|
int sys$spawn(const char* path);
|
||||||
|
pid_t sys$waitpid(pid_t);
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -116,6 +118,8 @@ public:
|
||||||
void didSchedule() { ++m_timesScheduled; }
|
void didSchedule() { ++m_timesScheduled; }
|
||||||
dword timesScheduled() const { return m_timesScheduled; }
|
dword timesScheduled() const { return m_timesScheduled; }
|
||||||
|
|
||||||
|
pid_t waitee() const { return m_waitee; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MemoryManager;
|
friend class MemoryManager;
|
||||||
|
|
||||||
|
@ -145,6 +149,7 @@ private:
|
||||||
int m_error { 0 };
|
int m_error { 0 };
|
||||||
void* m_kernelStack { nullptr };
|
void* m_kernelStack { nullptr };
|
||||||
dword m_timesScheduled { 0 };
|
dword m_timesScheduled { 0 };
|
||||||
|
pid_t m_waitee { -1 };
|
||||||
|
|
||||||
struct Region {
|
struct Region {
|
||||||
Region(LinearAddress, size_t, RetainPtr<Zone>&&, String&&);
|
Region(LinearAddress, size_t, RetainPtr<Zone>&&, String&&);
|
||||||
|
|
Binary file not shown.
|
@ -35,5 +35,10 @@ int close(int fd)
|
||||||
return Syscall::invoke(Syscall::PosixClose, fd);
|
return Syscall::invoke(Syscall::PosixClose, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid_t waitpid(pid_t waitee)
|
||||||
|
{
|
||||||
|
return Syscall::invoke(Syscall::PosixWaitpid, waitee);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ pid_t getpid();
|
||||||
int open(const char* path);
|
int open(const char* path);
|
||||||
ssize_t read(int fd, void* buf, size_t count);
|
ssize_t read(int fd, void* buf, size_t count);
|
||||||
int close(int fd);
|
int close(int fd);
|
||||||
|
pid_t waitpid(pid_t);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,9 @@ static int runcmd(char* cmd)
|
||||||
int ret = spawn(buf);
|
int ret = spawn(buf);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
printf("spawn failed: %s\n", cmd);
|
printf("spawn failed: %s\n", cmd);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
waitpid(ret);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue