github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/exp/page/main.go (about) 1 // Copyright 2012-2020 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 // Synopsis: 6 // 7 // page [file] 8 // 9 // Description: 10 // page prints a page at a time to stdout from either stdin or a named file. 11 // It stops every x rows, where x is the number of rows determined from gtty. 12 // Single character commands tell it what to do next. Currently the only ones 13 // are return and q. 14 // 15 // Options: 16 package main 17 18 import ( 19 "bufio" 20 "fmt" 21 "io" 22 "log" 23 "os" 24 25 "github.com/mvdan/u-root-coreutils/pkg/termios" 26 ) 27 28 func page(t *termios.TTYIO, r io.Reader, w io.Writer) error { 29 rows := int64(24) 30 if w, err := t.GetWinSize(); err != nil { 31 log.Printf("Could not get win size: %v; continuing assuming %d rows", err, rows) 32 } else { 33 rows = int64(w.Row) 34 } 35 36 l := int64(1) 37 scanner := bufio.NewScanner(r) 38 for { 39 cur := l 40 for { 41 if !scanner.Scan() { 42 return scanner.Err() 43 } 44 line := scanner.Text() 45 if _, err := fmt.Fprintf(w, "%s\r\n", string(line)); err != nil { 46 return err 47 } 48 cur++ 49 if cur > l+rows { 50 break 51 } 52 } 53 if cur == l { 54 break 55 } 56 l = cur 57 if _, err := fmt.Fprintf(t, ":"); err != nil { 58 return err 59 } 60 var cmd [1]byte 61 if _, err := t.Read(cmd[:]); err != nil { 62 return err 63 } 64 switch cmd[0] { 65 default: 66 fmt.Printf("%q:unknown\n", cmd[0]) 67 case '\n', ' ': 68 case 'q': 69 return nil 70 } 71 fmt.Fprintf(w, "\r") 72 } 73 74 return nil 75 } 76 77 func main() { 78 t, err := termios.New() 79 if err != nil { 80 log.Fatal(err) 81 } 82 in := os.Stdin 83 84 switch len(os.Args) { 85 case 1: 86 case 2: 87 f, err := os.Open(os.Args[1]) 88 if err != nil { 89 log.Fatal(err) 90 } 91 in = f 92 default: 93 log.Fatal("Usage: page [file]") 94 } 95 c, err := t.Raw() 96 if err != nil { 97 log.Fatal(err) 98 } 99 defer func() { 100 if err := t.Set(c); err != nil { 101 log.Printf("Restoring modes failed; sorry (%v)", err) 102 } 103 }() 104 if err := page(t, in, os.Stdout); err != nil { 105 log.Fatal(err) 106 } 107 }