github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/core/kill/kill.go (about)

     1  // Copyright 2016-2017 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !plan9
     6  // +build !plan9
     7  
     8  // Kill kills processes.
     9  //
    10  // Synopsis:
    11  //
    12  //	kill -l
    13  //	kill [<-s | --signal | -> <isgname|signum>] pid [pid...]
    14  //
    15  // Options:
    16  //
    17  //	-l:                       list the signal names
    18  //	-name, --signal name, -s: name is the message to send. On some systems
    19  //	                          this is a string, on others a number. It is
    20  //	                          optional and an OS-dependent value will be
    21  //	                          used if it is not set. pid is a list of at
    22  //	                          least one pid.
    23  package main
    24  
    25  import (
    26  	"fmt"
    27  	"io"
    28  	"log"
    29  	"os"
    30  )
    31  
    32  const eUsage = "Usage: kill -l | kill [<-s | --signal | -> <signame|signum>] pid [pid...]"
    33  
    34  func usage(w io.Writer) {
    35  	fmt.Fprintf(w, "%s\n", eUsage)
    36  }
    37  
    38  func killProcess(w io.Writer, args ...string) error {
    39  	if len(args) < 2 {
    40  		usage(w)
    41  		return nil
    42  	}
    43  	op := args[1]
    44  	pids := args[2:]
    45  	if op[0] != '-' {
    46  		op = defaultSignal
    47  		pids = args[1:]
    48  	}
    49  	// sadly, we can not use flag. Well, we could,
    50  	// it would be pretty cheap to just put in every
    51  	// possible flag as a switch, but it just gets
    52  	// messy.
    53  	//
    54  	// kill is one of the old school commands (1971)
    55  	// and arg processing was not really standard back then.
    56  	// Also, note, the -l has no meaning on Plan 9 or Harvey
    57  	// since signals on those systems are arbitrary strings.
    58  
    59  	if op[0:2] == "-l" {
    60  		if len(args) > 2 {
    61  			usage(w)
    62  			return nil
    63  		}
    64  		fmt.Fprintf(w, "%s\n", siglist())
    65  		return nil
    66  	}
    67  
    68  	// N.B. Be careful if you want to change this. It has to continue to work if
    69  	// the signal is an arbitrary string. We take the path that the signal
    70  	// has to start with a -, or might be preceded by -s or --string.
    71  
    72  	if op == "-s" || op == "--signal" {
    73  		if len(args) < 3 {
    74  			usage(w)
    75  			return nil
    76  		}
    77  		op = args[2]
    78  		pids = args[3:]
    79  	} else {
    80  		op = op[1:]
    81  	}
    82  
    83  	s, ok := signums[op]
    84  	if !ok {
    85  		return fmt.Errorf("%v is not a valid signal", op)
    86  	}
    87  
    88  	if len(pids) < 1 {
    89  		usage(w)
    90  		return nil
    91  	}
    92  	if err := kill(s, pids...); err != nil {
    93  		return fmt.Errorf("some processes could not be killed: %v", err)
    94  	}
    95  	return nil
    96  }
    97  
    98  func main() {
    99  	if err := killProcess(os.Stdout, os.Args...); err != nil {
   100  		log.Fatal(err)
   101  	}
   102  }