Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/20250801151058.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:bug: `filsystem` IsFile should return true for special unix files not just regular files
14 changes: 13 additions & 1 deletion utils/filesystem/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"os"
"os/user"
"path/filepath"
Expand Down Expand Up @@ -777,7 +778,7 @@ func (fs *VFS) IsFile(path string) (result bool, err error) {
if err != nil {
return
}
result = IsRegularFile(fi)
result = IsRegularFile(fi) || IsSpecialFile(fi)
return
}

Expand All @@ -788,6 +789,17 @@ func IsRegularFile(fi os.FileInfo) bool {
return fi.Mode().IsRegular()
}

func IsSpecialFile(fi os.FileInfo) bool {
if fi == nil {
return false
}
mode := fi.Mode()
isSocket := mode&fs.ModeSocket != 0
isDevice := mode&fs.ModeDevice != 0
isNamedPipe := mode&fs.ModeNamedPipe != 0
return isSocket || isDevice || isNamedPipe
}

func (fs *VFS) IsLink(path string) (result bool, err error) {
err = fs.checkWhetherUnderlyingResourceIsClosed()
if err != nil {
Expand Down
46 changes: 46 additions & 0 deletions utils/filesystem/files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"context"
"fmt"
"io"
"net"
"os"
"path/filepath"
"reflect"
Expand All @@ -22,6 +23,7 @@ import (
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sys/unix"

"github.com/ARM-software/golang-utils/utils/collection"
"github.com/ARM-software/golang-utils/utils/commonerrors"
Expand Down Expand Up @@ -546,6 +548,50 @@ func TestConvertPaths(t *testing.T) {
}
}

func TestIsFile(t *testing.T) {
if platform.IsWindows() {
t.Skip("Windows doesn't have features such as named pipes or unix sockets")
}
for _, fsType := range FileSystemTypes {
t.Run(fmt.Sprint(fsType), func(t *testing.T) {
fs := NewFs(fsType)

if fsType == InMemoryFS {
t.Skip("In-memory file system won't have hardware devices or special files")
}

b, err := fs.IsFile("/dev/null")
require.NoError(t, err)
assert.True(t, b)

tmpDir := t.TempDir()

fifoPath := filepath.Join(tmpDir, faker.Word())
require.NoError(t, err)
defer func() { _ = fs.Rm(fifoPath) }()
err = unix.Mkfifo(fifoPath, 0666)
require.NoError(t, err)
b, err = fs.IsFile(fifoPath)
require.NoError(t, err)
assert.True(t, b)
err = fs.Rm(fifoPath)
require.NoError(t, err)

socketPath := filepath.Join(tmpDir, faker.Word())
require.NoError(t, err)
defer func() { _ = fs.Rm(socketPath) }()
l, err := net.Listen("unix", socketPath)
require.NoError(t, err)
defer func() { _ = l.Close() }()
b, err = fs.IsFile(socketPath)
require.NoError(t, err)
assert.True(t, b)
err = fs.Rm(socketPath)
require.NoError(t, err)
})
}
}

func TestLink(t *testing.T) {
if platform.IsWindows() {
fmt.Println("In order to run TestLink on Windows, Developer mode must be enabled: https://github.com/golang/go/pull/24307")
Expand Down
Loading