From: David Uhden Collado Subject: [IMPROVEMENT] patch survey directly in devel/github-cli To: ports@openbsd.org, kn@openbsd.org Date: Mon, 28 Sep 2026 16:09:00 +0000 Hello, I'd like to propose keeping the OpenBSD-specific changes required for the survey module directly in the ports tree instead of using a separate fork. The attached diff removes the patched survey fork from DIST_TUPLE and uses the original upstream survey module already fetched as part of the Go dependency set. The required OpenBSD changes are then applied from devel/github-cli/files during the port build. The main reason for this approach is maintainability. The divergence from upstream is relatively small, so keeping it as normal ports patches makes the OpenBSD-specific changes immediately visible alongside the port that requires them. It should also make future github-cli updates easier. When the survey dependency changes, the patches can be tested directly against the new upstream version and refreshed or removed if they are no longer needed, without having to maintain and update a separate fork first. There is also a preservation advantage. By keeping the required changes in the official ports tree, they remain part of the OpenBSD ports history. If an external fork were abandoned or disappeared in the future, the changes required to make the module work on OpenBSD would not be lost with it. In this case, the port uses the upstream survey v2.3.7 module and adds the OpenBSD-specific changes as local patches. The terminal code is changed to use the ioctl(2) wrappers provided by golang.org/x/sys/unix instead of syscall.Syscall6, and go.mod is adjusted for the additional x/sys dependency. I think this is simpler and more sustainable than maintaining a separate fork for a small OpenBSD-specific portability change. Patch attached. Thank you for your time and consideration. Best regards, David. Index: devel/github-cli/Makefile =================================================================== RCS file: /cvs/ports/devel/github-cli/Makefile,v diff -u -p -u -p -r1.82 Makefile --- devel/github-cli/Makefile 21 Sep 2026 22:58:28 -0000 1.82 +++ devel/github-cli/Makefile 28 Sep 2026 15:56:03 -0000 @@ -7,11 +7,11 @@ MODGO_VERSION = v${V} DISTNAME = cli-${MODGO_VERSION} PKGNAME = github-cli-${V} -# replace "survey" module with a patched version that uses ioctl -# instead of unnecessary direct syscall() calls -SURVEY_V = vv2.3.8 -DIST_TUPLE = github bsdmp survey ${SURVEY_V} ../survey -EXTRACT_ONLY = bsdmp-survey-${SURVEY_V}.tar.gz +# The survey module still uses the indirect syscall(2) interface for +# termios, which OpenBSD 7.5 removed (golang/go#63900). Patch the module +# source from its distfile instead of fetching a fork. +SURVEY_MOD = github.com/!alec!aivazis/survey/v2 +SURVEY_V = v2.3.7 CATEGORIES = devel HOMEPAGE = https://cli.github.com/ @@ -29,6 +29,19 @@ MODGO_LDFLAGS += -X "${MODGO_MODNAME}/in TEST_TARGET = ./... PORTHOME = ${WRKDIR} + +post-extract: + ${UNZIP} -oq ${DISTDIR}/go_modules/${SURVEY_MOD}/@v/${SURVEY_V}.zip \ + -d ${WRKDIR}/survey-extract + mv ${WRKDIR}/survey-extract/github.com/AlecAivazis/survey/v2@${SURVEY_V} \ + ${WRKDIR}/survey + rm -rf ${WRKDIR}/survey-extract + +post-patch: + patch -d ${WRKDIR}/survey -p0 \ + < ${FILESDIR}/patch-survey_terminal_runereader_posix_go + patch -d ${WRKDIR}/survey -p0 \ + < ${FILESDIR}/patch-survey_go_mod pre-build: cd ${WRKSRC}; ${MODGO_CMD} mod edit -replace \ Index: devel/github-cli/distinfo =================================================================== RCS file: /cvs/ports/devel/github-cli/distinfo,v diff -u -p -u -p -r1.73 distinfo --- devel/github-cli/distinfo 21 Sep 2026 22:58:28 -0000 1.73 +++ devel/github-cli/distinfo 28 Sep 2026 15:56:03 -0000 @@ -1,4 +1,3 @@ -SHA256 (bsdmp-survey-vv2.3.8.tar.gz) = fPcSUSZ4Kkovs52dRmmAtg+lX8R/EDkhLaLMZJCphMU= SHA256 (cli-v2.101.0.zip) = SLs5klYDMaHMpiu5/IT/75+4b1K7A0YikzdUo/9sM60= SHA256 (go_modules/bitbucket.org/creachadair/shell/@v/v0.0.8.mod) = p5DeefOWpGgRzfiXR7IMnJJZnIfIuiXfICeZ+ODldMk= SHA256 (go_modules/bitbucket.org/creachadair/shell/@v/v0.0.8.zip) = KW2htHeMHqh5EXGvsVathbPZsI2eiI1Wh66jJt2/wyo= @@ -1310,7 +1309,6 @@ SHA256 (go_modules/sigs.k8s.io/yaml/@v/v SHA256 (go_modules/sigs.k8s.io/yaml/@v/v1.6.0.zip) = z4hkikcVgYF7AKQu6NJP1z6w41A5mM9G2OY3h+EeUFI= SHA256 (go_modules/software.sslmate.com/src/go-pkcs12/@v/v0.4.0.mod) = +/Vbaah9WjkQgv2brl5MdYEEH+Cbi7k7D+Fs3f6FzpU= SHA256 (go_modules/software.sslmate.com/src/go-pkcs12/@v/v0.4.0.zip) = VQGaOR5TAqUbpi6YkJ4AYiS4EgeGbakL6vWC7A3uA28= -SIZE (bsdmp-survey-vv2.3.8.tar.gz) = 125803 SIZE (cli-v2.101.0.zip) = 16062085 SIZE (go_modules/bitbucket.org/creachadair/shell/@v/v0.0.8.mod) = 89 SIZE (go_modules/bitbucket.org/creachadair/shell/@v/v0.0.8.zip) = 8712 Index: devel/github-cli/files/patch-survey_go_mod =================================================================== RCS file: devel/github-cli/files/patch-survey_go_mod diff -N devel/github-cli/files/patch-survey_go_mod --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/github-cli/files/patch-survey_go_mod 28 Sep 2026 15:56:03 -0000 @@ -0,0 +1,13 @@ +Require golang.org/x/sys, imported by the patched terminal code. + +Index: go.mod +--- go.mod.orig ++++ go.mod +@@ -10,6 +10,7 @@ + github.com/mattn/go-isatty v0.0.8 + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b + github.com/stretchr/testify v1.6.1 ++ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 + golang.org/x/text v0.4.0 + ) Index: devel/github-cli/files/patch-survey_terminal_runereader_posix_go =================================================================== RCS file: devel/github-cli/files/patch-survey_terminal_runereader_posix_go diff -N devel/github-cli/files/patch-survey_terminal_runereader_posix_go --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ devel/github-cli/files/patch-survey_terminal_runereader_posix_go 28 Sep 2026 15:56:03 -0000 @@ -0,0 +1,63 @@ +Use ioctl(2) through golang.org/x/sys/unix instead of the indirect +syscall(2) interface. OpenBSD 7.5 removed indirect system calls and Go +only reroutes the three-argument syscall.Syscall form of SYS_IOCTL to +the libc stub, so the syscall.Syscall6 calls used here fail with ENOSYS +(golang/go#63900). + +Index: terminal/runereader_posix.go +--- terminal/runereader_posix.go.orig ++++ terminal/runereader_posix.go +@@ -14,7 +14,7 @@ + "bytes" + "fmt" + "syscall" +- "unsafe" ++ "golang.org/x/sys/unix" + ) + + const ( +@@ -23,7 +23,7 @@ + ) + + type runeReaderState struct { +- term syscall.Termios ++ term unix.Termios + reader *bufio.Reader + buf *bytes.Buffer + } +@@ -45,19 +45,20 @@ + + // For reading runes we just want to disable echo. + func (rr *RuneReader) SetTermMode() error { +- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(rr.stdio.In.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&rr.state.term)), 0, 0, 0); err != 0 { ++ termios, err := unix.IoctlGetTermios((int)(rr.stdio.In.Fd()), ioctlReadTermios) ++ if err != nil { + return err + } + +- newState := rr.state.term +- newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG ++ rr.state.term = *termios ++ termios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG + // Because we are clearing canonical mode, we need to ensure VMIN & VTIME are + // set to the values we expect. This combination puts things in standard + // "blocking read" mode (see termios(3)). +- newState.Cc[syscall.VMIN] = 1 +- newState.Cc[syscall.VTIME] = 0 ++ termios.Cc[syscall.VMIN] = 1 ++ termios.Cc[syscall.VTIME] = 0 + +- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(rr.stdio.In.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { ++ if err = unix.IoctlSetTermios((int)(rr.stdio.In.Fd()), ioctlWriteTermios, termios); err != nil { + return err + } + +@@ -65,7 +66,7 @@ + } + + func (rr *RuneReader) RestoreTermMode() error { +- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(rr.stdio.In.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&rr.state.term)), 0, 0, 0); err != 0 { ++ if err := unix.IoctlSetTermios((int)(rr.stdio.In.Fd()), ioctlWriteTermios, &rr.state.term); err != nil { + return err + } + return nil