blob: 6706408f3afa906a50b742059c8c38f486d6870a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
package seccomp
import (
"io/fs"
"os"
"runtime"
"sync"
"sync/atomic"
)
type exporter struct {
opts SyscallOpts
r, w *os.File
prepareOnce sync.Once
prepareErr error
closeErr atomic.Pointer[error]
exportErr <-chan error
}
func (e *exporter) prepare() error {
e.prepareOnce.Do(func() {
if r, w, err := os.Pipe(); err != nil {
e.prepareErr = err
return
} else {
e.r, e.w = r, w
}
ec := make(chan error, 1)
go func() { ec <- exportFilter(e.w.Fd(), e.opts); close(ec); _ = e.closeWrite() }()
e.exportErr = ec
runtime.SetFinalizer(e, (*exporter).closeWrite)
})
return e.prepareErr
}
func (e *exporter) closeWrite() error {
if !e.closeErr.CompareAndSwap(nil, &fs.ErrInvalid) {
return *e.closeErr.Load()
}
if e.w == nil {
panic("closeWrite called on invalid exporter")
}
err := e.w.Close()
e.closeErr.Store(&err)
// no need for a finalizer anymore
runtime.SetFinalizer(e, nil)
return err
}
func newExporter(opts SyscallOpts) *exporter {
return &exporter{opts: opts}
}
|