20 #include "pedigree/kernel/Log.h"    21 #include <PosixSubsystem.h>    23 #include "pedigree/kernel/process/PerProcessorScheduler.h"    24 #include "pedigree/kernel/process/Scheduler.h"    25 #include "pedigree/kernel/process/SignalEvent.h"    26 #include "pedigree/kernel/process/Thread.h"    27 #include "pedigree/kernel/process/Uninterruptible.h"    28 #include "pedigree/kernel/processor/PhysicalMemoryManager.h"    29 #include "pedigree/kernel/processor/Processor.h"    30 #include "pedigree/kernel/processor/state.h"    31 #include "pedigree/kernel/processor/types.h"    32 #include "pedigree/kernel/syscallError.h"    34 #include "pedigree/kernel/LockGuard.h"    36 #include "pedigree/kernel/utilities/Tree.h"    38 #include "pedigree/kernel/utilities/assert.h"    40 #include "FileDescriptor.h"    41 #include "PosixProcess.h"    44 #include "modules/system/linker/DynamicLinker.h"    45 #include "modules/system/vfs/File.h"    46 #include "modules/system/vfs/LockedFile.h"    48 #include "modules/system/vfs/Symlink.h"    49 #include "modules/system/vfs/VFS.h"    50 #include "pedigree/kernel/linker/Elf.h"    52 #include "file-syscalls.h"    58 extern char __posix_compat_vsyscall_base;
    60 #define POSIX_VSYSCALL_ADDRESS 0xffffffffff600000    73 extern void pedigree_init_sigret();
    74 extern void pedigree_init_pthreads();
    76 ProcessGroupManager::ProcessGroupManager() : m_GroupIds()
    81 ProcessGroupManager::~ProcessGroupManager()
    87     size_t bit = m_GroupIds.getFirstClear();
    94     if (m_GroupIds.test(gid))
    96         PS_NOTICE(
"ProcessGroupManager: setGroupId called on a group ID that "   104     return m_GroupIds.test(gid);
   109     m_GroupIds.clear(gid);
   113     : 
Subsystem(s), m_SignalHandlers(), m_SignalHandlersLock(), m_FdMap(),
   114       m_NextFd(s.m_NextFd), m_FdLock(), m_FdBitmap(), m_LastFd(0),
   115       m_FreeCount(s.m_FreeCount), m_AltSigStack(), m_SyncObjects(), 
m_Threads(),
   116       m_ThreadWaiters(), m_NextThreadWaiter(1)
   127         size_t key = it.key();
   128         void *value = it.value();
   133             new SignalHandler(*reinterpret_cast<SignalHandler *>(value));
   144         void *key = it.key();
   150     m_NextThreadWaiter = s.m_NextThreadWaiter;
   192                 "PosixSubsystem object freed when a thread is still running?");
   225                 delete reinterpret_cast<Mutex *
>(p->pObject);
   227                 delete reinterpret_cast<Semaphore *
>(p->pObject);
   319 #ifdef POSIX_NO_EFAULT   325 #ifdef VERBOSE_KERNEL   327         "PosixSubsystem::checkAddress(" << 
Hex << addr << 
", " << 
Dec << extent
   328                                         << 
", " << 
Hex << flags << 
")");
   334 #ifdef VERBOSE_KERNEL   335         PS_NOTICE(
"  -> zero extent, address is sane.");
   340     uintptr_t aa = 
reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
   341 #ifdef VERBOSE_KERNEL   342     PS_NOTICE(
" -> ret: " << aa);
   349 #ifdef VERBOSE_KERNEL   350         PS_NOTICE(
"  -> outside of user address area.");
   358 #ifdef VERBOSE_KERNEL   359         PS_NOTICE(
"  -> inside memory map.");
   367         void *pAddr = 
reinterpret_cast<void *
>(addr + i);
   370 #ifdef VERBOSE_KERNEL   371             PS_NOTICE(
"  -> page " << 
Hex << pAddr << 
" is not mapped.");
   376         if (flags & SafeWrite)
   379             physical_uintptr_t phys = 0;
   385 #ifdef VERBOSE_KERNEL   386                 PS_NOTICE(
"  -> not writeable.");
   393 #ifdef VERBOSE_KERNEL   394     PS_NOTICE(
"  -> mapped and available.");
   405         "PosixSubsystem::exit(" << 
