github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+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 }