Capstan is a Golang web framework that shares some similarities with others in its segment.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.0KB

  1. package capstan
  2. import (
  3. "encoding/json"
  4. "os"
  5. )
  6. // Relaunch the current binary inheriting all socket connection file
  7. // descriptors.
  8. //
  9. // This should be called from a goroutine. Parent/child process management is
  10. // not handled by this function.
  11. func Relaunch() error {
  12. env := &fdenv{
  13. Sockets: make([]*fdencode, 0),
  14. ParentPID: os.Getpid(),
  15. }
  16. files, err := fds.Files()
  17. if err != nil {
  18. return err
  19. }
  20. for _, file := range files {
  21. env.Sockets = append(env.Sockets, &fdencode{file.fp.Name(), file.fd})
  22. }
  23. buf, _ := json.Marshal(env)
  24. cwd, _ := os.Getwd()
  25. exe, _ := os.Executable()
  26. os.Setenv("CAPSTAN_SOCKETS", string(buf))
  27. proc, err := os.StartProcess(exe, os.Args, &os.ProcAttr{
  28. Dir: cwd,
  29. Env: os.Environ(),
  30. Files: []*os.File{
  31. os.Stdin,
  32. os.Stdout,
  33. os.Stderr,
  34. },
  35. })
  36. if err != nil {
  37. return err
  38. }
  39. childPID = proc.Pid
  40. if _, err := proc.Wait(); err != nil {
  41. return err
  42. }
  43. return nil
  44. }
  45. // Restart the current binary without inheriting socket file descriptors. For
  46. // blank slate reinitialization, this is the best method to call. The parent
  47. // process environment, current working directory, command line arguments, and
  48. // STDIN, STDOUT, and STDERR are inherited by the child process.
  49. //
  50. // Consider using Router.Rebind() instead of Restart unless you need to listen
  51. // on different ports.
  52. //
  53. // Be aware that there appears to be a bug with fsnotify in that O_CLOEXEC on
  54. // its file descriptors isn't honored. You should consider closing any fsnotify
  55. // watchers that are active before this call if you don't want to leak
  56. // descriptors.
  57. //
  58. // This should be called from a goroutine. Parent/child process management is
  59. // not handled by this function.
  60. func Restart() error {
  61. cwd, _ := os.Getwd()
  62. exe, _ := os.Executable()
  63. proc, err := os.StartProcess(exe, os.Args, &os.ProcAttr{
  64. Dir: cwd,
  65. Env: os.Environ(),
  66. Files: []*os.File{
  67. os.Stdin,
  68. os.Stdout,
  69. os.Stderr,
  70. },
  71. })
  72. if err != nil {
  73. return err
  74. }
  75. if _, err := proc.Wait(); err != nil {
  76. return err
  77. }
  78. return nil
  79. }