tmpfile_linux.go 908 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. //go:build linux
  2. // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
  3. package utils
  4. import (
  5. "fmt"
  6. "io/fs"
  7. "os"
  8. "strconv"
  9. "golang.org/x/sys/unix"
  10. )
  11. var _ = fmt.Print
  12. func CreateAnonymousTemp(dir string, perms ...fs.FileMode) (*os.File, error) {
  13. if dir == "" {
  14. dir = os.TempDir()
  15. }
  16. var perm fs.FileMode = unix.S_IREAD | unix.S_IWRITE
  17. if len(perms) > 0 {
  18. perm = perms[0]
  19. }
  20. fd, err := unix.Open(dir, unix.O_RDWR|unix.O_TMPFILE|unix.O_CLOEXEC, uint32(perm&fs.ModePerm))
  21. if err == nil {
  22. path := "/proc/self/fd/" + strconv.FormatUint(uint64(fd), 10)
  23. return os.NewFile(uintptr(fd), path), nil
  24. }
  25. if err == unix.ENOENT {
  26. return nil, &os.PathError{
  27. Op: "open",
  28. Path: dir,
  29. Err: err,
  30. }
  31. }
  32. f, err := os.CreateTemp(dir, "")
  33. if err != nil {
  34. return nil, err
  35. }
  36. err = os.Remove(f.Name())
  37. if err != nil {
  38. f.Close()
  39. return nil, err
  40. }
  41. return f, err
  42. }