sync_pipe.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package namespaces
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "github.com/dotcloud/docker/pkg/libcontainer"
  8. )
  9. // SyncPipe allows communication to and from the child processes
  10. // to it's parent and allows the two independent processes to
  11. // syncronize their state.
  12. type SyncPipe struct {
  13. parent, child *os.File
  14. }
  15. func NewSyncPipe() (s *SyncPipe, err error) {
  16. s = &SyncPipe{}
  17. s.child, s.parent, err = os.Pipe()
  18. if err != nil {
  19. return nil, err
  20. }
  21. return s, nil
  22. }
  23. func NewSyncPipeFromFd(parendFd, childFd uintptr) (*SyncPipe, error) {
  24. s := &SyncPipe{}
  25. if parendFd > 0 {
  26. s.parent = os.NewFile(parendFd, "parendPipe")
  27. } else if childFd > 0 {
  28. s.child = os.NewFile(childFd, "childPipe")
  29. } else {
  30. return nil, fmt.Errorf("no valid sync pipe fd specified")
  31. }
  32. return s, nil
  33. }
  34. func (s *SyncPipe) Child() *os.File {
  35. return s.child
  36. }
  37. func (s *SyncPipe) Parent() *os.File {
  38. return s.parent
  39. }
  40. func (s *SyncPipe) SendToChild(context libcontainer.Context) error {
  41. data, err := json.Marshal(context)
  42. if err != nil {
  43. return err
  44. }
  45. s.parent.Write(data)
  46. return nil
  47. }
  48. func (s *SyncPipe) ReadFromParent() (libcontainer.Context, error) {
  49. data, err := ioutil.ReadAll(s.child)
  50. if err != nil {
  51. return nil, fmt.Errorf("error reading from sync pipe %s", err)
  52. }
  53. var context libcontainer.Context
  54. if len(data) > 0 {
  55. if err := json.Unmarshal(data, &context); err != nil {
  56. return nil, err
  57. }
  58. }
  59. return context, nil
  60. }
  61. func (s *SyncPipe) Close() error {
  62. if s.parent != nil {
  63. s.parent.Close()
  64. }
  65. if s.child != nil {
  66. s.child.Close()
  67. }
  68. return nil
  69. }