The Pedigree Project 0.1
module-syscalls.cc
1/* Copyright (c) 2026, Pedigree Developers. */
2#include "module-syscalls.h"
3#include "pedigree/kernel/linker/KernelElf.h"
4#include "pedigree/kernel/process/Process.h"
5#include "pedigree/kernel/process/Thread.h"
6#include "pedigree/kernel/process/Uninterruptible.h"
7#include "pedigree/kernel/processor/Processor.h"
8#include "pedigree/kernel/processor/ProcessorInformation.h"
9#include "pedigree/kernel/syscallError.h"
10
11#include "PosixSubsystem.h"
12#include "user-namespace.h"
13
14int posix_delete_module(const char* name, unsigned int flags) {
15 Uninterruptible lifetime;
16 Thread* thread = Processor::information().getCurrentThread();
17 if (!posix_global_capable(16)) {
18 SYSCALL_ERROR(NotEnoughPermissions);
19 return -1;
20 }
21 constexpr unsigned int nonblocking = 0x800;
22 constexpr unsigned int force = 0x200;
23 if (flags & ~(nonblocking | force)) {
24 SYSCALL_ERROR(InvalidArgument);
25 return -1;
26 }
27 if (flags & force) {
28 SYSCALL_ERROR(OperationNotSupported);
29 return -1;
30 }
31 // Linux includes the terminator in MODULE_NAME_LEN.
32 constexpr size_t nameBytes = 64 - sizeof(unsigned long);
33 String copiedName;
34 const auto copied = PosixSubsystem::copyUserString(name, copiedName, nameBytes);
35 if (copied != PosixSubsystem::UserStringSuccess) {
36 syscallError(copied == PosixSubsystem::UserStringTooLong ? Error::DoesNotExist
37 : Error::BadAddress);
38 return -1;
39 }
40 if (!copiedName.length()) {
41 SYSCALL_ERROR(DoesNotExist);
42 return -1;
43 }
44
45 using Result = KernelElf::RuntimeUnloadResult;
46 const auto result = KernelElf::instance().unloadModuleRuntime(copiedName.cstr());
47 switch (result) {
48 case Result::Unloaded:
49 // Module cleanup may use kernel interfaces which set the caller's errno.
50 thread->setErrno(0);
51 return 0;
52 case Result::NotFound:
53 SYSCALL_ERROR(DoesNotExist);
54 break;
55 case Result::Busy:
56 case Result::Pinned:
57 SYSCALL_ERROR(DeviceBusy);
58 break;
59 case Result::DependedOn:
60 SYSCALL_ERROR(NoMoreProcesses);
61 break;
62 case Result::Shutdown:
63 SYSCALL_ERROR(NotEnoughPermissions);
64 break;
65 }
66 return -1;
67}
static KernelElf & instance()
Definition KernelElf.h:135
RuntimeUnloadResult unloadModuleRuntime(const char *name)
Definition KernelElf.cc:960
static UserStringResult copyUserString(const char *userString, String &copy, size_t maxLength)
static ProcessorInformation & information()
void setErrno(size_t err)
Definition Thread.h:482