Dec << pProcess->
getId() << 
", code=" << code
   407     pProcess->markTerminating();
   436         while (pBlockingThread)
   439             pBlockingThread = pBlockingThread->getBlockingThread();
   448     delete pProcess->getLinker();
   453     if (pProcess->
getType() == Process::Posix)
   489     if (pParent && pParent->getSubsystem())
   500         " -> file lookup LRU cache had "   507     FATAL(
"PosixSubsystem::exit() running after Process::kill()!");
   515     if (pProcess->
getType() != Process::Posix)
   517         ERROR(
"PosixSubsystem::kill called with a non-POSIX process!");
   542         PS_NOTICE(
"PosixSubsystem - killing " << pThread->
getParent()->
getId());
   559         "PosixSubsystem::threadException -> "   567             PS_NOTICE(
"    (Page fault)");
   572             PS_NOTICE(
"    (Invalid opcode)");
   576         case GeneralProtectionFault:
   577             PS_NOTICE(
"    (General Fault)");
   582             PS_NOTICE(
"    (Division by zero)");
   587             PS_NOTICE(
"    (FPU error)");
   591         case SpecialFpuError:
   592             PS_NOTICE(
"    (FPU error - special)");
   597             PS_NOTICE(
"    (Attempt to read from terminal by non-foreground "   603             PS_NOTICE(
"    (Output to terminal by non-foreground process)");
   608             PS_NOTICE(
"    (Continuing a stopped process)");
   613             PS_NOTICE(
"    (Stopping a process)");
   618             PS_NOTICE(
"    (Interrupting a process)");
   623             PS_NOTICE(
"    (Requesting quit)");
   628             PS_NOTICE(
"    (Child status changed)");
   633             PS_NOTICE(
"    (Pipe broken)");
   638             PS_NOTICE(
"    (Unknown)");
   641                 "Unknown exception type in threadException - POSIX subsystem");
   651         "PosixSubsystem::sendSignal #" << signal << 
" -> pid:tid " << 
Dec   653                                        << pThread->
getId());
   656     if (pProcess->getType() != Process::Posix)
   659             "PosixSubsystem::threadException called with a non-POSIX process!");
   669         ERROR(
"Unknown signal in sendSignal - POSIX subsystem");
   680             WARNING(
"PosixSubsystem::sendSignal dropping signal as a previous "   681                     "generation has not delivered yet.");
   691                 if (pCurrentThread == pThread)
   709             "No event configured for signal #" << signal
   710                                                << 
", silently dropping!");
   776     size_t ret = m_NextFd++;
   842         size_t newFd = it.key();
   861     bool bOnlyCloExec, 
size_t iFirst, 
size_t iLast)
   875     bool bAllToBeFreed = ((iFirst == 0 && iLast == ~0UL) && !bOnlyCloExec);
   882         size_t Fd = it.key();
   887         if (!(Fd >= iFirst && Fd <= iLast))
   892             if (!(pFd->
fdflags & FD_CLOEXEC))
   906             fdsToRemove.
pushBack(reinterpret_cast<void *>(Fd));
   924              it != fdsToRemove.
end(); it++)
   971         if (thread->pThread != pThread)
   983 bool PosixSubsystem::checkAccess(
   991     File *pFile, uintptr_t mappedAddress, uintptr_t &newAddress,
   992     uintptr_t &finalAddress, 
bool &relocated)
   994     PS_NOTICE(
"PosixSubsystem::loadElf(" << pFile->
getName() << 
")");
  1002     if ((pHeader->ident[1] != 
'E') || (pHeader->ident[2] != 
'L') ||
  1003         (pHeader->ident[3] != 
'F') || (pHeader->ident[0] != 127))
  1008     size_t phnum = pHeader->phnum;
  1011             mappedAddress + pHeader->phoff);
  1014     uintptr_t startAddress = ~0U;
  1015     uintptr_t unalignedStartAddress = 0;
  1016     uintptr_t endAddress = 0;
  1017     for (
size_t i = 0; i < phnum; ++i)
  1019         if (phdrs[i].type != PT_LOAD)
  1024         if (phdrs[i].vaddr < startAddress)
  1026             startAddress = phdrs[i].vaddr;
  1029         uintptr_t maybeEndAddress = phdrs[i].vaddr + phdrs[i].memsz;
  1030         if (maybeEndAddress > endAddress)
  1032             endAddress = maybeEndAddress;
  1038     unalignedStartAddress = startAddress;
  1039     startAddress &= ~(pageSz - 1);
  1040     if (endAddress & (pageSz - 1))
  1042         endAddress = (endAddress + pageSz) & ~(pageSz - 1);
  1046     bool bRelocated = 
