Go SHM API to read simple data with size from SHM name

This commit is contained in:
Kovid Goyal
2023-02-20 21:23:23 +05:30
parent 3f829ccdde
commit 5a8d903a4d
7 changed files with 229 additions and 4 deletions

View File

@@ -5,13 +5,17 @@ package shm
import (
"crypto/rand"
"encoding/base32"
"encoding/binary"
"errors"
"fmt"
"io"
not_rand "math/rand"
"os"
"strconv"
"strings"
"kitty/tools/cli"
"golang.org/x/sys/unix"
)
@@ -109,3 +113,69 @@ func truncate_or_unlink(ans *os.File, size uint64) (err error) {
}
return
}
func read_till_buf_full(f *os.File, buf []byte) ([]byte, error) {
p := buf
for len(p) > 0 {
n, err := f.Read(p)
p = p[n:]
if err != nil {
if len(p) == 0 && errors.Is(err, io.EOF) {
err = nil
}
return buf[:len(buf)-len(p)], err
}
}
return buf, nil
}
func read_with_size(f *os.File) ([]byte, error) {
szbuf := []byte{0, 0, 0, 0}
szbuf, err := read_till_buf_full(f, szbuf)
if err != nil {
return nil, err
}
size := int(binary.BigEndian.Uint32(szbuf))
return read_till_buf_full(f, make([]byte, size))
}
func test_integration_with_python(args []string) (rc int, err error) {
switch args[0] {
default:
return 1, fmt.Errorf("Unknown test type: %s", args[0])
case "read":
data, err := ReadWithSizeAndUnlink(args[1])
if err != nil {
return 1, err
}
_, err = os.Stdout.Write(data)
if err != nil {
return 1, err
}
case "write":
data, err := io.ReadAll(os.Stdin)
if err != nil {
return 1, err
}
mmap, err := CreateTemp("shmtest-", uint64(len(data)+4))
if err != nil {
return 1, err
}
defer mmap.Close()
binary.BigEndian.PutUint32(mmap.Slice(), uint32(len(data)))
copy(mmap.Slice()[4:], data)
fmt.Println(mmap.Name())
}
return 0, nil
}
func TestEntryPoint(root *cli.Command) {
root.AddSubCommand(&cli.Command{
Name: "shm",
OnlyArgsAllowed: true,
Run: func(cmd *cli.Command, args []string) (rc int, err error) {
return test_integration_with_python(args)
},
})
}

View File

@@ -113,7 +113,7 @@ func create_temp(pattern string, size uint64) (ans MMap, err error) {
return file_mmap(f, size, WRITE, true, special_name)
}
func Open(name string, size uint64) (MMap, error) {
func open(name string) (*os.File, error) {
ans, err := os.OpenFile(file_path_from_name(name), os.O_RDONLY, 0)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
@@ -123,5 +123,23 @@ func Open(name string, size uint64) (MMap, error) {
}
return nil, err
}
return ans, nil
}
func Open(name string, size uint64) (MMap, error) {
ans, err := open(name)
if err != nil {
return nil, err
}
return file_mmap(ans, size, READ, false, name)
}
func ReadWithSizeAndUnlink(name string) ([]byte, error) {
f, err := open(name)
if err != nil {
return nil, err
}
defer f.Close()
defer os.Remove(f.Name())
return read_with_size(f)
}

View File

@@ -151,3 +151,13 @@ func Open(name string, size uint64) (MMap, error) {
}
return syscall_mmap(ans, size, READ, false)
}
func ReadWithSizeAndUnlink(name string) ([]byte, error) {
f, err := shm_open(name, os.O_RDONLY, 0)
if err != nil {
return nil, err
}
defer f.Close()
defer shm_unlink(f.Name())
return read_with_size(f)
}