0caa2d3992
We can't keep file descriptors without close-on-exec except with syscall.ForkLock held, as otherwise they could leak by accident into other children from forks in other threads. Instead we just use Cmd.ExtraFiles which handles all this for us. This fixes https://github.com/dotcloud/docker/issues/4493 Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
71 lines
1.4 KiB
Go
71 lines
1.4 KiB
Go
package nsinit
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/dotcloud/docker/pkg/libcontainer"
|
|
"io/ioutil"
|
|
"os"
|
|
)
|
|
|
|
// SyncPipe allows communication to and from the child processes
|
|
// to it's parent and allows the two independent processes to
|
|
// syncronize their state.
|
|
type SyncPipe struct {
|
|
parent, child *os.File
|
|
}
|
|
|
|
func NewSyncPipe() (s *SyncPipe, err error) {
|
|
s = &SyncPipe{}
|
|
s.child, s.parent, err = os.Pipe()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
func NewSyncPipeFromFd(parendFd, childFd uintptr) (*SyncPipe, error) {
|
|
s := &SyncPipe{}
|
|
if parendFd > 0 {
|
|
s.parent = os.NewFile(parendFd, "parendPipe")
|
|
} else if childFd > 0 {
|
|
s.child = os.NewFile(childFd, "childPipe")
|
|
} else {
|
|
return nil, fmt.Errorf("no valid sync pipe fd specified")
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
func (s *SyncPipe) SendToChild(context libcontainer.Context) error {
|
|
data, err := json.Marshal(context)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.parent.Write(data)
|
|
return nil
|
|
}
|
|
|
|
func (s *SyncPipe) ReadFromParent() (libcontainer.Context, error) {
|
|
data, err := ioutil.ReadAll(s.child)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error reading from sync pipe %s", err)
|
|
}
|
|
var context libcontainer.Context
|
|
if len(data) > 0 {
|
|
if err := json.Unmarshal(data, &context); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return context, nil
|
|
|
|
}
|
|
|
|
func (s *SyncPipe) Close() error {
|
|
if s.parent != nil {
|
|
s.parent.Close()
|
|
}
|
|
if s.child != nil {
|
|
s.child.Close()
|
|
}
|
|
return nil
|
|
}
|