lib9p

Go 9P library.
Log | Files | Refs

commit a97ff77ac15a8bacedb7e251f11933f31bf4fc20
parent ee1b3758df2258daf51be5af2152ad2dffaabafc
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Wed,  6 Sep 2023 10:01:37 +0900

add messages

Diffstat:
Mfcall.go | 318++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mfid.go | 2+-
Mstat.go | 23+++++++++++++++++++++++
Atestdir/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