Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 15 additions & 0 deletions interp/actime/os_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package actime

import (
"io/fs"
"syscall"
"time"
)

func GetAtime(info fs.FileInfo) time.Time {
stat, ok := info.Sys().(*syscall.Stat_t)
if !ok {
return info.ModTime()
}
return time.Unix(stat.Atimespec.Sec, stat.Atimespec.Nsec)
}
16 changes: 16 additions & 0 deletions interp/actime/os_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package actime

import (
"io/fs"
"syscall"
"time"
)

func GetAtime(info fs.FileInfo) time.Time {
stat, ok := info.Sys().(*syscall.Stat_t)

if !ok {
return info.ModTime()
}
return time.Unix(stat.Atim.Sec, stat.Atim.Nsec)
}
10 changes: 10 additions & 0 deletions interp/actime/os_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package actime

import (
"io/fs"
"time"
)

func GetAtime(info fs.FileInfo) time.Time {
return info.ModTime()
}
15 changes: 15 additions & 0 deletions interp/actime/os_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package actime

import (
"io/fs"
"syscall"
"time"
)

func GetAtime(info fs.FileInfo) time.Time {
stat, ok := info.Sys().(*syscall.Win32FileAttributeData)
if !ok {
return info.ModTime()
}
return time.Unix(0, stat.LastAccessTime.Nanoseconds())
}
15 changes: 13 additions & 2 deletions interp/interp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1960,9 +1960,20 @@ var runTests = []runTest{
"mkdir d; [ -r d ] && echo r; [ -w d ] && echo w; [ -x d ] && echo x",
"r\nw\nx\n",
},
// -N: true if file exists and was modified since last read
{
"test -N a",
"unsupported unary test op: -N\nexit status 1 #IGNORE",
">a; cat a; sleep 0.01; echo 'Hello' >> a; test -N a && echo yes",
"yes\n",
},
// -N: false for non-existent file
{
"test -N nonexistent",
"exit status 1",
},
// -N: false if file was read after last modification
{
">a; sleep 0.01; cat a; test -N a; echo $?",
"1\n",
},
{
"test -? a",
Expand Down
8 changes: 6 additions & 2 deletions interp/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"golang.org/x/term"

"mvdan.cc/sh/v3/expand"
"mvdan.cc/sh/v3/interp/actime"
"mvdan.cc/sh/v3/syntax"
)

Expand Down Expand Up @@ -166,8 +167,11 @@ func (r *Runner) unTest(ctx context.Context, op syntax.UnTestOperator, x string)
case syntax.TsGIDSet:
return r.statMode(ctx, x, os.ModeSetgid)
case syntax.TsModif:
r.errf("unsupported unary test op: %v\n", op)
return false
info, err := r.stat(ctx, x)
if err != nil {
return false
}
return info.ModTime().After(actime.GetAtime(info))
case syntax.TsRead:
return r.access(ctx, r.absPath(x), access_R_OK) == nil
case syntax.TsWrite:
Expand Down