github.com/rminnich/u-root@v7.0.0+incompatible/cmds/core/stty/stty.go (about)

     1  // Copyright 2012-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  // stty is an stty command in Go.
     6  // It follows many of the conventions of standard stty.
     7  // However, it can produce JSON output, for later use, and can
     8  // read that JSON later to configure it.
     9  //
    10  // stty has always had an odd set of flags. -flag means turn flag off;
    11  // flag means turn flag on. Except for those flags which make an argument;
    12  // in that case they look like flag <arg>
    13  // To make the flag package continue to work, we've changed the - to a ~.
    14  //
    15  // Programmatically, the options are set with a []string, not lots of magic numbers that
    16  // are not portable across kernels.
    17  //
    18  // The default action is to print in the model of standard stty, which is all most
    19  // people ever do anyway.
    20  
    21  // The command works like this:
    22  // stty [verb] [options]
    23  // Verbs are:
    24  // dump -- dump the json of the struct to stdout
    25  // load -- read a json file from stdin and use it to set
    26  // raw -- convenience command to set raw
    27  // cooked -- convenience command to set cooked
    28  // In common stty usage, options may be specified without a verb.
    29  //
    30  // any other verb, with a ~ or without, is taken to mean standard stty args, e.g.
    31  // stty ~echo
    32  // turns off echo. Flags with arguments work too:
    33  // stty intr 1
    34  // sets the interrupt character to ^A.
    35  //
    36  // The JSON encoding lets you do things like this:
    37  // stty dump | sed whatever > file
    38  // stty load file
    39  // Further, one can easily push and pop state in by storing the current
    40  // state in a file in JSON, making changes, and restoring it later. This has
    41  // always been inconvenient in standard stty.
    42  //
    43  // While GNU stty can do some of this, its way of doing it is harder to read and not
    44  // as portable, since the format they use is not self-describing:
    45  // stty -g
    46  // 4500:5:bf:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
    47  //
    48  // We always do our operations on fd 0, as that is standard, and we always do an initial
    49  // termios.GTTY to ensure we have access to fd 0.
    50  package main
    51  
    52  import (
    53  	"encoding/json"
    54  	"fmt"
    55  	"io/ioutil"
    56  	"log"
    57  	"os"
    58  
    59  	"github.com/u-root/u-root/pkg/termios"
    60  )
    61  
    62  func main() {
    63  	t, err := termios.GTTY(0)
    64  
    65  	if err != nil {
    66  		log.Fatalf("termios.GTTY: %v", err)
    67  	}
    68  
    69  	if len(os.Args) == 1 {
    70  		os.Args = append(os.Args, "pretty")
    71  	}
    72  
    73  	switch os.Args[1] {
    74  	case "pretty":
    75  		fmt.Printf("%v\n", t.String())
    76  	case "dump":
    77  		b, err := json.MarshalIndent(t, "", "\t")
    78  
    79  		if err != nil {
    80  			log.Fatalf("json marshal: %v", err)
    81  		}
    82  		fmt.Printf("%s\n", b)
    83  	case "load":
    84  		if len(os.Args) != 3 {
    85  			log.Fatalf("arg count")
    86  		}
    87  		b, err := ioutil.ReadFile(os.Args[2])
    88  		if err != nil {
    89  			log.Fatalf("stty load: %v", err)
    90  		}
    91  		if err := json.Unmarshal(b, t); err != nil {
    92  			log.Fatalf("stty load: %v", err)
    93  		}
    94  		n, err := t.STTY(0)
    95  		if err != nil {
    96  			log.Fatalf("stty: %v", err)
    97  		}
    98  		fmt.Printf("%v\n", n.String())
    99  	case "raw":
   100  		if _, err := termios.Raw(0); err != nil {
   101  			log.Fatalf("raw: %v", err)
   102  		}
   103  	default:
   104  		if err := t.SetOpts(os.Args[1:]); err != nil {
   105  			log.Fatalf("setting opts: %v", err)
   106  		}
   107  		n, err := t.STTY(0)
   108  		if err != nil {
   109  			log.Fatalf("stty: %v", err)
   110  		}
   111  		fmt.Printf("%v\n", n.String())
   112  	}
   113  }