20 #include "system-syscalls.h"    21 #include "file-syscalls.h"    22 #include "modules/system/linker/DynamicLinker.h"    23 #include "modules/system/vfs/File.h"    24 #include "modules/system/vfs/Symlink.h"    25 #include "modules/system/vfs/VFS.h"    26 #include "pedigree/kernel/Log.h"    27 #include "pedigree/kernel/Version.h"    28 #include "pedigree/kernel/compiler.h"    29 #include "pedigree/kernel/linker/Elf.h"    30 #include "pedigree/kernel/linker/KernelElf.h"    31 #include "pedigree/kernel/panic.h"    32 #include "pedigree/kernel/process/PerProcessorScheduler.h"    33 #include "pedigree/kernel/process/Process.h"    34 #include "pedigree/kernel/process/Scheduler.h"    35 #include "pedigree/kernel/process/Thread.h"    36 #include "pedigree/kernel/processor/PhysicalMemoryManager.h"    37 #include "pedigree/kernel/processor/Processor.h"    38 #include "pedigree/kernel/processor/StackFrame.h"    39 #include "pedigree/kernel/processor/VirtualAddressSpace.h"    40 #include "pedigree/kernel/processor/state.h"    41 #include "pedigree/kernel/processor/types.h"    42 #include "pedigree/kernel/syscallError.h"    43 #include "pedigree/kernel/utilities/String.h"    44 #include "pedigree/kernel/utilities/Vector.h"    45 #include "pipe-syscalls.h"    46 #include "posixSyscallNumbers.h"    47 #include "pthread-syscalls.h"    48 #include "signal-syscalls.h"    50 #define MACHINE_FORWARD_DECL_ONLY    51 #include "pedigree/kernel/machine/Machine.h"    52 #include "pedigree/kernel/machine/Timer.h"    54 #include "pedigree/kernel/Subsystem.h"    55 #include <PosixProcess.h>    56 #include <PosixSubsystem.h>    58 #include "modules/system/console/Console.h"    59 #include "modules/system/users/Group.h"    60 #include "modules/system/users/User.h"    61 #include "modules/system/users/UserManager.h"    68 #include <sys/resource.h>    69 #include <sys/times.h>    70 #include <sys/utsname.h>    75 #define ARCH_SET_FS 0x1002    76 #define ARCH_GET_FS 0x1003    79 #define _LINUX_CAPABILITY_VERSION_1 0x19980330    99     (Processor::information().getCurrentThread()->getParent()->getCwd())   106     if (pStockProcess->
getType() != Process::Posix)
   125         result += pStr->length() + 1;
   134 static char **load_string_array(
   136     uintptr_t &arrayEndLoc)
   138     char **pMasterArray = 
reinterpret_cast<char **
>(arrayLoc);
   140     char *pPtr = 
reinterpret_cast<char *
>(
   141         arrayLoc + 
sizeof(
char *) * (rArray.count() + 1));
   143     for (
auto it = rArray.begin(); it != rArray.end(); it++)
   147         StringCopy(pPtr, *pStr);
   148         pPtr[pStr->length()] = 
'\0';  
   150         pMasterArray[i] = pPtr;
   152         pPtr += pStr->length() + 1;
   157     arrayEndLoc = 
reinterpret_cast<uintptr_t
>(pPtr);
   162 long posix_sbrk(
int delta)
   164     SC_NOTICE(
"sbrk(" << delta << 
")");
   166     long ret = 
reinterpret_cast<long>(
   169     SC_NOTICE(
"    -> " << ret);
   172         SYSCALL_ERROR(OutOfMemory);
   179 uintptr_t posix_brk(uintptr_t theBreak)
   181     SC_NOTICE(
"brk(" << theBreak << 
")");
   183     void *newBreak = 
reinterpret_cast<void *
>(theBreak);
   187     if (newBreak < currentBreak)
   189         SC_NOTICE(
" -> " << currentBreak);
   190         return reinterpret_cast<uintptr_t
>(currentBreak);
   193     intptr_t difference = pointer_diff(currentBreak, newBreak);
   196         SC_NOTICE(
" -> " << currentBreak);
   197         return reinterpret_cast<uintptr_t
>(currentBreak);
   205         SYSCALL_ERROR(OutOfMemory);
   206         SC_NOTICE(
" -> ENOMEM");
   214     SC_NOTICE(
" -> " << currentBreak);
   215     return reinterpret_cast<uintptr_t
>(currentBreak);
   219     SyscallState &state, 
unsigned long flags, 
void *child_stack, 
int *ptid,
   220     int *ctid, 
unsigned long newtls)
   223         "clone(" << 
