capture.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright (C) 2014 Space Monkey, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package spacelog
  15. import (
  16. "fmt"
  17. "os"
  18. "os/exec"
  19. )
  20. // CaptureOutputToFile opens a filehandle using the given path, then calls
  21. // CaptureOutputToFd on the associated filehandle.
  22. func CaptureOutputToFile(path string) error {
  23. fh, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644)
  24. if err != nil {
  25. return err
  26. }
  27. defer fh.Close()
  28. return CaptureOutputToFd(int(fh.Fd()))
  29. }
  30. // CaptureOutputToProcess starts a process and using CaptureOutputToFd,
  31. // redirects stdout and stderr to the subprocess' stdin.
  32. // CaptureOutputToProcess expects the subcommand to last the lifetime of the
  33. // process, and if the subprocess dies, will panic.
  34. func CaptureOutputToProcess(command string, args ...string) error {
  35. cmd := exec.Command(command, args...)
  36. out, err := cmd.StdinPipe()
  37. if err != nil {
  38. return err
  39. }
  40. defer out.Close()
  41. type fder interface {
  42. Fd() uintptr
  43. }
  44. out_fder, ok := out.(fder)
  45. if !ok {
  46. return fmt.Errorf("unable to get underlying pipe")
  47. }
  48. err = CaptureOutputToFd(int(out_fder.Fd()))
  49. if err != nil {
  50. return err
  51. }
  52. err = cmd.Start()
  53. if err != nil {
  54. return err
  55. }
  56. go func() {
  57. err := cmd.Wait()
  58. if err != nil {
  59. panic(fmt.Errorf("captured output process died! %s", err))
  60. }
  61. }()
  62. return nil
  63. }