Implement waitid() system call.

Differential Revision:	https://reviews.freebsd.org/D1046
This commit is contained in:
Dmitry Chagin 2015-05-24 15:06:39 +00:00
parent 18599d43e9
commit e5fe4ccf59
6 changed files with 74 additions and 4 deletions

View File

@ -84,7 +84,6 @@ DUMMY(mq_timedreceive);
DUMMY(mq_notify);
DUMMY(mq_getsetattr);
DUMMY(kexec_load);
DUMMY(waitid);
/* linux 2.6.11: */
DUMMY(add_key);
DUMMY(request_key);

View File

@ -466,7 +466,9 @@
281 AUE_NULL STD { int linux_mq_notify(void); }
282 AUE_NULL STD { int linux_mq_getsetattr(void); }
283 AUE_NULL STD { int linux_kexec_load(void); }
284 AUE_NULL STD { int linux_waitid(void); }
284 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \
l_siginfo_t *info, int options, \
struct l_rusage *rusage); }
285 AUE_NULL UNIMPL
; linux 2.6.11:
286 AUE_NULL STD { int linux_add_key(void); }

View File

@ -916,6 +916,68 @@ linux_wait4(struct thread *td, struct linux_wait4_args *args)
return (error);
}
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;
struct proc *p;
int error;
options = 0;
linux_to_bsd_waitopts(args->options, &options);
if (options & ~(WNOHANG | WNOWAIT | WEXITED | WUNTRACED | WCONTINUED))
return (EINVAL);
if (!(options & (WEXITED | WUNTRACED | WCONTINUED)))
return (EINVAL);
switch (args->idtype) {
case LINUX_P_ALL:
idtype = P_ALL;
break;
case LINUX_P_PID:
if (args->id <= 0)
return (EINVAL);
idtype = P_PID;
break;
case LINUX_P_PGID:
if (args->id <= 0)
return (EINVAL);
idtype = P_PGID;
break;
default:
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) {
p = td->td_proc;
if (td->td_retval[0] == 0)
bzero(&lsi, sizeof(lsi));
else {
sig = BSD_TO_LINUX_SIGNAL(siginfo.si_signo);
siginfo_to_lsiginfo(&siginfo, &lsi, sig);
}
error = copyout(&lsi, args->info, sizeof(lsi));
}
td->td_retval[0] = 0;
return (error);
}
int
linux_mknod(struct thread *td, struct linux_mknod_args *args)
{

View File

@ -125,6 +125,12 @@ extern int stclohz;
#define __WALL 0x40000000
#define __WCLONE 0x80000000
/* Linux waitid idtype */
#define LINUX_P_ALL 0
#define LINUX_P_PID 1
#define LINUX_P_PGID 2
int linux_common_wait(struct thread *td, int pid, int *status,
int options, struct rusage *ru);
void linux_to_bsd_waitopts(int options, int *bsdopts);

View File

@ -80,7 +80,6 @@ DUMMY(mbind);
DUMMY(get_mempolicy);
DUMMY(set_mempolicy);
DUMMY(kexec_load);
DUMMY(waitid);
/* linux 2.6.11: */
DUMMY(add_key);
DUMMY(request_key);

View File

@ -474,7 +474,9 @@
282 AUE_NULL STD { int linux_mq_getsetattr(l_mqd_t mqd, const struct mq_attr *attr, \
struct mq_attr *oattr); }
283 AUE_NULL STD { int linux_kexec_load(void); }
284 AUE_NULL STD { int linux_waitid(void); }
284 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \
l_siginfo_t *info, int options, \
void *rusage); }
285 AUE_NULL UNIMPL
; linux 2.6.11:
286 AUE_NULL STD { int linux_add_key(void); }