Hex << flags << 
", " << child_stack << 
", " << ptid << 
", "   224                  << ctid << 
", " << newtls << 
")");
   229     SyscallState clonedState = state;
   232     if (flags & CLONE_CHILD_CLEARTID)
   234         SC_NOTICE(
" -> CLONE_CHILD_CLEARTID is not yet supported!");
   236     if (flags & CLONE_PARENT)
   238         SC_NOTICE(
" -> CLONE_PARENT is not yet supported!");
   240     if (flags & CLONE_VFORK)
   244         SC_NOTICE(
" -> CLONE_VFORK is not yet supported!");
   248     if (flags & CLONE_VM) SC_NOTICE(
"\t\t-> CLONE_VM");
   249     if (flags & CLONE_FS) SC_NOTICE(
"\t\t-> CLONE_FS");
   250     if (flags & CLONE_FILES) SC_NOTICE(
"\t\t-> CLONE_FILES");
   251     if (flags & CLONE_SIGHAND) SC_NOTICE(
"\t\t-> CLONE_SIGHAND");
   252     if (flags & CLONE_PTRACE) SC_NOTICE(
"\t\t-> CLONE_PTRACE");
   253     if (flags & CLONE_VFORK) SC_NOTICE(
"\t\t-> CLONE_VFORK");
   254     if (flags & CLONE_PARENT) SC_NOTICE(
"\t\t-> CLONE_PARENT");
   255     if (flags & CLONE_THREAD) SC_NOTICE(
"\t\t-> CLONE_THREAD");
   256     if (flags & CLONE_NEWNS) SC_NOTICE(
"\t\t-> CLONE_NEWNS");
   257     if (flags & CLONE_SYSVSEM) SC_NOTICE(
"\t\t-> CLONE_SYSVSEM");
   258     if (flags & CLONE_SETTLS) SC_NOTICE(
"\t\t-> CLONE_SETTLS");
   259     if (flags & CLONE_PARENT_SETTID) SC_NOTICE(
"\t\t-> CLONE_PARENT_SETTID");
   260     if (flags & CLONE_CHILD_CLEARTID) SC_NOTICE(
"\t\t-> CLONE_CHILD_CLEARTID");
   261     if (flags & CLONE_DETACHED) SC_NOTICE(
"\t\t-> CLONE_DETACHED");
   262     if (flags & CLONE_UNTRACED) SC_NOTICE(
"\t\t-> CLONE_UNTRACED");
   263     if (flags & CLONE_CHILD_SETTID) SC_NOTICE(
"\t\t-> CLONE_CHILD_SETTID");
   264     if (flags & CLONE_NEWUTS) SC_NOTICE(
"\t\t-> CLONE_NEWUTS");
   265     if (flags & CLONE_NEWIPC) SC_NOTICE(
"\t\t-> CLONE_NEWIPC");
   266     if (flags & CLONE_NEWUSER) SC_NOTICE(
"\t\t-> CLONE_NEWUSER");
   267     if (flags & CLONE_NEWPID) SC_NOTICE(
"\t\t-> CLONE_NEWPID");
   268     if (flags & CLONE_NEWNET) SC_NOTICE(
"\t\t-> CLONE_NEWNET");
   269     if (flags & CLONE_IO) SC_NOTICE(
"\t\t-> CLONE_IO");
   272     if ((flags & CLONE_VM) == CLONE_VM)
   279             SYSCALL_ERROR(InvalidArgument);
   284         clonedState.setStackPointer(reinterpret_cast<uintptr_t>(child_stack));
   287         clonedState.setSyscallReturnValue(0);
   296         Thread *pThread = 
new Thread(pParentProcess, clonedState, 
true);
   301         if (flags & CLONE_CHILD_SETTID)
   303             *ctid = pThread->
getId();
   305         if (flags & CLONE_PARENT_SETTID)
   307             *ptid = pThread->
getId();
   313         SC_NOTICE(
" -> " << pThread->
getId() << 
" [new thread]");
   314         return pThread->
getId();
   321         clonedState.setStackPointer(reinterpret_cast<uintptr_t>(child_stack));
   325     for (
int sig = 0; sig < 32; sig++)
   334         SYSCALL_ERROR(OutOfMemory);
   335         SC_NOTICE(
" -> ENOMEM");
   340         reinterpret_cast<PosixSubsystem *
>(pParentProcess->getSubsystem());
   342     if (!pSubsystem || !pParentSubsystem)
   344         ERROR(
"No subsystem for one or both of the processes!");
   348         if (pParentSubsystem)
   349             delete pParentSubsystem;
   352         SYSCALL_ERROR(OutOfMemory);
   355         for (
int sig = 0; sig < 32; sig++)
   358         SC_NOTICE(
" -> ENOMEM");
   361     pProcess->setSubsystem(pSubsystem);
   365     if (pParentProcess->
getType() == Process::Posix)
   368         pProcess->setProcessGroup(p->getProcessGroup());
   376             SC_NOTICE(
"fork parent was a group leader.");
   381                 "fork parent had status "   382                 << static_cast<int>(p->getGroupMembership()) << 
"...");
   383             pProcess->setGroupMembership(p->getGroupMembership());
   392         pProcess->setLinker(newLinker);
   401     clonedState.setSyscallReturnValue(0);
   404     for (
int sig = 0; sig < 32; sig++)
   408     if (flags & CLONE_CHILD_SETTID)
   414         *ctid = pProcess->
getId();
   426     pedigree_copy_posix_thread(
   431     SC_NOTICE(
" -> " << pProcess->
getId() << 
" [new process]");
   432     return pProcess->
getId();
   435 int posix_fork(SyscallState &state)
   439     return posix_clone(state, 0, 0, 0, 0, 0);
   443     const char *name, 
const char **argv, 
const char **env, SyscallState &state)
   447             reinterpret_cast<uintptr_t>(name), PATH_MAX,
   448             PosixSubsystem::SafeRead))
   450         SC_NOTICE(
"execve -> invalid address");
   451         SYSCALL_ERROR(InvalidArgument);
   455     SC_NOTICE(
"execve(\"" << name << 
"\")");
   458     if (argv == 0 || env == 0)
   460         SYSCALL_ERROR(ExecFormatError);
   470         ERROR(
"No subsystem for this process!");
   476     for (
const char **arg = argv; *arg != 0; ++arg)
   480     for (
const char **e = env; *e != 0; ++e)
   487     normalisePath(invokePath, name);
   489     if (!pSubsystem->
invoke(invokePath, listArgv, listEnv, state))
   491         SC_NOTICE(
" -> execve failed in invoke");
   506         : m_List(cleanupList), m_Lock(lock), m_pTerminated(0)
   517         m_pTerminated = pProcess;
   518         pProcess->removeWaiter(m_Lock);
   524              it != m_List->end(); ++it)
   526             if ((*it) == m_pTerminated)
   529             (*it)->removeWaiter(m_Lock);
   539 int posix_waitpid(
const int pid, 
int *status, 
int options)
   542                       reinterpret_cast<uintptr_t>(status), 
