atomicfile_test.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. //go:build !js && !windows
  4. package atomicfile
  5. import (
  6. "net"
  7. "os"
  8. "path/filepath"
  9. "runtime"
  10. "strings"
  11. "testing"
  12. )
  13. func TestDoesNotOverwriteIrregularFiles(t *testing.T) {
  14. // Per tailscale/tailscale#7658 as one example, almost any imagined use of
  15. // atomicfile.Write should likely not attempt to overwrite an irregular file
  16. // such as a device node, socket, or named pipe.
  17. const filename = "TestDoesNotOverwriteIrregularFiles"
  18. var path string
  19. // macOS private temp does not allow unix socket creation, but /tmp does.
  20. if runtime.GOOS == "darwin" {
  21. path = filepath.Join("/tmp", filename)
  22. t.Cleanup(func() { os.Remove(path) })
  23. } else {
  24. path = filepath.Join(t.TempDir(), filename)
  25. }
  26. // The least troublesome thing to make that is not a file is a unix socket.
  27. // Making a null device sadly requires root.
  28. ln, err := net.ListenUnix("unix", &net.UnixAddr{Name: path, Net: "unix"})
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. defer ln.Close()
  33. err = WriteFile(path, []byte("hello"), 0644)
  34. if err == nil {
  35. t.Fatal("expected error, got nil")
  36. }
  37. if !strings.Contains(err.Error(), "is not a regular file") {
  38. t.Fatalf("unexpected error: %v", err)
  39. }
  40. }