false;
  1047     if (pHeader->type == ET_REL || pHeader->type == ET_DYN)
  1049         if (!pProcess->getDynamicSpaceAllocator().allocate(
  1050                 endAddress - startAddress, newAddress))
  1051             if (!pProcess->getSpaceAllocator().allocate(
  1052                     endAddress - startAddress, newAddress))
  1056         unalignedStartAddress = newAddress + (startAddress & (pageSz - 1));
  1057         startAddress = newAddress;
  1059         newAddress = unalignedStartAddress;
  1065         if (!pProcess->getDynamicSpaceAllocator().allocateSpecific(
  1066                 startAddress, endAddress - startAddress))
  1067             if (!pProcess->getSpaceAllocator().allocateSpecific(
  1068                     startAddress, endAddress - startAddress))
  1071         newAddress = unalignedStartAddress;
  1074     finalAddress = startAddress + (endAddress - startAddress);
  1077     for (
size_t i = 0; i < phnum; ++i)
  1079         if (phdrs[i].type != PT_LOAD)
  1084         uintptr_t base = phdrs[i].vaddr;
  1087             base += startAddress;
  1089         uintptr_t unalignedBase = base;
  1090         if (base & (pageSz - 1))
  1092             base &= ~(pageSz - 1);
  1095         uintptr_t offset = phdrs[i].offset;
  1096         if (offset & (pageSz - 1))
  1098             offset &= ~(pageSz - 1);
  1104         size_t length = phdrs[i].memsz + (unalignedBase & (pageSz - 1));
  1105         if (length & (pageSz - 1))
  1107             length = (length + pageSz) & ~(pageSz - 1);
  1112         if (phdrs[i].flags & PF_X)
  1114             perms |= MemoryMappedObject::Exec;
  1116         if (phdrs[i].flags & PF_R)
  1118             perms |= MemoryMappedObject::Read;
  1120         if (phdrs[i].flags & PF_W)
  1122             perms |= MemoryMappedObject::Write;
  1126             pFile->
getName() << 
" PHDR[" << i << 
"]: @" << 
Hex << base << 
" -> "  1129             pFile, base, length, perms, offset);
  1132             ERROR(
"PosixSubsystem::loadElf: failed to map PT_LOAD section");
  1136         if (phdrs[i].memsz > phdrs[i].filesz)
  1138             uintptr_t end = unalignedBase + phdrs[i].memsz;
  1139             uintptr_t zeroStart = unalignedBase + phdrs[i].filesz;
  1140             if (zeroStart & (pageSz - 1))
  1142                 size_t numBytes = pageSz - (zeroStart & (pageSz - 1));
  1143                 if ((zeroStart + numBytes) > end)
  1145                     numBytes = end - zeroStart;
  1147                 ByteSet(reinterpret_cast<void *>(zeroStart), 0, numBytes);
  1148                 zeroStart += numBytes;
  1151             if (zeroStart < end)
  1155                         zeroStart, end - zeroStart, perms);
  1156                 if (!pAnonymousRegion)
  1158                     ERROR(
"PosixSubsystem::loadElf: failed to map anonymous "  1159                           "pages for filesz/memsz mismatch");
  1171     if (workingDir == 
nullptr)
  1174         workingDir = m_pProcess->
getCwd();
  1177     bool mountAwareAbi = 
getAbi() != PosixSubsystem::LinuxAbi;
  1182     if (mountAwareAbi || (path[0] != 
'/'))
  1190     File *target = 
