Kernel/LibC: implement proper getpgid and setpgid
This commit is contained in:
parent
d634fec8dc
commit
60a2185ee6
|
@ -80,12 +80,13 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_setegid(gid_t);
|
BAN::ErrorOr<long> sys_setegid(gid_t);
|
||||||
BAN::ErrorOr<long> sys_setreuid(uid_t, uid_t);
|
BAN::ErrorOr<long> sys_setreuid(uid_t, uid_t);
|
||||||
BAN::ErrorOr<long> sys_setregid(gid_t, gid_t);
|
BAN::ErrorOr<long> sys_setregid(gid_t, gid_t);
|
||||||
BAN::ErrorOr<long> sys_setpgrp();
|
BAN::ErrorOr<long> sys_setpgid(pid_t, pid_t);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_getuid() const { return m_credentials.ruid(); }
|
BAN::ErrorOr<long> sys_getuid() const { return m_credentials.ruid(); }
|
||||||
BAN::ErrorOr<long> sys_getgid() const { return m_credentials.rgid(); }
|
BAN::ErrorOr<long> sys_getgid() const { return m_credentials.rgid(); }
|
||||||
BAN::ErrorOr<long> sys_geteuid() const { return m_credentials.euid(); }
|
BAN::ErrorOr<long> sys_geteuid() const { return m_credentials.euid(); }
|
||||||
BAN::ErrorOr<long> sys_getegid() const { return m_credentials.egid(); }
|
BAN::ErrorOr<long> sys_getegid() const { return m_credentials.egid(); }
|
||||||
|
BAN::ErrorOr<long> sys_getpgid(pid_t);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_open(BAN::StringView, int, mode_t = 0);
|
BAN::ErrorOr<long> sys_open(BAN::StringView, int, mode_t = 0);
|
||||||
BAN::ErrorOr<long> sys_openat(int, BAN::StringView, int, mode_t = 0);
|
BAN::ErrorOr<long> sys_openat(int, BAN::StringView, int, mode_t = 0);
|
||||||
|
|
|
@ -1152,11 +1152,104 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_setpgrp()
|
BAN::ErrorOr<long> Process::sys_setpgid(pid_t pid, pid_t pgid)
|
||||||
|
{
|
||||||
|
if (pgid < 0)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
pid = m_pid;
|
||||||
|
if (pgid == 0)
|
||||||
|
pgid = m_pid;
|
||||||
|
|
||||||
|
if (pid != pgid)
|
||||||
|
{
|
||||||
|
bool pgid_valid = false;
|
||||||
|
for_each_process_in_session(m_sid,
|
||||||
|
[&](Process& process)
|
||||||
|
{
|
||||||
|
if (process.pgrp() == pgid)
|
||||||
|
{
|
||||||
|
pgid_valid = true;
|
||||||
|
return BAN::Iteration::Break;
|
||||||
|
}
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!pgid_valid)
|
||||||
|
return BAN::Error::from_errno(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pid == pid)
|
||||||
|
{
|
||||||
|
if (is_session_leader())
|
||||||
|
return BAN::Error::from_errno(EPERM);
|
||||||
|
m_pgrp = pgid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int error = ESRCH;
|
||||||
|
for_each_process(
|
||||||
|
[&](Process& process)
|
||||||
|
{
|
||||||
|
if (process.pid() != pid)
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
|
||||||
|
if (process.m_parent != m_pid)
|
||||||
|
error = ESRCH;
|
||||||
|
else if (process.is_session_leader())
|
||||||
|
error = EPERM;
|
||||||
|
else if (process.m_has_called_exec)
|
||||||
|
error = EACCES;
|
||||||
|
else if (process.m_sid != m_sid)
|
||||||
|
error = EPERM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error = 0;
|
||||||
|
process.m_pgrp = pgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BAN::Iteration::Break;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error == 0)
|
||||||
|
return 0;
|
||||||
|
return BAN::Error::from_errno(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> Process::sys_getpgid(pid_t pid)
|
||||||
{
|
{
|
||||||
LockGuard _(m_lock);
|
LockGuard _(m_lock);
|
||||||
m_pgrp = pid();
|
|
||||||
return pgrp();
|
if (pid == 0 || pid == m_pid)
|
||||||
|
return m_pgrp;
|
||||||
|
|
||||||
|
pid_t result;
|
||||||
|
int error = ESRCH;
|
||||||
|
for_each_process(
|
||||||
|
[&](Process& process)
|
||||||
|
{
|
||||||
|
if (process.pid() != pid)
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
|
||||||
|
if (process.sid() != m_sid)
|
||||||
|
error = EPERM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error = 0;
|
||||||
|
result = process.pgrp();
|
||||||
|
}
|
||||||
|
|
||||||
|
return BAN::Iteration::Break;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error == 0)
|
||||||
|
return result;
|
||||||
|
return BAN::Error::from_errno(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::String> Process::absolute_path_of(BAN::StringView path) const
|
BAN::ErrorOr<BAN::String> Process::absolute_path_of(BAN::StringView path) const
|
||||||
|
|
|
@ -173,11 +173,11 @@ namespace Kernel
|
||||||
case SYS_GET_PID:
|
case SYS_GET_PID:
|
||||||
ret = Process::current().pid();
|
ret = Process::current().pid();
|
||||||
break;
|
break;
|
||||||
case SYS_GET_PGRP:
|
case SYS_GET_PGID:
|
||||||
ret = Process::current().pgrp();
|
ret = Process::current().sys_getpgid((pid_t)arg1);
|
||||||
break;
|
break;
|
||||||
case SYS_SET_PGRP:
|
case SYS_SET_PGID:
|
||||||
ret = Process::current().sys_setpgrp();
|
ret = Process::current().sys_setpgid((pid_t)arg1, (pid_t)arg2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dwarnln("Unknown syscall {}", syscall);
|
dwarnln("Unknown syscall {}", syscall);
|
||||||
|
|
|
@ -48,8 +48,8 @@ __BEGIN_DECLS
|
||||||
#define SYS_SIGNAL_DONE 41
|
#define SYS_SIGNAL_DONE 41
|
||||||
#define SYS_TCSETPGRP 42
|
#define SYS_TCSETPGRP 42
|
||||||
#define SYS_GET_PID 43
|
#define SYS_GET_PID 43
|
||||||
#define SYS_GET_PGRP 44
|
#define SYS_GET_PGID 44
|
||||||
#define SYS_SET_PGRP 45
|
#define SYS_SET_PGID 45
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,12 @@ gid_t getegid(void)
|
||||||
|
|
||||||
pid_t getpgrp(void)
|
pid_t getpgrp(void)
|
||||||
{
|
{
|
||||||
return syscall(SYS_GET_PGRP);
|
return getpgid(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t getpgid(pid_t pid)
|
||||||
|
{
|
||||||
|
return syscall(SYS_GET_PGID, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int seteuid(uid_t uid)
|
int seteuid(uid_t uid)
|
||||||
|
@ -245,7 +250,13 @@ int setregid(gid_t rgid, gid_t egid)
|
||||||
|
|
||||||
pid_t setpgrp(void)
|
pid_t setpgrp(void)
|
||||||
{
|
{
|
||||||
return syscall(SYS_SET_PGRP);
|
setpgid(0, 0);
|
||||||
|
return getpgrp();
|
||||||
|
}
|
||||||
|
|
||||||
|
int setpgid(pid_t pid, pid_t pgid)
|
||||||
|
{
|
||||||
|
return syscall(SYS_SET_PGID, pid, pgid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcsetpgrp(int fildes, pid_t pgid_id)
|
int tcsetpgrp(int fildes, pid_t pgid_id)
|
||||||
|
|
Loading…
Reference in New Issue