4

In linux the stat struct contains the UID and GID of a file.

Is there a way to obtain the same information (UID and GID) of a file using Go(lang)?

kostix
  • 51,517
  • 14
  • 93
  • 176
Siscia
  • 1,421
  • 1
  • 12
  • 29
  • 2
    Looks like go's `os` package has a `Stat` function that doesn't include that information, and yet it has a `Chown` function that takes uid and gid... strange decisions there. – Shawn Oct 01 '19 at 07:14

1 Answers1

7

I figured out a reasonable way to do it.

import (
    "syscall"
    "os"
)

info, _ := os.Stat("/path/to/the/file")

var UID int
var GID int
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
    UID = int(stat.Uid)
    GID = int(stat.Gid)
} else {
    // we are not in linux, this won't work anyway in windows, 
    // but maybe you want to log warnings
    UID = os.Getuid()
    GID = os.Getgid()
}
Siscia
  • 1,421
  • 1
  • 12
  • 29
  • 1
    Yeah, I think it's not just "a reasonable way to do it". It's _the_ way to do it. https://github.com/golang/go/issues/14753 – 425nesp Oct 01 '19 at 07:23
  • 1
    Or alternatively you may directly call [`syscall.Stat()`](https://golang.org/pkg/syscall/#Stat) which returns [`*syscall.Stat_t`](https://golang.org/pkg/syscall/#Stat_t) but that is not available on all target OSes (e.g. on Window). – icza Oct 01 '19 at 07:29
  • 1
    I'd not create "fake" UID and GID for non-Unix-y platforms. A struct such as `type fileOwner struct { UID, GID int; Valid bool }` would be better: it would only have `Valid == true` on systems where the rest of the fields makes sense. – kostix Oct 01 '19 at 07:48
  • @kostix os.Getuid() should return -1 on Windows. The `Valid == true` check is equal to UID >= 0, making the Valid field redudant. – Siscia Oct 01 '19 at 08:53