未定义:syscall.Stat_t 计划 9

undefined: syscall.Stat_t for plan9

我正在为 9front/Plan9 开发文件管理器;开发工作在 64 位 Ubuntu 下的 Go v1.15 中完成,交叉编译以构建 Plan9 二进制文件。

让我们假设一个函数来检索 user/group 信息:

import "syscall"
func GetXid(info os.FileInfo) (string, string) {
    UID := "N/A"
    GID := "N/A"
    if stat, ok := info.Sys().(*syscall.Stat_t); ok {
        UID = strconv.Itoa(int(stat.Uid))
        GID = strconv.Itoa(int(stat.Gid))
    }
    return UID, GID
}

它在 Plan9 编译期间失败 undefined: syscall.Stat_t

syscall package page 指出它自 Go v1.4 以来已被弃用并替换为 OS-specific repos under golang.org/x/sys/.

极大地帮助了我的研究。简而言之,虽然 syscall 代码库被破坏并移至 golang.org/x/sys/ 下的 OS 特定包中,但我们仍然使用 syscall.xxx 语义来访问 golang.org/x/sys/ 中的结构:

  • 对于 Plan9,它是 Dir
var info os.FileInfo = ...
info.Sys().(*syscall.Dir)
var info os.FileInfo = ...
info.Sys().(*syscall.Stat_t)

为了将上述发现纳入解决方案,我遵循@torek 的建议并创建了两个文件,每个文件的顶部都有 func GetXid(info os.FileInfo) (string, string) 函数和 // +build <os> 指令:

  • file_details_plan9.go
// +build plan9

package model
import (
    "syscall"
    "os"
)

func GetXid(info os.FileInfo) (string, string) {
    UID := "N/A"
    GID := "N/A"
    if stat, ok := info.Sys().(*syscall.Dir); ok {
        UID = stat.Uid
        GID = stat.Gid
    }
    return UID, GID
}
  • file_details_unix.go
// +build linux

package model
import (
    "os"
    "strconv"
    "syscall"
)

func GetXid(info os.FileInfo) (string, string) {
    UID := "N/A"
    GID := "N/A"
    if stat, ok := info.Sys().(*syscall.Stat_t); ok {
        UID = strconv.Itoa(int(stat.Uid))
        GID = strconv.Itoa(int(stat.Gid))
    }
    return UID, GID
}

注意: 标准 Go 安装中似乎也缺少包 golang.org/x/sys/plan9,需要明确安装:

go get golang.org/x/sys/plan9
go mod vendor
go mod tidy