summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/syscalls/linux
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/syscalls/linux')
-rw-r--r--pkg/sentry/syscalls/linux/sys_thread.go67
1 files changed, 35 insertions, 32 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go
index 14fa7ef92..26f7e8ead 100644
--- a/pkg/sentry/syscalls/linux/sys_thread.go
+++ b/pkg/sentry/syscalls/linux/sys_thread.go
@@ -181,6 +181,32 @@ func Vfork(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
return clone(t, syscall.CLONE_VM|syscall.CLONE_VFORK|int(syscall.SIGCHLD), 0, 0, 0, 0)
}
+// parseCommonWaitOptions applies the options common to wait4 and waitid to
+// wopts.
+func parseCommonWaitOptions(wopts *kernel.WaitOptions, options int) error {
+ switch options & (linux.WCLONE | linux.WALL) {
+ case 0:
+ wopts.NonCloneTasks = true
+ case linux.WCLONE:
+ wopts.CloneTasks = true
+ case linux.WALL:
+ wopts.NonCloneTasks = true
+ wopts.CloneTasks = true
+ default:
+ return syscall.EINVAL
+ }
+ if options&linux.WCONTINUED != 0 {
+ wopts.Events |= kernel.EventGroupContinue
+ }
+ if options&linux.WNOHANG == 0 {
+ wopts.BlockInterruptErr = kernel.ERESTARTSYS
+ }
+ if options&linux.WNOTHREAD == 0 {
+ wopts.SiblingChildren = true
+ }
+ return nil
+}
+
// wait4 waits for the given child process to exit.
func wait4(t *kernel.Task, pid int, statusAddr usermem.Addr, options int, rusageAddr usermem.Addr) (uintptr, error) {
if options&^(linux.WNOHANG|linux.WUNTRACED|linux.WCONTINUED|linux.WNOTHREAD|linux.WALL|linux.WCLONE) != 0 {
@@ -207,29 +233,12 @@ func wait4(t *kernel.Task, pid int, statusAddr usermem.Addr, options int, rusage
wopts.SpecificTID = kernel.ThreadID(pid)
}
- switch options & (linux.WCLONE | linux.WALL) {
- case 0:
- wopts.NonCloneTasks = true
- case linux.WCLONE:
- wopts.CloneTasks = true
- case linux.WALL:
- wopts.NonCloneTasks = true
- wopts.CloneTasks = true
- default:
- return 0, syscall.EINVAL
+ if err := parseCommonWaitOptions(&wopts, options); err != nil {
+ return 0, err
}
if options&linux.WUNTRACED != 0 {
wopts.Events |= kernel.EventChildGroupStop
}
- if options&linux.WCONTINUED != 0 {
- wopts.Events |= kernel.EventGroupContinue
- }
- if options&linux.WNOHANG == 0 {
- wopts.BlockInterruptErr = kernel.ERESTARTSYS
- }
- if options&linux.WNOTHREAD == 0 {
- wopts.SiblingChildren = true
- }
wr, err := t.Wait(&wopts)
if err != nil {
@@ -281,16 +290,15 @@ func Waitid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal
options := int(args[3].Uint())
rusageAddr := args[4].Pointer()
- if options&^(linux.WNOHANG|linux.WEXITED|linux.WSTOPPED|linux.WCONTINUED|linux.WNOWAIT|linux.WNOTHREAD) != 0 {
+ if options&^(linux.WNOHANG|linux.WEXITED|linux.WSTOPPED|linux.WCONTINUED|linux.WNOWAIT|linux.WNOTHREAD|linux.WALL|linux.WCLONE) != 0 {
return 0, nil, syscall.EINVAL
}
if options&(linux.WEXITED|linux.WSTOPPED|linux.WCONTINUED) == 0 {
return 0, nil, syscall.EINVAL
}
wopts := kernel.WaitOptions{
- NonCloneTasks: true,
- Events: kernel.EventTraceeStop,
- ConsumeEvent: options&linux.WNOWAIT == 0,
+ Events: kernel.EventTraceeStop,
+ ConsumeEvent: options&linux.WNOWAIT == 0,
}
switch idtype {
case linux.P_ALL:
@@ -301,21 +309,16 @@ func Waitid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal
default:
return 0, nil, syscall.EINVAL
}
+
+ if err := parseCommonWaitOptions(&wopts, options); err != nil {
+ return 0, nil, err
+ }
if options&linux.WEXITED != 0 {
wopts.Events |= kernel.EventExit
}
if options&linux.WSTOPPED != 0 {
wopts.Events |= kernel.EventChildGroupStop
}
- if options&linux.WCONTINUED != 0 {
- wopts.Events |= kernel.EventGroupContinue
- }
- if options&linux.WNOHANG == 0 {
- wopts.BlockInterruptErr = kernel.ERESTARTSYS
- }
- if options&linux.WNOTHREAD == 0 {
- wopts.SiblingChildren = true
- }
wr, err := t.Wait(&wopts)
if err != nil {