nullptr;
  1213 #define STACK_PUSH(stack, value) *--stack = value  1214 #define STACK_PUSH2(stack, value1, value2) \  1215     STACK_PUSH(stack, value1);             \  1216     STACK_PUSH(stack, value2)  1217 #define STACK_PUSH_COPY(stack, value, length) \  1218     stack = adjust_pointer(stack, -(length)); \  1219     MemoryCopy(stack, value, length)  1220 #define STACK_PUSH_STRING(stack, str, length) \  1221     stack = adjust_pointer(stack, -(length)); \  1222     StringCopyN(reinterpret_cast<char *>(stack), str, length)  1223 #define STACK_PUSH_ZEROES(stack, length)      \  1224     stack = adjust_pointer(stack, -(length)); \  1225     ByteSet(stack, 0, length)  1226 #define STACK_ALIGN(stack, to) \  1227     STACK_PUSH_ZEROES(         \  1229         (to) - ((to) - (reinterpret_cast<uintptr_t>(stack) & ((to) -1))))  1234     return invoke(name, argv, env, 0);
  1239     SyscallState &state)
  1241     return invoke(name, argv, env, &state);
  1247     PS_NOTICE(
"Attempting to parse shebang in " << pFile->
getFullPath());
  1252     bool bSearchDone = 
false;
  1254     while (!bSearchDone)
  1258             pFile->
read(offset, 128, reinterpret_cast<uintptr_t>(buff));
  1266             char *newline = 
const_cast<char *
>(StringFind(buff, 
'\n'));
  1272             fileContents += 
String(buff);
  1283     if (!fileContents.startswith(
"#!"))
  1285         PS_NOTICE(
"no shebang found");
  1290     fileContents.lchomp();
  1291     fileContents.lchomp();
  1295     if (!additionalArgv.
count())
  1298         PS_NOTICE(
"split didn't find anything");
  1305     if (normalisePath(invokePath, static_cast<const char *>(newTarget)))
  1308         newTarget = invokePath;
  1312     File *pNewTarget = findFileWithAbiFallbacks(newTarget);
  1316         PS_NOTICE(
"target not found");
  1317         SYSCALL_ERROR(DoesNotExist);
  1323     while (additionalArgv.
count())
  1328     pOutFile = pNewTarget;
  1333 static File *traverseForInvoke(
File *pFile)
  1342         PS_NOTICE(
"PosixSubsystem::invoke: symlink traversal failed");
  1343         SYSCALL_ERROR(DoesNotExist);
  1350         PS_NOTICE(
"PosixSubsystem::invoke: target is a directory");
  1351         SYSCALL_ERROR(IsADirectory);
  1360         SyscallState *state)
  1363     String originalName(name);
  1366     File *originalFile = findFileWithAbiFallbacks(originalName);
  1370             "PosixSubsystem::invoke: could not find file '" << originalName << 
"'");
  1371         SYSCALL_ERROR(DoesNotExist);
  1375     return invoke(originalFile, originalName, argv, env, state);
  1382     return invoke(originalFile, originalName, argv, env, 0);
  1389     return invoke(originalFile, originalName, argv, env, &state);
  1396     PS_NOTICE(
"PosixSubsystem::invoke(" << originalName << 
")");
  1410         PS_NOTICE(
"invoke attempted with multiple threads in this process");
  1414     originalFile = traverseForInvoke(originalFile);
  1421     uint8_t validateBuffer[128];
  1423         originalFile->
read(0, 128, reinterpret_cast<uintptr_t>(validateBuffer));
  1425     Elf *validElf = 
new Elf();
  1426     if (!validElf->
validate(validateBuffer, nBytes))
  1429             "PosixSubsystem::invoke: '"  1430             << originalFile->
getName() << 
"' is not an ELF binary, looking for shebang...");
  1432         File *shebangFile = 0;
  1436                 "PosixSubsystem::invoke: failed to parse shebang line in '"  1437                 << originalFile->
getName() << 
"'");
  1445             originalFile = shebangFile;
  1448             originalFile = traverseForInvoke(originalFile);
  1463     File *interpreterFile = 0;
  1466     for (
int sig = 0; sig < 32; sig++)
  1472     pProcess->setLinker(pLinker);
  1476         interpreterFile = findFileWithAbiFallbacks(interpreter);
  1477         interpreterFile = traverseForInvoke(interpreterFile);
  1478         if (!interpreterFile)
  1481                 "PosixSubsystem::invoke: could not find interpreter '"  1482                 << interpreter << 
