Skip to content

Commit

Permalink
Make -O and -G unary test code build under Windows
Browse files Browse the repository at this point in the history
Move the -O & -G code into os_notunix.go and os_unix.go.

The Windows code still just panics.
  • Loading branch information
theclapp committed Jun 28, 2024
1 parent 7b9f78f commit 3438bbb
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 21 deletions.
11 changes: 11 additions & 0 deletions interp/os_notunix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
package interp

import (
"context"
"fmt"

"mvdan.cc/sh/v3/syntax"
)

func mkfifo(path string, mode uint32) error {
Expand All @@ -17,3 +20,11 @@ func mkfifo(path string, mode uint32) error {
func hasPermissionToDir(string) bool {
return true
}

// unTestOwnOrGrp panics. Under Unix, it implements the -O and -G unary tests,
// but under Windows, it's unclear how to implement those tests, since Windows
// doesn't have the concept of a file owner, just ACLs, and it's unclear how
// to map the one to the other.
func (r *Runner) unTestOwnOrGrp(ctx context.Context, op syntax.UnTestOperator, x string) bool {
panic(fmt.Sprintf("unhandled unary test op: %v", op))
}
25 changes: 25 additions & 0 deletions interp/os_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
package interp

import (
"context"
"os/user"
"strconv"
"syscall"

"golang.org/x/sys/unix"
"mvdan.cc/sh/v3/syntax"
)

func mkfifo(path string, mode uint32) error {
Expand All @@ -18,3 +24,22 @@ func mkfifo(path string, mode uint32) error {
func hasPermissionToDir(path string) bool {
return unix.Access(path, unix.X_OK) == nil
}

// unTestOwnOrGrp implements the -O and -G unary tests. If the file does not
// exist, or the current user cannot be retrieved, returns false.
func (r *Runner) unTestOwnOrGrp(ctx context.Context, op syntax.UnTestOperator, x string) bool {
info, err := r.stat(ctx, x)
if err != nil {
return false
}
u, err := user.Current()
if err != nil {
return false
}
if op == syntax.TsUsrOwn {
uid, _ := strconv.Atoi(u.Uid)
return uint32(uid) == info.Sys().(*syscall.Stat_t).Uid
}
gid, _ := strconv.Atoi(u.Gid)
return uint32(gid) == info.Sys().(*syscall.Stat_t).Gid
}
22 changes: 1 addition & 21 deletions interp/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import (
"fmt"
"os"
"os/exec"
"os/user"
"regexp"
"runtime"
"strconv"
"syscall"

"golang.org/x/term"

Expand Down Expand Up @@ -205,23 +201,7 @@ func (r *Runner) unTest(ctx context.Context, op syntax.UnTestOperator, x string)
case syntax.TsNot:
return x == ""
case syntax.TsUsrOwn, syntax.TsGrpOwn:
if runtime.GOOS == "windows" {
panic(fmt.Sprintf("unhandled unary test op: %v", op))
}
fi, err := os.Stat(x)
if err != nil {
return false
}
u, err := user.Current()
if err != nil {
return false
}
if op == syntax.TsUsrOwn {
uid, _ := strconv.Atoi(u.Uid)
return uint32(uid) == fi.Sys().(*syscall.Stat_t).Uid
}
gid, _ := strconv.Atoi(u.Gid)
return uint32(gid) == fi.Sys().(*syscall.Stat_t).Gid
return r.unTestOwnOrGrp(ctx, op, x)
default:
panic(fmt.Sprintf("unhandled unary test op: %v", op))
}
Expand Down

0 comments on commit 3438bbb

Please sign in to comment.