| /* 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 <errno.h> |
| #include <stdint.h> |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <fcntl.h> |
| #include <sys/ioctl.h> |
| #ifdef HAVE_SYSCALL_H |
| #include <syscall.h> |
| #endif |
| #ifdef HAVE_SYS_SYSCALL_H |
| #include <sys/syscall.h> |
| #endif |
| #ifdef HAVE_SYS_PTRACE_H |
| #include <sys/ptrace.h> |
| #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 |