Go版本
go版本 go1.21.8 netbsd/amd64
go env
在你的模块/工作区中的输出:
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='netbsd'
GOINSECURE=''
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='netbsd'
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/pkg/go121'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/pkg/go121/pkg/tool/netbsd_amd64'
GOVCS=''
GOVERSION='go1.21.8'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1420044071=/tmp/go-build -gno-record-gcc-switches'
你做了什么?
尽管测试用例 TestIoctlPtmget
在NetBSD上通过,但调试发现 ptm.Sn
是一个填充了零的字节数组,从而阻止我们获得 ptsname
。日志始终显示 sfd = 0, ptsname =
,而在正常情况下,我们期望看到类似 sfd = 0, ptsname = /dev/pts/0
的内容。
以下是 amd64
架构相关代码的示例。
func TestIoctlPtmget(t *testing.T) {
fd, err := unix.Open("/dev/ptmx", unix.O_NOCTTY|unix.O_RDWR, 0666)
if err != nil {
t.Skip("failed to open /dev/ptmx, skipping test")
}
defer unix.Close(fd)
ptm, err := unix.IoctlGetPtmget(fd, unix.TIOCPTSNAME)
if err != nil {
t.Fatalf("IoctlGetPtmget: %v\n", err)
}
t.Logf("sfd = %v, ptsname = %v", ptm.Sfd, unix.ByteSliceToString(ptm.Sn[:]))
}
const TIOCPTSNAME = 0x40287448
type Ptmget struct {
Cfd int32
Sfd int32
Cn [1024]byte
Sn [1024]byte
}
根据我的调查,这个错误是由于 Ptmget
结构中 Cn
和 Sn
的长度与 TIOCPTSNAME
的值不匹配所引起的。
在 NetBSD: src/sys/sys/ttycom.h 中,我们可以发现 TIOCPTSNAME
的值与 Ptmget
的大小有关。
#include <iostream>
#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
#define IOCPARM_SHIFT 16
#define IOCGROUP_SHIFT 8
#define _IOC(inout, group, num, len) \
((inout) | (((len) & IOCPARM_MASK) << IOCPARM_SHIFT) | \
((group) << IOCGROUP_SHIFT) | (num))
#define IOC_OUT (unsigned long)0x40000000
#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
#define TIOCPTSNAME _IOR('t', 72, struct ptmget) /* ptsname(3) */
#define PATH_MAX 1024
struct ptmget {
int cfd;
int sfd;
char cn[PATH_MAX];
char sn[PATH_MAX];
};
int main() {
std::cout << TIOCPTSNAME;
}
当我们将 PATH_MAX
设置为代码中当前使用的 1024
时,对应的 TIOCPTSNAME
值应该是 0x48087448
,而不是为 386
/ amd64
/ arm64
定义的 arm
(TIOCPTSNAME
的定义与当前代码中的 0x40287448
匹配正确)。
当 TIOCPTSNAME
为当前代码中使用的 0x40287448
时,相应的 PATH_MAX
应该为 16
。这确实与 netbsd man page / ptm 中的描述相符。
我将很快提交一个 CL 以修复此错误。这是我第一次为 Go 提交 CL。请告诉我是否有任何不适当的地方或有任何反馈。
你看到了什么发生?
没有
你期望看到什么?
没有
6条答案
按热度按时间eit6fx6z1#
https://go.dev/cl/579476提到了这个问题:
unix: fix IoctlGetPtmget get empty ptsname on NetBSD.
ffvjumwh2#
如果理解了bug报告,那么修复应该调整
TIOCPTSNAME
的值,而不是改变结构体大小。3phpmpom3#
如果我理解了这个bug报告,那么修复方法应该是调整
TIOCPTSNAME
的值,而不是改变结构体大小。是的,通过将TIOCPTSNAME
从0x40287448
设置为0x48087448
,IoctlGetPtmget
也可以获得正确的ptsname,而不需要改变Ptmget结构体的大小。请问我需要遵循这个逻辑来修改我提交的代码吗?tquggr8v4#
我可以问一下,我需要按照这个逻辑修改我提交的代码吗?
对不起,我不明白你的问题。
7rtdyuoh5#
函数
unix.IoctlGetPtmget
在Mac OS上不可用吗?我完全看不到这个功能。tyg4sfes6#
函数
unix.IoctlGetPtmget
在Mac OS上不可用吗?我完全看不到这个功能。不,如果需要的话,请查看iyzyi/aiopty/pty/nixpty/native/native_darwin.go。