github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/cmds/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 // 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 60 func main() { 61 t, err := gtty(0) 62 63 if err != nil { 64 log.Fatalf("gtty: %v", err) 65 } 66 67 if len(os.Args) == 1 { 68 os.Args = append(os.Args, "pretty") 69 } 70 71 switch os.Args[1] { 72 case "pretty": 73 pretty(os.Stdout, t) 74 case "dump": 75 b, err := json.MarshalIndent(t, "", "\t") 76 77 if err != nil { 78 log.Fatalf("json marshal: %v", err) 79 } 80 fmt.Printf("%s\n", b) 81 case "load": 82 if len(os.Args) != 3 { 83 log.Fatalf("arg count") 84 } 85 b, err := ioutil.ReadFile(os.Args[2]) 86 if err != nil { 87 log.Fatalf("stty load: %v", err) 88 } 89 if err := json.Unmarshal(b, t); err != nil { 90 log.Fatalf("stty load: %v", err) 91 } 92 if t, err = stty(0, t); err != nil { 93 log.Fatalf("stty: %v", err) 94 } 95 pretty(os.Stdout, t) 96 case "raw": 97 if _, err := setRaw(0); err != nil { 98 log.Fatalf("raw: %v", err) 99 } 100 default: 101 if err := setOpts(t, os.Args[1:]); err != nil { 102 log.Fatalf("setting opts: %v", err) 103 } 104 t, err = stty(0, t) 105 if err != nil { 106 log.Fatalf("stty: %v", err) 107 } 108 pretty(os.Stdout, t) 109 } 110 }