Beispiel #1
0
// Rcreate is used to respond to a succesful create request. With 9P, creating
// a file also opens the file for I/O. Once Rcreate returns, future read
// and write requests to the file handle will pass through rwc. The value
// rwc must meet the same criteria listed for the Ropen method of a Topen
// request.
func (t Tcreate) Rcreate(rwc interface{}, err error) {
	var (
		f styxfile.Interface
	)
	if err != nil {
		t.Rerror("%s", err)
		return
	}

	if dir, ok := rwc.(Directory); t.Mode.IsDir() && ok {
		f = styxfile.NewDir(dir, path.Join(t.Path(), t.Name), t.session.conn.qidpool)
	} else {
		f, err = styxfile.New(rwc)
	}
	if err != nil {
		t.session.conn.srv.logf("create %s failed: %s", t.Name, err)
		t.Rerror("create failed")
		return
	}
	file := file{name: path.Join(t.Path(), t.Name), rwc: f}

	// fid for parent directory is now the fid for the new file,
	// so there is no increase in references to this session.
	t.session.files.Put(t.fid, file)

	qtype := styxfile.QidType(styxfile.Mode9P(t.Mode))
	qid := t.session.conn.qid(file.name, qtype)
	t.session.unhandled = false
	if t.session.conn.clearTag(t.tag) {
		t.session.conn.Rcreate(t.tag, qid, 0)
	}
}
Beispiel #2
0
// Rstat responds to a succesful Tstat request. The styx package will
// translate the os.FileInfo value into the appropriate 9P structure. Rstat
// will attempt to resolve the names of the file's owner and group. If
// that cannot be done, an empty string is sent. If err is non-nil, and error
// is sent to the client instead.
func (t Tstat) Rstat(info os.FileInfo, err error) {
	if err != nil {
		t.Rerror("%s", err)
		return
	}
	buf := make([]byte, styxproto.MaxStatLen)
	uid, gid, muid := sys.FileOwner(info)
	name := info.Name()
	if name == "/" {
		name = "."
	}
	stat, _, err := styxproto.NewStat(buf, name, uid, gid, muid)
	if err != nil {
		// should never happen
		panic(err)
	}
	mode := styxfile.Mode9P(info.Mode())
	stat.SetLength(info.Size())
	stat.SetMode(mode)
	stat.SetAtime(uint32(info.ModTime().Unix())) // TODO: get atime
	stat.SetMtime(uint32(info.ModTime().Unix()))
	stat.SetQid(t.session.conn.qid(t.Path(), styxfile.QidType(mode)))
	t.session.unhandled = false
	if t.session.conn.clearTag(t.tag) {
		t.session.conn.Rstat(t.tag, stat)
	}
}
Beispiel #3
0
// Rwalk signals to the client that the file named by the Twalk's
// Path method exists and is of the given mode. The permission bits of
// mode are ignored, and only the file type bits, such as os.ModeDir,
// are sent to the client. If err is non-nil, an error response is sent to the
// client instead.
func (t Twalk) Rwalk(info os.FileInfo, err error) {
	var qid styxproto.Qid
	var mode os.FileMode
	if err == nil {
		mode = info.Mode()
		qid = t.session.conn.qid(t.Path(), styxfile.QidType(styxfile.Mode9P(mode)))
	}
	t.walk.filled[t.index] = 1
	elem := walkElem{qid: qid, index: t.index, err: err}
	select {
	case t.walk.collect <- elem:
	case <-t.walk.complete:
	}
}