"'");
  1483             SYSCALL_ERROR(ExecFormatError);
  1491         interpreterFile = originalFile;
  1497     pProcess->setLinker(pLinker);
  1519     uintptr_t originalBase = 0, interpreterBase = 0;
  1521                                             MemoryMappedObject::Write |
  1522                                             MemoryMappedObject::Exec;
  1524         originalFile, originalBase, originalFile->getSize(), perms);
  1527         PS_NOTICE(
"PosixSubsystem::invoke: failed to map target");
  1528         SYSCALL_ERROR(OutOfMemory);
  1533         interpreterFile, interpreterBase, interpreterFile->getSize(), perms);
  1536         PS_NOTICE(
"PosixSubsystem::invoke: failed to map interpreter");
  1538         SYSCALL_ERROR(OutOfMemory);
  1543     uintptr_t originalLoadedAddress = 0;
  1544     uintptr_t originalFinalAddress = 0;
  1545     bool originalRelocated = 
false;
  1547             originalFile, originalBase, originalLoadedAddress,
  1548             originalFinalAddress, originalRelocated))
  1551         PS_NOTICE(
"PosixSubsystem::invoke: failed to load target");
  1552         SYSCALL_ERROR(ExecFormatError);
  1557     uintptr_t interpreterLoadedAddress = 0;
  1558     uintptr_t interpreterFinalAddress = 0;
  1559     bool interpreterRelocated = 
false;
  1561             interpreterFile, interpreterBase, interpreterLoadedAddress,
  1562             interpreterFinalAddress, interpreterRelocated))
  1565         PS_NOTICE(
"PosixSubsystem::invoke: failed to load interpreter");
  1566         SYSCALL_ERROR(ExecFormatError);
  1571     uintptr_t originalEntryPoint = 0, interpreterEntryPoint = 0;
  1573         reinterpret_cast<uint8_t *>(originalBase), originalFile->getSize(),
  1574         originalEntryPoint);
  1576         reinterpret_cast<uint8_t *>(interpreterBase),
  1577         interpreterFile->getSize(), interpreterEntryPoint);
  1579     if (originalRelocated)
  1581         originalEntryPoint += originalLoadedAddress;
  1583     if (interpreterRelocated)
  1585         interpreterEntryPoint += interpreterLoadedAddress;
  1594     pProcess->resetCounts();
  1601     if (pProcess->
getType() == Process::Posix)
  1605         p->setSavedUserId(p->getEffectiveUserId());
  1606         p->setSavedGroupId(p->getEffectiveGroupId());
  1611                                                 MemoryMappedObject::Write |
  1612                                                 MemoryMappedObject::Exec;
  1613     uintptr_t vdsoAddress = 0;
  1619         PS_NOTICE(
"PosixSubsystem::invoke: failed to map VDSO");
  1625             reinterpret_cast<void *>(vdsoAddress), __vdso_so, __vdso_so_len);
  1631             vdsoPerms & ~MemoryMappedObject::Write);
  1636             reinterpret_cast<void *>(POSIX_VSYSCALL_ADDRESS)))
  1638         physical_uintptr_t vsyscallBase = 0;
  1639         size_t vsyscallFlags = 0;
  1641             &__posix_compat_vsyscall_base, vsyscallBase, vsyscallFlags);
  1643             vsyscallBase, reinterpret_cast<void *>(POSIX_VSYSCALL_ADDRESS),
  1650     uintptr_t *loaderStack = 
reinterpret_cast<uintptr_t *
>(stack->getTop());
  1653     STACK_PUSH(loaderStack, 0);
  1656     STACK_ALIGN(loaderStack, 16);
  1659     char **envs = 
new char *[env.
count()];
  1661     for (
size_t i = 0; i < env.
count(); ++i)
  1665             loaderStack, static_cast<const char *>(str), str.length() + 1);
  1666         PS_NOTICE(
"env[" << envc << 
"]: " << str);
  1667         envs[envc++] = 
reinterpret_cast<char *
>(loaderStack);
  1671     STACK_ALIGN(loaderStack, 16);
  1673     char **argvs = 
new char *[argv.
count()];
  1675     for (
size_t i = 0; i < argv.
count(); ++i)
  1679             loaderStack, static_cast<const char *>(str), str.length() + 1);
  1680         PS_NOTICE(
"argv[" << argc << 
"]: " << str);
  1681         argvs[argc++] = 
