// Connect to a 9P server that is listening at `addr', // and wrap ctl and data files of a remote serial device // into a Port. // Basename is the a file name prefix or directory, // where the device is expected to be found. It can // be "", if ctl and data files live in the 9P servers // root directory func Connect9P(addr, basename string) (port Port, err error) { c, err := clnt.Mount("tcp", addr, "", user.Current()) if err != nil { return } d := new(dev9) d.clnt = c if d.data, err = d.clnt.FOpen(basename+"/data", p.ORDWR); err == nil { if d.ctl, err = d.clnt.FOpen(basename+"/ctl", p.OWRITE); err != nil { goto noctl } } else if d.data, err = d.clnt.FOpen(basename, p.ORDWR); err == nil { if d.ctl, err = d.clnt.FOpen(basename+"ctl", p.OWRITE); err != nil { goto noctl } } else { goto unmount } port = d return noctl: d.data.Close() unmount: d.clnt.Unmount() return }
// Serve a previously opened serial device via 9P. // `addr' shoud be of form "host:port", where host // may be missing. func Serve9P(addr string, dev Port) (err error) { user := user.Current() root := new(srv.File) err = root.Add(nil, "/", user, nil, p.DMDIR|0555, nil) if err != nil { return } c := new(ctl) c.dev = dev err = c.Add(root, "ctl", user, nil, 0666, c) if err != nil { return } d := new(data) d.dev = dev d.rch = ioutil.ChannelizeReader(dev, nil) d.unblockch = make(chan bool) c.dataUnblockch = d.unblockch err = d.Add(root, "data", user, nil, 0666, d) if err != nil { return } s := srv.NewFileSrv(root) s.Dotu = true switch { case Debugall: s.Debuglevel = 2 case Debug: s.Debuglevel = 1 } s.Start(s) err = s.StartNetListener("tcp", addr) return }