commit a97ff77ac15a8bacedb7e251f11933f31bf4fc20
parent ee1b3758df2258daf51be5af2152ad2dffaabafc
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 6 Sep 2023 10:01:37 +0900
add messages
Diffstat:
| M | fcall.go | | | 318 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
| M | fid.go | | | 2 | +- |
| M | stat.go | | | 23 | +++++++++++++++++++++++ |
| A | testdir/e | | | 1 | + |
4 files changed, 326 insertions(+), 18 deletions(-)
diff --git a/fcall.go b/fcall.go
@@ -108,12 +108,12 @@ type RVersion struct {
version string
}
-func newRVersion(buf []byte) *RVersion {
+func newRVersion(buf []byte) *RVersion {
msg := new(RVersion)
msg.tag = gbit16(buf[5:7])
msg.mSize = gbit32(buf[7:11])
vs := gbit16(buf[11:13])
- msg.version = string(buf[13:13+vs])
+ msg.version = string(buf[13 : 13+vs])
return msg
}
func (msg *RVersion) Size() uint32 { return uint32(4 + 1 + 2 + 4 + 2 + len(msg.version)) }
@@ -238,9 +238,9 @@ func newRAuth(buf []byte) *RAuth {
msg.aqid = unmarshalQid(buf[7:])
return msg
}
-func (msg RAuth) Size() uint32 { return 4 + 1 + 2 + 13 }
-func (msg RAuth) Type() MsgType { return Rauth }
-func (msg RAuth) Tag() uint16 { return msg.tag }
+func (msg RAuth) Size() uint32 { return 4 + 1 + 2 + 13 }
+func (msg RAuth) Type() MsgType { return Rauth }
+func (msg RAuth) Tag() uint16 { return msg.tag }
func (msg RAuth) AQid() Qid { return msg.aqid }
func (msg RAuth) marshal() []byte {
cur := 0
@@ -363,10 +363,10 @@ func newRAttach(buf []byte) *RAttach {
msg.qid = unmarshalQid(buf[7:])
return msg
}
-func (msg RAttach) Size() uint32 { return 4 + 1 + 2 + 13 }
-func (msg RAttach) Type() MsgType { return Rattach }
-func (msg RAttach) Tag() uint16 { return msg.tag }
-func (msg RAttach) Qid() Qid { return msg.qid }
+func (msg RAttach) Size() uint32 { return 4 + 1 + 2 + 13 }
+func (msg RAttach) Type() MsgType { return Rattach }
+func (msg RAttach) Tag() uint16 { return msg.tag }
+func (msg RAttach) Qid() Qid { return msg.qid }
func (msg RAttach) marshal() []byte {
cur := 0
buf := make([]byte, msg.Size())
@@ -403,10 +403,10 @@ func newRError(buf []byte) *RError {
msg.ename = fmt.Errorf("%s", string(buf[9:9+es]))
return msg
}
-func (msg *RError) Size() uint32 { return uint32(4 + 1 + 2 + 2 + len(msg.EName())) }
-func (msg *RError) Type() MsgType { return Rerror }
-func (msg *RError) Tag() uint16 { return msg.tag }
-func (msg *RError) EName() string { return msg.ename.Error() }
+func (msg *RError) Size() uint32 { return uint32(4 + 1 + 2 + 2 + len(msg.EName())) }
+func (msg *RError) Type() MsgType { return Rerror }
+func (msg *RError) Tag() uint16 { return msg.tag }
+func (msg *RError) EName() string { return msg.ename.Error() }
func (msg *RError) marshal() []byte {
cur := 0
buf := make([]byte, msg.Size())
@@ -433,6 +433,58 @@ func (msg *RError) String() string {
return fmt.Sprintf("Rerror tag %d ename %v", msg.Tag(), msg.EName())
}
+type TFlush struct {
+ tag uint16
+ oldtag uint16
+}
+
+func newTFlush(buf []byte) *TFlush {
+ msg := new(TFlush)
+ msg.tag = gbit16(buf[5:7])
+ msg.oldtag = gbit16(buf[7:9])
+ return msg
+}
+
+func (msg *TFlush) Size() uint32 { return 9 }
+func (msg *TFlush) Type() MsgType { return Tflush }
+func (msg *TFlush) Tag() uint16 { return msg.tag }
+func (msg *TFlush) OldTag() uint16 { return msg.oldtag }
+func (msg *TFlush) marshal() []byte {
+ buf := make([]byte, msg.Size())
+ pbit32(buf[0:4], msg.Size())
+ buf[4] = uint8(msg.Type())
+ pbit16(buf[5:7], msg.Tag())
+ pbit16(buf[7:9], msg.OldTag())
+ return buf
+}
+func (msg *TFlush) String() string {
+ return fmt.Sprintf("Tflush tag %d oldtag %d", msg.Tag(), msg.OldTag())
+}
+
+type RFlush struct {
+ tag uint16
+}
+
+func newRFlush(buf []byte) *RFlush {
+ msg := new(RFlush)
+ msg.tag = gbit16(buf[5:7])
+ return msg
+}
+
+func (msg *RFlush) Size() uint32 { return 7 }
+func (msg *RFlush) Type() MsgType { return Rflush }
+func (msg *RFlush) Tag() uint16 { return msg.tag }
+func (msg *RFlush) marshal() []byte {
+ buf := make([]byte, msg.Size())
+ pbit32(buf[0:4], msg.Size())
+ buf[4] = uint8(msg.Type())
+ pbit16(buf[5:7], msg.Tag())
+ return buf
+}
+func (msg *RFlush) String() string {
+ return fmt.Sprintf("Rflush tag %d", msg.Tag())
+}
+
type TWalk struct {
size uint32
tag uint16
@@ -523,7 +575,7 @@ func newRWalk(buf []byte) *RWalk {
msg.qid = make([]Qid, nwqid)
cur := 9
for i := 0; i < nwqid; i++ {
- msg.qid[i] = unmarshalQid(buf[cur:cur+13])
+ msg.qid[i] = unmarshalQid(buf[cur : cur+13])
cur += 13
}
if int(msg.Size()) != cur {
@@ -666,6 +718,124 @@ func (msg *ROpen) String() string {
msg.Tag(), msg.Qid(), msg.IoUnit())
}
+type TCreat struct {
+ tag uint16
+ fid uint32
+ name string
+ perm FileMode
+ mode OpenMode
+}
+
+func newTCreat(buf []byte) *TCreat {
+ msg := new(TCreat)
+ cur := 5
+ msg.tag = gbit16(buf[cur : cur+2])
+ cur += 2
+ msg.fid = gbit32(buf[cur : cur+4])
+ cur += 4
+ nameSize := int(gbit16(buf[cur : cur+2]))
+ cur += 2
+ msg.name = string(buf[cur : cur+nameSize])
+ cur += nameSize
+ msg.perm = FileMode(gbit32(buf[cur : cur+4]))
+ cur += 4
+ msg.mode = OpenMode(buf[cur])
+ cur += 1
+ if cur != len(buf) {
+ panic("length and cursor position don't match")
+ }
+ return msg
+}
+
+func (msg *TCreat) Size() uint32 {
+ return uint32(4 + 1 + 2 + 4 + 2 + len(msg.name) + 4 + 1)
+}
+func (msg *TCreat) Type() MsgType { return Tcreate }
+func (msg *TCreat) Tag() uint16 { return msg.tag }
+func (msg *TCreat) Fid() uint32 { return msg.fid }
+func (msg *TCreat) Name() string { return msg.name }
+func (msg *TCreat) Perm() FileMode { return msg.perm }
+func (msg *TCreat) Mode() OpenMode { return msg.mode }
+func (msg *TCreat) marshal() []byte {
+ cur := 0
+ buf := make([]byte, msg.Size())
+ pbit32(buf[cur:cur+4], msg.Size())
+ cur += 4
+ buf[cur] = uint8(msg.Type())
+ cur += 1
+ pbit16(buf[cur:cur+2], msg.Tag())
+ cur += 2
+ pbit32(buf[cur:cur+4], msg.Fid())
+ cur += 4
+ nameSize := len(msg.Name())
+ pbit16(buf[cur:cur+2], uint16(nameSize))
+ cur += 2
+ name := msg.Name()
+ for i := 0; i < nameSize; i++ {
+ buf[cur+i] = name[i]
+ }
+ cur += nameSize
+ pbit32(buf[cur:cur+4], uint32(msg.Perm()))
+ cur += 4
+ buf[cur] = uint8(msg.Mode())
+ cur += 1
+ if cur != len(buf) {
+ panic("length of buf and cursor position don't match")
+ }
+ return buf
+}
+
+func (msg *TCreat) String() string {
+ return fmt.Sprintf("Tcreate tag %d fid %d name %s perm %v mode %v",
+ msg.Tag(), msg.Fid(), msg.Perm().PermString(), msg.Mode())
+}
+
+type RCreate struct {
+ tag uint16
+ qid Qid
+ iounit uint32
+}
+
+func newRCreate(buf []byte) *RCreate {
+ msg := new(RCreate)
+ msg.tag = gbit16(buf[5:7])
+ msg.qid = unmarshalQid(buf[7:20])
+ msg.iounit = gbit32(buf[20:24])
+ return msg
+}
+func (msg *RCreate) Size() uint32 {
+ return uint32(4 + 1 + 2 + 13 + 4)
+}
+func (msg *RCreate) Type() MsgType { return Rcreate }
+func (msg *RCreate) Tag() uint16 { return msg.tag }
+func (msg *RCreate) Qid() Qid { return msg.qid }
+func (msg *RCreate) IoUnit() uint32 { return msg.iounit }
+func (msg *RCreate) marshal() []byte {
+ cur := 0
+ buf := make([]byte, msg.Size())
+ pbit32(buf[cur:cur+4], msg.Size())
+ cur += 4
+ buf[cur] = uint8(msg.Type())
+ cur += 1
+ pbit16(buf[cur:cur+2], msg.Tag())
+ cur += 2
+ for i, bit := range msg.Qid().marshal() {
+ buf[cur+i] = bit
+ }
+ cur += 13
+ pbit32(buf[cur:cur+4], msg.IoUnit())
+ cur += 4
+ if cur != len(buf) {
+ panic("length of buf and cursor position don't match")
+ }
+
+ return buf
+}
+func (msg *RCreate) String() string {
+ return fmt.Sprintf("Rcreate tag %d qid %v iounit %d",
+ msg.Tag(), msg.Qid(), msg.IoUnit())
+}
+
type TRead struct {
size uint32
tag uint16
@@ -791,6 +961,111 @@ func (msg *RRead) String() string {
return s
}
+type TWrite struct {
+ tag uint16
+ fid uint32
+ offset uint64
+ count uint32
+ data []byte
+}
+
+func newTWrite(buf []byte) *TWrite {
+ cur := 5
+ msg := new(TWrite)
+ msg.tag = gbit16(buf[cur : cur+2])
+ cur += 2
+ msg.fid = gbit32(buf[cur : cur+4])
+ cur += 4
+ msg.offset = gbit64(buf[cur : cur+8])
+ cur += 8
+ msg.count = gbit32(buf[cur : cur+4])
+ cur += 4
+ msg.data = make([]byte, msg.count)
+ for i := 0; i < int(msg.count); i++ {
+ msg.data[i] = buf[cur+i]
+ }
+ cur += int(msg.count)
+ if cur != len(buf) {
+ panic("length of buf and cursor position don't match")
+ }
+ return msg
+}
+func (msg *TWrite) Size() uint32 {
+ return uint32(4 + 1 + 2 + 4 + 8 + 4 + len(msg.Data()))
+}
+func (msg *TWrite) Type() MsgType { return Tread }
+func (msg *TWrite) Tag() uint16 { return msg.tag }
+func (msg *TWrite) Fid() uint32 { return msg.fid }
+func (msg *TWrite) Offset() uint64 { return msg.offset }
+func (msg *TWrite) Count() uint32 { return msg.count }
+func (msg *TWrite) Data() []byte { return msg.data }
+func (msg *TWrite) marshal() []byte {
+ cur := 0
+ buf := make([]byte, msg.Size())
+ pbit32(buf[cur:cur+4], msg.Size())
+ cur += 4
+ buf[cur] = uint8(Tread)
+ cur += 1
+ pbit16(buf[cur:cur+2], msg.Tag())
+ cur += 2
+ pbit32(buf[cur:cur+4], msg.Fid())
+ cur += 4
+ pbit64(buf[cur:cur+8], msg.Offset())
+ cur += 8
+ pbit32(buf[cur:cur+4], msg.Count())
+ cur += 4
+ for i := 0; i < int(msg.Count()); i++ {
+ buf[cur+i] = msg.data[i]
+ }
+ cur += int(msg.Count())
+ if cur != len(buf) {
+ panic("length of buf and cursor position don't match")
+ }
+ return buf
+}
+func (msg *TWrite) String() string {
+ return fmt.Sprintf("Tread tag %d fid %d offset %d count %d '%s'",
+ msg.Tag(), msg.Fid(), msg.Offset(), msg.Count(), msg.Data())
+}
+
+type RWrite struct {
+ tag uint16
+ count uint32
+}
+
+func newRWrite(buf []byte) *RWrite {
+ msg := new(RWrite)
+ msg.tag = gbit16(buf[5:7])
+ msg.count = gbit32(buf[7:11])
+ return msg
+}
+func (msg *RWrite) Size() uint32 {
+ return uint32(4 + 1 + 2 + 4 + msg.Count())
+}
+func (msg *RWrite) Type() MsgType { return Rwrite }
+func (msg *RWrite) Tag() uint16 { return msg.tag }
+func (msg *RWrite) Count() uint32 { return msg.count }
+func (msg *RWrite) marshal() []byte {
+ cur := 0
+ buf := make([]byte, msg.Size())
+ pbit32(buf[cur:cur+4], msg.Size())
+ cur += 4
+ buf[cur] = uint8(msg.Type())
+ cur += 1
+ pbit16(buf[cur:cur+2], msg.Tag())
+ cur += 2
+ pbit32(buf[cur:cur+4], msg.Count())
+ cur += 4
+ if cur != len(buf) {
+ panic("length of buf and cursor position don't match")
+ }
+ return buf
+}
+
+func (msg *RWrite) String() string {
+ return fmt.Sprintf("Rwrite tag %d count %d", msg.Tag(), msg.Count())
+}
+
type TClunk struct {
size uint32
tag uint16
@@ -831,9 +1106,9 @@ func newRClunk(buf []byte) *RClunk {
msg.tag = gbit16(buf[5:7])
return msg
}
-func (msg *RClunk) Size() uint32 { return 7 }
-func (msg *RClunk) Type() MsgType { return Rclunk }
-func (msg *RClunk) Tag() uint16 { return msg.tag }
+func (msg *RClunk) Size() uint32 { return 7 }
+func (msg *RClunk) Type() MsgType { return Rclunk }
+func (msg *RClunk) Tag() uint16 { return msg.tag }
func (msg *RClunk) marshal() []byte {
m := make([]byte, msg.Size())
pbit32(m[0:4], msg.Size())
@@ -845,6 +1120,12 @@ func (msg *RClunk) String() string {
return fmt.Sprintf("Rclunk tag %d", msg.Tag())
}
+type TRemove struct{
+
+}
+
+type RRemove struct{}
+
type TStat struct {
size uint32
tag uint16
@@ -908,3 +1189,6 @@ func (msg *RStat) marshal() []byte {
func (msg *RStat) String() string {
return fmt.Sprintf("Rstat tag %d Stat %s", msg.Tag(), msg.stat)
}
+
+type TWStat struct{}
+type RWStat struct{}
diff --git a/fid.go b/fid.go
@@ -4,7 +4,7 @@ import (
"fmt"
)
-type OpenMode int32 // defined by 9P
+type OpenMode int8 // defined by 9P
const ( // TODO: is the mode should be implemented using interfaces?
OREAD OpenMode = 0
diff --git a/stat.go b/stat.go
@@ -15,6 +15,29 @@ const (
DMTMP = 0x04000000
)
+func (m FileMode)PermString() string {
+ s := ""
+ for i := 6; i >= 0; i -= 3 {
+ p := m >> i
+ if p&4 != 0 {
+ s += "r"
+ } else {
+ s += "-"
+ }
+ if p&2 != 0 {
+ s += "w"
+ } else {
+ s += "-"
+ }
+ if p&1 != 0 {
+ s += "x"
+ } else {
+ s += "-"
+ }
+ }
+ return s
+}
+
const (
AEXEC fs.FileMode = 1 << iota
AWRITE
diff --git a/testdir/e b/testdir/e
@@ -0,0 +1 @@
+unko