Switch to external shm package

This commit is contained in:
Kovid Goyal
2025-11-10 12:01:05 +05:30
parent 1c8e8e9530
commit d19fc375ba
23 changed files with 56 additions and 807 deletions

1
go.mod
View File

@@ -13,6 +13,7 @@ require (
github.com/google/uuid v1.6.0
github.com/kovidgoyal/dbus v0.0.0-20250519011319-e811c41c0bc1
github.com/kovidgoyal/go-parallel v1.1.1
github.com/kovidgoyal/go-shm v1.0.0
github.com/kovidgoyal/imaging v1.8.8
github.com/seancfoley/ipaddress-go v1.7.1
github.com/shirou/gopsutil/v4 v4.25.10

2
go.sum
View File

@@ -32,6 +32,8 @@ github.com/kovidgoyal/dbus v0.0.0-20250519011319-e811c41c0bc1 h1:rMY/hWfcVzBm6BL
github.com/kovidgoyal/dbus v0.0.0-20250519011319-e811c41c0bc1/go.mod h1:RbNG3Q1g6GUy1/WzWVx+S24m7VKyvl57vV+cr2hpt50=
github.com/kovidgoyal/go-parallel v1.1.1 h1:1OzpNjtrUkBPq3UaqrnvOoB2F9RttSt811uiUXyI7ok=
github.com/kovidgoyal/go-parallel v1.1.1/go.mod h1:BJNIbe6+hxyFWv7n6oEDPj3PA5qSw5OCtf0hcVxWJiw=
github.com/kovidgoyal/go-shm v1.0.0 h1:HJEel9D1F9YhULvClEHJLawoRSj/1u/EDV7MJbBPgQo=
github.com/kovidgoyal/go-shm v1.0.0/go.mod h1:Yzb80Xf9L3kaoB2RGok9hHwMIt7Oif61kT6t3+VnZds=
github.com/kovidgoyal/imaging v1.8.8 h1:PohlAOYuokFtmt6sjhgA90YAUKhuuL3i0dhd5gepp4g=
github.com/kovidgoyal/imaging v1.8.8/go.mod h1:GAbZkbyB86PSfosof5EnS2o6N15yUk9Vy2r61EWy1Wg=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik=

View File

@@ -8,11 +8,11 @@ import (
"os"
"time"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/kitty/tools/tui/graphics"
"github.com/kovidgoyal/kitty/tools/tui/loop"
"github.com/kovidgoyal/kitty/tools/utils"
"github.com/kovidgoyal/kitty/tools/utils/images"
"github.com/kovidgoyal/kitty/tools/utils/shm"
)
var _ = fmt.Print

View File

@@ -15,12 +15,12 @@ import (
"path/filepath"
"strings"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/kitty/tools/tui"
"github.com/kovidgoyal/kitty/tools/tui/graphics"
"github.com/kovidgoyal/kitty/tools/tui/loop"
"github.com/kovidgoyal/kitty/tools/utils"
"github.com/kovidgoyal/kitty/tools/utils/images"
"github.com/kovidgoyal/kitty/tools/utils/shm"
)
var _ = fmt.Print

View File

@@ -13,9 +13,9 @@ import (
"strings"
"time"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/kitty/tools/cli"
"github.com/kovidgoyal/kitty/tools/tty"
"github.com/kovidgoyal/kitty/tools/utils/shm"
)
var _ = fmt.Print

View File

@@ -28,6 +28,7 @@ import (
"syscall"
"time"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/kitty/tools/cli"
"github.com/kovidgoyal/kitty/tools/themes"
"github.com/kovidgoyal/kitty/tools/tty"
@@ -37,7 +38,6 @@ import (
"github.com/kovidgoyal/kitty/tools/utils"
"github.com/kovidgoyal/kitty/tools/utils/secrets"
"github.com/kovidgoyal/kitty/tools/utils/shlex"
"github.com/kovidgoyal/kitty/tools/utils/shm"
"golang.org/x/sys/unix"
)

View File

@@ -6,8 +6,8 @@ import (
"encoding/binary"
"encoding/json"
"fmt"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/kitty"
"github.com/kovidgoyal/kitty/tools/utils/shm"
"io/fs"
"os"
"os/exec"

View File

@@ -7,9 +7,9 @@ import (
"os/signal"
"strings"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/kitty/tools/cli"
"github.com/kovidgoyal/kitty/tools/utils"
"github.com/kovidgoyal/kitty/tools/utils/shm"
)
var _ = fmt.Print

View File

@@ -4,19 +4,62 @@ package pytest
import (
"fmt"
"io"
"os"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/kitty/kittens/ssh"
"github.com/kovidgoyal/kitty/tools/cli"
"github.com/kovidgoyal/kitty/tools/utils/shm"
)
var _ = fmt.Print
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 := shm.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 := shm.CreateTemp("shmtest-", uint64(len(data)+shm.NUM_BYTES_FOR_SIZE))
if err != nil {
return 1, err
}
if err = shm.WriteWithSize(mmap, data, 0); err != nil {
return 1, err
}
mmap.Close()
fmt.Println(mmap.Name())
}
return 0, nil
}
func shm_entry_point(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)
},
})
}
func EntryPoint(root *cli.Command) {
root = root.AddSubCommand(&cli.Command{
Name: "__pytest__",
Hidden: true,
})
shm.TestEntryPoint(root)
shm_entry_point(root)
ssh.TestEntryPoint(root)
}

