pkg.re/essentialkaos/ek@v12.36.0+incompatible/system/procname/setprocname.go (about) 1 // +build linux darwin 2 3 // Package procname provides methods for changing process name in the process tree 4 package procname 5 6 // ////////////////////////////////////////////////////////////////////////////////// // 7 // // 8 // Copyright (c) 2021 ESSENTIAL KAOS // 9 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 10 // // 11 // ////////////////////////////////////////////////////////////////////////////////// // 12 13 import ( 14 "errors" 15 "os" 16 "reflect" 17 "strings" 18 "unsafe" 19 ) 20 21 // ////////////////////////////////////////////////////////////////////////////////// // 22 23 var ( 24 // ErrWrongSize is returned if given slice have the wrong size 25 ErrWrongSize = errors.New("Given slice must have same size as os.Arg") 26 27 // ErrWrongArguments is returned if one of given arguments is empty 28 ErrWrongArguments = errors.New("Arguments can't be empty") 29 ) 30 31 // ////////////////////////////////////////////////////////////////////////////////// // 32 33 // Set changes current process command in process tree 34 func Set(args []string) error { 35 if len(args) != len(os.Args) { 36 return ErrWrongSize 37 } 38 39 for i := 0; i < len(args); i++ { 40 if args[i] == os.Args[i] { 41 continue 42 } 43 44 changeArgument(i, args[i]) 45 } 46 47 return nil 48 } 49 50 // Replace replaces one argument in process command 51 // 52 // WARNING: Be careful with using os.Args or options.Parse result 53 // as 'from' argument. After using this method given variable content 54 // will be replaced. Use strutil.Copy method in this case. 55 func Replace(from, to string) error { 56 if from == "" || to == "" { 57 return ErrWrongArguments 58 } 59 60 for i, arg := range os.Args { 61 if arg == from { 62 changeArgument(i, to) 63 } 64 } 65 66 return nil 67 } 68 69 // ////////////////////////////////////////////////////////////////////////////////// // 70 71 func changeArgument(index int, newArg string) { 72 argStrHr := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[index])) 73 arg := (*[1 << 30]byte)(unsafe.Pointer(argStrHr.Data))[:argStrHr.Len] 74 75 curArg := os.Args[index] 76 curArgLen := len(curArg) 77 newArgLen := len(newArg) 78 79 switch { 80 case curArgLen > newArgLen: 81 newArg = newArg + strings.Repeat(" ", curArgLen-newArgLen) 82 case curArgLen < newArgLen: 83 newArg = newArg[:curArgLen] 84 } 85 86 n := copy(arg, newArg) 87 88 if n < len(arg) { 89 arg[n] = 0 90 } 91 }