예제 #1
0
파일: ufs.go 프로젝트: KevinMGranger/go9p
func (*Ufs) Read(req *srv.Req) {
	fid := req.Fid.Aux.(*Fid)
	tc := req.Tc
	rc := req.Rc
	err := fid.stat()
	if err != nil {
		req.RespondError(err)
		return
	}

	p.InitRread(rc, tc.Count)
	var count int
	var e error
	if fid.st.IsDir() {
		b := rc.Data
		if tc.Offset == 0 {
			fid.file.Close()
			fid.file, e = os.OpenFile(fid.path, omode2uflags(req.Fid.Omode), 0)
			if e != nil {
				req.RespondError(toError(e))
				return
			}
		}

		for len(b) > 0 {
			if fid.dirs == nil {
				fid.dirs, e = fid.file.Readdir(16)
				if e != nil && e != io.EOF {
					req.RespondError(toError(e))
					return
				}

				if len(fid.dirs) == 0 {
					break
				}
			}

			var i int
			for i = 0; i < len(fid.dirs); i++ {
				path := fid.path + "/" + fid.dirs[i].Name()
				st := dir2Dir(path, fid.dirs[i], req.Conn.Dotu, req.Conn.Srv.Upool)
				sz := p.PackDir(st, b, req.Conn.Dotu)
				if sz == 0 {
					break
				}

				b = b[sz:]
				count += sz
			}

			if i < len(fid.dirs) {
				fid.dirs = fid.dirs[i:]
				break
			} else {
				fid.dirs = nil
			}
		}
	} else {
		count, e = fid.file.ReadAt(rc.Data, int64(tc.Offset))
		if e != nil && e != io.EOF {
			req.RespondError(toError(e))
			return
		}
	}

	p.SetRreadCount(rc, uint32(count))
	req.Respond()
}
예제 #2
0
파일: file.go 프로젝트: KevinMGranger/go9p
func (*Fsrv) Read(req *Req) {
	var i, n int
	var err error

	fid := req.Fid.Aux.(*FFid)
	f := fid.F
	tc := req.Tc
	rc := req.Rc
	p.InitRread(rc, tc.Count)

	if f.Mode&p.DMDIR != 0 {
		// directory
		if tc.Offset == 0 {
			var g *File
			f.Lock()
			for n, g = 0, f.cfirst; g != nil; n, g = n+1, g.next {
			}

			fid.dirs = make([]*File, n)
			for n, g = 0, f.cfirst; g != nil; n, g = n+1, g.next {
				fid.dirs[n] = g
			}
			f.Unlock()
		}

		n = 0
		b := rc.Data
		for i = 0; i < len(fid.dirs); i++ {
			g := fid.dirs[i]
			g.Lock()
			if (g.flags & Fremoved) != 0 {
				g.Unlock()
				continue
			}

			sz := p.PackDir(&g.Dir, b, req.Conn.Dotu)
			g.Unlock()
			if sz == 0 {
				break
			}

			b = b[sz:]
			n += sz
		}

		fid.dirs = fid.dirs[i:]
	} else {
		// file
		if rop, ok := f.Ops.(FReadOp); ok {
			n, err = rop.Read(fid, rc.Data, tc.Offset)
			if err != nil {
				req.RespondError(err)
				return
			}
		} else {
			req.RespondError(Eperm)
			return
		}
	}

	p.SetRreadCount(rc, uint32(n))
	req.Respond()
}