View File

@@ -10,11 +10,11 @@ import (
"sync"
"sync/atomic"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/kitty/tools/tui"
"github.com/kovidgoyal/kitty/tools/tui/loop"
"github.com/kovidgoyal/kitty/tools/utils"
"github.com/kovidgoyal/kitty/tools/utils/images"
"github.com/kovidgoyal/kitty/tools/utils/shm"
)
var _ = fmt.Print

View File

@@ -10,9 +10,9 @@ import (
"os"
"strings"
"github.com/kovidgoyal/go-shm"
"github.com/kovidgoyal/imaging/nrgb"
"github.com/kovidgoyal/kitty/tools/utils"
"github.com/kovidgoyal/kitty/tools/utils/shm"
"github.com/kovidgoyal/imaging"
)

View File

@@ -1,20 +0,0 @@
// License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
import (
"errors"
"fmt"
"golang.org/x/sys/unix"
)
var _ = fmt.Print
func Fallocate_simple(fd int, size int64) (err error) {
for {
if err = unix.Fallocate(fd, 0, 0, size); !errors.Is(err, unix.EINTR) {
return
}
}
}

View File

@@ -1,16 +0,0 @@
// License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
//go:build !linux
package shm
import (
"errors"
"fmt"
)
var _ = fmt.Print
func Fallocate_simple(fd int, size int64) (err error) {
return errors.ErrUnsupported
}

View File