sizeof(
int),
   543                       PosixSubsystem::SafeWrite))
   545         SC_NOTICE(
"waitpid -> invalid address");
   546         SYSCALL_ERROR(InvalidArgument);
   551         "waitpid(" << pid << 
" [" << 
Dec << pid << 
Hex << 
"], " << options
   568     ProcessGroup *pThisGroup = pThisProcess->getProcessGroup();
   571     bool bBlock = (options & WNOHANG) != WNOHANG;
   574         SC_NOTICE(
" -> blocking until a process reports status");
   578         SC_NOTICE(
" -> WNOHANG");
   585         if (pProcess == pThisProcess)
   588         if (pProcess->getState() == Process::Reaped)
   591         if ((pid <= 0) && (pProcess->
getType() == Process::Posix))
   594             ProcessGroup *pGroup = pPosixProcess->getProcessGroup();
   598                 if (!(pGroup && pThisGroup))
   606                 if (pProcess->
getParent() != pThisProcess)
   615         else if ((pid > 0) && (
static_cast<int>(pProcess->
getId()) != pid))
   617         else if (pProcess->
getType() != Process::Posix)
   626         if (bBlock || (pProcess->getState() == Process::Terminating))
   629                 "  -> adding our wait lock to process " << 
Dec   630                                                         << pProcess->
getId());
   631             pProcess->addWaiter(&waitLock);
   637     if (processList.
count() == 0)
   639         SYSCALL_ERROR(NoChildren);
   640         SC_NOTICE(
"  -> no children");
   649              it != processList.
end(); ++it)
   652             int this_pid = pProcess->
getId();
   660             if (pProcess->getState() == Process::Terminated ||
   661                 pProcess->getState() == Process::Reaped)
   668                     "waitpid: " << 
Dec << this_pid << 
" reaped ["   671                 if (pProcess->waiterCount() < 1)
   673                     SC_NOTICE(
"waitpid: destroying reaped process");
   678                     SC_NOTICE(
"waitpid: marking process reaped");
   684             else if ((options & 2) && pProcess->hasSuspended())
   689                 SC_NOTICE(
"waitpid: " << 
Dec << this_pid << 
" suspended.");
   693             else if ((options & 4) && pProcess->hasResumed())
   698                 SC_NOTICE(
"waitpid: " << 
Dec << this_pid << 
" resumed.");
   704                     "waitpid: " << 
Dec << this_pid << 
" has no status change");
   712             SC_NOTICE(
"waitpid: not blocking, no status to report");
   723             SC_NOTICE(
"waitpid: unwind state means exit");
   733 int posix_exit(
int code, 
bool allthreads)
   735     SC_NOTICE(
"exit(" << 
Dec << (code & 0xFF) << 
Hex << 
")");
   744         SC_NOTICE(
" -> thread group");
   745         pSubsystem->
exit(code);
   750         SC_NOTICE(
" -> current thread");
   755     FATAL(
"exit method returned in posix_exit");
   764     return pProcess->
getId();
   769     SC_NOTICE(
"getppid");
   778 int posix_gettimeofday(timeval *tv, 
struct timezone *tz)
   781             reinterpret_cast<uintptr_t>(tv), 
sizeof(timeval),
   782             PosixSubsystem::SafeWrite))
   784         SC_NOTICE(
"gettimeofday -> invalid address");
   785         SYSCALL_ERROR(InvalidArgument);
   789     SC_NOTICE(
"gettimeofday");
   800 int posix_settimeofday(
const timeval *tv, 
const struct timezone *tz)
   802     SC_NOTICE(
"settimeofday");
   805             reinterpret_cast<uintptr_t>(tv), 
sizeof(timeval),
   806             PosixSubsystem::SafeRead))
   808         SC_NOTICE(
" -> invalid address");
   809         SYSCALL_ERROR(BadAddress);
   818 time_t posix_time(time_t *tval)
   823                     reinterpret_cast<uintptr_t>(tval), 
sizeof(time_t),
   824                     PosixSubsystem::SafeWrite))
   826         SC_NOTICE(
" -> invalid address");
   827         SYSCALL_ERROR(BadAddress);
   831     time_t result = Time::getTime();
   840 clock_t posix_times(
struct tms *tm)
   843             reinterpret_cast<uintptr_t>(tm), 
sizeof(
struct tms),
   844             PosixSubsystem::SafeWrite))
   846         SC_NOTICE(
"posix_times -> invalid address");
   847         SYSCALL_ERROR(InvalidArgument);
   856     ByteSet(tm, 0, 
sizeof(
struct tms));
   858     tm->tms_stime = pProcess->getKernelTime();
   862                     << 
", s=" << pProcess->getKernelTime());
   864     return Time::getTimeNanoseconds() - pProcess->getStartTime();
   867 int posix_getrusage(
int who, 
struct rusage *r)
   869     SC_NOTICE(
"getrusage who=" << who);
   872             reinterpret_cast<uintptr_t>(r), 
