Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/cloudflare/tableflip/parent.go')
-rw-r--r--vendor/github.com/cloudflare/tableflip/parent.go76
1 files changed, 76 insertions, 0 deletions
diff --git a/vendor/github.com/cloudflare/tableflip/parent.go b/vendor/github.com/cloudflare/tableflip/parent.go
new file mode 100644
index 000000000..8b974d27c
--- /dev/null
+++ b/vendor/github.com/cloudflare/tableflip/parent.go
@@ -0,0 +1,76 @@
+package tableflip
+
+import (
+ "encoding/gob"
+ "io"
+ "io/ioutil"
+ "os"
+
+ "github.com/pkg/errors"
+)
+
+const (
+ sentinelEnvVar = "TABLEFLIP_HAS_PARENT_7DIU3"
+ notifyReady = 42
+)
+
+type parent struct {
+ wr *os.File
+ exited <-chan error
+}
+
+func newParent(env *env) (*parent, map[fileName]*file, error) {
+ if env.getenv(sentinelEnvVar) == "" {
+ return nil, make(map[fileName]*file), nil
+ }
+
+ wr := env.newFile(3, "write")
+ rd := env.newFile(4, "read")
+
+ var names [][]string
+ dec := gob.NewDecoder(rd)
+ if err := dec.Decode(&names); err != nil {
+ return nil, nil, errors.Wrap(err, "can't decode names from parent process")
+ }
+
+ files := make(map[fileName]*file)
+ for i, parts := range names {
+ var key fileName
+ copy(key[:], parts)
+
+ // Start at 5 to account for stdin, etc. and write
+ // and read pipes.
+ fd := 5 + i
+ env.closeOnExec(fd)
+ files[key] = &file{
+ env.newFile(uintptr(fd), key.String()),
+ uintptr(fd),
+ }
+ }
+
+ exited := make(chan error, 1)
+ go func() {
+ defer rd.Close()
+
+ n, err := io.Copy(ioutil.Discard, rd)
+ if n != 0 {
+ exited <- errors.New("unexpected data from parent process")
+ } else if err != nil {
+ exited <- errors.Wrap(err, "unexpected error while waiting for parent to exit")
+ }
+ close(exited)
+ }()
+
+ return &parent{
+ wr: wr,
+ exited: exited,
+ }, files, nil
+}
+
+func (ps *parent) sendReady() error {
+ defer ps.wr.Close()
+ if _, err := ps.wr.Write([]byte{notifyReady}); err != nil {
+ return errors.Wrap(err, "can't notify parent process")
+ }
+ return nil
+}