@@ -1,252 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
import (
"encoding/binary"
"errors"
"fmt"
"io"
"io/fs"
"os"
"strings"
"github.com/kovidgoyal/kitty/tools/cli"
"golang.org/x/sys/unix"
)
var _ = fmt.Print
var ErrPatternHasSeparator = errors.New("The specified pattern has file path separators in it")
var ErrPatternTooLong = errors.New("The specified pattern for the SHM name is too long")
type ErrNotSupported struct {
err error
}
func (self *ErrNotSupported) Error() string {
return fmt.Sprintf("POSIX shared memory not supported on this platform: with underlying error: %v", self.err)
}
// prefix_and_suffix splits pattern by the last wildcard "*", if applicable,
// returning prefix as the part before "*" and suffix as the part after "*".
func prefix_and_suffix(pattern string) (prefix, suffix string, err error) {
for i := 0; i < len(pattern); i++ {
if os.IsPathSeparator(pattern[i]) {
return "", "", ErrPatternHasSeparator
}
}
if pos := strings.LastIndexByte(pattern, '*'); pos != -1 {
prefix, suffix = pattern[:pos], pattern[pos+1:]
} else {
prefix = pattern
}
return prefix, suffix, nil
}
type MMap interface {
Close() error
Unlink() error
Slice() []byte
Name() string
IsFileSystemBacked() bool
FileSystemName() string
Stat() (fs.FileInfo, error)
Flush() error
Seek(offset int64, whence int) (ret int64, err error)
Read(b []byte) (n int, err error)
Write(b []byte) (n int, err error)
}
type AccessFlags int
const (
READ AccessFlags = iota
WRITE
COPY
)
func mmap(sz int, access AccessFlags, fd int, off int64) ([]byte, error) {
flags := unix.MAP_SHARED
prot := unix.PROT_READ
switch access {
case COPY:
prot |= unix.PROT_WRITE
flags = unix.MAP_PRIVATE
case WRITE:
prot |= unix.PROT_WRITE
}
b, err := unix.Mmap(fd, off, sz, prot, flags)
if err != nil {
return nil, err
}
return b, nil
}
func munmap(s []byte) error {
return unix.Munmap(s)
}
func CreateTemp(pattern string, size uint64) (MMap, error) {
return create_temp(pattern, size)
}
func truncate_or_unlink(ans *os.File, size uint64, unlink func(string) error) (err error) {
fd := int(ans.Fd())
sz := int64(size)
if err = Fallocate_simple(fd, sz); err != nil {
if !errors.Is(err, errors.ErrUnsupported) {
return fmt.Errorf("fallocate() failed on fd from shm_open(%s) with size: %d with error: %w", ans.Name(), size, err)
}
for {
if err = unix.Ftruncate(fd, sz); !errors.Is(err, unix.EINTR) {
break
}
}
}
if err != nil {
_ = ans.Close()
_ = unlink(ans.Name())
return fmt.Errorf("Failed to ftruncate() SHM file %s to size: %d with error: %w", ans.Name(), size, err)
}
return
}
const NUM_BYTES_FOR_SIZE = 4
var ErrRegionTooSmall = errors.New("mmaped region too small")
func WriteWithSize(self MMap, b []byte, at int) error {
if len(self.Slice()) < at+len(b)+NUM_BYTES_FOR_SIZE {
return ErrRegionTooSmall
}
binary.BigEndian.PutUint32(self.Slice()[at:], uint32(len(b)))
copy(self.Slice()[at+NUM_BYTES_FOR_SIZE:], b)
return nil
}
func ReadWithSize(self MMap, at int) ([]byte, error) {
s := self.Slice()[at:]
if len(s) < NUM_BYTES_FOR_SIZE {
return nil, ErrRegionTooSmall
}
size := int(binary.BigEndian.Uint32(self.Slice()[at : at+NUM_BYTES_FOR_SIZE]))
s = s[NUM_BYTES_FOR_SIZE:]
if len(s) < size {
return nil, ErrRegionTooSmall
}
return s[:size], nil
}
func ReadWithSizeAndUnlink(name string, file_callback ...func(fs.FileInfo) error) ([]byte, error) {
mmap, err := Open(name, 0)
if err != nil {
return nil, err
}
if len(file_callback) > 0 {
s, err := mmap.Stat()
if err != nil {
return nil, fmt.Errorf("Failed to stat SHM file with error: %w", err)
}
for _, f := range file_callback {
err = f(s)
if err != nil {
return nil, err
}
}
}
defer func() {
mmap.Close()
_ = mmap.Unlink()
}()
slice, err := ReadWithSize(mmap, 0)
if err != nil {
return nil, err
}
ans := make([]byte, len(slice))
copy(ans, slice)
return ans, nil
}
func Read(self MMap, b []byte) (n int, err error) {
pos, err := self.Seek(0, io.SeekCurrent)
if err != nil {
return 0, err
}
if pos < 0 {
pos = 0
}
s := self.Slice()
sz := int64(len(s))
if pos >= sz {
return 0, io.EOF
}
n = copy(b, s[pos:])
_, err = self.Seek(int64(n), io.SeekCurrent)
return
}
func Write(self MMap, b []byte) (n int, err error) {
if len(b) == 0 {
return 0, nil
}
pos, _ := self.Seek(0, io.SeekCurrent)
if pos < 0 {
pos = 0
}
s := self.Slice()
if pos >= int64(len(s)) {
return 0, io.ErrShortWrite
}
n = copy(s[pos:], b)
if _, err = self.Seek(int64(n), io.SeekCurrent); err != nil {
return n, err
}
if n < len(b) {
return n, io.ErrShortWrite
}
return n, nil
}
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)+NUM_BYTES_FOR_SIZE))
if err != nil {
return 1, err
}
if err = WriteWithSize(mmap, data, 0); err != nil {
return 1, err
}
mmap.Close()
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

