GCC PR go/67874 points out that not all systems define syscall.SYS_FCNTL. Some only have SYS_FCNTL64. This patch changes libgo to use the C library fcntl function instead. It uses a helper function because Go code can not call C varargs functions directly, and to handle errno and avoid problems with type differences. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 228550) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -3039d79149901d25d89c2412bdd8684f3cbcd09e +651e71a729e5dcbd9dc14c1b59b6eff05bfe3d26 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: libgo/go/net/fd_unix.go =================================================================== --- libgo/go/net/fd_unix.go (revision 228306) +++ libgo/go/net/fd_unix.go (working copy) @@ -442,13 +442,21 @@ func (fd *netFD) accept() (netfd *netFD, return netfd, nil } +// Use a helper function to call fcntl. This is defined in C in +// libgo/runtime. +//extern __go_fcntl_uintptr +func fcntl(uintptr, uintptr, uintptr) (uintptr, uintptr) + // tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used. // If the kernel doesn't support it, this is set to 0. var tryDupCloexec = int32(1) func dupCloseOnExec(fd int) (newfd int, err error) { if atomic.LoadInt32(&tryDupCloexec) == 1 && syscall.F_DUPFD_CLOEXEC != 0 { - r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0) + syscall.Entersyscall() + r0, errno := fcntl(uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0) + syscall.Exitsyscall() + e1 := syscall.Errno(errno) if runtime.GOOS == "darwin" && e1 == syscall.EBADF { // On OS X 10.6 and below (but we only support // >= 10.6), F_DUPFD_CLOEXEC is unsupported Index: libgo/runtime/go-varargs.c =================================================================== --- libgo/runtime/go-varargs.c (revision 228306) +++ libgo/runtime/go-varargs.c (working copy) @@ -6,6 +6,8 @@ #include "config.h" +#include <errno.h> +#include <stdint.h> #include <sys/types.h> #include <fcntl.h> @@ -32,6 +34,28 @@ __go_fcntl_flock (int fd, int cmd, struc return fcntl (fd, cmd, arg); } +// This is for the net package. We use uintptr_t to make sure that +// the types match, since the Go and C "int" types are not the same. +struct go_fcntl_ret { + uintptr_t r; + uintptr_t err; +}; + +struct go_fcntl_ret +__go_fcntl_uintptr (uintptr_t fd, uintptr_t cmd, uintptr_t arg) +{ + int r; + struct go_fcntl_ret ret; + + r = fcntl ((int) fd, (int) cmd, (int) arg); + ret.r = (uintptr_t) r; + if (r < 0) + ret.err = (uintptr_t) errno; + else + ret.err = 0; + return ret; +} + #ifdef HAVE_OPEN64 int