re PR go/67874 (fd_unix.go does not build when there is fcntl64 and no fcntl syscall)

PR go/67874
    net, runtime: Call C library fcntl function rather than syscall.Syscall.
    
    Not all systems define a fcntl syscall; some only have fcntl64.
    
    Fixes GCC PR go/67874.
    
    Reviewed-on: https://go-review.googlesource.com/15497

From-SVN: r228576
This commit is contained in:
Ian Lance Taylor 2015-10-07 17:22:08 +00:00
parent 919e06d3f5
commit 0786e1fe86
3 changed files with 34 additions and 2 deletions

View File

@ -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.

View File

@ -442,13 +442,21 @@ func (fd *netFD) accept() (netfd *netFD, err error) {
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

View File

@ -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, struct flock *arg)
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