sizeof(
struct rusage),
   873             PosixSubsystem::SafeWrite))
   875         SC_NOTICE(
"posix_getrusage -> invalid address");
   876         SYSCALL_ERROR(BadAddress);
   880     if (who != RUSAGE_SELF)
   882         SC_NOTICE(
"posix_getrusage -> non-RUSAGE_SELF not supported");
   883         SYSCALL_ERROR(InvalidArgument);
   884         ByteSet(r, 0, 
sizeof(
struct rusage));
   892     Time::Timestamp kernel = pProcess->getKernelTime();
   894     ByteSet(r, 0, 
sizeof(
struct rusage));
   895     r->ru_utime.tv_sec = user / Time::Multiplier::Second;
   896     r->ru_utime.tv_usec =
   897         (user % Time::Multiplier::Second) / Time::Multiplier::Microsecond;
   898     r->ru_stime.tv_sec = kernel / Time::Multiplier::Second;
   899     r->ru_stime.tv_usec =
   900         (kernel % Time::Multiplier::Second) / Time::Multiplier::Microsecond;
   905 static char *store_str_to(
char *str, 
char *strend, 
String s)
   908     while (s[i] && str != strend)
   915 int posix_getpwent(passwd *pw, 
int n, 
char *str)
   919             reinterpret_cast<uintptr_t>(pw), 
sizeof(passwd),
   920             PosixSubsystem::SafeWrite))
   922         SC_NOTICE(
"getpwent -> invalid address");
   923         SYSCALL_ERROR(InvalidArgument);
   927     SC_NOTICE(
"getpwent(" << 
Dec << n << 
Hex << 
")");
   934     char *strend = str + 256;  
   937     str = store_str_to(str, strend, pUser->
getUsername());
   942     pw->pw_uid = pUser->
getId();
   944     str = store_str_to(str, strend, pUser->
getFullName());
   949     str = store_str_to(str, strend, pUser->
getHome());
   952     store_str_to(str, strend, pUser->
getShell());
   957 int posix_getpwnam(passwd *pw, 
const char *name, 
char *str)
   961               reinterpret_cast<uintptr_t>(pw), 
sizeof(passwd),
   962               PosixSubsystem::SafeWrite) &&
   964               reinterpret_cast<uintptr_t>(name), PATH_MAX,
   965               PosixSubsystem::SafeRead)))
   967         SC_NOTICE(
"getpwname -> invalid address");
   968         SYSCALL_ERROR(InvalidArgument);
   972     SC_NOTICE(
"getpwname(" << name << 
")");
   979     char *strend = str + 256;  
   982     str = store_str_to(str, strend, pUser->
getUsername());
   987     pw->pw_uid = pUser->
getId();
   989     str = store_str_to(str, strend, pUser->
getFullName());
   995     str = store_str_to(str, strend, pUser->
getHome());
   998     store_str_to(str, strend, pUser->
getShell());
  1003 int posix_getgrnam(
const char *name, 
struct group *out)
  1006               reinterpret_cast<uintptr_t>(name), PATH_MAX,
  1007               PosixSubsystem::SafeRead) &&
  1009               reinterpret_cast<uintptr_t>(out), 
sizeof(
struct group),
  1010               PosixSubsystem::SafeWrite)))
  1012         SC_NOTICE(
"getgrnam -> invalid address");
  1013         SYSCALL_ERROR(InvalidArgument);
  1017     SC_NOTICE(
"getgrnam(" << name << 
")");
  1027     StringCopy(out->gr_name, static_cast<const char *>(pGroup->
getName()));
  1028     out->gr_gid = pGroup->
getId();
  1033 int posix_getgrgid(gid_t 
id, 
struct group *out)
  1036             reinterpret_cast<uintptr_t>(out), 
sizeof(
struct group),
  1037             PosixSubsystem::SafeWrite)))
  1039         SC_NOTICE(
"getgrgid( -> invalid address");
  1040         SYSCALL_ERROR(InvalidArgument);
  1044     SC_NOTICE(
"getgrgid(" << 
id << 
")");
  1054     StringCopy(out->gr_name, static_cast<const char *>(pGroup->
getName()));
  1055     out->gr_gid = pGroup->
getId();
  1060 uid_t posix_getuid()
  1062     SC_NOTICE(
"getuid");
  1065     posix_getresuid(&uid, 
nullptr, 
nullptr);
  1069 gid_t posix_getgid()
  1071     SC_NOTICE(
"getgid");
  1074     posix_getresgid(&gid, 
nullptr, 
nullptr);
  1078 uid_t posix_geteuid()
  1080     SC_NOTICE(
"geteuid");
  1083     posix_getresuid(
nullptr, &euid, 
nullptr);
  1087 gid_t posix_getegid()
  1089     SC_NOTICE(
"getegid");
  1092     posix_getresgid(
nullptr, &egid, 
nullptr);
  1096 int posix_setuid(uid_t uid)
  1098     SC_NOTICE(
"setuid(" << uid << 
")");
  1099     return posix_setresuid(uid, uid, -1);
  1102 int posix_setgid(gid_t gid)
  1104     SC_NOTICE(
"setgid(" << gid << 
")");
  1105     return posix_setresgid(gid, gid, -1);
  1108 int posix_seteuid(uid_t euid)
  1110     SC_NOTICE(
"seteuid(" << euid << 
")");
  1111     return posix_setresuid(-1, euid, -1);
  1114 int posix_setegid(gid_t egid)
  1116     SC_NOTICE(
"setegid(" << egid << 
")");
  1117     return posix_setresgid(-1, egid, -1);
  1123             reinterpret_cast<uintptr_t>(password), PATH_MAX,
  1124             PosixSubsystem::SafeRead))
  1126         SC_NOTICE(
"pedigree_login -> invalid address");
  1127         SYSCALL_ERROR(InvalidArgument);
  1144     SC_NOTICE(
"setsid");
  1149     if (pStockProcess->
getType() != Process::Posix)
  1151         ERROR(
"setsid called on something not a POSIX process");
  1162         if (!pProcess->getProcessGroup())
  1163             FATAL(
"Process' is apparently a member of a group, but its group "  1164                   "pointer is invalid.");
  1169             SC_NOTICE(
"setsid() called while the leader of another group");
  1170             SYSCALL_ERROR(PermissionDenied);
  1176                 "setsid() called while a member of another group ["  1185         pProcess->setProcessGroup(0);
  1189         if (pGroup->Members.count() <= 1)  
  1195     pNewSession->
