Viewing file: go-varargs.c (2.59 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* 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
|