commit b7719d8a5e561508c673b484c530428dd745a9fb
parent 63cee6f48d6426cf99b7aa3a527f2e28e69dc487
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Thu, 11 Jan 2024 08:09:55 +0900
update
Diffstat:
10 files changed, 42 insertions(+), 38 deletions(-)
diff --git a/client/file_test.go b/client/file_test.go
@@ -78,7 +78,7 @@ func TestClose(t *testing.T) {
 			t.Error(err)
 			return nil
 		}
-		cf, err := cfs.OpenFile(path, lib9p.OREAD)
+		cf, err := cfs.OpenFile(path, lib9p.O_RDONLY)
 		if err != nil {
 			if strings.Contains(err.Error(), "permission") {
 				return nil
@@ -119,7 +119,7 @@ func TestFileRead(t *testing.T) {
 			t.Error(err)
 			return nil
 		}
-		cf, err := cfs.OpenFile(path, lib9p.OREAD)
+		cf, err := cfs.OpenFile(path, lib9p.O_RDONLY)
 		if err != nil {
 			if strings.Contains(err.Error(), "permission") {
 				return nil
@@ -161,7 +161,7 @@ func TestReadDir(t *testing.T) {
 		if !d.IsDir() {
 			return nil
 		}
-		cf, err := cfs.OpenFile(path, lib9p.OREAD)
+		cf, err := cfs.OpenFile(path, lib9p.O_RDONLY)
 		if err != nil {
 			if !strings.Contains(err.Error(), "permission") {
 				t.Error(err)
@@ -175,7 +175,7 @@ func TestReadDir(t *testing.T) {
 				return nil
 			}
 		}
-		tf, err := testfs.OpenFile(path, lib9p.OREAD)
+		tf, err := testfs.OpenFile(path, lib9p.O_RDONLY)
 		if err != nil {
 			if !strings.Contains(err.Error(), "permission") {
 				t.Error(err)
diff --git a/client/fs.go b/client/fs.go
@@ -18,7 +18,8 @@ type FS struct {
 
 // OpenFile opens the file named name in fsys with omode.
 // If the file does not exist, it create it with perm.
-func (fsys *FS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) {
+// The flag bits which are not implemeted by the library are just ignored.
+func (fsys *FS) OpenFile(name string, flag int) (lib9p.File, error) {
 	var (
 		qid    lib9p.Qid
 		iounit uint32
@@ -32,14 +33,14 @@ func (fsys *FS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) 
 		if err != nil {
 			return nil, err
 		}
-		qid, iounit, err = fsys.c.Open(tag, f.fid.fid, omode)
+		qid, iounit, err = fsys.c.Open(tag, f.fid.fid, lib9p.FlagToMode(flag))
 		fsys.tPool.delete(tag)
 		if err != nil {
 			f.Close()
 			return nil, fmt.Errorf("open: %v", err)
 		}
 	}
-	f.fid.omode = omode
+	f.fid.omode = lib9p.FlagToMode(flag)
 	f.qid = qid
 	f.iounit = iounit
 	return f, nil
diff --git a/client/fs2_test.go b/client/fs2_test.go
@@ -43,7 +43,7 @@ func TestOpenFile(t *testing.T) {
 	}
 	defer cancel()
 	walk := func(path string, d fs.DirEntry, err error) error {
-		cf, err := cfs.OpenFile(path, lib9p.OREAD)
+		cf, err := cfs.OpenFile(path, lib9p.O_RDONLY)
 		if err != nil {
 			if !strings.Contains(err.Error(), "permission") {
 				t.Error(err)
@@ -56,7 +56,7 @@ func TestOpenFile(t *testing.T) {
 			return err
 		}
 		cst := cfi.Sys().(*lib9p.Stat)
-		tf, err := testfs.OpenFile(path, lib9p.OREAD)
+		tf, err := testfs.OpenFile(path, lib9p.O_RDONLY)
 		if err != nil {
 			if !strings.Contains(err.Error(), "permission") {
 				t.Error(err)
diff --git a/client/fs_test.go b/client/fs_test.go
@@ -112,7 +112,7 @@ type group struct {
 	members map[string]bool
 }
 
-func (fs *testFS) OpenFile(path string, omode lib9p.OpenMode) (lib9p.File, error) {
+func (fs *testFS) OpenFile(path string, _ int) (lib9p.File, error) {
 	wnames := strings.Split(path, "/")
 	f, err := fs.walk(wnames)
 	if err != nil {
diff --git a/cmd/numfs/main.go b/cmd/numfs/main.go
@@ -38,7 +38,7 @@ func fsysString(f *numFile) string {
 	return s
 }
 
-func (fsys *numFS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) {
+func (fsys *numFS) OpenFile(name string, _ int) (lib9p.File, error) {
 	if name == "." || name == "" {
 		return fsys.root, nil
 	}
diff --git a/cmd/semfs/fs.go b/cmd/semfs/fs.go
@@ -17,7 +17,7 @@ type semFS struct {
 	lastpath int
 }
 
-func (fsys *semFS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) {
+func (fsys *semFS) OpenFile(name string, _ int) (lib9p.File, error) {
 	wnames := strings.Split(name, "/")
 	if len(wnames) != 1 {
 		return nil, errors.New("not found")
diff --git a/diskfs/fs.go b/diskfs/fs.go
@@ -44,7 +44,7 @@ func Open(name string) (*FS, error) {
 }
 
 // OpenFile opens the named file with specified omode by calling os.OpenFile.
-func (fsys *FS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) {
+func (fsys *FS) OpenFile(name string, flag int) (lib9p.File, error) {
 	if !fs.ValidPath(name) {
 		return nil, &fs.PathError{
 			Op:   "openfile",
@@ -53,26 +53,7 @@ func (fsys *FS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) 
 		}
 	}
 	fp := filepath.Join(fsys.rootPath, name)
-	var m int
-	switch omode & 3 {
-	case lib9p.OREAD:
-		m = os.O_RDONLY
-	case lib9p.OWRITE:
-		m = os.O_WRONLY
-	case lib9p.ORDWR:
-		m = os.O_RDWR
-	}
-	if omode&lib9p.OTRUNC != 0 {
-		m |= os.O_TRUNC
-	}
-	if omode&lib9p.ORCLOSE != 0 {
-		return nil, &fs.PathError{
-			Op:   "openfile",
-			Path: name,
-			Err:  fmt.Errorf("orclose not implemented"),
-		}
-	}
-	osf, err := os.OpenFile(fp, m, 0)
+	osf, err := os.OpenFile(fp, flag, 0)
 	if err != nil {
 		return nil, &fs.PathError{
 			Op:   "openfile",
diff --git a/fid.go b/fid.go
@@ -21,7 +21,10 @@ const (
 	ORCLOSE = 64
 )
 
-func modeToFlag(m OpenMode) int {
+// ModeToFlag converts OpenMode (OREAD etc.) to open flag (O_RDONLY etc.).
+// ORCLOSE is not implemented and ignored silently.
+// O_APPEND, O_CREATE, O_EXCL, O_SYNC can't be specified.
+func ModeToFlag(m OpenMode) int {
 	var flag int
 	switch m&3 {
 	case OREAD, OEXEC:
@@ -38,6 +41,25 @@ func modeToFlag(m OpenMode) int {
 	return flag
 }
 
+// FlugToMode converts open flag (O_RDONLY etc.) to OpenMode (OREAD etc.).
+// O_APPEND, O_CREATE, O_EXCL, O_SYNC are not implemented and ignored silently.
+// ORCLOSE can't be specified.
+func FlagToMode(f int) OpenMode {
+	var m OpenMode
+	switch {
+	case f&O_RDONLY != 0:
+		m = OREAD
+	case f&O_WRONLY != 0:
+		m = OWRITE
+	case f&O_RDWR != 0:
+		m = ORDWR
+	}
+	if f&O_TRUNC != 0 {
+		m |= OTRUNC
+	}
+	return m
+}
+
 // An fid represents an fid defined by 9P.
 // It is used as the identifier of a file in 9P session.
 // It is specified by the client and the server connects it to a file in the
diff --git a/iofs/fs.go b/iofs/fs.go
@@ -24,8 +24,8 @@ func NewFS(fsys fs.FS) *FS {
 	return fs
 }
 
-func (fsys *FS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) {
-	if omode != lib9p.OREAD {
+func (fsys *FS) OpenFile(name string, flag int) (lib9p.File, error) {
+	if flag != lib9p.O_RDONLY {
 		return nil, errors.New("read only file system")
 	}
 	if name == "" {
diff --git a/server.go b/server.go
@@ -589,7 +589,7 @@ func sOpen(ctx context.Context, c *conn, rc <-chan *request) {
 				}
 				continue
 			}
-			r.fid.file, err = r.fid.fs.OpenFile(r.fid.path, modeToFlag(ifcall.Mode))
+			r.fid.file, err = r.fid.fs.OpenFile(r.fid.path, ModeToFlag(ifcall.Mode))
 			if err != nil {
 				setError(r, err)
 				select {
@@ -749,7 +749,7 @@ func sRead(ctx context.Context, c *conn, rc <-chan *request) {
 						if err = r.fid.file.Close(); err != nil {
 							return
 						}
-						r.fid.file, err = r.fid.fs.OpenFile(r.fid.path, modeToFlag(r.fid.omode))
+						r.fid.file, err = r.fid.fs.OpenFile(r.fid.path, ModeToFlag(r.fid.omode))
 						if err != nil {
 							return
 						}