9fans.net/go@v0.0.7/cmd/samterm/unix.go (about)

     1  // +build unix
     2  
     3  package main
     4  
     5  import (
     6  	"fmt"
     7  	"io/fs"
     8  	"os"
     9  	"syscall"
    10  
    11  	"golang.org/x/sys/unix"
    12  )
    13  
    14  func extstart() {
    15  	user := os.Getenv("USER")
    16  	if user == "" {
    17  		return
    18  	}
    19  	disp := os.Getenv("DISPLAY")
    20  	if disp != "" {
    21  		exname = fmt.Sprintf("/tmp/.sam.%s.%s", user, disp)
    22  	} else {
    23  		exname = fmt.Sprintf("/tmp/.sam.%s", user)
    24  	}
    25  	err := syscall.Mkfifo(exname, 0600)
    26  	if err != nil {
    27  		if !os.IsExist(err) {
    28  			return
    29  		}
    30  		st, err := os.Stat(exname)
    31  		if err != nil {
    32  			return
    33  		}
    34  		if st.Mode()&fs.ModeNamedPipe == 0 {
    35  			removeextern()
    36  			if err := syscall.Mkfifo(exname, 0600); err != nil {
    37  				return
    38  			}
    39  		}
    40  	}
    41  
    42  	fd, err := syscall.Open(exname, syscall.O_RDONLY|syscall.O_NONBLOCK, 0)
    43  	if err != nil {
    44  		removeextern()
    45  		return
    46  	}
    47  
    48  	// Turn off no-delay and provide ourselves as a lingering
    49  	// writer so as not to get end of file on read.
    50  	flags, err := unix.FcntlInt(uintptr(fd), syscall.F_GETFL, 0)
    51  	if err != nil {
    52  		goto Fail
    53  	}
    54  	if _, err := unix.FcntlInt(uintptr(fd), syscall.F_SETFL, flags & ^syscall.O_NONBLOCK); err != nil {
    55  		goto Fail
    56  	}
    57  	if _, err := syscall.Open(exname, syscall.O_WRONLY, 0); err != nil {
    58  		goto Fail
    59  	}
    60  
    61  	plumbc = make(chan string)
    62  	go extproc(plumbc, os.NewFile(uintptr(fd), exname))
    63  	// atexit(removeextern)
    64  	return
    65  
    66  Fail:
    67  	syscall.Close(fd)
    68  	removeextern()
    69  }