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