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

     1  // Copyright 2019 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  // getty Open a TTY and invoke a shell
     6  // There are no special options and no login support
     7  // Also getty exits after starting the shell so if one exits the shell, there
     8  // is no more shell!
     9  //
    10  // Synopsis:
    11  //
    12  //	getty <port> <baud> [term]
    13  package main
    14  
    15  import (
    16  	"flag"
    17  	"fmt"
    18  	"log"
    19  	"os"
    20  	"os/exec"
    21  	"strconv"
    22  
    23  	"github.com/mvdan/u-root-coreutils/pkg/termios"
    24  	"github.com/mvdan/u-root-coreutils/pkg/upath"
    25  )
    26  
    27  var (
    28  	verbose = flag.Bool("v", false, "verbose log")
    29  	debug   = func(string, ...interface{}) {}
    30  	cmdList []string
    31  	envs    []string
    32  )
    33  
    34  func init() {
    35  	r := upath.UrootPath
    36  	cmdList = []string{
    37  		r("/bin/defaultsh"),
    38  		r("/bin/sh"),
    39  	}
    40  }
    41  
    42  func main() {
    43  	flag.Parse()
    44  
    45  	if *verbose {
    46  		debug = log.Printf
    47  	}
    48  
    49  	port := flag.Arg(0)
    50  	baud, err := strconv.Atoi(flag.Arg(1))
    51  	if err != nil {
    52  		baud = 0
    53  	}
    54  	term := flag.Arg(2)
    55  
    56  	log.SetPrefix("getty: ")
    57  
    58  	ttyS, err := termios.NewTTYS(port)
    59  	if err != nil {
    60  		log.Fatalf("Unable to open port %s: %v", port, err)
    61  	}
    62  
    63  	if _, err := ttyS.Serial(baud); err != nil {
    64  		log.Printf("Unable to configure port %s and set baudrate %d: %v", port, baud, err)
    65  	}
    66  
    67  	// Output the u-root banner
    68  	log.New(ttyS, "", log.LstdFlags).Printf("Welcome to u-root!")
    69  	fmt.Fprintln(ttyS, `                              _`)
    70  	fmt.Fprintln(ttyS, `   _   _      _ __ ___   ___ | |_`)
    71  	fmt.Fprintln(ttyS, `  | | | |____| '__/ _ \ / _ \| __|`)
    72  	fmt.Fprintln(ttyS, `  | |_| |____| | | (_) | (_) | |_`)
    73  	fmt.Fprintln(ttyS, `   \__,_|    |_|  \___/ \___/ \__|`)
    74  	fmt.Fprintln(ttyS)
    75  
    76  	if term != "" {
    77  		err = os.Setenv("TERM", term)
    78  		if err != nil {
    79  			debug("Unable to set 'TERM=%s': %v", port, err)
    80  		}
    81  	}
    82  	envs = os.Environ()
    83  	debug("envs %v", envs)
    84  
    85  	for _, v := range cmdList {
    86  		debug("Trying to run %v", v)
    87  		if _, err := os.Stat(v); os.IsNotExist(err) {
    88  			debug("%v", err)
    89  			continue
    90  		}
    91  
    92  		cmd := exec.Command(v)
    93  		cmd.Env = envs
    94  		ttyS.Ctty(cmd)
    95  		debug("running %v", cmd)
    96  		if err := cmd.Start(); err != nil {
    97  			log.Printf("Error starting %v: %v", v, err)
    98  			continue
    99  		}
   100  		if err := cmd.Process.Release(); err != nil {
   101  			log.Printf("Error releasing process %v:%v", v, err)
   102  		}
   103  		// stop after first valid command
   104  		return
   105  	}
   106  	log.Printf("No suitable executable found in %+v", cmdList)
   107  }