@@ -1,189 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
//go:build linux || netbsd || openbsd || dragonfly
package shm
import (
"crypto/sha256"
"errors"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/kovidgoyal/kitty/tools/utils"
"golang.org/x/sys/unix"
)
var _ = fmt.Print
type file_based_mmap struct {
f *os.File
pos int64
region []byte
unlinked bool
special_name string
}
func ShmUnlink(name string) error {
if runtime.GOOS == "openbsd" {
return os.Remove(openbsd_shm_path(name))
}
name = strings.TrimPrefix(name, "/")
return os.Remove(filepath.Join(SHM_DIR, name))
}
func file_mmap(f *os.File, size uint64, access AccessFlags, truncate bool, special_name string) (MMap, error) {
if truncate {
err := truncate_or_unlink(f, size, os.Remove)
if err != nil {
return nil, err
}
}
region, err := mmap(int(size), access, int(f.Fd()), 0)
if err != nil {
f.Close()
os.Remove(f.Name())
return nil, err
}
return &file_based_mmap{f: f, region: region, special_name: special_name}, nil
}
func (self *file_based_mmap) Seek(offset int64, whence int) (ret int64, err error) {
switch whence {
case io.SeekStart:
self.pos = offset
case io.SeekEnd:
self.pos = int64(len(self.region)) + offset
case io.SeekCurrent:
self.pos += offset
}
return self.pos, nil
}
func (self *file_based_mmap) Read(b []byte) (n int, err error) {
return Read(self, b)
}
func (self *file_based_mmap) Write(b []byte) (n int, err error) {
return Write(self, b)
}
func (self *file_based_mmap) Stat() (fs.FileInfo, error) {
return self.f.Stat()
}
func (self *file_based_mmap) Name() string {
if self.special_name != "" {
return self.special_name
}
return filepath.Base(self.f.Name())
}
func (self *file_based_mmap) Flush() error {
return unix.Msync(self.region, unix.MS_SYNC)
}
func (self *file_based_mmap) FileSystemName() string {
return self.f.Name()
}
func (self *file_based_mmap) Slice() []byte {
return self.region
}
func (self *file_based_mmap) Close() (err error) {
if self.region != nil {
self.f.Close()
err = munmap(self.region)
self.region = nil
}
return err
}
func (self *file_based_mmap) Unlink() (err error) {
if self.unlinked {
return nil
}
self.unlinked = true
return os.Remove(self.f.Name())
}
func (self *file_based_mmap) IsFileSystemBacked() bool { return true }
func openbsd_shm_path(name string) string {
hash := sha256.Sum256(utils.UnsafeStringToBytes(name))
return filepath.Join(SHM_DIR, utils.UnsafeBytesToString(hash[:])+".shm")
}
func file_path_from_name(name string) string {
// See https://github.com/openbsd/src/blob/master/lib/libc/gen/shm_open.c
if runtime.GOOS == "openbsd" {
return openbsd_shm_path(name)
}
return filepath.Join(SHM_DIR, name)
}
func create_temp(pattern string, size uint64) (ans MMap, err error) {
special_name := ""
var prefix, suffix string
prefix, suffix, err = prefix_and_suffix(pattern)
if err != nil {
return
}
var f *os.File
try := 0
for {
name := prefix + utils.RandomFilename() + suffix
path := file_path_from_name(name)
f, err = os.OpenFile(path, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
if errors.Is(err, fs.ErrExist) {
try += 1
if try > 10000 {
return nil, &os.PathError{Op: "createtemp", Path: prefix + "*" + suffix, Err: fs.ErrExist}
}
continue
}
if errors.Is(err, fs.ErrNotExist) {
return nil, &ErrNotSupported{err: err}
}
return
}
break
}
return file_mmap(f, size, WRITE, true, special_name)
}
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) {
if _, serr := os.Stat(SHM_DIR); serr != nil && errors.Is(serr, fs.ErrNotExist) {
return nil, &ErrNotSupported{err: serr}
}
}
return nil, err
}
return ans, nil
}
func Open(name string, size uint64) (MMap, error) {
ans, err := open(name)
if err != nil {
return nil, err
}
if size == 0 {
s, err := ans.Stat()
if err != nil {
ans.Close()
return nil, fmt.Errorf("Failed to stat SHM file with error: %w", err)
}
size = uint64(s.Size())
}
return file_mmap(ans, size, READ, false, name)
}

