Ensure temp files and other resources are cleaned up even if kitty crashes or is SIGKILLed

This commit is contained in:
Kovid Goyal
2025-01-05 12:51:59 +05:30
parent 48d5c90bb8
commit 334adf9c1a
9 changed files with 93 additions and 32 deletions

View File

@@ -2,12 +2,15 @@ package atexit
import (
"bufio"
"errors"
"fmt"
"io/fs"
"os"
"os/signal"
"strings"
"kitty/tools/cli"
"kitty/tools/utils/shm"
)
var _ = fmt.Print
@@ -40,13 +43,18 @@ func main() (rc int, err error) {
if action, rest, found := strings.Cut(line, " "); found {
switch action {
case "unlink":
if err := os.Remove(rest); err != nil {
fmt.Fprintln(os.Stderr, "Failed to remove:", rest, "with error:", err)
if err := os.Remove(rest); err != nil && !errors.Is(err, fs.ErrNotExist) {
fmt.Fprintln(os.Stderr, "Failed to unlink:", rest, "with error:", err)
rc = 1
}
case "shm_unlink":
if err := shm.ShmUnlink(rest); err != nil && !errors.Is(err, fs.ErrNotExist) {
fmt.Fprintln(os.Stderr, "Failed to shm_unlink:", rest, "with error:", err)
rc = 1
}
case "rmtree":
if err := os.RemoveAll(rest); err != nil {
fmt.Fprintln(os.Stderr, "Failed to remove:", rest, "with error:", err)
if err := os.RemoveAll(rest); err != nil && !errors.Is(err, fs.ErrNotExist) {
fmt.Fprintln(os.Stderr, "Failed to rmtree:", rest, "with error:", err)
rc = 1
}
}

View File

@@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"runtime"
"strings"
"kitty/tools/utils"
@@ -28,6 +29,16 @@ type file_based_mmap struct {
special_name string
}
func ShmUnlink(name string) error {
if runtime.GOOS == "openbsd" {
return os.Remove(openbsd_shm_path(name))
}
if strings.HasPrefix(name, "/") {
name = name[1:]
}
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)
@@ -106,11 +117,15 @@ func (self *file_based_mmap) Unlink() (err error) {
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" {
hash := sha256.Sum256(utils.UnsafeStringToBytes(name))
return filepath.Join(SHM_DIR, utils.UnsafeBytesToString(hash[:])+".shm")
return openbsd_shm_path(name)
}
return filepath.Join(SHM_DIR, name)
}

View File

@@ -37,7 +37,11 @@ func shm_unlink(name string) (err error) {
_, _, errno := unix.Syscall(unix.SYS_SHM_UNLINK, uintptr(unsafe.Pointer(bname)), 0, 0)
if errno != unix.EINTR {
if errno != 0 {
err = fmt.Errorf("shm_unlink() failed with error: %w", errno)
if errno == unix.ENOENT {
err = fs.ErrNotExist
} else {
err = fmt.Errorf("shm_unlink() failed with error: %w", errno)
}
}
break
}
@@ -45,6 +49,10 @@ func shm_unlink(name string) (err error) {
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