github.com/alecthomas/kong@v0.9.1-0.20240410131203-2ab5733f1179/guesswidth_unix.go (about)

     1  //go:build (!appengine && linux) || freebsd || darwin || dragonfly || netbsd || openbsd
     2  // +build !appengine,linux freebsd darwin dragonfly netbsd openbsd
     3  
     4  package kong
     5  
     6  import (
     7  	"io"
     8  	"os"
     9  	"strconv"
    10  	"syscall"
    11  	"unsafe"
    12  )
    13  
    14  func guessWidth(w io.Writer) int {
    15  	// check if COLUMNS env is set to comply with
    16  	// http://pubs.opengroup.org/onlinepubs/009604499/basedefs/xbd_chap08.html
    17  	colsStr := os.Getenv("COLUMNS")
    18  	if colsStr != "" {
    19  		if cols, err := strconv.Atoi(colsStr); err == nil {
    20  			return cols
    21  		}
    22  	}
    23  
    24  	if t, ok := w.(*os.File); ok {
    25  		fd := t.Fd()
    26  		var dimensions [4]uint16
    27  
    28  		if _, _, err := syscall.Syscall6(
    29  			syscall.SYS_IOCTL,
    30  			uintptr(fd), //nolint: unconvert
    31  			uintptr(syscall.TIOCGWINSZ),
    32  			uintptr(unsafe.Pointer(&dimensions)), //nolint: gas
    33  			0, 0, 0,
    34  		); err == 0 {
    35  			if dimensions[1] == 0 {
    36  				return 80
    37  			}
    38  			return int(dimensions[1])
    39  		}
    40  	}
    41  	return 80
    42  }