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)