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  }