Leader = pProcess;
  1196     pProcess->setSession(pNewSession);
  1201     pNewGroup->
Leader = pProcess;
  1205     pProcess->setProcessGroup(pNewGroup);
  1219 int posix_setpgid(
int pid_, 
int pgid)
  1222     SC_NOTICE(
"setpgid(" << pid << 
", " << pgid << 
")");
  1227         SYSCALL_ERROR(InvalidArgument);
  1228         SC_NOTICE(
" -> EINVAL");
  1234     if (pBaseProcess->
getType() != Process::Posix)
  1236         SC_NOTICE(
"  -> not a posix process");
  1246         pid = pProcess->
getId();
  1258     if (pid != pProcess->
getId())
  1261         Process *pTargetProcess = 
nullptr;
  1265             if (check->
getType() != Process::Posix)
  1268             if (check->
getId() == pid)
  1270                 pTargetProcess = check;
  1275         if (!pTargetProcess)
  1277             SC_NOTICE(
"  -> process doesn't exist");
  1278             SYSCALL_ERROR(NoSuchProcess);
  1284         while (parent != 
nullptr)
  1286             if (parent == pProcess)
  1293         if (parent != pProcess)
  1296             SC_NOTICE(
"  -> target process is not a descendant of the current "  1298             SYSCALL_ERROR(NoSuchProcess);
  1302         if (static_cast<PosixProcess *>(pTargetProcess)->getSession() !=
  1305             SC_NOTICE(
"  -> target process is in a different session");
  1306             SYSCALL_ERROR(NotEnoughPermissions);
  1310         pBaseProcess = pTargetProcess;
  1311         pProcess = 
static_cast<PosixProcess *
>(pTargetProcess);
  1312         pGroup = pProcess->getProcessGroup();
  1313         pSession = pProcess->getSession();
  1319         SC_NOTICE(
" -> OK, already a member!");
  1323     if (pSession && (pSession->
Leader == pProcess))
  1326         SYSCALL_ERROR(PermissionDenied);
  1327         SC_NOTICE(
" -> EPERM (already leader)");
  1336         if (check->
getType() != Process::Posix)
  1340         ProcessGroup *pGroupCheck = posixCheck->getProcessGroup();
  1346                 pProcess->setProcessGroup(pGroupCheck);
  1348                 SC_NOTICE(
" -> OK, joined!");
  1357     pNewGroup->
Leader = pProcess;
  1361     pProcess->setProcessGroup(pNewGroup);
  1364     SC_NOTICE(
" -> OK, created!");
  1368 int posix_getpgid(
int pid)
  1372         return posix_getpgrp();
  1377     SC_NOTICE(
"getpgid(" << pid << 
")");
  1380     Process *pTargetProcess = 
nullptr;
  1384         if (check->
getType() != Process::Posix)
  1387         if (check->
getId() == pid_)
  1389             pTargetProcess = check;
  1394     if (!pTargetProcess)
  1396         SC_NOTICE(
" -> target process not found");
  1397         SYSCALL_ERROR(NoSuchProcess);
  1410     SC_NOTICE(
" -> target process did not have a group");
  1411     SYSCALL_ERROR(NoSuchProcess);
  1417     SC_NOTICE(
"getpgrp");
  1426         SC_NOTICE(
" -> using existing group id");
  1431         SC_NOTICE(
" -> using pid only");
  1432         result = pProcess->
getId();  
  1435     SC_NOTICE(
" -> " << result);
  1439 mode_t posix_umask(mode_t mask)
  1441     SC_NOTICE(
"umask(" << 
Oct << mask << 
")");
  1446     if (pStockProcess->
getType() != Process::Posix)
  1448         SC_NOTICE(
"umask -> called on something not a POSIX process");
  1449         SYSCALL_ERROR(InvalidArgument);
  1455     uint32_t previous = pProcess->getMask();
  1456     pProcess->setMask(mask);
  1461 int posix_linux_syslog(
int type, 
char *buf, 
int len)
  1464             reinterpret_cast<uintptr_t>(buf), len, PosixSubsystem::SafeRead))
  1466         SC_NOTICE(
"linux_syslog -> invalid address");
  1467         SYSCALL_ERROR(InvalidArgument);
  1471     SC_NOTICE(
"linux_syslog");
  1479             SC_NOTICE(
" -> close log");
  1483             SC_NOTICE(
" -> open log");
  1489             SC_NOTICE(
" -> read log");
  1495             SC_NOTICE(
" -> read up to last 4k");
  1500             SC_NOTICE(
" -> read and clear last 4k");
  1504             SC_NOTICE(
" -> clear");
  1508             SC_NOTICE(
" -> disable write to console");
  1512             SC_NOTICE(
" -> enable write to console");
  1516             SC_NOTICE(
" -> set console write level");
  1520             SC_NOTICE(
" -> unknown!");
  1521             SYSCALL_ERROR(InvalidArgument);
  1526 int posix_syslog(
const char *msg, 
int prio)
  1529             reinterpret_cast<uintptr_t>(msg), PATH_MAX,
  1530             PosixSubsystem::SafeRead))
  1532         SC_NOTICE(
"klog -> invalid address");
  1533         SYSCALL_ERROR(InvalidArgument);
  1541         if (prio <= LOG_CRIT)
  1542             FATAL(
"[" << 
Dec << 
id << 
Hex << 
"]\tklog: " << msg);
  1545     if (prio <= LOG_ERR)
  1546         ERROR(
"[" << 
Dec << 
id << 
Hex << 
"]\tklog: " << msg);
  1547     else if (prio == LOG_WARNING)
  1549     else if (prio == LOG_NOTICE || prio == LOG_INFO)
  1558 extern void system_reset();
  1567         SYSCALL_ERROR(NotEnoughPermissions);
  1571     WARNING(
"System shutting down...");
  1575         Subsystem *subsys = proc->getSubsystem();
  1608         bool allZombie = 
