diff options
Diffstat (limited to 'pkg/sentry/kernel/sessions.go')
-rw-r--r-- | pkg/sentry/kernel/sessions.go | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index 78a5b4063..6fd65f2b0 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -17,6 +17,7 @@ package kernel import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/refs" + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -119,6 +120,13 @@ func (pg *ProcessGroup) Originator() *ThreadGroup { return pg.originator } +// IsOrphan returns true if this process group is an orphan. +func (pg *ProcessGroup) IsOrphan() bool { + pg.originator.TaskSet().mu.RLock() + defer pg.originator.TaskSet().mu.RUnlock() + return pg.ancestors == 0 +} + // incRefWithParent grabs a reference. // // This function is called when this ProcessGroup is being associated with some @@ -224,6 +232,27 @@ func (pg *ProcessGroup) Session() *Session { return pg.session } +// SendSignal sends a signal to all processes inside the process group. It is +// analagous to kernel/signal.c:kill_pgrp. +func (pg *ProcessGroup) SendSignal(info *arch.SignalInfo) error { + tasks := pg.originator.TaskSet() + tasks.mu.RLock() + defer tasks.mu.RUnlock() + + var lastErr error + for t := range tasks.Root.tids { + if t == t.tg.leader && t.tg.ProcessGroup() == pg { + t.tg.signalHandlers.mu.Lock() + defer t.tg.signalHandlers.mu.Unlock() + infoCopy := *info + if err := t.sendSignalLocked(&infoCopy, true /*group*/); err != nil { + lastErr = err + } + } + } + return lastErr +} + // CreateSession creates a new Session, with the ThreadGroup as the leader. // // EPERM may be returned if either the given ThreadGroup is already a Session |