View File

@@ -1,200 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
//go:build darwin || freebsd
package shm
import (
"errors"
"fmt"
"io"
"io/fs"
"os"
"strings"
"unsafe"
"github.com/kovidgoyal/kitty/tools/utils"
"golang.org/x/sys/unix"
)
var _ = fmt.Print
// ByteSliceFromString makes a zero terminated byte slice from the string
func ByteSliceFromString(s string) []byte {
a := make([]byte, len(s)+1)
copy(a, s)
return a
}
func BytePtrFromString(s string) *byte {
a := ByteSliceFromString(s)
return &a[0]
}
func shm_unlink(name string) (err error) {
bname := BytePtrFromString(name)
for {
_, _, errno := unix.Syscall(unix.SYS_SHM_UNLINK, uintptr(unsafe.Pointer(bname)), 0, 0)
if errno != unix.EINTR {
if errno != 0 {
if errno == unix.ENOENT {
err = fs.ErrNotExist
} else {
err = fmt.Errorf("shm_unlink() failed with error: %w", errno)
}
}
break
}
}
return
}
func ShmUnlink(name string) error {
return shm_unlink(name)
}
func shm_open(name string, flags, perm int) (ans *os.File, err error) {
bname := BytePtrFromString(name)
var fd uintptr
var errno unix.Errno
for {
fd, _, errno = unix.Syscall(unix.SYS_SHM_OPEN, uintptr(unsafe.Pointer(bname)), uintptr(flags), uintptr(perm))
if errno != unix.EINTR {
if errno != 0 {
err = fmt.Errorf("shm_open() failed with error: %w", errno)
}
break
}
}
if err == nil {
ans = os.NewFile(fd, name)
}
return
}
type syscall_based_mmap struct {
f *os.File
pos int64
region []byte
unlinked bool
}
func syscall_mmap(f *os.File, size uint64, access AccessFlags, truncate bool) (MMap, error) {
if truncate {
err := truncate_or_unlink(f, size, shm_unlink)
if err != nil {
return nil, fmt.Errorf("truncate failed with error: %w", err)
}
}
region, err := mmap(int(size), access, int(f.Fd()), 0)
if err != nil {
_ = f.Close()
_ = shm_unlink(f.Name())
return nil, fmt.Errorf("mmap failed with error: %w", err)
}
return &syscall_based_mmap{f: f, region: region}, nil
}
func (self *syscall_based_mmap) Name() string {
return self.f.Name()
}
func (self *syscall_based_mmap) Stat() (fs.FileInfo, error) {
return self.f.Stat()
}
func (self *syscall_based_mmap) Flush() error {
return unix.Msync(self.region, unix.MS_SYNC)
}
func (self *syscall_based_mmap) Slice() []byte {
return self.region
}
func (self *syscall_based_mmap) Close() (err error) {
if self.region != nil {
self.f.Close()
munmap(self.region)
self.region = nil
}
return
}
func (self *syscall_based_mmap) Unlink() (err error) {
if self.unlinked {
return nil
}
self.unlinked = true
return shm_unlink(self.Name())
}
func (self *syscall_based_mmap) Seek(offset int64, whence int) (ret int64, err error) {
switch whence {
case io.SeekStart:
self.pos = offset
case io.SeekEnd:
self.pos = int64(len(self.region)) + offset
case io.SeekCurrent:
self.pos += offset
}
return self.pos, nil
}
func (self *syscall_based_mmap) Read(b []byte) (n int, err error) {
return Read(self, b)
}
func (self *syscall_based_mmap) Write(b []byte) (n int, err error) {
return Write(self, b)
}
func (self *syscall_based_mmap) IsFileSystemBacked() bool { return false }
func (self *syscall_based_mmap) FileSystemName() string { return "" }
func create_temp(pattern string, size uint64) (ans MMap, err error) {
var prefix, suffix string
prefix, suffix, err = prefix_and_suffix(pattern)
if err != nil {
return
}
if SHM_REQUIRED_PREFIX != "" && !strings.HasPrefix(pattern, SHM_REQUIRED_PREFIX) {
// FreeBSD requires name to start with /
prefix = SHM_REQUIRED_PREFIX + prefix
}
var f *os.File
try := 0
for {
name := prefix + utils.RandomFilename() + suffix
if len(name) > SHM_NAME_MAX {
return nil, ErrPatternTooLong
}
f, err = shm_open(name, os.O_EXCL|os.O_CREATE|os.O_RDWR, 0600)
if err != nil && (errors.Is(err, fs.ErrExist) || errors.Unwrap(err) == unix.EEXIST) {
try += 1
if try > 10000 {
return nil, &os.PathError{Op: "createtemp", Path: prefix + "*" + suffix, Err: fs.ErrExist}
}
continue
}
break
}
if err != nil {
return nil, err
}
return syscall_mmap(f, size, WRITE, true)
}
func Open(name string, size uint64) (MMap, error) {
ans, err := shm_open(name, os.O_RDONLY, 0)
if err != nil {
return nil, err
}
if size == 0 {
s, err := ans.Stat()
if err != nil {
ans.Close()
return nil, fmt.Errorf("Failed to stat SHM file with error: %w", err)
}
size = uint64(s.Size())
}
return syscall_mmap(ans, size, READ, false)
}

