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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
package tableflip
import (
"fmt"
"os"
"strings"
)
type testProcess struct {
fds []*os.File
env env
signals chan os.Signal
sigErr chan error
waitErr chan error
quit chan struct{}
}
func newTestProcess(fds []*os.File, envstr []string) (*testProcess, error) {
environ := make(map[string]string)
for _, entry := range envstr {
parts := strings.SplitN(entry, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid env entry: %s", entry)
}
environ[parts[0]] = parts[1]
}
return &testProcess{
fds,
env{
newFile: func(fd uintptr, name string) *os.File {
return fds[fd-3]
},
getenv: func(key string) string {
return environ[key]
},
closeOnExec: func(int) {},
},
make(chan os.Signal, 1),
make(chan error),
make(chan error),
make(chan struct{}),
}, nil
}
func (tp *testProcess) Signal(sig os.Signal) error {
select {
case tp.signals <- sig:
return <-tp.sigErr
case <-tp.quit:
return nil
}
}
func (tp *testProcess) Wait() error {
select {
case err := <-tp.waitErr:
return err
case <-tp.quit:
return nil
}
}
func (tp *testProcess) String() string {
return fmt.Sprintf("tp=%p", tp)
}
func (tp *testProcess) exit(err error) {
select {
case tp.waitErr <- err:
close(tp.quit)
case <-tp.quit:
}
}
func (tp *testProcess) recvSignal(err error) os.Signal {
sig := <-tp.signals
tp.sigErr <- err
return sig
}
func (tp *testProcess) notify() (map[fileName]*file, <-chan error, error) {
parent, files, err := newParent(&tp.env)
if err != nil {
return nil, nil, err
}
return files, parent.result, parent.sendReady()
}
|