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  }