View File

@@ -1,61 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
import (
"crypto/rand"
"errors"
"fmt"
"io/fs"
"os"
"reflect"
"testing"
)
var _ = fmt.Print
func TestSHM(t *testing.T) {
data := make([]byte, 13347)
_, _ = rand.Read(data)
mm, err := CreateTemp("test-kitty-shm-", uint64(len(data)))
if err != nil {
t.Fatal(err)
}
copy(mm.Slice(), data)
err = mm.Flush()
if err != nil {
t.Fatalf("Failed to msync() with error: %v", err)
}
err = mm.Close()
if err != nil {
t.Fatalf("Failed to close with error: %v", err)
}
g, err := Open(mm.Name(), uint64(len(data)))
if err != nil {
t.Fatal(err)
}
data2 := g.Slice()
if !reflect.DeepEqual(data, data2) {
t.Fatalf("Could not read back written data: Written data length: %d Read data length: %d", len(data), len(data2))
}
err = g.Close()
if err != nil {
t.Fatalf("Failed to close with error: %v", err)
}
err = g.Unlink()
if err != nil {
t.Fatalf("Failed to unlink with error: %v", err)
}
g, err = Open(mm.Name(), uint64(len(data)))
if err == nil {
t.Fatalf("Unlinking failed could re-open the SHM data. Data equal: %v Data length: %d", reflect.DeepEqual(g.Slice(), data), len(g.Slice()))
}
if mm.IsFileSystemBacked() {
_, err = os.Stat(mm.FileSystemName())
if !errors.Is(err, fs.ErrNotExist) {
t.Fatalf("Unlinking %s did not work", mm.Name())
}
}
}

View File

@@ -1,7 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
const SHM_NAME_MAX = 30
const SHM_REQUIRED_PREFIX = ""
const SHM_DIR = ""

View File

@@ -1,12 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
import (
"fmt"
)
var _ = fmt.Print
// https://www.dragonflybsd.org/cgi/web-man?command=shm_open&section=3
const SHM_DIR = "/var/run/shm"

View File

@@ -1,7 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
const SHM_NAME_MAX = 1023
const SHM_REQUIRED_PREFIX = "/"
const SHM_DIR = ""

View File

@@ -1,11 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
import (
"fmt"
)
var _ = fmt.Print
const SHM_DIR = "/dev/shm"

View File

@@ -1,11 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
import (
"fmt"
)
var _ = fmt.Print
const SHM_DIR = "/var/shm"

View File

@@ -1,11 +0,0 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package shm
import (
"fmt"
)
var _ = fmt.Print
const SHM_DIR = "/tmp"