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 }