diff --git a/docs/src/kernel/linux-compatibility.md b/docs/src/kernel/linux-compatibility.md index 1146e0e8..682cbfa8 100644 --- a/docs/src/kernel/linux-compatibility.md +++ b/docs/src/kernel/linux-compatibility.md @@ -141,7 +141,7 @@ provided by Linux on x86-64 architecture. | 118 | getresuid | ✅ | | 119 | setresgid | ✅ | | 120 | getresgid | ✅ | -| 121 | getpgid | ❌ | +| 121 | getpgid | ✅ | | 122 | setfsuid | ✅ | | 123 | setfsgid | ✅ | | 124 | getsid | ✅ | diff --git a/kernel/src/syscall/arch/riscv.rs b/kernel/src/syscall/arch/riscv.rs index 0a3d1c94..9b28dafd 100644 --- a/kernel/src/syscall/arch/riscv.rs +++ b/kernel/src/syscall/arch/riscv.rs @@ -33,7 +33,7 @@ use crate::syscall::{ getgid::sys_getgid, getgroups::sys_getgroups, getpeername::sys_getpeername, - getpgrp::sys_getpgrp, + getpgid::sys_getpgid, getpid::sys_getpid, getppid::sys_getppid, getrandom::sys_getrandom, @@ -214,7 +214,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_SETFSUID = 151 => sys_setfsuid(args[..1]); SYS_SETFSGID = 152 => sys_setfsgid(args[..1]); SYS_SETPGID = 154 => sys_setpgid(args[..2]); - SYS_GETPGRP = 155 => sys_getpgrp(args[..0]); + SYS_GETPGID = 155 => sys_getpgid(args[..1]); SYS_GETSID = 156 => sys_getsid(args[..1]); SYS_SETSID = 157 => sys_setsid(args[..0]); SYS_GETGROUPS = 158 => sys_getgroups(args[..2]); diff --git a/kernel/src/syscall/arch/x86.rs b/kernel/src/syscall/arch/x86.rs index 6c847473..dc136138 100644 --- a/kernel/src/syscall/arch/x86.rs +++ b/kernel/src/syscall/arch/x86.rs @@ -36,6 +36,7 @@ use crate::syscall::{ getgid::sys_getgid, getgroups::sys_getgroups, getpeername::sys_getpeername, + getpgid::sys_getpgid, getpgrp::sys_getpgrp, getpid::sys_getpid, getppid::sys_getppid, @@ -241,6 +242,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_GETRESUID = 118 => sys_getresuid(args[..3]); SYS_SETRESGID = 119 => sys_setresgid(args[..3]); SYS_GETRESGID = 120 => sys_getresgid(args[..3]); + SYS_GETPGID = 121 => sys_getpgid(args[..1]); SYS_SETFSUID = 122 => sys_setfsuid(args[..1]); SYS_SETFSGID = 123 => sys_setfsgid(args[..1]); SYS_GETSID = 124 => sys_getsid(args[..1]); diff --git a/kernel/src/syscall/getpgid.rs b/kernel/src/syscall/getpgid.rs new file mode 100644 index 00000000..baa581e2 --- /dev/null +++ b/kernel/src/syscall/getpgid.rs @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MPL-2.0 + +use super::SyscallReturn; +use crate::{ + prelude::*, + process::{process_table, Pid}, +}; + +pub fn sys_getpgid(pid: Pid, ctx: &Context) -> Result { + debug!("pid = {}", pid); + // type Pid = u32, pid would never less than 0. + // if pid < 0 { + // return_errno_with_message!(Errno::EINVAL, "pid cannot be negative"); + // } + + // if pid is 0, should return the pgid of current process + if pid == 0 { + return Ok(SyscallReturn::Return(ctx.process.pgid() as _)); + } + + let process = process_table::get_process(pid) + .ok_or(Error::with_message(Errno::ESRCH, "process does not exist"))?; + + if !Arc::ptr_eq(&ctx.process.session().unwrap(), &process.session().unwrap()) { + return_errno_with_message!( + Errno::EPERM, + "the process and current process does not belong to the same session" + ); + } + + Ok(SyscallReturn::Return(process.pgid() as _)) +} diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 5a1903f7..2f851fbe 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -44,6 +44,7 @@ mod geteuid; mod getgid; mod getgroups; mod getpeername; +mod getpgid; mod getpgrp; mod getpid; mod getppid;