reinterpret_cast<char *
>(loaderStack);
  1685     STACK_ALIGN(loaderStack, 16);
  1688     STACK_PUSH_STRING(loaderStack, 
"x86_64", 7);
  1689     void *platform = loaderStack;
  1691     STACK_PUSH_STRING(loaderStack, originalName, originalName.length() + 1);
  1692     void *execfn = loaderStack;
  1695     STACK_ALIGN(loaderStack, 16);
  1698     STACK_PUSH_ZEROES(loaderStack, 16);
  1699     void *random = loaderStack;
  1702     if (((argc + envc) % 2) == 0)
  1704         STACK_PUSH_ZEROES(loaderStack, 8);
  1708     STACK_PUSH2(loaderStack, 0, 0);  
  1710         loaderStack, reinterpret_cast<uintptr_t>(platform), 15);  
  1712         loaderStack, reinterpret_cast<uintptr_t>(random), 25);  
  1713     STACK_PUSH2(loaderStack, 0, 23);
  1714     STACK_PUSH2(loaderStack, pProcess->
getUserId(), 14);            
  1715     STACK_PUSH2(loaderStack, pProcess->getGroupId(), 13);           
  1716     STACK_PUSH2(loaderStack, pProcess->getEffectiveUserId(), 12);   
  1717     STACK_PUSH2(loaderStack, pProcess->getEffectiveGroupId(), 11);  
  1719         loaderStack, reinterpret_cast<uintptr_t>(execfn), 31);  
  1724         STACK_PUSH2(loaderStack, 0, 32);            
  1725         STACK_PUSH2(loaderStack, vdsoAddress, 33);  
  1729     STACK_PUSH2(loaderStack, originalEntryPoint, 9);        
  1730     STACK_PUSH2(loaderStack, interpreterLoadedAddress, 7);  
  1733     STACK_PUSH2(loaderStack, originalHeader->phnum, 5);         
  1734     STACK_PUSH2(loaderStack, originalHeader->phentsize, 4);     
  1736         loaderStack, originalLoadedAddress + originalHeader->phoff,
  1740     STACK_PUSH(loaderStack, 0);  
  1741     for (
size_t i = 0; i < envc; ++i)
  1743         STACK_PUSH(loaderStack, reinterpret_cast<uintptr_t>(envs[i]));
  1747     STACK_PUSH(loaderStack, 0);  
  1748     for (ssize_t i = argc - 1; i >= 0; --i)
  1750         STACK_PUSH(loaderStack, reinterpret_cast<uintptr_t>(argvs[i]));
  1754     STACK_PUSH(loaderStack, argc);
  1760     pInterpreter = pOriginal = 0;
  1763     pedigree_init_sigret();
  1774             reinterpret_cast<Thread::ThreadStartFunc>(interpreterEntryPoint), 0,
  1784         ByteSet(&s, 0, 
sizeof(s));
  1785         pThread->
state() = s;
  1788         for (
int sig = 0; sig < 32; sig++)
  1796             0, interpreterEntryPoint, reinterpret_cast<uintptr_t>(loaderStack));
 void store(const K &key, const T &object)
