mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
[op] Move SignalAct to abi/linux package.
There were also other duplicate definitions of the same struct that I have now removed. Updates #214 PiperOrigin-RevId: 378579954
This commit is contained in:
@@ -227,6 +227,21 @@ type Sigevent struct {
|
||||
UnRemainder [44]byte
|
||||
}
|
||||
|
||||
// LINT.IfChange
|
||||
|
||||
// SigAction represents struct sigaction.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type SigAction struct {
|
||||
Handler uint64
|
||||
Flags uint64
|
||||
Restorer uint64
|
||||
Mask SignalSet
|
||||
}
|
||||
|
||||
// LINT.ThenChange(../../safecopy/safecopy_unsafe.go)
|
||||
|
||||
// Possible values for Sigevent.Notify, aka struct sigevent::sigev_notify.
|
||||
const (
|
||||
SIGEV_SIGNAL = 0
|
||||
|
||||
@@ -342,6 +342,9 @@ func errorFromFaultSignal(addr uintptr, sig int32) error {
|
||||
// handler however, and if this is function is being used externally then the
|
||||
// same courtesy is expected.
|
||||
func ReplaceSignalHandler(sig unix.Signal, handler uintptr, previous *uintptr) error {
|
||||
// TODO(gvisor.dev/issue/6160): This struct is the same as linux.SigAction.
|
||||
// Once the usermem dependency is removed from primitive, delete this replica
|
||||
// and remove IFTTT comments in abi/linux/signal.go.
|
||||
var sa struct {
|
||||
handler uintptr
|
||||
flags uint64
|
||||
|
||||
@@ -15,7 +15,6 @@ go_library(
|
||||
"arch_x86_impl.go",
|
||||
"auxv.go",
|
||||
"signal.go",
|
||||
"signal_act.go",
|
||||
"signal_amd64.go",
|
||||
"signal_arm64.go",
|
||||
"signal_info.go",
|
||||
|
||||
@@ -134,10 +134,6 @@ type Context interface {
|
||||
// RegisterMap returns a map of all registers.
|
||||
RegisterMap() (map[string]uintptr, error)
|
||||
|
||||
// NewSignalAct returns a new object that is equivalent to struct sigaction
|
||||
// in the guest architecture.
|
||||
NewSignalAct() NativeSignalAct
|
||||
|
||||
// NewSignalStack returns a new object that is equivalent to stack_t in the
|
||||
// guest architecture.
|
||||
NewSignalStack() NativeSignalStack
|
||||
@@ -148,7 +144,7 @@ type Context interface {
|
||||
// st is the stack where the signal handler frame should be
|
||||
// constructed.
|
||||
//
|
||||
// act is the SignalAct that specifies how this signal is being
|
||||
// act is the SigAction that specifies how this signal is being
|
||||
// handled.
|
||||
//
|
||||
// info is the SignalInfo of the signal being delivered.
|
||||
@@ -157,7 +153,7 @@ type Context interface {
|
||||
// stack is not going to be used).
|
||||
//
|
||||
// sigset is the signal mask before entering the signal handler.
|
||||
SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt *SignalStack, sigset linux.SignalSet) error
|
||||
SignalSetup(st *Stack, act *linux.SigAction, info *SignalInfo, alt *SignalStack, sigset linux.SignalSet) error
|
||||
|
||||
// SignalRestore restores context after returning from a signal
|
||||
// handler.
|
||||
|
||||
@@ -19,28 +19,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
)
|
||||
|
||||
// SignalAct represents the action that should be taken when a signal is
|
||||
// delivered, and is equivalent to struct sigaction.
|
||||
//
|
||||
// +marshal
|
||||
// +stateify savable
|
||||
type SignalAct struct {
|
||||
Handler uint64
|
||||
Flags uint64
|
||||
Restorer uint64 // Only used on amd64.
|
||||
Mask linux.SignalSet
|
||||
}
|
||||
|
||||
// SerializeFrom implements NativeSignalAct.SerializeFrom.
|
||||
func (s *SignalAct) SerializeFrom(other *SignalAct) {
|
||||
*s = *other
|
||||
}
|
||||
|
||||
// DeserializeTo implements NativeSignalAct.DeserializeTo.
|
||||
func (s *SignalAct) DeserializeTo(other *SignalAct) {
|
||||
*other = *s
|
||||
}
|
||||
|
||||
// SignalStack represents information about a user stack, and is equivalent to
|
||||
// stack_t.
|
||||
//
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
// Copyright 2018 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package arch
|
||||
|
||||
import "gvisor.dev/gvisor/pkg/marshal"
|
||||
|
||||
// Special values for SignalAct.Handler.
|
||||
const (
|
||||
// SignalActDefault is SIG_DFL and specifies that the default behavior for
|
||||
// a signal should be taken.
|
||||
SignalActDefault = 0
|
||||
|
||||
// SignalActIgnore is SIG_IGN and specifies that a signal should be
|
||||
// ignored.
|
||||
SignalActIgnore = 1
|
||||
)
|
||||
|
||||
// Available signal flags.
|
||||
const (
|
||||
SignalFlagNoCldStop = 0x00000001
|
||||
SignalFlagNoCldWait = 0x00000002
|
||||
SignalFlagSigInfo = 0x00000004
|
||||
SignalFlagRestorer = 0x04000000
|
||||
SignalFlagOnStack = 0x08000000
|
||||
SignalFlagRestart = 0x10000000
|
||||
SignalFlagInterrupt = 0x20000000
|
||||
SignalFlagNoDefer = 0x40000000
|
||||
SignalFlagResetHandler = 0x80000000
|
||||
)
|
||||
|
||||
// IsSigInfo returns true iff this handle expects siginfo.
|
||||
func (s SignalAct) IsSigInfo() bool {
|
||||
return s.Flags&SignalFlagSigInfo != 0
|
||||
}
|
||||
|
||||
// IsNoDefer returns true iff this SignalAct has the NoDefer flag set.
|
||||
func (s SignalAct) IsNoDefer() bool {
|
||||
return s.Flags&SignalFlagNoDefer != 0
|
||||
}
|
||||
|
||||
// IsRestart returns true iff this SignalAct has the Restart flag set.
|
||||
func (s SignalAct) IsRestart() bool {
|
||||
return s.Flags&SignalFlagRestart != 0
|
||||
}
|
||||
|
||||
// IsResetHandler returns true iff this SignalAct has the ResetHandler flag set.
|
||||
func (s SignalAct) IsResetHandler() bool {
|
||||
return s.Flags&SignalFlagResetHandler != 0
|
||||
}
|
||||
|
||||
// IsOnStack returns true iff this SignalAct has the OnStack flag set.
|
||||
func (s SignalAct) IsOnStack() bool {
|
||||
return s.Flags&SignalFlagOnStack != 0
|
||||
}
|
||||
|
||||
// HasRestorer returns true iff this SignalAct has the Restorer flag set.
|
||||
func (s SignalAct) HasRestorer() bool {
|
||||
return s.Flags&SignalFlagRestorer != 0
|
||||
}
|
||||
|
||||
// NativeSignalAct is a type that is equivalent to struct sigaction in the
|
||||
// guest architecture.
|
||||
type NativeSignalAct interface {
|
||||
marshal.Marshallable
|
||||
|
||||
// SerializeFrom copies the data in the host SignalAct s into this object.
|
||||
SerializeFrom(s *SignalAct)
|
||||
|
||||
// DeserializeTo copies the data in this object into the host SignalAct s.
|
||||
DeserializeTo(s *SignalAct)
|
||||
}
|
||||
@@ -81,11 +81,6 @@ type UContext64 struct {
|
||||
Sigset linux.SignalSet
|
||||
}
|
||||
|
||||
// NewSignalAct implements Context.NewSignalAct.
|
||||
func (c *context64) NewSignalAct() NativeSignalAct {
|
||||
return &SignalAct{}
|
||||
}
|
||||
|
||||
// NewSignalStack implements Context.NewSignalStack.
|
||||
func (c *context64) NewSignalStack() NativeSignalStack {
|
||||
return &SignalStack{}
|
||||
@@ -110,7 +105,7 @@ func (c *context64) fpuFrameSize() (size int, useXsave bool) {
|
||||
|
||||
// SignalSetup implements Context.SignalSetup. (Compare to Linux's
|
||||
// arch/x86/kernel/signal.c:__setup_rt_frame().)
|
||||
func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt *SignalStack, sigset linux.SignalSet) error {
|
||||
func (c *context64) SignalSetup(st *Stack, act *linux.SigAction, info *SignalInfo, alt *SignalStack, sigset linux.SignalSet) error {
|
||||
sp := st.Bottom
|
||||
|
||||
// "The 128-byte area beyond the location pointed to by %rsp is considered
|
||||
@@ -187,7 +182,7 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt
|
||||
// Prior to proceeding, figure out if the frame will exhaust the range
|
||||
// for the signal stack. This is not allowed, and should immediately
|
||||
// force signal delivery (reverting to the default handler).
|
||||
if act.IsOnStack() && alt.IsEnabled() && !alt.Contains(frameBottom) {
|
||||
if act.Flags&linux.SA_ONSTACK != 0 && alt.IsEnabled() && !alt.Contains(frameBottom) {
|
||||
return unix.EFAULT
|
||||
}
|
||||
|
||||
@@ -203,7 +198,7 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt
|
||||
return err
|
||||
}
|
||||
ucAddr := st.Bottom
|
||||
if act.HasRestorer() {
|
||||
if act.Flags&linux.SA_RESTORER != 0 {
|
||||
// Push the restorer return address.
|
||||
// Note that this doesn't need to be popped.
|
||||
if _, err := primitive.CopyUint64Out(st, StackBottomMagic, act.Restorer); err != nil {
|
||||
|
||||
@@ -71,18 +71,13 @@ type UContext64 struct {
|
||||
MContext SignalContext64
|
||||
}
|
||||
|
||||
// NewSignalAct implements Context.NewSignalAct.
|
||||
func (c *context64) NewSignalAct() NativeSignalAct {
|
||||
return &SignalAct{}
|
||||
}
|
||||
|
||||
// NewSignalStack implements Context.NewSignalStack.
|
||||
func (c *context64) NewSignalStack() NativeSignalStack {
|
||||
return &SignalStack{}
|
||||
}
|
||||
|
||||
// SignalSetup implements Context.SignalSetup.
|
||||
func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt *SignalStack, sigset linux.SignalSet) error {
|
||||
func (c *context64) SignalSetup(st *Stack, act *linux.SigAction, info *SignalInfo, alt *SignalStack, sigset linux.SignalSet) error {
|
||||
sp := st.Bottom
|
||||
|
||||
// Construct the UContext64 now since we need its size.
|
||||
@@ -114,7 +109,7 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt
|
||||
// Prior to proceeding, figure out if the frame will exhaust the range
|
||||
// for the signal stack. This is not allowed, and should immediately
|
||||
// force signal delivery (reverting to the default handler).
|
||||
if act.IsOnStack() && alt.IsEnabled() && !alt.Contains(frameBottom) {
|
||||
if act.Flags&linux.SA_ONSTACK != 0 && alt.IsEnabled() && !alt.Contains(frameBottom) {
|
||||
return unix.EFAULT
|
||||
}
|
||||
|
||||
@@ -137,7 +132,7 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt
|
||||
c.Regs.Regs[0] = uint64(info.Signo)
|
||||
c.Regs.Regs[1] = uint64(infoAddr)
|
||||
c.Regs.Regs[2] = uint64(ucAddr)
|
||||
c.Regs.Regs[30] = uint64(act.Restorer)
|
||||
c.Regs.Regs[30] = act.Restorer
|
||||
|
||||
// Save the thread's floating point state.
|
||||
c.sigFPState = append(c.sigFPState, c.fpState)
|
||||
|
||||
@@ -16,7 +16,6 @@ package kernel
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
@@ -30,14 +29,14 @@ type SignalHandlers struct {
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
|
||||
// actions is the action to be taken upon receiving each signal.
|
||||
actions map[linux.Signal]arch.SignalAct
|
||||
actions map[linux.Signal]linux.SigAction
|
||||
}
|
||||
|
||||
// NewSignalHandlers returns a new SignalHandlers specifying all default
|
||||
// actions.
|
||||
func NewSignalHandlers() *SignalHandlers {
|
||||
return &SignalHandlers{
|
||||
actions: make(map[linux.Signal]arch.SignalAct),
|
||||
actions: make(map[linux.Signal]linux.SigAction),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +58,9 @@ func (sh *SignalHandlers) CopyForExec() *SignalHandlers {
|
||||
sh.mu.Lock()
|
||||
defer sh.mu.Unlock()
|
||||
for sig, act := range sh.actions {
|
||||
if act.Handler == arch.SignalActIgnore {
|
||||
sh2.actions[sig] = arch.SignalAct{
|
||||
Handler: arch.SignalActIgnore,
|
||||
if act.Handler == linux.SIG_IGN {
|
||||
sh2.actions[sig] = linux.SigAction{
|
||||
Handler: linux.SIG_IGN,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,15 +72,15 @@ func (sh *SignalHandlers) IsIgnored(sig linux.Signal) bool {
|
||||
sh.mu.Lock()
|
||||
defer sh.mu.Unlock()
|
||||
sa, ok := sh.actions[sig]
|
||||
return ok && sa.Handler == arch.SignalActIgnore
|
||||
return ok && sa.Handler == linux.SIG_IGN
|
||||
}
|
||||
|
||||
// dequeueActionLocked returns the SignalAct that should be used to handle sig.
|
||||
//
|
||||
// Preconditions: sh.mu must be locked.
|
||||
func (sh *SignalHandlers) dequeueAction(sig linux.Signal) arch.SignalAct {
|
||||
func (sh *SignalHandlers) dequeueAction(sig linux.Signal) linux.SigAction {
|
||||
act := sh.actions[sig]
|
||||
if act.IsResetHandler() {
|
||||
if act.Flags&linux.SA_RESETHAND != 0 {
|
||||
delete(sh.actions, sig)
|
||||
}
|
||||
return act
|
||||
|
||||
@@ -670,10 +670,10 @@ func (t *Task) exitNotifyLocked(fromPtraceDetach bool) {
|
||||
t.parent.tg.signalHandlers.mu.Lock()
|
||||
if t.tg.terminationSignal == linux.SIGCHLD || fromPtraceDetach {
|
||||
if act, ok := t.parent.tg.signalHandlers.actions[linux.SIGCHLD]; ok {
|
||||
if act.Handler == arch.SignalActIgnore {
|
||||
if act.Handler == linux.SIG_IGN {
|
||||
t.exitParentAcked = true
|
||||
signalParent = false
|
||||
} else if act.Flags&arch.SignalFlagNoCldWait != 0 {
|
||||
} else if act.Flags&linux.SA_NOCLDWAIT != 0 {
|
||||
t.exitParentAcked = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ var defaultActions = map[linux.Signal]SignalAction{
|
||||
}
|
||||
|
||||
// computeAction figures out what to do given a signal number
|
||||
// and an arch.SignalAct. SIGSTOP always results in a SignalActionStop,
|
||||
// and an linux.SigAction. SIGSTOP always results in a SignalActionStop,
|
||||
// and SIGKILL always results in a SignalActionTerm.
|
||||
// Signal 0 is always ignored as many programs use it for various internal functions
|
||||
// and don't expect it to do anything.
|
||||
@@ -97,7 +97,7 @@ var defaultActions = map[linux.Signal]SignalAction{
|
||||
// 0, the default action is taken;
|
||||
// 1, the signal is ignored;
|
||||
// anything else, the function returns SignalActionHandler.
|
||||
func computeAction(sig linux.Signal, act arch.SignalAct) SignalAction {
|
||||
func computeAction(sig linux.Signal, act linux.SigAction) SignalAction {
|
||||
switch sig {
|
||||
case linux.SIGSTOP:
|
||||
return SignalActionStop
|
||||
@@ -108,9 +108,9 @@ func computeAction(sig linux.Signal, act arch.SignalAct) SignalAction {
|
||||
}
|
||||
|
||||
switch act.Handler {
|
||||
case arch.SignalActDefault:
|
||||
case linux.SIG_DFL:
|
||||
return defaultActions[sig]
|
||||
case arch.SignalActIgnore:
|
||||
case linux.SIG_IGN:
|
||||
return SignalActionIgnore
|
||||
default:
|
||||
return SignalActionHandler
|
||||
@@ -155,7 +155,7 @@ func (t *Task) PendingSignals() linux.SignalSet {
|
||||
}
|
||||
|
||||
// deliverSignal delivers the given signal and returns the following run state.
|
||||
func (t *Task) deliverSignal(info *arch.SignalInfo, act arch.SignalAct) taskRunState {
|
||||
func (t *Task) deliverSignal(info *arch.SignalInfo, act linux.SigAction) taskRunState {
|
||||
sigact := computeAction(linux.Signal(info.Signo), act)
|
||||
|
||||
if t.haveSyscallReturn {
|
||||
@@ -172,7 +172,7 @@ func (t *Task) deliverSignal(info *arch.SignalInfo, act arch.SignalAct) taskRunS
|
||||
fallthrough
|
||||
case sre == syserror.ERESTART_RESTARTBLOCK:
|
||||
fallthrough
|
||||
case (sre == syserror.ERESTARTSYS && !act.IsRestart()):
|
||||
case (sre == syserror.ERESTARTSYS && act.Flags&linux.SA_RESTART == 0):
|
||||
t.Debugf("Not restarting syscall %d after errno %d: interrupted by signal %d", t.Arch().SyscallNo(), sre, info.Signo)
|
||||
t.Arch().SetReturn(uintptr(-ExtractErrno(syserror.EINTR, -1)))
|
||||
default:
|
||||
@@ -236,7 +236,7 @@ func (t *Task) deliverSignal(info *arch.SignalInfo, act arch.SignalAct) taskRunS
|
||||
|
||||
// deliverSignalToHandler changes the task's userspace state to enter the given
|
||||
// user-configured handler for the given signal.
|
||||
func (t *Task) deliverSignalToHandler(info *arch.SignalInfo, act arch.SignalAct) error {
|
||||
func (t *Task) deliverSignalToHandler(info *arch.SignalInfo, act linux.SigAction) error {
|
||||
// Signal delivery to an application handler interrupts restartable
|
||||
// sequences.
|
||||
t.rseqInterrupt()
|
||||
@@ -248,7 +248,7 @@ func (t *Task) deliverSignalToHandler(info *arch.SignalInfo, act arch.SignalAct)
|
||||
// N.B. This is a *copy* of the alternate stack that the user's signal
|
||||
// handler expects to see in its ucontext (even if it's not in use).
|
||||
alt := t.signalStack
|
||||
if act.IsOnStack() && alt.IsEnabled() {
|
||||
if act.Flags&linux.SA_ONSTACK != 0 && alt.IsEnabled() {
|
||||
alt.SetOnStack()
|
||||
if !alt.Contains(sp) {
|
||||
sp = hostarch.Addr(alt.Top())
|
||||
@@ -289,7 +289,7 @@ func (t *Task) deliverSignalToHandler(info *arch.SignalInfo, act arch.SignalAct)
|
||||
|
||||
// Add our signal mask.
|
||||
newMask := t.signalMask | act.Mask
|
||||
if !act.IsNoDefer() {
|
||||
if act.Flags&linux.SA_NODEFER == 0 {
|
||||
newMask |= linux.SignalSetOf(linux.Signal(info.Signo))
|
||||
}
|
||||
t.SetSignalMask(newMask)
|
||||
@@ -572,9 +572,9 @@ func (t *Task) forceSignal(sig linux.Signal, unconditional bool) {
|
||||
func (t *Task) forceSignalLocked(sig linux.Signal, unconditional bool) {
|
||||
blocked := linux.SignalSetOf(sig)&t.signalMask != 0
|
||||
act := t.tg.signalHandlers.actions[sig]
|
||||
ignored := act.Handler == arch.SignalActIgnore
|
||||
ignored := act.Handler == linux.SIG_IGN
|
||||
if blocked || ignored || unconditional {
|
||||
act.Handler = arch.SignalActDefault
|
||||
act.Handler = linux.SIG_DFL
|
||||
t.tg.signalHandlers.actions[sig] = act
|
||||
if blocked {
|
||||
t.setSignalMaskLocked(t.signalMask &^ linux.SignalSetOf(sig))
|
||||
@@ -680,11 +680,11 @@ func (t *Task) SetSignalStack(alt arch.SignalStack) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SetSignalAct atomically sets the thread group's signal action for signal sig
|
||||
// SetSigAction atomically sets the thread group's signal action for signal sig
|
||||
// to *actptr (if actptr is not nil) and returns the old signal action.
|
||||
func (tg *ThreadGroup) SetSignalAct(sig linux.Signal, actptr *arch.SignalAct) (arch.SignalAct, error) {
|
||||
func (tg *ThreadGroup) SetSigAction(sig linux.Signal, actptr *linux.SigAction) (linux.SigAction, error) {
|
||||
if !sig.IsValid() {
|
||||
return arch.SignalAct{}, syserror.EINVAL
|
||||
return linux.SigAction{}, syserror.EINVAL
|
||||
}
|
||||
|
||||
tg.pidns.owner.mu.RLock()
|
||||
@@ -718,27 +718,6 @@ func (tg *ThreadGroup) SetSignalAct(sig linux.Signal, actptr *arch.SignalAct) (a
|
||||
return oldact, nil
|
||||
}
|
||||
|
||||
// CopyOutSignalAct converts the given SignalAct into an architecture-specific
|
||||
// type and then copies it out to task memory.
|
||||
func (t *Task) CopyOutSignalAct(addr hostarch.Addr, s *arch.SignalAct) error {
|
||||
n := t.Arch().NewSignalAct()
|
||||
n.SerializeFrom(s)
|
||||
_, err := n.CopyOut(t, addr)
|
||||
return err
|
||||
}
|
||||
|
||||
// CopyInSignalAct copies an architecture-specific sigaction type from task
|
||||
// memory and then converts it into a SignalAct.
|
||||
func (t *Task) CopyInSignalAct(addr hostarch.Addr) (arch.SignalAct, error) {
|
||||
n := t.Arch().NewSignalAct()
|
||||
var s arch.SignalAct
|
||||
if _, err := n.CopyIn(t, addr); err != nil {
|
||||
return s, err
|
||||
}
|
||||
n.DeserializeTo(&s)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// CopyOutSignalStack converts the given SignalStack into an
|
||||
// architecture-specific type and then copies it out to task memory.
|
||||
func (t *Task) CopyOutSignalStack(addr hostarch.Addr, s *arch.SignalStack) error {
|
||||
@@ -909,7 +888,7 @@ func (t *Task) signalStop(target *Task, code int32, status int32) {
|
||||
t.tg.signalHandlers.mu.Lock()
|
||||
defer t.tg.signalHandlers.mu.Unlock()
|
||||
act, ok := t.tg.signalHandlers.actions[linux.SIGCHLD]
|
||||
if !ok || (act.Handler != arch.SignalActIgnore && act.Flags&arch.SignalFlagNoCldStop == 0) {
|
||||
if !ok || (act.Handler != linux.SIG_IGN && act.Flags&linux.SA_NOCLDSTOP == 0) {
|
||||
sigchld := &arch.SignalInfo{
|
||||
Signo: int32(linux.SIGCHLD),
|
||||
Code: code,
|
||||
|
||||
@@ -21,25 +21,16 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
)
|
||||
|
||||
// FIXME(gvisor.dev/issue/214): Move to pkg/abi/linux along with definitions in
|
||||
// pkg/sentry/arch.
|
||||
type sigaction struct {
|
||||
handler uintptr
|
||||
flags uint64
|
||||
restorer uintptr
|
||||
mask uint64
|
||||
}
|
||||
|
||||
// IgnoreChildStop sets the SA_NOCLDSTOP flag, causing child processes to not
|
||||
// generate SIGCHLD when they stop.
|
||||
func IgnoreChildStop() error {
|
||||
var sa sigaction
|
||||
var sa linux.SigAction
|
||||
|
||||
// Get the existing signal handler information, and set the flag.
|
||||
if _, _, e := unix.RawSyscall6(unix.SYS_RT_SIGACTION, uintptr(unix.SIGCHLD), 0, uintptr(unsafe.Pointer(&sa)), linux.SignalSetSize, 0, 0); e != 0 {
|
||||
return e
|
||||
}
|
||||
sa.flags |= linux.SA_NOCLDSTOP
|
||||
sa.Flags |= linux.SA_NOCLDSTOP
|
||||
if _, _, e := unix.RawSyscall6(unix.SYS_RT_SIGACTION, uintptr(unix.SIGCHLD), uintptr(unsafe.Pointer(&sa)), 0, linux.SignalSetSize, 0, 0); e != 0 {
|
||||
return e
|
||||
}
|
||||
|
||||
@@ -130,8 +130,8 @@ func sigAction(t *kernel.Task, addr hostarch.Addr) string {
|
||||
return "null"
|
||||
}
|
||||
|
||||
sa, err := t.CopyInSignalAct(addr)
|
||||
if err != nil {
|
||||
var sa linux.SigAction
|
||||
if _, err := sa.CopyIn(t, addr); err != nil {
|
||||
return fmt.Sprintf("%#x (error copying sigaction: %v)", addr, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -251,20 +251,20 @@ func RtSigaction(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.S
|
||||
return 0, nil, syserror.EINVAL
|
||||
}
|
||||
|
||||
var newactptr *arch.SignalAct
|
||||
var newactptr *linux.SigAction
|
||||
if newactarg != 0 {
|
||||
newact, err := t.CopyInSignalAct(newactarg)
|
||||
if err != nil {
|
||||
var newact linux.SigAction
|
||||
if _, err := newact.CopyIn(t, newactarg); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
newactptr = &newact
|
||||
}
|
||||
oldact, err := t.ThreadGroup().SetSignalAct(sig, newactptr)
|
||||
oldact, err := t.ThreadGroup().SetSigAction(sig, newactptr)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if oldactarg != 0 {
|
||||
if err := t.CopyOutSignalAct(oldactarg, &oldact); err != nil {
|
||||
if _, err := oldact.CopyOut(t, oldactarg); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user