writeLauncher writes the embedded launcher to target via atomic rename, so a currently-running launcher keeps reading its old inode.
(target string)
| 119 | // writeLauncher writes the embedded launcher to target via atomic rename, |
| 120 | // so a currently-running launcher keeps reading its old inode. |
| 121 | func writeLauncher(target string) error { |
| 122 | dir, name := filepath.Split(target) |
| 123 | f, err := os.CreateTemp(dir, name+".*") |
| 124 | if err != nil { |
| 125 | return fmt.Errorf("creating temp launcher: %v", err) |
| 126 | } |
| 127 | tmp := f.Name() |
| 128 | if _, err := f.Write(Launcher); err != nil { |
| 129 | f.Close() |
| 130 | os.Remove(tmp) |
| 131 | return fmt.Errorf("writing temp launcher: %v", err) |
| 132 | } |
| 133 | if err := f.Close(); err != nil { |
| 134 | os.Remove(tmp) |
| 135 | return err |
| 136 | } |
| 137 | if err := os.Chmod(tmp, 0755); err != nil { |
| 138 | os.Remove(tmp) |
| 139 | return err |
| 140 | } |
| 141 | if err := os.Rename(tmp, target); err != nil { |
| 142 | os.Remove(tmp) |
| 143 | return fmt.Errorf("installing launcher: %v", err) |
| 144 | } |
| 145 | return nil |
| 146 | } |
| 147 | |
| 148 | func findHookDir() (string, error) { |
| 149 | out, err := exec.Command("git", "rev-parse", "--git-path", "hooks").CombinedOutput() |