// watcher tracks the changes to the value file of a pin func (pin *Pin) watcher() { buf := make([]byte, syscall.SizeofInotifyEvent) n, err := syscall.Read(pin.Fd, buf) for err == nil && n == syscall.SizeofInotifyEvent { data, _ := ioutil.ReadFile(pin.ValuePath) pin.State = data[0] pin.EventChannel <- &Event{State: pin.State} n, err = syscall.Read(pin.Fd, buf) } }
func readPipe(p int, c chan<- string) { var s string buf := make([]byte, 4096) n, _ := syscall.Read(p, buf) for n > 0 { s += string(buf[:n]) n, _ = syscall.Read(p, buf) } c <- s }
// handle requests func (nbd *NBD) handle() { buf := make([]byte, 2<<19) var x request for { syscall.Read(nbd.socket, buf[0:28]) x.magic = binary.BigEndian.Uint32(buf) x.typus = binary.BigEndian.Uint32(buf[4:8]) x.handle = binary.BigEndian.Uint64(buf[8:16]) x.from = binary.BigEndian.Uint64(buf[16:24]) x.len = binary.BigEndian.Uint32(buf[24:28]) switch x.magic { case NBD_REPLY_MAGIC: fallthrough case NBD_REQUEST_MAGIC: switch x.typus { case NBD_CMD_READ: nbd.device.ReadAt(buf[16:16+x.len], int64(x.from)) binary.BigEndian.PutUint32(buf[0:4], NBD_REPLY_MAGIC) binary.BigEndian.PutUint32(buf[4:8], 0) syscall.Write(nbd.socket, buf[0:16+x.len]) case NBD_CMD_WRITE: n, _ := syscall.Read(nbd.socket, buf[28:28+x.len]) for uint32(n) < x.len { m, _ := syscall.Read(nbd.socket, buf[28+n:28+x.len]) n += m } nbd.device.WriteAt(buf[28:28+x.len], int64(x.from)) binary.BigEndian.PutUint32(buf[0:4], NBD_REPLY_MAGIC) binary.BigEndian.PutUint32(buf[4:8], 0) syscall.Write(nbd.socket, buf[0:16]) case NBD_CMD_DISC: panic("Disconnect") case NBD_CMD_FLUSH: nbd.device.Sync() binary.BigEndian.PutUint32(buf[0:4], NBD_REPLY_MAGIC) binary.BigEndian.PutUint32(buf[4:8], 1) syscall.Write(nbd.socket, buf[0:16]) case NBD_CMD_TRIM: binary.BigEndian.PutUint32(buf[0:4], NBD_REPLY_MAGIC) binary.BigEndian.PutUint32(buf[4:8], 1) syscall.Write(nbd.socket, buf[0:16]) default: panic("unknown command") } default: panic("Invalid packet") } } }
func kmemleakScan(report bool) { fd, err := syscall.Open("/sys/kernel/debug/kmemleak", syscall.O_RDWR, 0) if err != nil { panic(err) } defer syscall.Close(fd) // Kmemleak has false positives. To mitigate most of them, it checksums // potentially leaked objects, and reports them only on the next scan // iff the checksum does not change. Because of that we do the following // intricate dance: // Scan, sleep, scan again. At this point we can get some leaks. // If there are leaks, we sleep and scan again, this can remove // false leaks. Then, read kmemleak again. If we get leaks now, then // hopefully these are true positives during the previous testing cycle. if _, err := syscall.Write(fd, []byte("scan")); err != nil { panic(err) } time.Sleep(time.Second) if _, err := syscall.Write(fd, []byte("scan")); err != nil { panic(err) } if report { if kmemleakBuf == nil { kmemleakBuf = make([]byte, 128<<10) } n, err := syscall.Read(fd, kmemleakBuf) if err != nil { panic(err) } if n != 0 { time.Sleep(time.Second) if _, err := syscall.Write(fd, []byte("scan")); err != nil { panic(err) } n, err := syscall.Read(fd, kmemleakBuf) if err != nil { panic(err) } if n != 0 { // BUG in output should be recognized by manager. Logf(0, "BUG: memory leak:\n%s\n", kmemleakBuf[:n]) } } } if _, err := syscall.Write(fd, []byte("clear")); err != nil { panic(err) } }
func (fd *netFD) Read(p []byte) (n int, err os.Error) { if fd == nil || fd.sysfile == nil { return 0, os.EINVAL } fd.rio.Lock() defer fd.rio.Unlock() fd.incref() defer fd.decref() if fd.rdeadline_delta > 0 { fd.rdeadline = pollserver.Now() + fd.rdeadline_delta } else { fd.rdeadline = 0 } var oserr os.Error for { var errno int n, errno = syscall.Read(fd.sysfile.Fd(), p) if errno == syscall.EAGAIN && fd.rdeadline >= 0 { pollserver.WaitRead(fd) continue } if errno != 0 { n = 0 oserr = os.Errno(errno) } else if n == 0 && errno == 0 && fd.proto != syscall.SOCK_DGRAM { err = os.EOF } break } if oserr != nil { err = &OpError{"read", fd.net, fd.raddr, oserr} } return }
func main() { acceptingFd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0) check(err) addr := &syscall.SockaddrInet4{Port: 3000, Addr: [4]byte{0, 0, 0, 0}} err = syscall.Bind(acceptingFd, addr) check(err) err = syscall.Listen(acceptingFd, 100) check(err) for { connectionFd, _, err := syscall.Accept(acceptingFd) check(err) fmt.Println("Accepted new connectrion") data := make([]byte, 1024) _, err = syscall.Read(connectionFd, data) check(err) fmt.Printf("Received: %s\n", string(data)) _, err = syscall.Write(connectionFd, data) check(err) err = syscall.Close(connectionFd) check(err) } }
func read(u U, a []uint64) uint64 { fd, buf, size := int(a[0]), a[1], a[2] tmp := make([]byte, size) n, _ := syscall.Read(fd, tmp) u.MemWrite(buf, tmp[:n]) return uint64(n) }
func (fd *netFD) Read(p []byte) (n int, err error) { if err := fd.readLock(); err != nil { return 0, err } defer fd.readUnlock() if err := fd.pd.prepareRead(); err != nil { return 0, err } for { n, err = syscall.Read(fd.sysfd, p) if err != nil { n = 0 if err == syscall.EAGAIN { if err = fd.pd.waitRead(); err == nil { continue } } } err = fd.eofError(n, err) break } if _, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("read", err) } return }
func (tc *TunnelConn) readOnce(fd int) (num int, err error) { num, err = syscall.Read(fd, buf) if num == 0 || err != nil && err != syscall.EAGAIN { tc.shutdown() } return }
func (fd *netFD) Read(p []byte) (n int, err error) { fd.rio.Lock() defer fd.rio.Unlock() if err := fd.incref(false); err != nil { return 0, err } defer fd.decref() for { n, err = syscall.Read(int(fd.sysfd), p) if err == syscall.EAGAIN { err = errTimeout if fd.rdeadline >= 0 { if err = fd.pollServer.WaitRead(fd); err == nil { continue } } } if err != nil { n = 0 } else if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM { err = io.EOF } break } if err != nil && err != io.EOF { err = &OpError{"read", fd.net, fd.raddr, err} } return }
// Read reads up to len(p) bytes into p. It returns the number of // bytes read (0 <= n <= len(p)) and any error encountered. If some // data is available but not len(p) bytes, Read returns what is // available instead of waiting for more. Read is formally and // semantically compatible with the Read method of the io.Reader // interface. See documentation of this interface method for more // details. In addition Read honors the timeout set by // (*FD).SetDeadline and (*FD).SetReadDeadline. If no data are read // before the timeout expires Read returns with err == ErrTimeout (and // n == 0). If the read(2) system-call returns 0, Read returns with // err = io.EOF (and n == 0). func (fd *FD) Read(p []byte) (n int, err error) { if err = fd.readLock(); err != nil { return 0, err } defer fd.readUnlock() if err = fd.pd.PrepareRead(); err != nil { return 0, err } for { n, err = syscall.Read(int(fd.sysfd), p) if err != nil { n = 0 if err != syscall.EAGAIN { break } if err = fd.pd.WaitRead(); err != nil { break } continue } if n == 0 && len(p) > 0 { err = io.EOF } break } return n, err }
func main() { args := Arguments() infile, args, err := args.String("in-file", nil) Check(err) outfile, args, err := args.String("out-file", nil) Check(err) infd, err := syscall.Open(infile, int(ReadOnly), 0) Check(err) defer func() { Check(syscall.Close(infd)) }() flags := Create | WriteOnly | Truncate perms := 0 | UserRead | UserWrite | GroupRead | GroupWrite | OtherRead | OtherWrite outfd, err := syscall.Open(outfile, int(flags), uint32(perms)) Check(err) defer func() { Check(syscall.Close(outfd)) }() bufSize := 1024 buf := make([]byte, bufSize) var n int for { n, err = syscall.Read(infd, buf) Check(err) if n == 0 { break } _, err = syscall.Write(outfd, buf[:n]) Check(err) } }
func main() { flag.Parse() args = flag.Args() if len(args) <= 0 { fmt.Fprintf(os.Stderr, "Must specify at least one argument to run:\n") fmt.Fprintf(os.Stderr, "\t%s <options> <command> <arguments>...\n", os.Args[0]) flag.PrintDefaults() return } startCommand(false) usr1c := make(chan os.Signal) signal.Notify(usr1c, syscall.SIGUSR1) go func() { for { <-usr1c if canExecute() { startCommand(true) } } }() for { inotifyFd, err := syscall.InotifyInit() if err != nil { log.Fatalf("Inotify init failed: %v", err) } recdepth := 0 if *recurse { recdepth = *depth } registerDirectory(inotifyFd, ".", recdepth) inotifyBuf := make([]byte, 1024*syscall.SizeofInotifyEvent+16) for { n, err := syscall.Read(inotifyFd, inotifyBuf[0:]) if err == io.EOF { break } if err != nil { log.Printf("Can not read inotify: %v", err) break } if n > syscall.SizeofInotifyEvent { if canExecute() { startCommand(true) } } } syscall.Close(inotifyFd) } }
func (fd *netFD) Read(p []byte) (n int, err error) { // 每个读写都被加锁,因此可以序列化运行 if err := fd.readLock(); err != nil { // 对每个fd的读都序列化 return 0, err } defer fd.readUnlock() // 在退出时解锁 if err := fd.pd.PrepareRead(); err != nil { // 如果读错误,返回 return 0, err } for { n, err = syscall.Read(fd.sysfd, p) if err != nil { // 如果读出现错误 n = 0 if err == syscall.EAGAIN { // 如果是EAGAIN调用WaitRead,等待读事件 if err = fd.pd.WaitRead(); err == nil { // 事件出现后返回,异步变为同步操作 continue } } } err = fd.eofError(n, err) break // 跳出循环 } if _, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("read", err) } return }
func (w *Watcher) readEvent() { var ( buf [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events n int // Number of bytes read with read() errno error // Syscall errno ) for { select { case <-w.done: syscall.Close(w.fd) close(w.acceptEvent) close(w.Error) return default: } n, errno = syscall.Read(w.fd, buf[0:]) if n == 0 { syscall.Close(w.fd) close(w.acceptEvent) close(w.Error) return } if n < syscall.SizeofInotifyEvent { log.Fatal("size of InotifyEvent error", errno) } var offset uint32 = 0 for offset <= uint32(n-syscall.SizeofInotifyEvent) { raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset])) event := new(FileEvent) event.wd = raw.Wd event.nameLen = raw.Len event.mask = raw.Mask event.cookie = raw.Cookie path := w.wm.paths[int(raw.Wd)] if raw.Len > 0 { // Point "bytes" at the first byte of the filename bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent])) // The filename is padded with NUL bytes. TrimRight() gets rid of those. event.fileName = path + "/" + strings.TrimRight(string(bytes[0:raw.Len]), "\000") } if _, found := w.skipExt[filepath.Ext(event.fileName)]; !found { fmt.Println("--->", w.skipExt, "--->", filepath.Ext(event.fileName), "--->", found) //发送事件acceptEvent通道 w.acceptEvent <- event } else { fmt.Println("过滤文件:", event.fileName) } offset += syscall.SizeofInotifyEvent + raw.Len } } }
func (fd *netFD) Read(p []byte) (n int, err error) { if err := fd.readLock(); err != nil { return 0, err } defer fd.readUnlock() if len(p) == 0 { // If the caller wanted a zero byte read, return immediately // without trying. (But after acquiring the readLock.) Otherwise // syscall.Read returns 0, nil and eofError turns that into // io.EOF. // TODO(bradfitz): make it wait for readability? (Issue 15735) return 0, nil } if err := fd.pd.prepareRead(); err != nil { return 0, err } for { n, err = syscall.Read(fd.sysfd, p) if err != nil { n = 0 if err == syscall.EAGAIN { if err = fd.pd.waitRead(); err == nil { continue } } } err = fd.eofError(n, err) break } if _, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("read", err) } return }
func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) inotify_fd, err := syscall.InotifyInit() if err != nil { log.Fatal(err) } paths := make(map[int]string) add_watch_r(inotify_fd, "/home/feng/workspace/rssminer", paths) log.Print("watcher added") for { var ( buf [syscall.SizeofInotifyEvent * 4096]byte ) n, _ := syscall.Read(inotify_fd, buf[0:]) offset := 0 for offset <= n-syscall.SizeofInotifyEvent { raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset])) wd := int(raw.Wd) file := paths[wd] mask := raw.Mask printEvent(file, mask) offset += syscall.SizeofInotifyEvent + int(raw.Len) } } }
func CgcSyscall(u models.Usercorn) { // TODO: handle errors or something args, _ := u.ReadRegs(LinuxRegs) eax, _ := u.RegRead(uc.X86_REG_EAX) var ret uint64 switch eax { case 1: // _terminate syscall.Exit(int(args[0])) case 2: // transmit mem, _ := u.MemRead(args[1], args[2]) n, _ := syscall.Write(int(args[0]), mem) writeAddr(u, args[3], uint64(n)) case 3: // receive tmp := make([]byte, args[2]) n, _ := syscall.Read(int(args[0]), tmp) u.MemWrite(args[1], tmp[:n]) writeAddr(u, args[3], uint64(n)) case 5: // allocate addr, _ := u.Mmap(0, args[0]) // args[1] == is executable writeAddr(u, args[2], addr) case 7: // random tmp := make([]byte, args[1]) rand.Read(tmp) u.MemWrite(args[0], tmp) writeAddr(u, args[2], args[1]) } u.RegWrite(uc.X86_REG_EAX, ret) }
func TestMonitorAndParseRIB(t *testing.T) { if testing.Short() || os.Getuid() != 0 { t.Skip("must be root") } // We suppose that using an IPv4 link-local address and the // dot1Q ID for Token Ring and FDDI doesn't harm anyone. pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"} if err := pv.configure(1002); err != nil { t.Skip(err) } if err := pv.setup(); err != nil { t.Skip(err) } pv.teardown() s, err := syscall.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC) if err != nil { t.Fatal(err) } defer syscall.Close(s) go func() { b := make([]byte, os.Getpagesize()) for { n, err := syscall.Read(s, b) if err != nil { return } ms, err := ParseRIB(0, b[:n]) if err != nil { t.Error(err) return } ss, err := msgs(ms).validate() if err != nil { t.Error(err) return } for _, s := range ss { t.Log(s) } } }() for _, vid := range []int{1002, 1003, 1004, 1005} { pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"} if err := pv.configure(vid); err != nil { t.Fatal(err) } if err := pv.setup(); err != nil { t.Fatal(err) } time.Sleep(200 * time.Millisecond) if err := pv.teardown(); err != nil { t.Fatal(err) } time.Sleep(200 * time.Millisecond) } }
// read reads events from an inotify file descriptor. It does not handle errors // returned from read(2) function since they are not critical to watcher logic. func (i *inotify) read() (es []*event) { n, err := syscall.Read(int(i.fd), i.buffer[:]) if err != nil || n < syscall.SizeofInotifyEvent { return } var sys *syscall.InotifyEvent nmin := n - syscall.SizeofInotifyEvent for pos, path := 0, ""; pos <= nmin; { sys = (*syscall.InotifyEvent)(unsafe.Pointer(&i.buffer[pos])) pos += syscall.SizeofInotifyEvent if path = ""; sys.Len > 0 { endpos := pos + int(sys.Len) path = string(bytes.TrimRight(i.buffer[pos:endpos], "\x00")) pos = endpos } es = append(es, &event{ sys: syscall.InotifyEvent{ Wd: sys.Wd, Mask: sys.Mask, Cookie: sys.Cookie, }, path: path, }) } return }
func (fd *netFD) Read(p []byte) (n int, err error) { fd.rio.Lock() defer fd.rio.Unlock() if err := fd.incref(false); err != nil { return 0, err } defer fd.decref() for { if fd.rdeadline.expired() { err = errTimeout break } n, err = syscall.Read(int(fd.sysfd), p) if err != nil { n = 0 if err == syscall.EAGAIN { if err = fd.pollServer.WaitRead(fd); err == nil { continue } } } err = chkReadErr(n, err, fd) break } if err != nil && err != io.EOF { err = &OpError{"read", fd.net, fd.raddr, err} } return }
/* c.sa = new(syscall.SockaddrInet4) c.sa.Addr = [4]byte{10, 1, 1, 131} c.sa.Port = port */ func (c *Worker) socket() { begin := time.Now() s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0) if err != nil { syscall.Close(s) return } err = syscall.Connect(s, nil) //TODO if err != nil { lg(err) syscall.Close(s) return } _, err = syscall.Write(s, message.content) if err != nil { syscall.Close(s) return } _, err = syscall.Read(s, c.data) if err != nil { syscall.Close(s) return } syscall.Close(s) time.Now().Sub(begin) }
func (fdr fdReader) Read(p []byte) (int, error) { n, e := syscall.Read(int(fdr), p) if n < 0 { n = 0 } return n, e }
// readEvents reads from the inotify file descriptor, converts the // received events into Event objects and sends them via the Event channel func (w *Watcher) readEvents() { var ( buf [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events n int // Number of bytes read with read() errno int // Syscall errno ) for { n, errno = syscall.Read(w.fd, buf[0:]) // See if there is a message on the "done" channel _, done := <-w.done // If EOF or a "done" message is received if n == 0 || done { errno := syscall.Close(w.fd) if errno == -1 { w.Error <- os.NewSyscallError("close", errno) } close(w.Event) close(w.Error) return } if n < 0 { w.Error <- os.NewSyscallError("read", errno) continue } if n < syscall.SizeofInotifyEvent { w.Error <- os.NewError("inotify: short read in readEvents()") continue } var offset uint32 = 0 // We don't know how many events we just read into the buffer // While the offset points to at least one whole event... for offset <= uint32(n-syscall.SizeofInotifyEvent) { // Point "raw" to the event in the buffer raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset])) event := new(Event) event.Mask = uint32(raw.Mask) event.Cookie = uint32(raw.Cookie) nameLen := uint32(raw.Len) // If the event happened to the watched directory or the watched file, the kernel // doesn't append the filename to the event, but we would like to always fill the // the "Name" field with a valid filename. We retrieve the path of the watch from // the "paths" map. event.Name = w.paths[int(raw.Wd)] if nameLen > 0 { // Point "bytes" at the first byte of the filename bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent])) // The filename is padded with NUL bytes. TrimRight() gets rid of those. event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000") } // Send the event on the events channel w.Event <- event // Move to the next event in the buffer offset += syscall.SizeofInotifyEvent + nameLen } } }
func (b *BPFSniffer) ReadPacketData() ([]byte, gopacket.CaptureInfo, error) { var err error if b.readBytesConsumed >= b.lastReadLen { b.readBytesConsumed = 0 b.readBuffer = make([]byte, b.options.ReadBufLen) b.lastReadLen, err = syscall.Read(b.fd, b.readBuffer) if err != nil { b.lastReadLen = 0 return nil, gopacket.CaptureInfo{}, err } } hdr := (*unix.BpfHdr)(unsafe.Pointer(&b.readBuffer[b.readBytesConsumed])) frameStart := b.readBytesConsumed + int(hdr.Hdrlen) b.readBytesConsumed += bpfWordAlign(int(hdr.Hdrlen) + int(hdr.Caplen)) if frameStart+int(hdr.Caplen) > len(b.readBuffer) { captureInfo := gopacket.CaptureInfo{ Timestamp: time.Unix(int64(hdr.Tstamp.Sec), int64(hdr.Tstamp.Usec)*1000), CaptureLength: 0, Length: 0, } return nil, captureInfo, fmt.Errorf("BPF captured frame received with corrupted BpfHdr struct.") } rawFrame := b.readBuffer[frameStart : frameStart+int(hdr.Caplen)] captureInfo := gopacket.CaptureInfo{ Timestamp: time.Unix(int64(hdr.Tstamp.Sec), int64(hdr.Tstamp.Usec)*1000), CaptureLength: len(rawFrame), Length: len(rawFrame), } return rawFrame, captureInfo, nil }
/* Read events from Eventfd. p should be at max 8 bytes. * Returns the number of read bytes or 0 and error is set. */ func (e *EventFD) Read(p []byte) (int, error) { n, err := syscall.Read(e.fd, p[:]) if err != nil { return 0, err } return n, nil }
func kmemleakScan(report bool) { fd, err := syscall.Open("/sys/kernel/debug/kmemleak", syscall.O_RDWR, 0) if err != nil { panic(err) } defer syscall.Close(fd) if _, err := syscall.Write(fd, []byte("scan")); err != nil { panic(err) } if report { if kmemleakBuf == nil { kmemleakBuf = make([]byte, 128<<10) } n, err := syscall.Read(fd, kmemleakBuf) if err != nil { panic(err) } if n != 0 { // BUG in output should be recognized by manager. logf(0, "BUG: memory leak:\n%s\n", kmemleakBuf[:n]) } } if _, err := syscall.Write(fd, []byte("clear")); err != nil { panic(err) } }
func (fd *netFD) Read(p []byte) (n int, err error) { if fd == nil { return 0, os.EINVAL } fd.rio.Lock() defer fd.rio.Unlock() fd.incref() defer fd.decref() if fd.sysfile == nil { return 0, os.EINVAL } for { n, err = syscall.Read(fd.sysfile.Fd(), p) if err == syscall.EAGAIN { if fd.rdeadline >= 0 { pollserver.WaitRead(fd) continue } err = errTimeout } if err != nil { n = 0 } else if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM { err = io.EOF } break } if err != nil && err != io.EOF { err = &OpError{"read", fd.net, fd.raddr, err} } return }
func (fd *netFD) Read(p []byte) (n int, err error) { if err := fd.readLock(); err != nil { return 0, err } defer fd.readUnlock() if err := fd.pd.PrepareRead(); err != nil { return 0, &OpError{"read", fd.net, fd.raddr, err} } for { n, err = syscall.Read(int(fd.sysfd), p) if err != nil { n = 0 if err == syscall.EAGAIN { if err = fd.pd.WaitRead(); err == nil { continue } } } err = chkReadErr(n, err, fd) break } if err != nil && err != io.EOF { err = &OpError{"read", fd.net, fd.raddr, err} } return }
func REPL(handler ReplHandler) error { var err error input = make(chan byte, 1) go func() { var ch [1]byte for { n, err := syscall.Read(syscall.Stdin, ch[:]) if err != nil || n == 0 { panic("Problem reading stdin") } else { input <- ch[0] if ch[0] == 0 { return } } } }() state, err = MakeCbreak(syscall.Stdin) if err == nil { defer Restore(syscall.Stdin, state) err = repl(handler) return err } else { return err } }