/* go-varargs.c -- functions for calling C varargs functions. Copyright 2013 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYSCALL_H #include #endif #ifdef HAVE_SYS_SYSCALL_H #include #endif #ifdef HAVE_SYS_PTRACE_H #include #endif /* The syscall package calls C functions. The Go compiler can not represent a C varargs functions. On some systems it's important that the declaration of a function match the call. This function holds non-varargs C functions that the Go code can call. */ int __go_open (char *path, int mode, mode_t perm) { return open (path, mode, perm); } int __go_fcntl (int fd, int cmd, int arg) { return fcntl (fd, cmd, arg); } int __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; } int __go_ioctl (int d, int request, int arg) { return ioctl (d, request, arg); } int __go_ioctl_ptr (int d, int request, void *arg) { return ioctl (d, request, arg); } #ifdef HAVE_OPEN64 int __go_open64 (char *path, int mode, mode_t perm) { return open64 (path, mode, perm); } #endif #ifdef HAVE_OPENAT int __go_openat (int fd, char *path, int flags, mode_t mode) { return openat (fd, path, flags, mode); } #endif #ifdef HAVE_SYSCALL // __go_syscall6 is called by both the runtime and syscall packages. // We use uintptr_t to make sure that the types match, since the Go // and C "int" types are not the same. uintptr_t __go_syscall6(uintptr_t flag, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6) { return syscall (flag, a1, a2, a3, a4, a5, a6); } #endif #if defined(HAVE_SYS_PTRACE_H) && defined(__linux__) // Despite documented appearances, this is actually implemented as // a variadic function within glibc on Linux. long __go_ptrace(int request, pid_t pid, void *addr, void *data) { return ptrace (request, pid, addr, data); } #endif