true;
  1650 int posix_uname(
struct utsname *n)
  1654         SYSCALL_ERROR(InvalidArgument);
  1663     StringCopy(n->sysname, 
"Pedigree");
  1665     if (pSubsystem->
getAbi() == PosixSubsystem::LinuxAbi)
  1668         StringCopy(n->release, 
"2.6.32-generic");
  1669         StringCopy(n->version, g_pBuildRevision);
  1673         StringCopy(n->release, g_pBuildRevision);
  1674         StringCopy(n->version, 
"Foster");
  1677     StringCopy(n->machine, g_pBuildTarget);
  1680     StringCopy(n->nodename, 
"pedigree");
  1685     int option, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
  1688         "prctl(" << 
Hex << option << 
", " << arg2 << 
", " << arg3 << 
", "  1689                  << arg4 << 
", " << arg5 << 
")");
  1693 int posix_arch_prctl(
int code, 
unsigned long addr)
  1695     unsigned long *pAddr = 
reinterpret_cast<unsigned long *
>(addr);
  1708             SYSCALL_ERROR(InvalidArgument);
  1721     SYSCALL_ERROR(Interrupted);
  1725 int posix_setgroups(
size_t size, 
const gid_t *list)
  1727     SC_NOTICE(
"setgroups(" << size << 
", " << list << 
")");
  1732             reinterpret_cast<uintptr_t>(list), size * 
sizeof(gid_t),
  1733             PosixSubsystem::SafeRead))
  1735         SC_NOTICE(
" -> invalid address");
  1736         SYSCALL_ERROR(BadAddress);
  1748     for (
size_t i = 0; i < size; ++i)
  1753     pProcess->setSupplementalGroupIds(newGroups);
  1758 int posix_getgroups(
size_t size, gid_t *list)
  1760     SC_NOTICE(
"getgroups(" << size << 
", " << list << 
")");
  1763                     reinterpret_cast<uintptr_t>(list), size * 
sizeof(gid_t),
  1764                     PosixSubsystem::SafeWrite))
  1766         SC_NOTICE(
"getgroups -> invalid address");
  1767         SYSCALL_ERROR(BadAddress);
  1779     pProcess->getSupplementalGroupIds(groups);
  1781     for (
size_t i = 0; i < size && i < groups.
count(); ++i)
  1783         list[i] = groups[i];
  1786     SC_NOTICE(
" -> " << groups.
count());
  1787     return groups.
count();
  1790 int posix_getrlimit(
int resource, 
struct rlimit *rlim)
  1793     SC_NOTICE(
"getrlimit(" << 
Dec << resource << 
")");
  1800             rlim->rlim_cur = rlim->rlim_max = RLIM_INFINITY;
  1803             rlim->rlim_cur = rlim->rlim_max = RLIM_INFINITY;
  1806             rlim->rlim_cur = rlim->rlim_max = RLIM_INFINITY;
  1810             rlim->rlim_max = RLIM_INFINITY;
  1813             rlim->rlim_cur = rlim->rlim_max = 1ULL << 48ULL;
  1816             rlim->rlim_cur = rlim->rlim_max = RLIM_INFINITY;
  1819             rlim->rlim_cur = rlim->rlim_max = 16384;
  1821         case RLIMIT_MEMLOCK:
  1822             rlim->rlim_cur = rlim->rlim_max = 1ULL << 24ULL;
  1825             rlim->rlim_cur = rlim->rlim_max = 1ULL << 48ULL;
  1828             rlim->rlim_cur = rlim->rlim_max = 1024;
  1830         case RLIMIT_SIGPENDING:
  1831             rlim->rlim_cur = rlim->rlim_max = 16;
  1833         case RLIMIT_MSGQUEUE:
  1834             rlim->rlim_cur = rlim->rlim_max = 0x100000;
  1837             rlim->rlim_cur = rlim->rlim_max = 1;
  1840             SYSCALL_ERROR(InvalidArgument);
  1841             SC_NOTICE(
" -> RTPRIO not supported");
  1844             SYSCALL_ERROR(InvalidArgument);
  1845             SC_NOTICE(
" -> unknown resource!");
  1849     SC_NOTICE(
" -> cur = " << rlim->rlim_cur);
  1850     SC_NOTICE(
" -> max = " << rlim->rlim_max);
  1854 int posix_setrlimit(
int resource, 
const struct rlimit *rlim)
  1857     SC_NOTICE(
"setrlimit(" << 
Dec << resource << 
")");
  1864 int posix_getpriority(
int which, 
int who)
  1867     SC_NOTICE(
"getpriority(" << which << 
", " << 
Dec << who << 
")");
  1868     SYSCALL_ERROR(NoError);  
  1872 int posix_setpriority(
int which, 
int who, 
int prio)
  1876         "setpriority(" << which << 
