git: 0c6b1ff7de56 - main - linux(4): Consolidate wait* facility into linux_common_wait().
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 31 Mar 2022 17:50:35 UTC
The branch main has been updated by dchagin:
URL: https://cgit.FreeBSD.org/src/commit/?id=0c6b1ff7de56ccaef9bb22bacfd69b07ab4aeb8a
commit 0c6b1ff7de56ccaef9bb22bacfd69b07ab4aeb8a
Author: Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-03-31 17:40:22 +0000
Commit: Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-03-31 17:40:22 +0000
linux(4): Consolidate wait* facility into linux_common_wait().
Also fix bug in waitid() implementation, use wru_self not wru_children.
Differential revision: https://reviews.freebsd.org/D31552
MFC after: 2 weeks
---
sys/compat/linux/linux_misc.c | 107 ++++++++++++++++++------------------------
1 file changed, 46 insertions(+), 61 deletions(-)
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index a084e1e9992a..b5e72989ac0a 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -988,35 +988,18 @@ linux_futimesat(struct thread *td, struct linux_futimesat_args *args)
#endif
static int
-linux_common_wait(struct thread *td, int pid, int *statusp,
- int options, struct __wrusage *wrup)
+linux_common_wait(struct thread *td, idtype_t idtype, int id, int *statusp,
+ int options, void *rup, l_siginfo_t *infop)
{
+ l_siginfo_t lsi;
siginfo_t siginfo;
- idtype_t idtype;
- id_t id;
- int error, status, tmpstat;
-
- if (pid == WAIT_ANY) {
- idtype = P_ALL;
- id = 0;
- } else if (pid < 0) {
- idtype = P_PGID;
- id = (id_t)-pid;
- } else {
- idtype = P_PID;
- id = (id_t)pid;
- }
+ struct __wrusage wru;
+ int error, status, tmpstat, sig;
- /*
- * For backward compatibility we implicitly add flags WEXITED
- * and WTRAPPED here.
- */
- options |= WEXITED | WTRAPPED;
- error = kern_wait6(td, idtype, id, &status, options, wrup, &siginfo);
- if (error)
- return (error);
+ error = kern_wait6(td, idtype, id, &status, options,
+ rup != NULL ? &wru : NULL, &siginfo);
- if (statusp) {
+ if (error == 0 && statusp) {
tmpstat = status & 0xffff;
if (WIFSIGNALED(tmpstat)) {
tmpstat = (tmpstat & 0xffffff80) |
@@ -1035,6 +1018,13 @@ linux_common_wait(struct thread *td, int pid, int *statusp,
}
error = copyout(&tmpstat, statusp, sizeof(int));
}
+ if (error == 0 && rup != NULL)
+ error = linux_copyout_rusage(&wru.wru_self, rup);
+ if (error == 0 && infop != NULL && td->td_retval[0] != 0) {
+ sig = bsd_to_linux_signal(siginfo.si_signo);
+ siginfo_to_lsiginfo(&siginfo, &lsi, sig);
+ error = copyout(&lsi, infop, sizeof(lsi));
+ }
return (error);
}
@@ -1057,37 +1047,48 @@ linux_waitpid(struct thread *td, struct linux_waitpid_args *args)
int
linux_wait4(struct thread *td, struct linux_wait4_args *args)
{
- int error, options;
- struct __wrusage wru, *wrup;
+ struct proc *p;
+ int options, id, idtype;
if (args->options & ~(LINUX_WUNTRACED | LINUX_WNOHANG |
LINUX_WCONTINUED | __WCLONE | __WNOTHREAD | __WALL))
return (EINVAL);
- options = WEXITED;
+ options = 0;
linux_to_bsd_waitopts(args->options, &options);
- if (args->rusage != NULL)
- wrup = &wru;
- else
- wrup = NULL;
- error = linux_common_wait(td, args->pid, args->status, options, wrup);
- if (error != 0)
- return (error);
- if (args->rusage != NULL)
- error = linux_copyout_rusage(&wru.wru_self, args->rusage);
- return (error);
+ /*
+ * For backward compatibility we implicitly add flags WEXITED
+ * and WTRAPPED here.
+ */
+ options |= WEXITED | WTRAPPED;
+
+ if (args->pid == WAIT_ANY) {
+ idtype = P_ALL;
+ id = 0;
+ } else if (args->pid < 0) {
+ idtype = P_PGID;
+ id = (id_t)-args->pid;
+ } else if (args->pid == 0) {
+ idtype = P_PGID;
+ p = td->td_proc;
+ PROC_LOCK(p);
+ id = p->p_pgid;
+ PROC_UNLOCK(p);
+ } else {
+ idtype = P_PID;
+ id = (id_t)args->pid;
+ }
+
+ return (linux_common_wait(td, idtype, id, args->status, options,
+ args->rusage, NULL));
}
int
linux_waitid(struct thread *td, struct linux_waitid_args *args)
{
- int status, options, sig;
- struct __wrusage wru;
- siginfo_t siginfo;
- l_siginfo_t lsi;
idtype_t idtype;
- int error;
+ int error, options;
options = 0;
linux_to_bsd_waitopts(args->options, &options);
@@ -1115,24 +1116,8 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
return (EINVAL);
}
- error = kern_wait6(td, idtype, args->id, &status, options,
- &wru, &siginfo);
- if (error != 0)
- return (error);
- if (args->rusage != NULL) {
- error = linux_copyout_rusage(&wru.wru_children,
- args->rusage);
- if (error != 0)
- return (error);
- }
- if (args->info != NULL) {
- bzero(&lsi, sizeof(lsi));
- if (td->td_retval[0] != 0) {
- sig = bsd_to_linux_signal(siginfo.si_signo);
- siginfo_to_lsiginfo(&siginfo, &lsi, sig);
- }
- error = copyout(&lsi, args->info, sizeof(lsi));
- }
+ error = linux_common_wait(td, idtype, args->id, NULL, options,
+ args->rusage, args->info);
td->td_retval[0] = 0;
return (error);