github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/minterm/minterm_windows.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  //go:build windows
     5  // +build windows
     6  
     7  package minterm
     8  
     9  import (
    10  	"io"
    11  	"os"
    12  
    13  	"github.com/keybase/client/go/logger"
    14  	"github.com/keybase/go-crypto/ssh/terminal"
    15  )
    16  
    17  // terminal takes io.ReadWriter, so for windows we mash
    18  // stdin and stdout back together with this.
    19  type WindowsReadWriter struct {
    20  	r io.Reader
    21  	w io.Writer
    22  }
    23  
    24  func (rw WindowsReadWriter) Read(p []byte) (n int, err error) {
    25  	return rw.r.Read(p)
    26  }
    27  
    28  func (rw WindowsReadWriter) Write(p []byte) (n int, err error) {
    29  	return rw.w.Write(p)
    30  }
    31  
    32  func (m *MinTerm) open() error {
    33  	// Must be O_RDWR, or we can't mask the password as the user types it.
    34  	fin, err := os.OpenFile("CONIN$", os.O_RDWR, 0)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	// Must be O_RDWR, or else GetSize below breaks.
    39  	fout, err := os.OpenFile("CONOUT$", os.O_RDWR, 0)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	m.termIn = fin
    45  	m.termOut = fout
    46  	m.closeTermOut = true // since it's a different file...
    47  	fdout := int(fout.Fd())
    48  	w, h, err := terminal.GetSize(fdout)
    49  	if err != nil {
    50  		return err
    51  	}
    52  	m.width, m.height = w, h
    53  	return nil
    54  }
    55  
    56  // Use a Windows output writer to eat control codes that look ugly on legacy terminals.
    57  // As a bonus, we can do color prompts this way.
    58  func (m *MinTerm) getReadWriter() io.ReadWriter {
    59  	return WindowsReadWriter{r: m.termIn, w: logger.OutputWriterFromFile(m.termOut)}
    60  }