github.com/line/ostracon@v1.0.10-0.20230328032236-7f20145f065d/libs/os/os.go (about) 1 package os 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "os" 8 "os/signal" 9 "syscall" 10 ) 11 12 type logger interface { 13 Info(msg string, keyvals ...interface{}) 14 } 15 16 // TrapSignal catches the SIGTERM/SIGINT and executes cb function. After that it exits 17 // with code 0. 18 func TrapSignal(logger logger, cb func()) { 19 c := make(chan os.Signal, 1) 20 signal.Notify(c, os.Interrupt, syscall.SIGTERM) 21 go func() { 22 for sig := range c { 23 logger.Info(fmt.Sprintf("captured %v, exiting...", sig)) 24 if cb != nil { 25 cb() 26 } 27 os.Exit(0) 28 } 29 }() 30 } 31 32 // Kill the running process by sending itself SIGTERM. 33 func Kill() error { 34 p, err := os.FindProcess(os.Getpid()) 35 if err != nil { 36 return err 37 } 38 return p.Signal(syscall.SIGTERM) 39 } 40 41 func Exit(s string) { 42 fmt.Printf(s + "\n") 43 os.Exit(1) 44 } 45 46 // EnsureDir ensures the given directory exists, creating it if necessary. 47 // Errors if the path already exists as a non-directory. 48 func EnsureDir(dir string, mode os.FileMode) error { 49 err := os.MkdirAll(dir, mode) 50 if err != nil { 51 return fmt.Errorf("could not create directory %q: %w", dir, err) 52 } 53 return nil 54 } 55 56 func FileExists(filePath string) bool { 57 _, err := os.Stat(filePath) 58 return !os.IsNotExist(err) 59 } 60 61 func ReadFile(filePath string) ([]byte, error) { 62 return os.ReadFile(filePath) 63 } 64 65 func MustReadFile(filePath string) []byte { 66 fileBytes, err := os.ReadFile(filePath) 67 if err != nil { 68 Exit(fmt.Sprintf("MustReadFile failed: %v", err)) 69 return nil 70 } 71 return fileBytes 72 } 73 74 func WriteFile(filePath string, contents []byte, mode os.FileMode) error { 75 return os.WriteFile(filePath, contents, mode) 76 } 77 78 func MustWriteFile(filePath string, contents []byte, mode os.FileMode) { 79 err := WriteFile(filePath, contents, mode) 80 if err != nil { 81 Exit(fmt.Sprintf("MustWriteFile failed: %v", err)) 82 } 83 } 84 85 // CopyFile copies a file. It truncates the destination file if it exists. 86 func CopyFile(src, dst string) error { 87 srcfile, err := os.Open(src) 88 if err != nil { 89 return err 90 } 91 defer srcfile.Close() 92 93 info, err := srcfile.Stat() 94 if err != nil { 95 return err 96 } 97 if info.IsDir() { 98 return errors.New("cannot read from directories") 99 } 100 101 // create new file, truncate if exists and apply same permissions as the original one 102 dstfile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode().Perm()) 103 if err != nil { 104 return err 105 } 106 defer dstfile.Close() 107 108 _, err = io.Copy(dstfile, srcfile) 109 return err 110 }