", " << 
Dec << who << 
", " << prio << 
")");
  1880 int posix_setreuid(uid_t ruid, uid_t euid)
  1882     SC_NOTICE(
"setreuid(" << ruid << 
", " << euid << 
")");
  1883     return posix_setresuid(ruid, euid, -1);
  1886 int posix_setregid(gid_t rgid, gid_t egid)
  1888     SC_NOTICE(
"setregid(" << rgid << 
", " << egid << 
")");
  1889     return posix_setresgid(rgid, egid, -1);
  1892 int posix_setresuid(uid_t ruid, uid_t euid, uid_t suid)
  1894     SC_NOTICE(
"setresuid(" << ruid << 
", " << euid << 
", " << suid << 
")");
  1903     if (ruid != static_cast<uid_t>(-1))
  1905         pProcess->setUserId(ruid);
  1907     if (euid != static_cast<uid_t>(-1))
  1909         pProcess->setEffectiveUserId(euid);
  1911     if (suid != static_cast<uid_t>(-1))
  1913         pProcess->setSavedUserId(suid);
  1919 int posix_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
  1921     SC_NOTICE(
"setresgid(" << rgid << 
", " << egid << 
", " << sgid << 
")");
  1930     if (rgid != static_cast<gid_t>(-1))
  1932         pProcess->setGroupId(rgid);
  1934     if (egid != static_cast<gid_t>(-1))
  1936         pProcess->setEffectiveGroupId(egid);
  1938     if (sgid != static_cast<gid_t>(-1))
  1940         pProcess->setSavedGroupId(sgid);
  1946 int posix_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
  1948     SC_NOTICE(
"getresuid");
  1956         SC_NOTICE(
" -> uid=" << *ruid);
  1961         *euid = pStockProcess->getEffectiveUserId();
  1962         SC_NOTICE(
" -> euid=" << *euid);
  1970             *suid = pProcess->getSavedUserId();
  1971             SC_NOTICE(
" -> suid=" << *suid);
  1978 int posix_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
  1980     SC_NOTICE(
"getresgid");
  1987         *rgid = pStockProcess->getGroupId();
  1988         SC_NOTICE(
" -> gid=" << *rgid);
  1993         *egid = pStockProcess->getEffectiveGroupId();
  1994         SC_NOTICE(
" -> egid=" << *egid);
  2002             *sgid = pProcess->getSavedGroupId();
  2003             SC_NOTICE(
" -> sgid=" << *sgid);
  2010 int posix_get_robust_list(
  2011     int pid, 
struct robust_list_head **head_ptr, 
size_t *len_ptr)
  2013     SC_NOTICE(
"get_robust_list");
  2016               reinterpret_cast<uintptr_t>(head_ptr), 
sizeof(
void *),
  2017               PosixSubsystem::SafeWrite) &&
  2019               reinterpret_cast<uintptr_t>(len_ptr), 
sizeof(
size_t),
  2020               PosixSubsystem::SafeWrite)))
  2022         SC_NOTICE(
" -> invalid address");
  2023         SYSCALL_ERROR(InvalidArgument);
  2030     auto data = pProcess->getRobustList();
  2031     *head_ptr = 
reinterpret_cast<struct robust_list_head *
>(data.head);
  2032     *len_ptr = data.head_len;
  2037 int posix_set_robust_list(
struct robust_list_head *head, 
size_t len)
  2039     SC_NOTICE(
"set_robust_list");
  2046     data.head_len = len;
  2048     pProcess->setRobustList(data);
  2053 int posix_ioperm(
unsigned long from, 
unsigned long num, 
int turn_on)
  2055     SC_NOTICE(
"ioperm(" << from << 
", " << num << 
", " << turn_on << 
")");
  2062 int posix_iopl(
int level)
  2064     SC_NOTICE(
"iopl(" << level << 
")");
  2069 #define SC_NOTICE(x)  2071 int posix_getitimer(
int which, 
struct itimerval *curr_value)
  2073     SC_NOTICE(
"posix_getitimer(" << which << 
", " << curr_value << 
")");
  2080     Time::Timestamp interval = 0;
  2081     Time::Timestamp value = 0;
  2084     if (which == ITIMER_REAL)
  2086         SC_NOTICE(
" -> ITIMER_REAL");
  2088     else if (which == ITIMER_VIRTUAL)
  2090         SC_NOTICE(
" -> ITIMER_VIRTUAL");
  2092         itimer = &pProcess->getVirtualIntervalTimer();
  2094     else if (which == ITIMER_PROF)
  2096         SC_NOTICE(
" -> ITIMER_VIRTUAL");
  2098         itimer = &pProcess->getProfileIntervalTimer();
  2102         SYSCALL_ERROR(InvalidArgument);
  2106     itimer->getIntervalAndValue(interval, value);
  2108     curr_value->it_interval.tv_sec = interval / Time::Multiplier::Second;
  2109     curr_value->it_interval.tv_usec =
  2110         (interval % Time::Multiplier::Second) / Time::Multiplier::Microsecond;
  2112     curr_value->it_value.tv_sec = value / Time::Multiplier::Second;
  2113     curr_value->it_value.tv_usec =
  2114         (value % Time::Multiplier::Second) / Time::Multiplier::Microsecond;
  2117         " -> period = " << 