virtual bool kill(KillReason killReason, Thread *pThread)
virtual ~PosixSubsystem()
File * find(const String &path, File *pStartNode=0)
void pushBack(const T &value)
static size_t getPageSize() PURE
Tree< size_t, PosixThreadKey * > m_ThreadData
void popState(bool clean=true)
Iterator erase(Iterator &Iter)
Thread * m_pAcquiredThread
virtual void getMapping(void *virtualAddress, physical_uintptr_t &physicalAddress, size_t &flags)=0
void freeFd(size_t fdNum)
A vector / dynamic array. 
virtual bool invoke(const char *name, Vector< String > &argv, Vector< String > &env)
Tree< size_t, FileDescriptor * > m_FdMap
int followLink(char *pBuffer, size_t bufLen)
MemoryMappedObject * mapAnon(uintptr_t &address, size_t length, MemoryMappedObject::Permissions perms)
virtual uintptr_t getUserStart() const =0
ExtensibleBitmap m_FdBitmap
virtual bool isMapped(void *virtualAddress)=0
bool copyDescriptors(PosixSubsystem *pSubsystem)
static const size_t Execute
virtual uintptr_t getUserReservedStart() const =0
void freeMultipleFds(bool bOnlyCloExec=false, size_t iFirst=0, size_t iLast=-1)
virtual int64_t getUserId() const 
size_t getStateLevel() const 
Tree< size_t, PosixThread * > m_Threads
void setUnwindState(UnwindType ut)
bool acquire(bool recurse=false, bool safe=true)
Tree< void *, Semaphore * > m_ThreadWaiters
Filesystem * lookupFilesystem(const String &alias)
virtual uintptr_t getKernelStart() const =0
virtual void threadException(Thread *pThread, ExceptionType eType)
void free(T address, T length, bool merge=true)
static ProcessorInformation & information()
void addFileDescriptor(size_t fd, FileDescriptor *pFd)
static void switchAddressSpace(VirtualAddressSpace &AddressSpace)
void setGroupId(size_t gid)
File * file
Our open file pointer. 
bool test(size_t n) const 
void unmap(MemoryMappedObject *pObj)
Tree< size_t, SignalHandler * > m_SignalHandlers
Tree< size_t, PosixSyncObject * > m_SyncObjects
size_t setPermissions(uintptr_t base, size_t length, MemoryMappedObject::Permissions perms)
bool hasEvent(Event *pEvent)
static bool checkAddress(uintptr_t addr, size_t extent, size_t flags)
Vector< Thread * > m_Threads
static bool extractEntryPoint(uint8_t *pBuffer, size_t length, uintptr_t &entry)
static const size_t Write
bool sendEvent(Event *pEvent)
void insert(const K &key, const E &value)
SignalHandler * getSignalHandler(size_t sig)
void exit(int code) NORETURN
Memory-mapped file interface. 
void allocateFd(size_t fdNum)
MemoryAllocator & getDynamicSpaceAllocator()
LruCache< String, File * > m_FindFileCache
LRU cache for file lookups. Many usage patterns involve something like a stat() immediately followed ...
SignalEvent * pEvent
Event for the signal handler. 
virtual String getFullPath(bool bWithLabel=true)
void setExitStatus(int code)
static void jumpUser(volatile uintptr_t *pLock, uintptr_t address, uintptr_t stack, uintptr_t p1=0, uintptr_t p2=0, uintptr_t p3=0, uintptr_t p4=0) NORETURN
static MemoryMapManager & instance()
void recordTime(bool bUserspace)
static Scheduler & instance()
virtual uintptr_t getDynamicEnd() const 
static void setInterrupts(bool bEnable)
MemoryMappedObject * mapFile(File *pFile, uintptr_t &address, size_t length, MemoryMappedObject::Permissions perms, size_t offset=0, bool bCopyOnWrite=true)
virtual uintptr_t getDynamicStart() const 
virtual uint64_t read(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
static Symlink * fromFile(File *pF)
Thread * getThread(size_t n)
Process * getParent() const 
void pushFront(const T &value)
List< PosixProcess * > Members
UnlikelyLock m_SignalHandlersLock
void setSignalHandler(size_t sig, SignalHandler *handler)
virtual void threadRemoved(Thread *pThread)
VirtualAddressSpace * getAddressSpace()
bool parseShebang(File *pFile, File *&outFile, Vector< String > &argv)
int fdflags
File descriptor flags (fcntl) 
void returnGroupId(size_t gid)
LargeStaticString & description()
virtual ProcessType getType()
virtual void revertToKernelAddressSpace()=0
bool loadElf(File *pFile, uintptr_t mappedAddress, uintptr_t &newAddress, uintptr_t &finalAddress, bool &relocated)
FileDescriptor * getFileDescriptor(size_t fd)
virtual bool isDirectory()
bool validate(uint8_t *pBuffer, size_t length)
void remove(const K &key)
virtual void sendSignal(Thread *pThread, int signal, bool yield=true)
An iterator applicable for many data structures. 
bool tryAcquire(size_t n=1)
bool checkInterpreter(File *pFile, String &actualFilename)
virtual void acquire()
Acquire full mutual exclusion for all Subsystem resources. 
bool get(const K &key, T &object)
virtual File * findFile(const String &path, File *workingDir)
E lookup(const K &key) const 
bool isGroupIdValid(size_t gid) const 
static bool checkAccess(File *pFile, bool bRead, bool bWrite, bool bExecute)
static const size_t CopyOnWrite
MemoryAllocator & getSpaceAllocator()
Implements a Radix Tree, a kind of Trie with compressed keys. 
virtual void threadException(Thread *pThread, ExceptionType eType)
virtual File * getRoot() const =0