Advertisement
Guest User

Untitled

a guest
Apr 21st, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.59 KB | None | 0 0
  1. package capture
  2.  
  3. import (
  4. "bufio"
  5. "fmt"
  6. "io"
  7. "os"
  8. "syscall"
  9. "testing"
  10. )
  11.  
  12. type Capture struct {
  13. done chan struct{}
  14. fd int
  15. oldfile *os.File
  16. io.Reader
  17. }
  18.  
  19. func (c *Capture) Close() error {
  20. // fd -> closefd
  21. closefd, err := syscall.Dup(c.fd)
  22. if err != nil {
  23. return err
  24. }
  25.  
  26. // oldfile.fd -> fd
  27. err = syscall.Dup2(int(c.oldfile.Fd()), c.fd)
  28. if err != nil {
  29. return err
  30. }
  31.  
  32. err = syscall.Close(closefd)
  33. if err != nil {
  34. return err
  35. }
  36.  
  37. <-c.done
  38.  
  39. return nil
  40. }
  41.  
  42. func NewCapture(fd int) (*Capture, error) {
  43. c := &Capture{
  44. done: make(chan struct{}),
  45. fd: fd,
  46. }
  47.  
  48. // fd -> oldfd
  49. oldfd, err := syscall.Dup(c.fd)
  50. if err != nil {
  51. return nil, err
  52. }
  53.  
  54. c.oldfile = os.NewFile(uintptr(oldfd), "")
  55.  
  56. ospr, ospw, err := os.Pipe()
  57. if err != nil {
  58. c.oldfile.Close()
  59. return nil, err
  60. }
  61. defer ospw.Close()
  62.  
  63. // ospw -> fd
  64. err = syscall.Dup2(int(ospw.Fd()), c.fd)
  65. if err != nil {
  66. c.oldfile.Close()
  67. ospr.Close()
  68. return nil, err
  69. }
  70.  
  71. iopr, iopw := io.Pipe()
  72.  
  73. go func() {
  74. // copy from ospr -> c.oldfile and iopw (read by c.Reader)
  75. _, err = io.Copy(io.MultiWriter(c.oldfile, iopw), ospr)
  76. iopw.CloseWithError(err)
  77. close(c.done)
  78. }()
  79.  
  80. c.Reader = iopr
  81.  
  82. return c, nil
  83. }
  84.  
  85. func TestCapture(t *testing.T) {
  86. c, err := NewCapture(1)
  87. if err != nil {
  88. t.Fatal(err)
  89. }
  90.  
  91. done := make(chan struct{})
  92. go func() {
  93. br := bufio.NewReader(c)
  94. for {
  95. s, err := br.ReadString('\n')
  96. if err != nil {
  97. break
  98. }
  99. fmt.Fprint(os.Stderr, s) // TODO: write to insights
  100. }
  101. close(done)
  102. }()
  103.  
  104. fmt.Println("Hello!")
  105.  
  106. err = c.Close()
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110.  
  111. <-done
  112.  
  113. fmt.Println("Message 2")
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement