mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 08:28:11 +00:00
Implement errno in LibC.
This also meant I had to implement BSS (SHT_NOBITS) sections in ELFLoader. I also added an strerror() so we can print out what the errors are.
This commit is contained in:
parent
434b6a8688
commit
260b14e505
14 changed files with 209 additions and 27 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <VirtualFileSystem/VirtualFileSystem.h>
|
||||
#include <ELFLoader/ExecSpace.h>
|
||||
#include "MemoryManager.h"
|
||||
#include "errno.h"
|
||||
|
||||
//#define DEBUG_IO
|
||||
//#define TASK_DEBUG
|
||||
|
@ -166,25 +167,32 @@ int Task::sys$munmap(void* addr, size_t size)
|
|||
|
||||
int Task::sys$spawn(const char* path)
|
||||
{
|
||||
auto* child = Task::createUserTask(path, m_uid, m_gid, m_pid);
|
||||
int error = 0;
|
||||
auto* child = Task::createUserTask(path, m_uid, m_gid, m_pid, error);
|
||||
if (child)
|
||||
return child->pid();
|
||||
return -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
Task* Task::createUserTask(const String& path, uid_t uid, gid_t gid, pid_t parentPID)
|
||||
Task* Task::createUserTask(const String& path, uid_t uid, gid_t gid, pid_t parentPID, int& error)
|
||||
{
|
||||
auto parts = path.split('/');
|
||||
if (parts.isEmpty())
|
||||
if (parts.isEmpty()) {
|
||||
error = -ENOENT;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto handle = VirtualFileSystem::the().open(path);
|
||||
if (!handle)
|
||||
if (!handle) {
|
||||
error = -ENOENT; // FIXME: Get a more detailed error from VFS.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto elfData = handle->readEntireFile();
|
||||
if (!elfData)
|
||||
if (!elfData) {
|
||||
error = -EIO; // FIXME: Get a more detailed error from VFS.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
InterruptDisabler disabler; // FIXME: Get rid of this, jesus christ. This "critical" section is HUGE.
|
||||
Task* t = new Task(parts.takeLast(), uid, gid, parentPID, Ring3);
|
||||
|
@ -203,12 +211,14 @@ Task* Task::createUserTask(const String& path, uid_t uid, gid_t gid, pid_t paren
|
|||
if (!success) {
|
||||
delete t;
|
||||
kprintf("Failure loading ELF %s\n", path.characters());
|
||||
error = -ENOEXEC;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
t->m_tss.eip = (dword)space.symbolPtr("_start");
|
||||
if (!t->m_tss.eip) {
|
||||
delete t;
|
||||
error = -ENOEXEC;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -221,6 +231,7 @@ Task* Task::createUserTask(const String& path, uid_t uid, gid_t gid, pid_t paren
|
|||
kprintf("Task %u (%s) spawned @ %p\n", t->pid(), t->name().characters(), t->m_tss.eip);
|
||||
#endif
|
||||
|
||||
error = 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -758,11 +769,6 @@ Task* Task::kernelTask()
|
|||
return s_kernelTask;
|
||||
}
|
||||
|
||||
void Task::setError(int error)
|
||||
{
|
||||
m_error = error;
|
||||
}
|
||||
|
||||
Task::Region::Region(LinearAddress a, size_t s, RetainPtr<Zone>&& z, String&& n)
|
||||
: linearAddress(a)
|
||||
, size(s)
|
||||
|
|
|
@ -16,7 +16,7 @@ class Task : public InlineLinkedListNode<Task> {
|
|||
friend class InlineLinkedListNode<Task>;
|
||||
public:
|
||||
static Task* createKernelTask(void (*entry)(), String&& name);
|
||||
static Task* createUserTask(const String& path, uid_t, gid_t, pid_t parentPID);
|
||||
static Task* createUserTask(const String& path, uid_t, gid_t, pid_t parentPID, int& error);
|
||||
~Task();
|
||||
|
||||
static Vector<Task*> allTasks();
|
||||
|
@ -100,7 +100,6 @@ public:
|
|||
int sys$getcwd(char*, size_t);
|
||||
|
||||
static void initialize();
|
||||
void setError(int);
|
||||
|
||||
static void taskDidCrash(Task*);
|
||||
|
||||
|
|
Binary file not shown.
38
Kernel/errno.h
Normal file
38
Kernel/errno.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#define EPERM 1 // Operation not permitted
|
||||
#define ENOENT 2 // No such file or directory
|
||||
#define ESRCH 3 // No such process
|
||||
#define EINTR 4 // Interrupted system call
|
||||
#define EIO 5 // I/O error
|
||||
#define ENXIO 6 // No such device or address
|
||||
#define E2BIG 7 // Argument list too long
|
||||
#define ENOEXEC 8 // Exec format error
|
||||
#define EBADF 9 // Bad file number
|
||||
#define ECHILD 10 // No child processes
|
||||
#define EAGAIN 11 // Try again
|
||||
#define ENOMEM 12 // Out of memory
|
||||
#define EACCES 13 // Permission denied
|
||||
#define EFAULT 14 // Bad address
|
||||
#define ENOTBLK 15 // Block device required
|
||||
#define EBUSY 16 // Device or resource busy
|
||||
#define EEXIST 17 // File exists
|
||||
#define EXDEV 18 // Cross-device link
|
||||
#define ENODEV 19 // No such device
|
||||
#define ENOTDIR 20 // Not a directory
|
||||
#define EISDIR 21 // Is a directory
|
||||
#define EINVAL 22 // Invalid argument
|
||||
#define ENFILE 23 // File table overflow
|
||||
#define EMFILE 24 // Too many open files
|
||||
#define ENOTTY 25 // Not a typewriter
|
||||
#define ETXTBSY 26 // Text file busy
|
||||
#define EFBIG 27 // File too large
|
||||
#define ENOSPC 28 // No space left on device
|
||||
#define ESPIPE 29 // Illegal seek
|
||||
#define EROFS 30 // Read-only file system
|
||||
#define EMLINK 31 // Too many links
|
||||
#define EPIPE 32 // Broken pipe
|
||||
#define EDOM 33 // Math argument out of domain of func
|
||||
#define ERANGE 34 // Math result not representable
|
||||
|
||||
#define EOVERFLOW 75 // Value too large for defined data type
|
|
@ -140,7 +140,8 @@ static void init_stage2()
|
|||
dword lastAlloc = sum_alloc;
|
||||
|
||||
for (unsigned i = 0; i < 100; ++i) {
|
||||
auto* shTask = Task::createUserTask("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0);
|
||||
int error;
|
||||
auto* shTask = Task::createUserTask("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error);
|
||||
kprintf("malloc stats: alloc:%u free:%u\n", sum_alloc, sum_free);
|
||||
kprintf("sizeof(Task):%u\n", sizeof(Task));
|
||||
kprintf("delta:%u\n",sum_alloc - lastAlloc);
|
||||
|
@ -149,7 +150,8 @@ static void init_stage2()
|
|||
}
|
||||
#endif
|
||||
|
||||
auto* shTask = Task::createUserTask("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0);
|
||||
int error;
|
||||
auto* shTask = Task::createUserTask("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error);
|
||||
|
||||
banner();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue