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