mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:02:45 +00:00 
			
		
		
		
	Start working on sessions and process groups.
This commit is contained in:
		
							parent
							
								
									05565bad58
								
							
						
					
					
						commit
						d8f0dd6f3b
					
				
					 8 changed files with 157 additions and 2 deletions
				
			
		|  | @ -277,10 +277,12 @@ ByteBuffer procfs$summary() | ||||||
|     auto processes = Process::allProcesses(); |     auto processes = Process::allProcesses(); | ||||||
|     auto buffer = ByteBuffer::createUninitialized(processes.size() * 256); |     auto buffer = ByteBuffer::createUninitialized(processes.size() * 256); | ||||||
|     char* ptr = (char*)buffer.pointer(); |     char* ptr = (char*)buffer.pointer(); | ||||||
|     ptr += ksprintf(ptr, "PID    OWNER  STATE      PPID   NSCHED      FDS  TTY  NAME\n"); |     ptr += ksprintf(ptr, "PID PGP SID  OWNER  STATE      PPID NSCHED     FDS  TTY  NAME\n"); | ||||||
|     for (auto* process : processes) { |     for (auto* process : processes) { | ||||||
|         ptr += ksprintf(ptr, "% 5u  % 4u   % 8s   % 5u  % 10u  % 3u  % 4s  %s\n", |         ptr += ksprintf(ptr, "% 3u % 3u % 3u  % 4u   % 8s   % 3u  % 9u  % 3u  % 4s  %s\n", | ||||||
|             process->pid(), |             process->pid(), | ||||||
|  |             process->pgid(), | ||||||
|  |             process->sid(), | ||||||
|             process->uid(), |             process->uid(), | ||||||
|             toString(process->state()), |             toString(process->state()), | ||||||
|             process->parentPID(), |             process->parentPID(), | ||||||
|  |  | ||||||
|  | @ -129,6 +129,16 @@ void Process::allocateLDT() | ||||||
|     m_tss.ldt = m_ldt_selector; |     m_tss.ldt = m_ldt_selector; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template<typename Callback> | ||||||
|  | static void forEachProcess(Callback callback) | ||||||
|  | { | ||||||
|  |     ASSERT_INTERRUPTS_DISABLED(); | ||||||
|  |     for (auto* process = s_processes->head(); process; process = process->next()) { | ||||||
|  |         if (!callback(*process)) | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Vector<Process*> Process::allProcesses() | Vector<Process*> Process::allProcesses() | ||||||
| { | { | ||||||
|     InterruptDisabler disabler; |     InterruptDisabler disabler; | ||||||
|  | @ -406,6 +416,16 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel | ||||||
|     , m_tty(tty) |     , m_tty(tty) | ||||||
|     , m_parentPID(parentPID) |     , m_parentPID(parentPID) | ||||||
| { | { | ||||||
|  |     { | ||||||
|  |         // FIXME: Use a ProcessHandle? Presumably we're executing *IN* the parent right now though..
 | ||||||
|  |         InterruptDisabler disabler; | ||||||
|  |         if (auto* parent = Process::fromPID(m_parentPID)) { | ||||||
|  |             m_sid = parent->m_sid; | ||||||
|  |             m_pgid = parent->m_pgid; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     m_page_directory = (PageDirectory*)kmalloc_page_aligned(sizeof(PageDirectory)); |     m_page_directory = (PageDirectory*)kmalloc_page_aligned(sizeof(PageDirectory)); | ||||||
|     MM.populate_page_directory(*this); |     MM.populate_page_directory(*this); | ||||||
| 
 | 
 | ||||||
|  | @ -1152,3 +1172,80 @@ bool Process::validate_user_write(LinearAddress laddr) const | ||||||
|     InterruptDisabler disabler; |     InterruptDisabler disabler; | ||||||
|     return MM.validate_user_write(*this, laddr); |     return MM.validate_user_write(*this, laddr); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | pid_t Process::sys$getsid(pid_t pid) | ||||||
|  | { | ||||||
|  |     if (pid == 0) | ||||||
|  |         return m_sid; | ||||||
|  |     InterruptDisabler disabler; | ||||||
|  |     auto* process = Process::fromPID(pid); | ||||||
|  |     if (!process) | ||||||
|  |         return -ESRCH; | ||||||
|  |     if (m_sid != process->m_sid) | ||||||
|  |         return -EPERM; | ||||||
|  |     return process->m_sid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pid_t Process::sys$setsid() | ||||||
|  | { | ||||||
|  |     InterruptDisabler disabler; | ||||||
|  |     bool found_process_with_same_pgid_as_my_pid = false; | ||||||
|  |     forEachProcess([&] (auto& process) { | ||||||
|  |         if (process.pgid() == pid()) { | ||||||
|  |             found_process_with_same_pgid_as_my_pid = true; | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  |     if (found_process_with_same_pgid_as_my_pid) | ||||||
|  |         return -EPERM; | ||||||
|  |     m_sid = m_pid; | ||||||
|  |     m_pgid = m_pid; | ||||||
|  |     return m_sid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pid_t Process::sys$getpgid(pid_t pid) | ||||||
|  | { | ||||||
|  |     if (pid == 0) | ||||||
|  |         return m_pgid; | ||||||
|  |     InterruptDisabler disabler; // FIXME: Use a ProcessHandle
 | ||||||
|  |     auto* process = Process::fromPID(pid); | ||||||
|  |     if (!process) | ||||||
|  |         return -ESRCH; | ||||||
|  |     return process->m_pgid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pid_t Process::sys$getpgrp() | ||||||
|  | { | ||||||
|  |     return m_pgid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static pid_t get_sid_from_pgid(pid_t pgid) | ||||||
|  | { | ||||||
|  |     InterruptDisabler disabler; | ||||||
|  |     auto* group_leader = Process::fromPID(pgid); | ||||||
|  |     if (!group_leader) | ||||||
|  |         return -1; | ||||||
|  |     return group_leader->sid(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid) | ||||||
|  | { | ||||||
|  |     InterruptDisabler disabler; // FIXME: Use a ProcessHandle
 | ||||||
|  |     pid_t pid = specified_pid ? specified_pid : m_pid; | ||||||
|  |     if (specified_pgid < 0) | ||||||
|  |         return -EINVAL; | ||||||
|  |     auto* process = Process::fromPID(pid); | ||||||
|  |     if (!process) | ||||||
|  |         return -ESRCH; | ||||||
|  |     pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid; | ||||||
|  |     pid_t current_sid = get_sid_from_pgid(process->m_pgid); | ||||||
|  |     pid_t new_sid = get_sid_from_pgid(new_pgid); | ||||||
|  |     if (current_sid != new_sid) { | ||||||
|  |         // Can't move a process between sessions.
 | ||||||
|  |         return -EPERM; | ||||||
|  |     } | ||||||
|  |     // FIXME: There are more EPERM conditions to check for here..
 | ||||||
|  |     process->m_pgid = new_pgid; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -50,6 +50,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     const String& name() const { return m_name; } |     const String& name() const { return m_name; } | ||||||
|     pid_t pid() const { return m_pid; } |     pid_t pid() const { return m_pid; } | ||||||
|  |     pid_t sid() const { return m_sid; } | ||||||
|  |     pid_t pgid() const { return m_pgid; } | ||||||
|     DWORD ticks() const { return m_ticks; } |     DWORD ticks() const { return m_ticks; } | ||||||
|     WORD selector() const { return m_farPtr.selector; } |     WORD selector() const { return m_farPtr.selector; } | ||||||
|     TSS32& tss() { return m_tss; } |     TSS32& tss() { return m_tss; } | ||||||
|  | @ -79,6 +81,11 @@ public: | ||||||
|     void setSelector(WORD s) { m_farPtr.selector = s; } |     void setSelector(WORD s) { m_farPtr.selector = s; } | ||||||
|     void set_state(State s) { m_state = s; } |     void set_state(State s) { m_state = s; } | ||||||
| 
 | 
 | ||||||
|  |     pid_t sys$setsid(); | ||||||
|  |     pid_t sys$getsid(pid_t); | ||||||
|  |     int sys$setpgid(pid_t pid, pid_t pgid); | ||||||
|  |     pid_t sys$getpgrp(); | ||||||
|  |     pid_t sys$getpgid(pid_t); | ||||||
|     uid_t sys$getuid(); |     uid_t sys$getuid(); | ||||||
|     gid_t sys$getgid(); |     gid_t sys$getgid(); | ||||||
|     pid_t sys$getpid(); |     pid_t sys$getpid(); | ||||||
|  | @ -160,6 +167,8 @@ private: | ||||||
|     pid_t m_pid { 0 }; |     pid_t m_pid { 0 }; | ||||||
|     uid_t m_uid { 0 }; |     uid_t m_uid { 0 }; | ||||||
|     gid_t m_gid { 0 }; |     gid_t m_gid { 0 }; | ||||||
|  |     pid_t m_sid { 0 }; | ||||||
|  |     pid_t m_pgid { 0 }; | ||||||
|     DWORD m_ticks { 0 }; |     DWORD m_ticks { 0 }; | ||||||
|     DWORD m_ticksLeft { 0 }; |     DWORD m_ticksLeft { 0 }; | ||||||
|     DWORD m_stackTop0 { 0 }; |     DWORD m_stackTop0 { 0 }; | ||||||
|  |  | ||||||
|  | @ -114,6 +114,16 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3) | ||||||
|         return current->sys$readlink((const char*)arg1, (char*)arg2, (size_t)arg3); |         return current->sys$readlink((const char*)arg1, (char*)arg2, (size_t)arg3); | ||||||
|     case Syscall::PosixTtynameR: |     case Syscall::PosixTtynameR: | ||||||
|         return current->sys$ttyname_r((int)arg1, (char*)arg2, (size_t)arg3); |         return current->sys$ttyname_r((int)arg1, (char*)arg2, (size_t)arg3); | ||||||
|  |     case Syscall::PosixSetsid: | ||||||
|  |         return current->sys$setsid(); | ||||||
|  |     case Syscall::PosixGetsid: | ||||||
|  |         return current->sys$getsid((pid_t)arg1); | ||||||
|  |     case Syscall::PosixSetpgid: | ||||||
|  |         return current->sys$setpgid((pid_t)arg1, (pid_t)arg2); | ||||||
|  |     case Syscall::PosixGetpgid: | ||||||
|  |         return current->sys$getpgid((pid_t)arg1); | ||||||
|  |     case Syscall::PosixGetpgrp: | ||||||
|  |         return current->sys$getpgrp(); | ||||||
|     default: |     default: | ||||||
|         kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3); |         kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3); | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|  | @ -40,6 +40,11 @@ enum Function { | ||||||
|     PosixTtynameR = 0x2008, |     PosixTtynameR = 0x2008, | ||||||
|     PosixStat = 0x2009, |     PosixStat = 0x2009, | ||||||
|     GetEnvironment = 0x2010, |     GetEnvironment = 0x2010, | ||||||
|  |     PosixGetsid = 0x2011, | ||||||
|  |     PosixSetsid = 0x2012, | ||||||
|  |     PosixGetpgid = 0x2013, | ||||||
|  |     PosixSetpgid = 0x2014, | ||||||
|  |     PosixGetpgrp = 0x2015, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void initialize(); | void initialize(); | ||||||
|  |  | ||||||
|  | @ -20,6 +20,31 @@ pid_t getpid() | ||||||
|     return Syscall::invoke(Syscall::PosixGetpid); |     return Syscall::invoke(Syscall::PosixGetpid); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pid_t setsid() | ||||||
|  | { | ||||||
|  |     return Syscall::invoke(Syscall::PosixSetsid); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pid_t sys$getsid(pid_t pid) | ||||||
|  | { | ||||||
|  |     return Syscall::invoke(Syscall::PosixSetsid, (dword)pid); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int setpgid(pid_t pid, pid_t pgid) | ||||||
|  | { | ||||||
|  |     return Syscall::invoke(Syscall::PosixSetpgid, (dword)pid, (dword)pgid); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pid_t getpgid(pid_t pid) | ||||||
|  | { | ||||||
|  |     return Syscall::invoke(Syscall::PosixGetpgid, (dword)pid); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pid_t getpgrp() | ||||||
|  | { | ||||||
|  |     return Syscall::invoke(Syscall::PosixGetpgrp); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int open(const char* path, int options) | int open(const char* path, int options) | ||||||
| { | { | ||||||
|     int rc = Syscall::invoke(Syscall::PosixOpen, (dword)path, (dword)options); |     int rc = Syscall::invoke(Syscall::PosixOpen, (dword)path, (dword)options); | ||||||
|  |  | ||||||
|  | @ -8,6 +8,11 @@ __BEGIN_DECLS | ||||||
| extern char** environ; | extern char** environ; | ||||||
| 
 | 
 | ||||||
| inline int getpagesize() { return 4096; } | inline int getpagesize() { return 4096; } | ||||||
|  | pid_t getsid(pid_t); | ||||||
|  | pid_t setsid(); | ||||||
|  | int setpgid(pid_t pid, pid_t pgid); | ||||||
|  | pid_t getpgid(pid_t); | ||||||
|  | pid_t getpgrp(); | ||||||
| uid_t getuid(); | uid_t getuid(); | ||||||
| gid_t getgid(); | gid_t getgid(); | ||||||
| pid_t getpid(); | pid_t getpid(); | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ struct GlobalState { | ||||||
|     const char* ttyname_short { nullptr }; |     const char* ttyname_short { nullptr }; | ||||||
|     char ttyname[32]; |     char ttyname[32]; | ||||||
|     char hostname[32]; |     char hostname[32]; | ||||||
|  |     pid_t sid; | ||||||
| }; | }; | ||||||
| static GlobalState* g; | static GlobalState* g; | ||||||
| 
 | 
 | ||||||
|  | @ -171,6 +172,7 @@ static void greeting() | ||||||
| int main(int, char**) | int main(int, char**) | ||||||
| { | { | ||||||
|     g = new GlobalState; |     g = new GlobalState; | ||||||
|  |     g->sid = setsid(); | ||||||
|     int rc = gethostname(g->hostname, sizeof(g->hostname)); |     int rc = gethostname(g->hostname, sizeof(g->hostname)); | ||||||
|     if (rc < 0) |     if (rc < 0) | ||||||
|         perror("gethostname"); |         perror("gethostname"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling