linux(4): Fixup waitid handling P_PGID idtype.

Since Linux 5.4, if id is zero, then wait for any child that is in the same
process grop as the caller's process group.

Differential revision:  https://reviews.freebsd.org/D31567
MFC after:		2 weeks

(cherry picked from commit 4e3aefb923)
This commit is contained in:
Dmitry Chagin 2022-03-31 20:44:00 +03:00
parent 2c029214d3
commit cbb2112dca
2 changed files with 12 additions and 2 deletions

View file

@ -60,8 +60,10 @@ int linux_kernver(struct thread *td);
#define LINUX_KERNVER_2004000 LINUX_KERNVER(2,4,0)
#define LINUX_KERNVER_2006000 LINUX_KERNVER(2,6,0)
#define LINUX_KERNVER_2006039 LINUX_KERNVER(2,6,39)
#define LINUX_KERNVER_5004000 LINUX_KERNVER(5,4,0)
#define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000)
#define linux_use54(t) (linux_kernver(t) >= LINUX_KERNVER_5004000)
extern int linux_debug;
extern int linux_default_openfiles;

View file

@ -1097,6 +1097,8 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
{
idtype_t idtype;
int error, options;
struct proc *p;
pid_t id;
if (args->options & ~(LINUX_WNOHANG | LINUX_WNOWAIT | LINUX_WEXITED |
LINUX_WSTOPPED | LINUX_WCONTINUED | __WCLONE | __WNOTHREAD | __WALL))
@ -1108,6 +1110,7 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
options |= WEXITED | WTRAPPED | WUNTRACED |
WCONTINUED | WLINUXCLONE;
id = args->id;
switch (args->idtype) {
case LINUX_P_ALL:
idtype = P_ALL;
@ -1118,7 +1121,12 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
idtype = P_PID;
break;
case LINUX_P_PGID:
if (args->id <= 0)
if (linux_use54(td) && args->id == 0) {
p = td->td_proc;
PROC_LOCK(p);
id = p->p_pgid;
PROC_UNLOCK(p);
} else if (args->id <= 0)
return (EINVAL);
idtype = P_PGID;
break;
@ -1129,7 +1137,7 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
return (EINVAL);
}
error = linux_common_wait(td, idtype, args->id, NULL, options,
error = linux_common_wait(td, idtype, id, NULL, options,
args->rusage, args->info);
td->td_retval[0] = 0;