Dec << curr_value->it_interval.tv_sec << 
"s "  2118                         << curr_value->it_interval.tv_usec << 
"us");
  2120         " -> value = " << 
Dec << curr_value->it_value.tv_sec << 
"s "  2121                        << curr_value->it_value.tv_usec << 
"us");
  2126 int posix_setitimer(
  2127     int which, 
const struct itimerval *new_value, 
struct itimerval *old_value)
  2130         "posix_setitimer(" << which << 
", " << new_value << 
", " << old_value
  2133         " -> period = " << 
Dec << new_value->it_interval.tv_sec << 
"s "  2134                         << new_value->it_interval.tv_usec << 
"us");
  2136         " -> value = " << 
Dec << new_value->it_value.tv_sec << 
"s "  2137                        << new_value->it_value.tv_usec << 
"us");
  2144     Time::Timestamp interval = 0;
  2145     Time::Timestamp value = 0;
  2147     Time::Timestamp prevInterval = 0;
  2148     Time::Timestamp prevValue = 0;
  2150     interval = (new_value->it_interval.tv_sec * Time::Multiplier::Second) +
  2151                (new_value->it_interval.tv_usec * Time::Multiplier::Microsecond);
  2152     value = (new_value->it_value.tv_sec * Time::Multiplier::Second) +
  2153             (new_value->it_value.tv_usec * Time::Multiplier::Microsecond);
  2156     if (which == ITIMER_REAL)
  2158         SC_NOTICE(
" -> ITIMER_REAL");
  2160     else if (which == ITIMER_VIRTUAL)
  2162         SC_NOTICE(
" -> ITIMER_VIRTUAL");
  2164         itimer = &pProcess->getVirtualIntervalTimer();
  2166     else if (which == ITIMER_PROF)
  2168         SC_NOTICE(
" -> ITIMER_VIRTUAL");
  2170         itimer = &pProcess->getProfileIntervalTimer();
  2174         SYSCALL_ERROR(InvalidArgument);
  2182         old_value->it_interval.tv_sec = prevInterval / Time::Multiplier::Second;
  2183         old_value->it_interval.tv_usec =
  2184             (prevInterval % Time::Multiplier::Second) /
  2185             Time::Multiplier::Microsecond;
  2187         old_value->it_value.tv_sec = prevValue / Time::Multiplier::Second;
  2188         old_value->it_value.tv_usec = (prevValue % Time::Multiplier::Second) /
  2189                                       Time::Multiplier::Microsecond;
  2195 int posix_capget(
void *hdrp, 
void *datap)
  2209         SYSCALL_ERROR(BadAddress);
  2213     if (header->version != _LINUX_CAPABILITY_VERSION_1)
  2216         header->version = _LINUX_CAPABILITY_VERSION_1;
  2217         SYSCALL_ERROR(InvalidArgument);
  2224         data->effective = 0xFFFFFFFF;
  2225         data->permitted = 0xFFFFFFFF;
  2226         data->inheritable = 0xFFFFFFFF;
  2232 int posix_capset(
void *hdrp, 
const void *datap)
  2236         reinterpret_cast<const struct 
cap_data *
>(datap);
  2240         SYSCALL_ERROR(BadAddress);
  2244     if (header->version != _LINUX_CAPABILITY_VERSION_1)
  2246         header->version = _LINUX_CAPABILITY_VERSION_1;
  2247         SYSCALL_ERROR(InvalidArgument);
 void terminated(Process *pProcess)
void pushBack(const T &value)
void pushBack(const T &value)
bool acquire(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
A vector / dynamic array. 
virtual bool invoke(const char *name, Vector< String > &argv, Vector< String > &env)
virtual Timer * getTimer()=0
bool copyDescriptors(PosixSubsystem *pSubsystem)
void setTlsBase(uintptr_t base)
virtual int64_t getUserId() const 
User * getUser(size_t id)
static ProcessorInformation & information()
static void switchAddressSpace(VirtualAddressSpace &AddressSpace)
virtual Time::Timestamp getUnixTimestamp()
Group * getGroup(size_t id)
void removeProcess(Process *pProcess)
static bool checkAddress(uintptr_t addr, size_t extent, size_t flags)
static const size_t Write
void exit(int code) NORETURN
Memory-mapped file interface. 
Time::Timestamp getUserTime() const 
Group * getDefaultGroup()
static MemoryMapManager & instance()
static Scheduler & instance()
Process * getProcess(size_t n)
virtual uint64_t getNanosecond()=0
static void setInterrupts(bool bEnable)
Thread * getThread(size_t n)
List< PosixProcess * > Members
void setIntervalAndValue(Time::Timestamp interval, Time::Timestamp value, Time::Timestamp *prevInterval=nullptr, Time::Timestamp *prevValue=nullptr)
Set both interval and value atomically. 
void clone(Process *pTarget)
VirtualAddressSpace * getAddressSpace()
virtual ProcessType getType()
static UserManager & instance()
bool login(String password)
virtual bool kill(KillReason killReason, Thread *pThread=0)=0
virtual void setProcess(Process *p)