From 40d7cd0fd78fe2004e2a53c4618c148339b02733 Mon Sep 17 00:00:00 2001 From: Jing Yu Date: Mon, 19 Dec 2011 16:56:54 -0800 Subject: Add gcc-4.6. Synced to @180989 Change-Id: Ie3676586e1d8e3c8cd9f07d022f450d05fa08439 svn://gcc.gnu.org/svn/gcc/branches/google/gcc-4_6-mobile --- gcc-4.6/libgo/syscalls/errno.c | 25 ++ gcc-4.6/libgo/syscalls/errstr.go | 24 ++ gcc-4.6/libgo/syscalls/errstr_decl.go | 9 + gcc-4.6/libgo/syscalls/errstr_decl_linux.go | 9 + gcc-4.6/libgo/syscalls/errstr_decl_rtems.go | 10 + gcc-4.6/libgo/syscalls/errstr_rtems.go | 26 ++ gcc-4.6/libgo/syscalls/exec.go | 248 +++++++++++++ gcc-4.6/libgo/syscalls/exec_helpers.go | 154 ++++++++ gcc-4.6/libgo/syscalls/exec_stubs.go | 25 ++ gcc-4.6/libgo/syscalls/sleep_rtems.go | 19 + gcc-4.6/libgo/syscalls/sleep_select.go | 13 + gcc-4.6/libgo/syscalls/socket.go | 383 +++++++++++++++++++ gcc-4.6/libgo/syscalls/socket_bsd.go | 74 ++++ gcc-4.6/libgo/syscalls/socket_epoll.go | 50 +++ gcc-4.6/libgo/syscalls/socket_linux.go | 75 ++++ gcc-4.6/libgo/syscalls/socket_solaris.go | 76 ++++ gcc-4.6/libgo/syscalls/stringbyte.go | 24 ++ gcc-4.6/libgo/syscalls/syscall.go | 48 +++ gcc-4.6/libgo/syscalls/syscall_linux.go | 188 ++++++++++ gcc-4.6/libgo/syscalls/syscall_linux_386.go | 15 + gcc-4.6/libgo/syscalls/syscall_linux_amd64.go | 15 + gcc-4.6/libgo/syscalls/syscall_rtems.go | 7 + gcc-4.6/libgo/syscalls/syscall_solaris.go | 7 + gcc-4.6/libgo/syscalls/syscall_solaris_386.go | 20 + gcc-4.6/libgo/syscalls/syscall_solaris_amd64.go | 21 ++ gcc-4.6/libgo/syscalls/syscall_solaris_sparc.go | 17 + gcc-4.6/libgo/syscalls/syscall_solaris_sparc64.go | 21 ++ gcc-4.6/libgo/syscalls/syscall_stubs.go | 33 ++ gcc-4.6/libgo/syscalls/syscall_uname.go | 7 + gcc-4.6/libgo/syscalls/syscall_unix.go | 24 ++ gcc-4.6/libgo/syscalls/sysfile_largefile.go | 13 + gcc-4.6/libgo/syscalls/sysfile_posix.go | 427 ++++++++++++++++++++++ gcc-4.6/libgo/syscalls/sysfile_regfile.go | 13 + gcc-4.6/libgo/syscalls/sysfile_stat_largefile.go | 12 + gcc-4.6/libgo/syscalls/sysfile_stat_regfile.go | 12 + 35 files changed, 2144 insertions(+) create mode 100644 gcc-4.6/libgo/syscalls/errno.c create mode 100644 gcc-4.6/libgo/syscalls/errstr.go create mode 100644 gcc-4.6/libgo/syscalls/errstr_decl.go create mode 100644 gcc-4.6/libgo/syscalls/errstr_decl_linux.go create mode 100644 gcc-4.6/libgo/syscalls/errstr_decl_rtems.go create mode 100644 gcc-4.6/libgo/syscalls/errstr_rtems.go create mode 100644 gcc-4.6/libgo/syscalls/exec.go create mode 100644 gcc-4.6/libgo/syscalls/exec_helpers.go create mode 100644 gcc-4.6/libgo/syscalls/exec_stubs.go create mode 100644 gcc-4.6/libgo/syscalls/sleep_rtems.go create mode 100644 gcc-4.6/libgo/syscalls/sleep_select.go create mode 100644 gcc-4.6/libgo/syscalls/socket.go create mode 100644 gcc-4.6/libgo/syscalls/socket_bsd.go create mode 100644 gcc-4.6/libgo/syscalls/socket_epoll.go create mode 100644 gcc-4.6/libgo/syscalls/socket_linux.go create mode 100644 gcc-4.6/libgo/syscalls/socket_solaris.go create mode 100644 gcc-4.6/libgo/syscalls/stringbyte.go create mode 100644 gcc-4.6/libgo/syscalls/syscall.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_linux.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_linux_386.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_linux_amd64.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_rtems.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_solaris.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_solaris_386.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_solaris_amd64.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_solaris_sparc.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_solaris_sparc64.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_stubs.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_uname.go create mode 100644 gcc-4.6/libgo/syscalls/syscall_unix.go create mode 100644 gcc-4.6/libgo/syscalls/sysfile_largefile.go create mode 100644 gcc-4.6/libgo/syscalls/sysfile_posix.go create mode 100644 gcc-4.6/libgo/syscalls/sysfile_regfile.go create mode 100644 gcc-4.6/libgo/syscalls/sysfile_stat_largefile.go create mode 100644 gcc-4.6/libgo/syscalls/sysfile_stat_regfile.go (limited to 'gcc-4.6/libgo/syscalls') diff --git a/gcc-4.6/libgo/syscalls/errno.c b/gcc-4.6/libgo/syscalls/errno.c new file mode 100644 index 000000000..34771a0d8 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/errno.c @@ -0,0 +1,25 @@ +/* errno.c -- functions for getting and setting errno + + Copyright 2010 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 + +/* errno is typically a macro. These functions set + and get errno specific to the libc being used. */ + +int GetErrno() asm ("libgo_syscalls.syscall.GetErrno"); +void SetErrno(int) asm ("libgo_syscalls.syscall.SetErrno"); + +int +GetErrno() +{ + return errno; +} + +void +SetErrno(int value) +{ + errno = value; +} diff --git a/gcc-4.6/libgo/syscalls/errstr.go b/gcc-4.6/libgo/syscalls/errstr.go new file mode 100644 index 000000000..a95abc686 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/errstr.go @@ -0,0 +1,24 @@ +// errstr.go -- Error strings. + +// Copyright 2009 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. + +package syscall + +func Errstr(errno int) string { + for len := Size_t(128); ; len *= 2 { + b := make([]byte, len) + r := libc_strerror_r(errno, &b[0], len) + if r >= 0 { + i := 0 + for b[i] != 0 { + i++ + } + return string(b[:i]) + } + if GetErrno() != ERANGE { + return "Errstr failure" + } + } +} diff --git a/gcc-4.6/libgo/syscalls/errstr_decl.go b/gcc-4.6/libgo/syscalls/errstr_decl.go new file mode 100644 index 000000000..b6bff0fb0 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/errstr_decl.go @@ -0,0 +1,9 @@ +// errstr.go -- Declare strerror_r. + +// Copyright 2010 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. + +package syscall + +func libc_strerror_r(int, *byte, Size_t) int __asm__ ("strerror_r") diff --git a/gcc-4.6/libgo/syscalls/errstr_decl_linux.go b/gcc-4.6/libgo/syscalls/errstr_decl_linux.go new file mode 100644 index 000000000..4c1cb82a0 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/errstr_decl_linux.go @@ -0,0 +1,9 @@ +// errstr_decl_linux.go -- Declare strerror_r for GNU/Linux. + +// Copyright 2010 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. + +package syscall + +func libc_strerror_r(int, *byte, Size_t) int __asm__ ("__xpg_strerror_r") diff --git a/gcc-4.6/libgo/syscalls/errstr_decl_rtems.go b/gcc-4.6/libgo/syscalls/errstr_decl_rtems.go new file mode 100644 index 000000000..b83eedc8e --- /dev/null +++ b/gcc-4.6/libgo/syscalls/errstr_decl_rtems.go @@ -0,0 +1,10 @@ +// errstr.go -- Declare strerror_r for RTEMS. + +// Copyright 2010 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. + +package syscall + +// RTEMS uses strerror_r in newlib, which is a GNU extension returning a char *. +func libc_strerror_r(int, *byte, Size_t) *byte __asm__ ("strerror_r") diff --git a/gcc-4.6/libgo/syscalls/errstr_rtems.go b/gcc-4.6/libgo/syscalls/errstr_rtems.go new file mode 100644 index 000000000..f6b453bdc --- /dev/null +++ b/gcc-4.6/libgo/syscalls/errstr_rtems.go @@ -0,0 +1,26 @@ +// errstr_rtems.go -- RTEMS specific error strings. + +// Copyright 2010 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. + +package syscall + +func Errstr(errno int) string { + for len := Size_t(128); ; len *= 2 { + b := make([]byte, len+1) + + // The newlib strerror_r always returns the string in buffer. + libc_strerror_r(errno, &b[0], len) + b[len] = 0 + + i := 0 + for b[i] != 0 { + i++ + } + + if Size_t(i) < len { + return string(b[0:i]) + } + } +} diff --git a/gcc-4.6/libgo/syscalls/exec.go b/gcc-4.6/libgo/syscalls/exec.go new file mode 100644 index 000000000..d0f56d3b9 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/exec.go @@ -0,0 +1,248 @@ +// exec.go -- fork/exec syscall support. + +// Copyright 2009 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. + +// Fork, exec, wait, etc. + +package syscall + +import "unsafe" + +func libc_fcntl(fd int, cmd int, arg int) int __asm__ ("fcntl") +func libc_fork() Pid_t __asm__ ("fork") +func libc_chdir(name *byte) int __asm__ ("chdir"); +func libc_dup2(int, int) int __asm__ ("dup2") +func libc_execve(*byte, **byte, **byte) int __asm__ ("execve") +func libc_sysexit(int) __asm__ ("_exit") +func libc_wait4(Pid_t, *int, int, *Rusage) Pid_t __asm__ ("wait4") + +// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child. +// If a dup or exec fails, write the errno int to pipe. +// (Pipe is close-on-exec so if exec succeeds, it will be closed.) +// In the child, this function must not acquire any locks, because +// they might have been locked at the time of the fork. This means +// no rescheduling, no malloc calls, and no new stack segments. +func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, dir *byte, fd []int, pipe int) (pid int, err int) { + // Declare all variables at top in case any + // declarations require heap allocation (e.g., err1). + var r1, r2, err1 uintptr; + var nextfd int; + var i int; + + darwin := OS == "darwin"; + + // About to call fork. + // No more allocation or calls of non-assembly functions. + child := libc_fork(); + if child == -1 { + return 0, GetErrno(); + } + + if child != 0 { + // parent; return PID + return int(child), 0 + } + + // Fork succeeded, now in child. + + // Enable tracing if requested. + if traceme { + if libc_ptrace(_PTRACE_TRACEME, 0, 0, nil) < 0 { + goto childerror; + } + } + + // Chdir + if dir != nil { + r := libc_chdir(dir); + if r < 0 { + goto childerror; + } + } + + // Pass 1: look for fd[i] < i and move those up above len(fd) + // so that pass 2 won't stomp on an fd it needs later. + nextfd = int(len(fd)); + if pipe < nextfd { + r := libc_dup2(pipe, nextfd); + if r == -1 { + goto childerror; + } + libc_fcntl(nextfd, F_SETFD, FD_CLOEXEC); + pipe = nextfd; + nextfd++; + } + for i = 0; i < len(fd); i++ { + if fd[i] >= 0 && fd[i] < int(i) { + r := libc_dup2(fd[i], nextfd); + if r == -1 { + goto childerror; + } + libc_fcntl(nextfd, F_SETFD, FD_CLOEXEC); + fd[i] = nextfd; + nextfd++; + if nextfd == pipe { // don't stomp on pipe + nextfd++; + } + } + } + + // Pass 2: dup fd[i] down onto i. + for i = 0; i < len(fd); i++ { + if fd[i] == -1 { + libc_close(i); + continue; + } + if fd[i] == int(i) { + // dup2(i, i) won't clear close-on-exec flag on Linux, + // probably not elsewhere either. + r := libc_fcntl(fd[i], F_SETFD, 0); + if r != 0 { + goto childerror; + } + continue; + } + // The new fd is created NOT close-on-exec, + // which is exactly what we want. + r := libc_dup2(fd[i], i); + if r == -1 { + goto childerror; + } + } + + // By convention, we don't close-on-exec the fds we are + // started with, so if len(fd) < 3, close 0, 1, 2 as needed. + // Programs that know they inherit fds >= 3 will need + // to set them close-on-exec. + for i = len(fd); i < 3; i++ { + libc_close(i); + } + + // Time to exec. + libc_execve(argv0, &argv[0], &envv[0]); + +childerror: + // send error code on pipe + var e uintptr = uintptr(GetErrno()); + libc_write(pipe, (*byte)(unsafe.Pointer(&e)), + Size_t(unsafe.Sizeof(err1))); + for { + libc_sysexit(253) + } + + // Calling panic is not actually safe, + // but the for loop above won't break + // and this shuts up the compiler. + panic("unreached"); +} + +func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir string, fd []int) (pid int, err int) { + var p [2]int; + var r1 int; + var err1 uintptr; + var wstatus WaitStatus; + + p[0] = -1; + p[1] = -1; + + // Convert args to C form. + argv0p := StringBytePtr(argv0); + argvp := StringArrayPtr(argv); + envvp := StringArrayPtr(envv); + var dirp *byte; + if len(dir) > 0 { + dirp = StringBytePtr(dir); + } + + // Acquire the fork lock so that no other threads + // create new fds that are not yet close-on-exec + // before we fork. + ForkLock.Lock(); + + // Allocate child status pipe close on exec. + if err = Pipe(p[0:]); err != 0 { + goto error; + } + var val int; + if val, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != 0 { + goto error; + } + if val, err = fcntl(p[1], F_SETFD, FD_CLOEXEC); err != 0 { + goto error; + } + + // Kick off child. + pid, err = forkAndExecInChild(argv0p, argvp, envvp, traceme, dirp, fd, p[1]); + if err != 0 { + error: + if p[0] >= 0 { + Close(p[0]); + Close(p[1]); + } + ForkLock.Unlock(); + return 0, err + } + ForkLock.Unlock(); + + // Read child error status from pipe. + Close(p[1]); + n := libc_read(p[0], (*byte)(unsafe.Pointer(&err1)), + Size_t(unsafe.Sizeof(err1))); + err = 0; + if n < 0 { + err = GetErrno(); + } + Close(p[0]); + if err != 0 || n != 0 { + if int(n) == unsafe.Sizeof(err1) { + err = int(err1); + } + if err == 0 { + err = EPIPE; + } + + // Child failed; wait for it to exit, to make sure + // the zombies don't accumulate. + pid1, err1 := Wait4(pid, &wstatus, 0, nil); + for err1 == EINTR { + pid1, err1 = Wait4(pid, &wstatus, 0, nil); + } + return 0, err + } + + // Read got EOF, so pipe closed on exec, so exec succeeded. + return pid, 0 +} + +// Combination of fork and exec, careful to be thread safe. +func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) { + return forkExec(argv0, argv, envv, false, dir, fd); +} + +// PtraceForkExec is like ForkExec, but starts the child in a traced state. +func PtraceForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) { + return forkExec(argv0, argv, envv, true, dir, fd); +} + +// Ordinary exec. +func Exec(argv0 string, argv []string, envv []string) (err int) { + argv_arg := StringArrayPtr(argv); + envv_arg := StringArrayPtr(envv); + libc_execve(StringBytePtr(argv0), &argv_arg[0], &envv_arg[0]); + return GetErrno(); +} + +func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) { + var status int; + r := libc_wait4(Pid_t(pid), &status, options, rusage); + wpid = int(r); + if r < 0 { + errno = GetErrno(); + } + if wstatus != nil { + *wstatus = WaitStatus(status); + } + return; +} diff --git a/gcc-4.6/libgo/syscalls/exec_helpers.go b/gcc-4.6/libgo/syscalls/exec_helpers.go new file mode 100644 index 000000000..c8a68a058 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/exec_helpers.go @@ -0,0 +1,154 @@ +// exec_helpers.go -- helper functions used with fork, exec, wait. + +// Copyright 2010 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. + +package syscall + +import "sync" + +// Lock synchronizing creation of new file descriptors with fork. +// +// We want the child in a fork/exec sequence to inherit only the +// file descriptors we intend. To do that, we mark all file +// descriptors close-on-exec and then, in the child, explicitly +// unmark the ones we want the exec'ed program to keep. +// Unix doesn't make this easy: there is, in general, no way to +// allocate a new file descriptor close-on-exec. Instead you +// have to allocate the descriptor and then mark it close-on-exec. +// If a fork happens between those two events, the child's exec +// will inherit an unwanted file descriptor. +// +// This lock solves that race: the create new fd/mark close-on-exec +// operation is done holding ForkLock for reading, and the fork itself +// is done holding ForkLock for writing. At least, that's the idea. +// There are some complications. +// +// Some system calls that create new file descriptors can block +// for arbitrarily long times: open on a hung NFS server or named +// pipe, accept on a socket, and so on. We can't reasonably grab +// the lock across those operations. +// +// It is worse to inherit some file descriptors than others. +// If a non-malicious child accidentally inherits an open ordinary file, +// that's not a big deal. On the other hand, if a long-lived child +// accidentally inherits the write end of a pipe, then the reader +// of that pipe will not see EOF until that child exits, potentially +// causing the parent program to hang. This is a common problem +// in threaded C programs that use popen. +// +// Luckily, the file descriptors that are most important not to +// inherit are not the ones that can take an arbitrarily long time +// to create: pipe returns instantly, and the net package uses +// non-blocking I/O to accept on a listening socket. +// The rules for which file descriptor-creating operations use the +// ForkLock are as follows: +// +// 1) Pipe. Does not block. Use the ForkLock. +// 2) Socket. Does not block. Use the ForkLock. +// 3) Accept. If using non-blocking mode, use the ForkLock. +// Otherwise, live with the race. +// 4) Open. Can block. Use O_CLOEXEC if available (Linux). +// Otherwise, live with the race. +// 5) Dup. Does not block. Use the ForkLock. +// On Linux, could use fcntl F_DUPFD_CLOEXEC +// instead of the ForkLock, but only for dup(fd, -1). + +type WaitStatus int + +var ForkLock sync.RWMutex + +// Convert array of string to array +// of NUL-terminated byte pointer. +func StringArrayPtr(ss []string) []*byte { + bb := make([]*byte, len(ss)+1); + for i := 0; i < len(ss); i++ { + bb[i] = StringBytePtr(ss[i]); + } + bb[len(ss)] = nil; + return bb; +} + +func CloseOnExec(fd int) { + fcntl(fd, F_SETFD, FD_CLOEXEC); +} + +func SetNonblock(fd int, nonblocking bool) (errno int) { + flag, err := fcntl(fd, F_GETFL, 0); + if err != 0 { + return err; + } + if nonblocking { + flag |= O_NONBLOCK; + } else { + flag &= ^O_NONBLOCK; + } + flag, err = fcntl(fd, F_SETFL, flag); + return err; +} + +// Wait status is 7 bits at bottom, either 0 (exited), +// 0x7F (stopped), or a signal number that caused an exit. +// The 0x80 bit is whether there was a core dump. +// An extra number (exit code, signal causing a stop) +// is in the high bits. At least that's the idea. +// There are various irregularities. For example, the +// "continued" status is 0xFFFF, distinguishing itself +// from stopped via the core dump bit. + +const ( + mask = 0x7F; + core = 0x80; + exited = 0x00; + stopped = 0x7F; + shift = 8; +) + +func (w WaitStatus) Exited() bool { + return w&mask == exited; +} + +func (w WaitStatus) Signaled() bool { + return w&mask != stopped && w&mask != exited; +} + +func (w WaitStatus) Stopped() bool { + return w&0xFF == stopped; +} + +func (w WaitStatus) Continued() bool { + return w == 0xFFFF; +} + +func (w WaitStatus) CoreDump() bool { + return w.Signaled() && w&core != 0; +} + +func (w WaitStatus) ExitStatus() int { + if !w.Exited() { + return -1; + } + return int(w >> shift) & 0xFF; +} + +func (w WaitStatus) Signal() int { + if !w.Signaled() { + return -1; + } + return int(w & mask); +} + +func (w WaitStatus) StopSignal() int { + if !w.Stopped() { + return -1; + } + return int(w >> shift) & 0xFF; +} + +func (w WaitStatus) TrapCause() int { + if w.StopSignal() != SIGTRAP { + return -1; + } + return int(w >> shift) >> 8; +} diff --git a/gcc-4.6/libgo/syscalls/exec_stubs.go b/gcc-4.6/libgo/syscalls/exec_stubs.go new file mode 100644 index 000000000..7b4346cc4 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/exec_stubs.go @@ -0,0 +1,25 @@ +// exec_stubs.go -- fork/exec stubs. + +// Copyright 2010 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. + +// Stubs for fork, exec and wait. + +package syscall + +func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) { + return -1, ENOSYS; +} + +func PtraceForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) { + return -1, ENOSYS; +} + +func Exec(argv0 string, argv []string, envv []string) (err int) { + return ENOSYS; +} + +func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) { + return -1, ENOSYS; +} diff --git a/gcc-4.6/libgo/syscalls/sleep_rtems.go b/gcc-4.6/libgo/syscalls/sleep_rtems.go new file mode 100644 index 000000000..8a9ae8a30 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/sleep_rtems.go @@ -0,0 +1,19 @@ +// sleep_rtems.go -- Sleep on RTEMS. + +// Copyright 2010 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. + +package syscall + +func libc_nanosleep(req *Timespec, rem *Timespec) int __asm__ ("nanosleep") + +func Sleep(nsec int64) (errno int) { + errno = 0 + ts := NsecToTimespec(nsec) + r := libc_nanosleep(&ts, nil) + if r < 0 { + errno = GetErrno() + } + return +} diff --git a/gcc-4.6/libgo/syscalls/sleep_select.go b/gcc-4.6/libgo/syscalls/sleep_select.go new file mode 100644 index 000000000..6fc13a0ea --- /dev/null +++ b/gcc-4.6/libgo/syscalls/sleep_select.go @@ -0,0 +1,13 @@ +// sleep_select.go -- Sleep using select. + +// Copyright 2011 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. + +package syscall + +func Sleep(nsec int64) (errno int) { + tv := NsecToTimeval(nsec); + n, err := Select(0, nil, nil, nil, &tv); + return err; +} diff --git a/gcc-4.6/libgo/syscalls/socket.go b/gcc-4.6/libgo/syscalls/socket.go new file mode 100644 index 000000000..65c191671 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/socket.go @@ -0,0 +1,383 @@ +// socket.go -- Socket handling. + +// Copyright 2009 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. + +// Low-level socket interface. +// Only for implementing net package. +// DO NOT USE DIRECTLY. + +package syscall + +import "unsafe" + +type RawSockaddrAny struct { + Addr RawSockaddr; + Pad [12]int8; +} + +const SizeofSockaddrAny = 0x1c; + +// For testing: clients can set this flag to force +// creation of IPv6 sockets to return EAFNOSUPPORT. +var SocketDisableIPv6 bool + +type Sockaddr interface { + sockaddr() (ptr *RawSockaddrAny, len Socklen_t, errno int); // lowercase; only we can define Sockaddrs +} + +type SockaddrInet4 struct { + Port int; + Addr [4]byte; + raw RawSockaddrInet4; +} + +type SockaddrInet6 struct { + Port int; + Addr [16]byte; + raw RawSockaddrInet6; +} + +type SockaddrUnix struct { + Name string; + raw RawSockaddrUnix; +} + +type Linger struct { + Onoff int32; + Linger int32; +} + +func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, int) { + if sa.Port < 0 || sa.Port > 0xFFFF { + return nil, 0, EINVAL; + } + sa.raw.Family = AF_INET; + n := sa.raw.setLen() + p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)); + p[0] = byte(sa.Port>>8); + p[1] = byte(sa.Port); + for i := 0; i < len(sa.Addr); i++ { + sa.raw.Addr[i] = sa.Addr[i]; + } + return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), n, 0; +} + +func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, int) { + if sa.Port < 0 || sa.Port > 0xFFFF { + return nil, 0, EINVAL; + } + sa.raw.Family = AF_INET6; + n := sa.raw.setLen() + p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)); + p[0] = byte(sa.Port>>8); + p[1] = byte(sa.Port); + for i := 0; i < len(sa.Addr); i++ { + sa.raw.Addr[i] = sa.Addr[i]; + } + return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), n, 0; +} + +func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, int) { + name := sa.Name; + n := len(name); + if n >= len(sa.raw.Path) || n == 0 { + return nil, 0, EINVAL; + } + sa.raw.Family = AF_UNIX; + sa.raw.setLen(n) + for i := 0; i < n; i++ { + sa.raw.Path[i] = int8(name[i]); + } + if sa.raw.Path[0] == '@' { + sa.raw.Path[0] = 0; + } + + // length is family (uint16), name, NUL. + return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), 2 + Socklen_t(n) + 1, 0; +} + +func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) { + switch rsa.Addr.Family { + case AF_UNIX: + pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) + sa := new(SockaddrUnix) + n, err := pp.getLen() + if err != 0 { + return nil, err + } + bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0])); + sa.Name = string(bytes[0:n]); + return sa, 0; + + case AF_INET: + pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)); + sa := new(SockaddrInet4); + p := (*[2]byte)(unsafe.Pointer(&pp.Port)); + sa.Port = int(p[0])<<8 + int(p[1]); + for i := 0; i < len(sa.Addr); i++ { + sa.Addr[i] = pp.Addr[i]; + } + return sa, 0; + + case AF_INET6: + pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)); + sa := new(SockaddrInet6); + p := (*[2]byte)(unsafe.Pointer(&pp.Port)); + sa.Port = int(p[0])<<8 + int(p[1]); + for i := 0; i < len(sa.Addr); i++ { + sa.Addr[i] = pp.Addr[i]; + } + return sa, 0; + } + return nil, EAFNOSUPPORT; +} + +func libc_accept(fd int, sa *RawSockaddrAny, len *Socklen_t) int __asm__ ("accept"); +func libc_bind(fd int, sa *RawSockaddrAny, len Socklen_t) int __asm__ ("bind"); +func libc_connect(fd int, sa *RawSockaddrAny, len Socklen_t) int __asm__ ("connect"); +func libc_socket(domain, typ, protocol int) int __asm__ ("socket"); +func libc_setsockopt(fd, level, optname int, optval *byte, optlen Socklen_t) int __asm__ ("setsockopt"); +func libc_listen(fd, backlog int) int __asm__ ("listen"); +func libc_getsockopt(fd, level, optname int, optval *byte, optlen *Socklen_t) int __asm__ ("getsockopt"); +func libc_getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) int __asm__ ("getsockname"); +func libc_getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) int __asm__ ("getpeername"); +func libc_recv(fd int, buf *byte, len Size_t, flags int) Ssize_t __asm__ ("recv"); +func libc_recvfrom(fd int, buf *byte, len Size_t, flags int, + from *RawSockaddrAny, fromlen *Socklen_t) Ssize_t __asm__("recvfrom"); +func libc_recvmsg(fd int, msg *Msghdr, flags int) Ssize_t __asm__("recvmsg") +func libc_send(fd int, buf *byte, len Size_t, flags int) Ssize_t __asm__("send"); +func libc_sendto(fd int, buf *byte, len Size_t, flags int, + to *RawSockaddrAny, tolen Socklen_t) Ssize_t __asm__("sendto"); +func libc_sendmsg(fd int, msg *Msghdr, flags int) Ssize_t __asm__("sendmsg") +func libc_shutdown(fd int, how int) int __asm__ ("shutdown"); + +func Accept(fd int) (nfd int, sa Sockaddr, errno int) { + var rsa RawSockaddrAny; + var len Socklen_t = SizeofSockaddrAny; + nfd = libc_accept(fd, &rsa, &len); + if nfd < 0 { + errno = GetErrno(); + return; + } + sa, errno = anyToSockaddr(&rsa); + if errno != 0 { + Close(nfd); + nfd = 0; + } + return; +} + +func Bind(fd int, sa Sockaddr) (errno int) { + ptr, n, err := sa.sockaddr(); + if err != 0 { + return err; + } + if libc_bind(fd, ptr, n) < 0 { + errno = GetErrno(); + } + return; +} + +func Connect(fd int, sa Sockaddr) (errno int) { + ptr, n, err := sa.sockaddr(); + if err != 0 { + return err; + } + if libc_connect(fd, ptr, n) < 0 { + errno = GetErrno(); + } + return; +} + +func Socket(domain, typ, proto int) (fd, errno int) { + if domain == AF_INET6 && SocketDisableIPv6 { + return -1, EAFNOSUPPORT + } + fd = libc_socket(int(domain), int(typ), int(proto)); + if fd < 0 { + errno = GetErrno(); + } + return; +} + +func Listen(fd int, n int) (errno int) { + r := libc_listen(int(fd), int(n)); + if r < 0 { errno = GetErrno() } + return; +} + +func setsockopt(fd, level, opt int, valueptr uintptr, length Socklen_t) (errno int) { + r := libc_setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(valueptr)), + length); + if r < 0 { errno = GetErrno() } + return; +} + +func SetsockoptInt(fd, level, opt int, value int) (errno int) { + var n = int32(value); + return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4); +} + +func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) { + return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(tv)), Socklen_t(unsafe.Sizeof(*tv))); +} + +func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) { + return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(l)), Socklen_t(unsafe.Sizeof(*l))); +} + +func SetsockoptString(fd, level, opt int, s string) (errno int) { + return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&[]byte(s)[0])), Socklen_t(len(s))) +} + +func Getsockname(fd int) (sa Sockaddr, errno int) { + var rsa RawSockaddrAny; + var len Socklen_t = SizeofSockaddrAny; + if libc_getsockname(fd, &rsa, &len) != 0 { + errno = GetErrno(); + return; + } + return anyToSockaddr(&rsa); +} + +func Getpeername(fd int) (sa Sockaddr, errno int) { + var rsa RawSockaddrAny; + var len Socklen_t = SizeofSockaddrAny; + if libc_getpeername(fd, &rsa, &len) != 0 { + errno = GetErrno(); + return; + } + return anyToSockaddr(&rsa); +} + +func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) { + var rsa RawSockaddrAny; + var slen Socklen_t = SizeofSockaddrAny; + var _p0 *byte; + if len(p) > 0 { _p0 = &p[0]; } + r := libc_recvfrom(fd, _p0, Size_t(len(p)), flags, &rsa, &slen); + n = int(r); + if r == -1 { + errno = GetErrno(); + } else { + from, errno = anyToSockaddr(&rsa); + } + return; +} + +func (iov *Iovec) SetLen(length int) { + iov.Len = Iovec_len_t(length) +} + +func (msghdr *Msghdr) SetControllen(length int) { + msghdr.Controllen = Msghdr_controllen_t(length) +} + +func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, errno int) { + var msg Msghdr + var rsa RawSockaddrAny + msg.Name = (*byte)(unsafe.Pointer(&rsa)) + msg.Namelen = uint32(SizeofSockaddrAny) + var iov Iovec + if len(p) > 0 { + iov.Base = (*byte)(unsafe.Pointer(&p[0])) + iov.SetLen(len(p)) + } + var dummy byte + if len(oob) > 0 { + // receive at least one normal byte + if len(p) == 0 { + iov.Base = &dummy + iov.SetLen(1) + } + msg.Control = (*byte)(unsafe.Pointer(&oob[0])) + msg.SetControllen(len(oob)) + } + msg.Iov = &iov + msg.Iovlen = 1 + if n, errno = recvmsg(fd, &msg, flags); errno != 0 { + return + } + oobn = int(msg.Controllen) + recvflags = int(msg.Flags) + // source address is only specified if the socket is unconnected + if rsa.Addr.Family != 0 { + from, errno = anyToSockaddr(&rsa) + } + return +} + +func recvmsg(s int, msg *Msghdr, flags int) (n int, errno int) { + r := libc_recvmsg(s, msg, flags) + if r < 0 { + errno = GetErrno() + } else { + n = int(r) + } + return +} + +func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) { + ptr, n, err := to.sockaddr(); + if err != 0 { + return err; + } + var _p0 *byte; + if len(p) > 0 { _p0 = &p[0]; } + r := libc_sendto(fd, _p0, Size_t(len(p)), flags, ptr, n); + if r == -1 { errno = GetErrno(); } + return; +} + +func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (errno int) { + var ptr *RawSockaddrAny + var nsock Socklen_t + if to != nil { + var err int + ptr, nsock, err = to.sockaddr() + if err != 0 { + return err + } + } + var msg Msghdr + msg.Name = (*byte)(unsafe.Pointer(ptr)) + msg.Namelen = uint32(nsock) + var iov Iovec + if len(p) > 0 { + iov.Base = (*byte)(unsafe.Pointer(&p[0])) + iov.SetLen(len(p)) + } + var dummy byte + if len(oob) > 0 { + // send at least one normal byte + if len(p) == 0 { + iov.Base = &dummy + iov.SetLen(1) + } + msg.Control = (*byte)(unsafe.Pointer(&oob[0])) + msg.SetControllen(len(oob)) + } + msg.Iov = &iov + msg.Iovlen = 1 + if errno = sendmsg(fd, &msg, flags); errno != 0 { + return + } + return +} + +func sendmsg(s int, msg *Msghdr, flags int) (errno int) { + if libc_sendmsg(s, msg, flags) < 0 { + errno = GetErrno() + } + return +} + +func Shutdown(fd int, how int) (errno int) { + r := libc_shutdown(fd, how); + if r < 0 { errno = GetErrno() } + return; +} + +// FIXME: No getsockopt. diff --git a/gcc-4.6/libgo/syscalls/socket_bsd.go b/gcc-4.6/libgo/syscalls/socket_bsd.go new file mode 100644 index 000000000..f4d06b4f5 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/socket_bsd.go @@ -0,0 +1,74 @@ +// socket_bsd.go -- Socket handling specific to *BSD based systems. + +// Copyright 2010 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. + +package syscall + +const SizeofSockaddrInet4 = 16 +const SizeofSockaddrInet6 = 28 +const SizeofSockaddrUnix = 110 + +type RawSockaddrInet4 struct { + Len uint8; + Family uint8; + Port uint16; + Addr [4]byte /* in_addr */; + Zero [8]uint8; +} + +func (sa *RawSockaddrInet4) setLen() Socklen_t { + sa.Len = SizeofSockaddrInet4 + return SizeofSockaddrInet4 +} + +type RawSockaddrInet6 struct { + Len uint8; + Family uint8; + Port uint16; + Flowinfo uint32; + Addr [16]byte /* in6_addr */; + Scope_id uint32; +} + +func (sa *RawSockaddrInet6) setLen() Socklen_t { + sa.Len = SizeofSockaddrInet6 + return SizeofSockaddrInet6 +} + +type RawSockaddrUnix struct { + Len uint8; + Family uint8; + Path [108]int8; +} + +func (sa *RawSockaddrUnix) setLen(n int) { + sa.Len = uint8(3 + n) // 2 for Family, Len; 1 for NUL. +} + +func (sa *RawSockaddrUnix) getLen() (int, int) { + if sa.Len < 3 || sa.Len > SizeofSockaddrUnix { + return 0, EINVAL + } + n := int(sa.Len) - 3 // subtract leading Family, Len, terminating NUL. + for i := 0; i < n; i++ { + if sa.Path[i] == 0 { + // found early NUL; assume Len is overestimating. + n = i + break + } + } + return n, 0 +} + +type RawSockaddr struct { + Len uint8; + Family uint8; + Data [14]int8; +} + +// BindToDevice binds the socket associated with fd to device. +func BindToDevice(fd int, device string) (errno int) { + return ENOSYS +} diff --git a/gcc-4.6/libgo/syscalls/socket_epoll.go b/gcc-4.6/libgo/syscalls/socket_epoll.go new file mode 100644 index 000000000..0013f3349 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/socket_epoll.go @@ -0,0 +1,50 @@ +// socket_epoll.go -- GNU/Linux epoll handling. + +// Copyright 2009 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. + +// Support for GNU/Linux epoll. +// Only for implementing net package. +// DO NOT USE DIRECTLY. + +package syscall + +// We don't take this type directly from the header file because it +// uses a union. FIXME. + +type EpollEvent struct { + Events uint32; + Fd int32; + Pad int32; +}; + +func libc_epoll_create(size int) int __asm__ ("epoll_create"); +func libc_epoll_ctl(epfd, op, fd int, event *EpollEvent) int __asm__ ("epoll_ctl"); +func libc_epoll_wait(epfd int, events *EpollEvent, maxevents int, + timeout int) int __asm__ ("epoll_wait"); + + +func EpollCreate(size int) (fd int, errno int) { + fd = libc_epoll_create(int(size)); + if fd < 0 { errno = GetErrno() } + return; +} + +func EpollCtl(epfd, op, fd int, ev *EpollEvent) (errno int) { + r := libc_epoll_ctl(epfd, op, fd, ev); + if r < 0 { errno = GetErrno() } + return; +} + +func EpollWait(epfd int, ev []EpollEvent, msec int) (n int, errno int) { + var events *EpollEvent; + var maxevents int; + if len(ev) > 0 { + maxevents = len(ev); + events = &ev[0] + } + n = libc_epoll_wait(epfd, events, maxevents, msec); + if n < 0 { errno = GetErrno() } + return; +} diff --git a/gcc-4.6/libgo/syscalls/socket_linux.go b/gcc-4.6/libgo/syscalls/socket_linux.go new file mode 100644 index 000000000..cdcdf4ff2 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/socket_linux.go @@ -0,0 +1,75 @@ +// socket_linux.go -- Socket handling specific to Linux. + +// Copyright 2010 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. + +package syscall + +const SizeofSockaddrInet4 = 16 +const SizeofSockaddrInet6 = 28 +const SizeofSockaddrUnix = 110 + +type RawSockaddrInet4 struct { + Family uint16; + Port uint16; + Addr [4]byte /* in_addr */; + Zero [8]uint8; +} + +func (sa *RawSockaddrInet4) setLen() Socklen_t { + return SizeofSockaddrInet4 +} + +type RawSockaddrInet6 struct { + Family uint16; + Port uint16; + Flowinfo uint32; + Addr [16]byte /* in6_addr */; + Scope_id uint32; +} + +func (sa *RawSockaddrInet6) setLen() Socklen_t { + return SizeofSockaddrInet6 +} + +type RawSockaddrUnix struct { + Family uint16; + Path [108]int8; +} + +func (sa *RawSockaddrUnix) setLen(int) { +} + +func (sa *RawSockaddrUnix) getLen() (int, int) { + if sa.Path[0] == 0 { + // "Abstract" Unix domain socket. + // Rewrite leading NUL as @ for textual display. + // (This is the standard convention.) + // Not friendly to overwrite in place, + // but the callers below don't care. + sa.Path[0] = '@'; + } + + // Assume path ends at NUL. + // This is not technically the Linux semantics for + // abstract Unix domain sockets--they are supposed + // to be uninterpreted fixed-size binary blobs--but + // everyone uses this convention. + n := 0; + for n < len(sa.Path) - 3 && sa.Path[n] != 0 { + n++; + } + + return n, 0 +} + +type RawSockaddr struct { + Family uint16; + Data [14]int8; +} + +// BindToDevice binds the socket associated with fd to device. +func BindToDevice(fd int, device string) (errno int) { + return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device) +} diff --git a/gcc-4.6/libgo/syscalls/socket_solaris.go b/gcc-4.6/libgo/syscalls/socket_solaris.go new file mode 100644 index 000000000..13fe727c3 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/socket_solaris.go @@ -0,0 +1,76 @@ +// socket_solaris.go -- Socket handling specific to Solaris. + +// Copyright 2010 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. + +package syscall + +const SizeofSockaddrInet4 = 16 +const SizeofSockaddrInet6 = 32 +const SizeofSockaddrUnix = 110 + +type RawSockaddrInet4 struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]uint8 +} + +func (sa *RawSockaddrInet4) setLen() Socklen_t { + return SizeofSockaddrInet4 +} + +type RawSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 + Src_id uint32 +} + +func (sa *RawSockaddrInet6) setLen() Socklen_t { + return SizeofSockaddrInet6 +} + +type RawSockaddrUnix struct { + Family uint16 + Path [108]int8 +} + +func (sa *RawSockaddrUnix) setLen(int) { +} + +func (sa *RawSockaddrUnix) getLen() (int, int) { + if sa.Path[0] == 0 { + // "Abstract" Unix domain socket. + // Rewrite leading NUL as @ for textual display. + // (This is the standard convention.) + // Not friendly to overwrite in place, + // but the callers below don't care. + sa.Path[0] = '@' + } + + // Assume path ends at NUL. + // This is not technically the Linux semantics for + // abstract Unix domain sockets--they are supposed + // to be uninterpreted fixed-size binary blobs--but + // everyone uses this convention. + n := 0 + for n < len(sa.Path) - 3 && sa.Path[n] != 0 { + n++ + } + + return n, 0 +} + +type RawSockaddr struct { + Family uint16 + Data [14]int8 +} + +// BindToDevice binds the socket associated with fd to device. +func BindToDevice(fd int, device string) (errno int) { + return ENOSYS +} diff --git a/gcc-4.6/libgo/syscalls/stringbyte.go b/gcc-4.6/libgo/syscalls/stringbyte.go new file mode 100644 index 000000000..b673c9b02 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/stringbyte.go @@ -0,0 +1,24 @@ +// stringbyte.go -- string to bytes functions. + +// Copyright 2010 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. + +package syscall + +// StringByteSlice returns a NUL-terminated slice of bytes +// containing the text of s. +func StringByteSlice(s string) []byte { + a := make([]byte, len(s)+1); + for i := 0; i < len(s); i++ { + a[i] = s[i]; + } + return a; +} + +// StringBytePtr returns a pointer to a NUL-terminated array of bytes +// containing the text of s. +func StringBytePtr(s string) *byte { + p := StringByteSlice(s); + return &p[0]; +} diff --git a/gcc-4.6/libgo/syscalls/syscall.go b/gcc-4.6/libgo/syscalls/syscall.go new file mode 100644 index 000000000..fa7d9d068 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall.go @@ -0,0 +1,48 @@ +// syscall.go -- Basic syscall interface. + +// Copyright 2009 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. + +// This package contains an interface to the low-level operating system +// primitives. The details vary depending on the underlying system. +// Its primary use is inside other packages that provide a more portable +// interface to the system, such as "os", "time" and "net". Use those +// packages rather than this one if you can. +// For details of the functions and data types in this package consult +// the manuals for the appropriate operating system. +package syscall + +import "unsafe" + +func libc_syscall32(trap int32, a1, a2, a3, a4, a5, a6 int32) int32 __asm__ ("syscall"); +func libc_syscall64(trap int64, a1, a2, a3, a4, a5, a6 int64) int64 __asm__ ("syscall"); + +// Do a system call. We look at the size of uintptr to see how to pass +// the arguments, so that we don't pass a 64-bit value when the function +// expects a 32-bit one. +func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + var r uintptr; + if unsafe.Sizeof(r) == 4 { + r1 := libc_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0); + r = uintptr(r1); + } else { + r1 := libc_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0); + r = uintptr(r1); + } + return r, 0, uintptr(GetErrno()); +} + +func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + var r uintptr; + if unsafe.Sizeof(r) == 4 { + r1 := libc_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), + int32(a4), int32(a5), int32(a6)); + r = uintptr(r1); + } else { + r1 := libc_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), + int64(a4), int64(a5), int64(a6)); + r = uintptr(r1); + } + return r, 0, uintptr(GetErrno()); +} diff --git a/gcc-4.6/libgo/syscalls/syscall_linux.go b/gcc-4.6/libgo/syscalls/syscall_linux.go new file mode 100644 index 000000000..bdb92c5f4 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_linux.go @@ -0,0 +1,188 @@ +// syscall_linux.go -- GNU/Linux specific syscall interface. + +// Copyright 2009 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. + +package syscall + +import "unsafe" + +func libc_ptrace(request int, pid Pid_t, addr uintptr, data *byte) _C_long __asm__ ("ptrace") + +var dummy *byte +const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy)) + +func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, errno int) { + // The peek requests are machine-size oriented, so we wrap it + // to retrieve arbitrary-length data. + + var buf [sizeofPtr]byte; + + // Leading edge. PEEKTEXT/PEEKDATA don't require aligned + // access (PEEKUSER warns that it might), but if we don't + // align our reads, we might straddle an unmapped page + // boundary and not get the bytes leading up to the page + // boundary. + n := 0; + if addr % sizeofPtr != 0 { + SetErrno(0); + val := libc_ptrace(req, Pid_t(pid), addr - addr%sizeofPtr, nil); + if errno := GetErrno(); errno != 0 { + return 0, errno; + } + *(*_C_long)(unsafe.Pointer(&buf[0])) = val; + n += copy(out, buf[addr%sizeofPtr:]); + out = out[n:]; + } + + // Remainder. + for len(out) > 0 { + // We use an internal buffer to gaurantee alignment. + // It's not documented if this is necessary, but we're paranoid. + SetErrno(0); + val := libc_ptrace(req, Pid_t(pid), addr+uintptr(n), nil); + if errno = GetErrno(); errno != 0 { + return n, errno; + } + *(*_C_long)(unsafe.Pointer(&buf[0])) = val; + copied := copy(out, buf[0:]); + n += copied; + out = out[copied:]; + } + + return n, 0; +} + +func PtracePeekText(pid int, addr uintptr, out []byte) (count int, errno int) { + return ptracePeek(_PTRACE_PEEKTEXT, pid, addr, out); +} + +func PtracePeekData(pid int, addr uintptr, out []byte) (count int, errno int) { + return ptracePeek(_PTRACE_PEEKDATA, pid, addr, out); +} + +func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, errno int) { + // As for ptracePeek, we need to align our accesses to deal + // with the possibility of straddling an invalid page. + + // Leading edge. + n := 0; + if addr % sizeofPtr != 0 { + var buf [sizeofPtr]byte; + if libc_ptrace(peekReq, Pid_t(pid), addr - addr%sizeofPtr, &buf[0]) < 0 { + return 0, GetErrno(); + } + n += copy(buf[addr%sizeofPtr:], data); + word := (*byte)(unsafe.Pointer(*((*uintptr)(unsafe.Pointer(&buf[0]))))); + if libc_ptrace(pokeReq, Pid_t(pid), addr - addr%sizeofPtr, word) < 0 { + return 0, GetErrno(); + } + data = data[n:len(data)]; + } + + // Interior. + for uintptr(len(data)) > sizeofPtr { + word := (*byte)(unsafe.Pointer(*((*uintptr)(unsafe.Pointer(&data[0]))))); + if libc_ptrace(pokeReq, Pid_t(pid), addr+uintptr(n), word) < 0 { + return n, GetErrno(); + } + n += int(sizeofPtr); + data = data[sizeofPtr:len(data)]; + } + + // Trailing edge. + if len(data) > 0 { + var buf [sizeofPtr]byte; + if libc_ptrace(peekReq, Pid_t(pid), addr+uintptr(n), &buf[0]) < 0 { + return n, GetErrno(); + } + copy(buf[0:], data); + word := (*byte)(unsafe.Pointer(*((*uintptr)(unsafe.Pointer(&buf[0]))))); + if libc_ptrace(pokeReq, Pid_t(pid), addr+uintptr(n), word) < 0 { + return n, GetErrno(); + } + n += len(data); + } + + return n, 0; +} + +func PtracePokeText(pid int, addr uintptr, data []byte) (count int, errno int) { + return ptracePoke(_PTRACE_POKETEXT, _PTRACE_PEEKTEXT, pid, addr, data); +} + +func PtracePokeData(pid int, addr uintptr, data []byte) (count int, errno int) { + return ptracePoke(_PTRACE_POKEDATA, _PTRACE_PEEKDATA, pid, addr, data); +} + +func PtraceGetRegs(pid int, regsout *PtraceRegs) (errno int) { + if libc_ptrace(_PTRACE_GETREGS, Pid_t(pid), 0, (*byte)(unsafe.Pointer(regsout))) < 0 { + return GetErrno(); + } else { + return 0; + } +} + +func PtraceSetRegs(pid int, regs *PtraceRegs) (errno int) { + if libc_ptrace(_PTRACE_SETREGS, Pid_t(pid), 0, (*byte)(unsafe.Pointer(regs))) < 0 { + return GetErrno(); + } else { + return 0; + } +} + +func PtraceSetOptions(pid int, options int) (errno int) { + if libc_ptrace(_PTRACE_SETOPTIONS, Pid_t(pid), 0, (*byte)(unsafe.Pointer(uintptr(options)))) < 0 { + return GetErrno(); + } else { + return 0; + } +} + +func PtraceGetEventMsg(pid int) (msg uint, errno int) { + var data _C_long; + if libc_ptrace(_PTRACE_GETEVENTMSG, Pid_t(pid), 0, (*byte)(unsafe.Pointer(&data))) < 0 { + errno = GetErrno(); + } + msg = uint(data); + return; +} + +func PtraceCont(pid int, signal int) (errno int) { + if libc_ptrace(_PTRACE_CONT, Pid_t(pid), 0, (*byte)(unsafe.Pointer(uintptr(signal)))) < 0 { + return GetErrno(); + } else { + return 0; + } +} + +func PtraceSingleStep(pid int) (errno int) { + if libc_ptrace(_PTRACE_SINGLESTEP, Pid_t(pid), 0, nil) < 0 { + return GetErrno(); + } else { + return 0; + } +} + +func PtraceAttach(pid int) (errno int) { + if libc_ptrace(_PTRACE_ATTACH, Pid_t(pid), 0, nil) < 0 { + return GetErrno(); + } else { + return 0; + } +} + +func PtraceDetach(pid int) (errno int) { + if libc_ptrace(_PTRACE_DETACH, Pid_t(pid), 0, nil) < 0 { + return GetErrno(); + } else { + return 0; + } +} + +func Tgkill(tgid int, tid int, sig int) (errno int) { + r1, r2, err := Syscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), + uintptr(sig)); + return int(err); +} diff --git a/gcc-4.6/libgo/syscalls/syscall_linux_386.go b/gcc-4.6/libgo/syscalls/syscall_linux_386.go new file mode 100644 index 000000000..aca9c7bf5 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_linux_386.go @@ -0,0 +1,15 @@ +// syscall_linux_386.go -- GNU/Linux 386 specific support + +// Copyright 2009 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. + +package syscall + +func (r *PtraceRegs) PC() uint64 { + return uint64(uint32(r.Eip)); +} + +func (r *PtraceRegs) SetPC(pc uint64) { + r.Eip = int32(pc); +} diff --git a/gcc-4.6/libgo/syscalls/syscall_linux_amd64.go b/gcc-4.6/libgo/syscalls/syscall_linux_amd64.go new file mode 100644 index 000000000..9932579cc --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_linux_amd64.go @@ -0,0 +1,15 @@ +// syscall_linux_amd64.go -- GNU/Linux 386 specific support + +// Copyright 2009 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. + +package syscall + +func (r *PtraceRegs) PC() uint64 { + return r.Rip; +} + +func (r *PtraceRegs) SetPC(pc uint64) { + r.Rip = pc; +} diff --git a/gcc-4.6/libgo/syscalls/syscall_rtems.go b/gcc-4.6/libgo/syscalls/syscall_rtems.go new file mode 100644 index 000000000..7f0c11954 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_rtems.go @@ -0,0 +1,7 @@ +// syscall_rtems.go -- RTEMS specific syscall interface. + +// Copyright 2011 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. + +package syscall diff --git a/gcc-4.6/libgo/syscalls/syscall_solaris.go b/gcc-4.6/libgo/syscalls/syscall_solaris.go new file mode 100644 index 000000000..ec229339d --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_solaris.go @@ -0,0 +1,7 @@ +// syscall_solaris.go -- Solaris 2 specific syscall interface. + +// Copyright 2011 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. + +package syscall diff --git a/gcc-4.6/libgo/syscalls/syscall_solaris_386.go b/gcc-4.6/libgo/syscalls/syscall_solaris_386.go new file mode 100644 index 000000000..7ff8f5b07 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_solaris_386.go @@ -0,0 +1,20 @@ +// syscall_solaris_386.go -- Solaris/x86 specific support + +// Copyright 2011 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. + +package syscall + +import "unsafe" + +// FIXME: ptrace(3C) has this, but exec.go expects the next. +//func libc_ptrace(request int, pid Pid_t, addr int, data int) int __asm__ ("ptrace") + +func libc_ptrace(request int, pid Pid_t, addr uintptr, data *byte) int __asm__ ("ptrace") + +var dummy *byte +const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy)) + +// 32-bit Solaris 2/x86 needs to use _nuname internally, cf. . +func libc_uname(buf *Utsname) (errno int) __asm__("_nuname") diff --git a/gcc-4.6/libgo/syscalls/syscall_solaris_amd64.go b/gcc-4.6/libgo/syscalls/syscall_solaris_amd64.go new file mode 100644 index 000000000..15d225615 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_solaris_amd64.go @@ -0,0 +1,21 @@ +// syscall_solaris_amd64.go -- Solaris/x64 specific support + +// Copyright 2011 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. + +package syscall + +import "unsafe" + +// FIXME: ptrace(3C) has this, but exec.go expects the next. +//func libc_ptrace(request int, pid Pid_t, addr int, data int) int __asm__ ("ptrace") + +// 64-bit ptrace(3C) doesn't exist +func libc_ptrace(request int, pid Pid_t, addr uintptr, data *byte) int { + SetErrno(ENOSYS) + return -1 +} + +var dummy *byte +const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy)) diff --git a/gcc-4.6/libgo/syscalls/syscall_solaris_sparc.go b/gcc-4.6/libgo/syscalls/syscall_solaris_sparc.go new file mode 100644 index 000000000..0be60b929 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_solaris_sparc.go @@ -0,0 +1,17 @@ +// syscall_solaris_sparc.go -- Solaris/SPARC specific support + +// Copyright 2011 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. + +package syscall + +import "unsafe" + +// FIXME: ptrace(3C) has this, but exec.go expects the next. +//func libc_ptrace(request int, pid Pid_t, addr int, data int) int __asm__ ("ptrace") + +func libc_ptrace(request int, pid Pid_t, addr uintptr, data *byte) int __asm__ ("ptrace") + +var dummy *byte +const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy)) diff --git a/gcc-4.6/libgo/syscalls/syscall_solaris_sparc64.go b/gcc-4.6/libgo/syscalls/syscall_solaris_sparc64.go new file mode 100644 index 000000000..81e2010cd --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_solaris_sparc64.go @@ -0,0 +1,21 @@ +// syscall_solaris_sparc64.go -- Solaris/SPARCV9 specific support + +// Copyright 2011 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. + +package syscall + +import "unsafe" + +// FIXME: ptrace(3C) has this, but exec.go expects the next. +//func libc_ptrace(request int, pid Pid_t, addr int, data int) int __asm__ ("ptrace") + +// 64-bit ptrace(3C) doesn't exist +func libc_ptrace(request int, pid Pid_t, addr uintptr, data *byte) int { + SetErrno(ENOSYS) + return -1 +} + +var dummy *byte +const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy)) diff --git a/gcc-4.6/libgo/syscalls/syscall_stubs.go b/gcc-4.6/libgo/syscalls/syscall_stubs.go new file mode 100644 index 000000000..d864902ea --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_stubs.go @@ -0,0 +1,33 @@ +// syscall_stubs.go -- Stubs of the basic syscall interface. + +// Copyright 2010 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. + +// This package contains an interface to the low-level operating system +// primitives. The details vary depending on the underlying system. +// Its primary use is inside other packages that provide a more portable +// interface to the system, such as "os", "time" and "net". Use those +// packages rather than this one if you can. +// For details of the functions and data types in this package consult +// the manuals for the appropriate operating system. + +// These are stubs. + +package syscall + +func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + var r uintptr; + var i int; + i = -1; + r = uintptr(i); + return r, 0, uintptr(ENOSYS); +} + +func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + var r uintptr; + var i int; + i = -1; + r = uintptr(i); + return r, 0, uintptr(ENOSYS); +} diff --git a/gcc-4.6/libgo/syscalls/syscall_uname.go b/gcc-4.6/libgo/syscalls/syscall_uname.go new file mode 100644 index 000000000..955866c89 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_uname.go @@ -0,0 +1,7 @@ +// Copyright 2011 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. + +package syscall + +func libc_uname(buf *Utsname) (errno int) __asm__("uname") diff --git a/gcc-4.6/libgo/syscalls/syscall_unix.go b/gcc-4.6/libgo/syscalls/syscall_unix.go new file mode 100644 index 000000000..a29b6b54b --- /dev/null +++ b/gcc-4.6/libgo/syscalls/syscall_unix.go @@ -0,0 +1,24 @@ +// Copyright 2009 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. + +package syscall + +var ( + Stdin = 0 + Stdout = 1 + Stderr = 2 +) + +const ENONE = 0 + +func GetErrno() int +func SetErrno(int) + +func Uname(buf *Utsname) (errno int) { + r := libc_uname(buf) + if r < 0 { + errno = GetErrno() + } + return +} diff --git a/gcc-4.6/libgo/syscalls/sysfile_largefile.go b/gcc-4.6/libgo/syscalls/sysfile_largefile.go new file mode 100644 index 000000000..963a624bd --- /dev/null +++ b/gcc-4.6/libgo/syscalls/sysfile_largefile.go @@ -0,0 +1,13 @@ +// sysfile_largefile.go -- For systems which use the large file interface. + +// Copyright 2011 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. + +package syscall + +func libc_pread(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t __asm__ ("pread64") +func libc_pwrite(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t __asm__ ("pwrite64") +func libc_lseek(int, Offset_t, int) Offset_t __asm__ ("lseek64") +func libc_truncate(path *byte, length Offset_t) int __asm__ ("truncate64") +func libc_ftruncate(fd int, length Offset_t) int __asm__ ("ftruncate64") diff --git a/gcc-4.6/libgo/syscalls/sysfile_posix.go b/gcc-4.6/libgo/syscalls/sysfile_posix.go new file mode 100644 index 000000000..8b724983c --- /dev/null +++ b/gcc-4.6/libgo/syscalls/sysfile_posix.go @@ -0,0 +1,427 @@ +// sysfile_posix.go -- POSIX File handling. + +// Copyright 2010 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. + +// Support for basic Unix file operations. This file simply +// translates from Go data types to Unix data types, and handles +// errno. FIXME: This could probably be done mechanically. + +package syscall + +import "unsafe" + +func libc_open(name *byte, mode int, perm Mode_t) int __asm__ ("open"); +func libc_close(fd int) int __asm__ ("close"); +func libc_read(fd int, buf *byte, count Size_t) Ssize_t __asm__ ("read"); +func libc_write(fd int, buf *byte, count Size_t) Ssize_t __asm__ ("write"); +func libc_fsync(fd int) int __asm__ ("fsync") +func libc_pipe(filedes *int) int __asm__("pipe"); +func libc_unlink(name *byte) int __asm__ ("unlink"); +func libc_rmdir(name *byte) int __asm__ ("rmdir"); +func libc_fcntl(fd int, cmd int, arg int) int __asm__ ("fcntl"); +func libc_mkdir(name *byte, perm Mode_t) int __asm__ ("mkdir"); +func libc_dup(int) int __asm__ ("dup") +func libc_gettimeofday(tv *Timeval, tz *byte) int __asm__ ("gettimeofday"); +func libc_select(int, *byte, *byte, *byte, *Timeval) int __asm__ ("select"); +func libc_chdir(name *byte) int __asm__ ("chdir"); +func libc_fchdir(int) int __asm__ ("fchdir"); +func libc_getcwd(*byte, Size_t) *byte __asm__ ("getcwd"); +func libc_link(oldpath *byte, newpath *byte) int __asm__ ("link"); +func libc_symlink(oldpath *byte, newpath *byte) int __asm__ ("symlink"); +func libc_readlink(*byte, *byte, Size_t) Ssize_t __asm__ ("readlink"); +func libc_rename(oldpath *byte, newpath *byte) int __asm__ ("rename"); +func libc_chmod(path *byte, mode Mode_t) int __asm__ ("chmod"); +func libc_fchmod(fd int, mode Mode_t) int __asm__ ("fchmod"); +func libc_chown(path *byte, owner Uid_t, group Gid_t) int __asm__ ("chown"); +func libc_fchown(fd int, owner Uid_t, group Gid_t) int __asm__ ("fchown"); +func libc_lchown(path *byte, owner Uid_t, group Gid_t) int __asm__ ("lchown"); +func libc_utimes(filename *byte, times *[2]Timeval) int __asm__ ("utimes"); +func libc_getuid() Uid_t __asm__ ("getuid"); +func libc_geteuid() Uid_t __asm__ ("geteuid"); +func libc_getgid() Gid_t __asm__ ("getgid"); +func libc_getegid() Gid_t __asm__ ("getegid"); +func libc_getgroups(size int, list *Gid_t) int __asm__ ("getgroups"); +func libc_getpagesize() int __asm__ ("getpagesize"); +func libc_exit(status int) __asm__ ("exit") +func libc_getpid() Pid_t __asm__ ("getpid") +func libc_getppid() Pid_t __asm__ ("getppid") +func libc_kill(Pid_t, int) int __asm__ ("kill") + +func Open(name string, mode int, perm uint32) (fd int, errno int) { + fd = libc_open(StringBytePtr(name), mode, Mode_t(perm)); + if fd < 0 { errno = GetErrno() } + return; +} + +func Creat(name string, perm uint32) (fd int, errno int) { + fd = libc_open(StringBytePtr(name), O_CREAT | O_WRONLY | O_TRUNC, Mode_t(perm)); + if fd < 0 { errno = GetErrno() } + return; +} + +func Close(fd int) (errno int) { + r := libc_close(fd); + if r < 0 { errno = GetErrno() } + return; +} + +func Read(fd int, p []byte) (n int, errno int) { + var _p0 *byte; + if len(p) > 0 { _p0 = &p[0]; } + r := libc_read(fd, _p0, Size_t(len(p))); + if r == -1 { errno = GetErrno() } + n = int(r); + return; +} + +func Write(fd int, p []byte) (n int, errno int) { + var _p0 *byte; + if len(p) > 0 { _p0 = &p[0]; } + r := libc_write(fd, _p0, Size_t(len(p))); + if r == -1 { errno = GetErrno() } + n = int(r); + return; +} + +func Fsync(fd int) (errno int) { + if libc_fsync(fd) < 0 { + errno = GetErrno() + } + return +} + +func Pread(fd int, p []byte, offset int64) (n int, errno int) { + var _p0 *byte; + if len(p) > 0 { _p0 = &p[0]; } + r := libc_pread(fd, _p0, Size_t(len(p)), Offset_t(offset)); + if r == -1 { errno = GetErrno() } + n = int(r); + return; +} + +func Pwrite(fd int, p []byte, offset int64) (n int, errno int) { + var _p0 *byte; + if len(p) > 0 { _p0 = &p[0]; } + r := libc_pwrite(fd, _p0, Size_t(len(p)), Offset_t(offset)); + if r == -1 { errno = GetErrno() } + n = int(r); + return; +} + +func Seek(fd int, offset int64, whence int) (off int64, errno int) { + r := libc_lseek(fd, Offset_t(offset), whence); + if r == -1 { errno = GetErrno() } + off = int64(r); + return; +} + +func Pipe(p []int) (errno int) { + if len(p) != 2 { + return EINVAL; + } + var pp [2]int; + r := libc_pipe(&pp[0]); + if r < 0 { + errno = GetErrno(); + } + p[0] = pp[0]; + p[1] = pp[1]; + return; +} + +func Stat(name string, buf *Stat_t) (errno int) { + r := libc_stat(StringBytePtr(name), buf); + if r < 0 { errno = GetErrno() } + return; +} + +func Lstat(name string, buf *Stat_t) (errno int) { + r := libc_lstat(StringBytePtr(name), buf); + if r < 0 { errno = GetErrno() } + return; +} + +func Fstat(fd int, buf *Stat_t) (errno int) { + r := libc_fstat(fd, buf); + if r < 0 { errno = GetErrno() } + return; +} + +func Unlink(name string) (errno int) { + r := libc_unlink(StringBytePtr(name)); + if r < 0 { errno = GetErrno() } + return; +} + +func Rmdir(name string) (errno int) { + r := libc_rmdir(StringBytePtr(name)); + if r < 0 { errno = GetErrno() } + return; +} + +func Mkdir(path string, mode uint32) (errno int) { + r := libc_mkdir(StringBytePtr(path), Mode_t(mode)); + if r < 0 { errno = GetErrno() } + return; +} + +func Dup(oldfd int) (fd int, errno int) { + fd = libc_dup(oldfd) + if fd < 0 { + errno = GetErrno() + } + return +} + +func Gettimeofday(tv *Timeval) (errno int) { + r := libc_gettimeofday(tv, nil); + if r < 0 { errno = GetErrno() } + return; +} + +type FdSet_t struct { + Fds_bits [(FD_SETSIZE + 63) / 64]int64; +} + +func FDSet(fd int, set *FdSet_t) { + set.Fds_bits[fd / 64] |= (1 << (uint)(fd % 64)) +} + +func FDClr(fd int, set *FdSet_t) { + set.Fds_bits[fd / 64] &= ^(1 << (uint)(fd % 64)) +} + +func FDIsSet(fd int, set *FdSet_t) bool { + if set.Fds_bits[fd / 64] & (1 << (uint)(fd % 64)) != 0 { + return true + } else { + return false + } +} + +func FDZero(set *FdSet_t) { + for i := 0; i < ((FD_SETSIZE + 63) / 64); i++ { + set.Fds_bits[i] = 0 + } +} + +func Select(nfds int, r *FdSet_t, w *FdSet_t, e *FdSet_t, timeout *Timeval) (n int, errno int) { + n = libc_select(nfds, (*byte)(unsafe.Pointer(r)), + (*byte)(unsafe.Pointer(e)), + (*byte)(unsafe.Pointer(e)), timeout); + if n < 0 { errno = GetErrno() } + return; +} + +func Chdir(path string) (errno int) { + r := libc_chdir(StringBytePtr(path)); + if r < 0 { errno = GetErrno() } + return; +} + +func Fchdir(fd int) (errno int) { + r := libc_fchdir(int(fd)); + if r < 0 { errno = GetErrno() } + return; +} + +const ImplementsGetwd = true + +func Getwd() (ret string, errno int) { + for len := Size_t(4096); ; len *= 2 { + b := make([]byte, len); + p := libc_getcwd(&b[0], len); + if p != nil { + i := 0; + for b[i] != 0 { + i++; + } + return string(b[0:i]), 0; + } + e := GetErrno(); + if e != ERANGE { + return "", e; + } + } +} + +func Link(oldpath, newpath string) (errno int) { + r := libc_link(StringBytePtr(oldpath), StringBytePtr(newpath)); + if r < 0 { errno = GetErrno() } + return; +} + +func Symlink(oldpath, newpath string) (errno int) { + r := libc_symlink(StringBytePtr(oldpath), StringBytePtr(newpath)); + if r < 0 { errno = GetErrno() } + return; +} + +func Readlink(path string, buf []byte) (n int, errno int) { + var _p0 *byte; + if len(buf) > 0 { _p0 = &buf[0]; } + r := libc_readlink(StringBytePtr(path), _p0, Size_t(len(buf))); + if r < 0 { errno = GetErrno() } + n = int(r); + return; +} + +func Rename(oldpath, newpath string) (errno int) { + r := libc_rename(StringBytePtr(oldpath), StringBytePtr(newpath)); + if r < 0 { errno = GetErrno() } + return +} + +func Chmod(path string, mode uint32) (errno int) { + r := libc_chmod(StringBytePtr(path), Mode_t(mode)); + if r < 0 { errno = GetErrno() } + return; +} + +func Fchmod(fd int, mode uint32) (errno int) { + r := libc_fchmod(fd, Mode_t(mode)); + if r < 0 { errno = GetErrno() } + return; +} + +func Chown(path string, uid int, gid int) (errno int) { + r := libc_chown(StringBytePtr(path), Uid_t(uid), Gid_t(gid)); + if r < 0 { errno = GetErrno() } + return; +} + +func Lchown(path string, uid int, gid int) (errno int) { + r := libc_lchown(StringBytePtr(path), Uid_t(uid), Gid_t(gid)); + if r < 0 { errno = GetErrno() } + return; +} + +func Fchown(fd int, uid int, gid int) (errno int) { + r := libc_fchown(fd, Uid_t(uid), Gid_t(gid)); + if r < 0 { errno = GetErrno() } + return; +} + +func Truncate(path string, length int64) (errno int) { + r := libc_truncate(StringBytePtr(path), Offset_t(length)); + if r < 0 { errno = GetErrno() } + return; +} + +func Ftruncate(fd int, length int64) (errno int) { + r := libc_ftruncate(fd, Offset_t(length)); + if r < 0 { errno = GetErrno() } + return; +} + +func Utimes(path string, tv []Timeval) (errno int) { + if len(tv) != 2 { + return EINVAL; + } + r := libc_utimes(StringBytePtr(path), + (*[2]Timeval)(unsafe.Pointer(&tv[0]))); + if r < 0 { + errno = GetErrno(); + } + return; +} + +// Getuid returns the numeric user id of the caller. +func Getuid() int { + return int(libc_getuid()); +} + +// Geteuid returns the numeric effective user id of the caller. +func Geteuid() int { + return int(libc_geteuid()); +} + +// Getgid returns the numeric group id of the caller. +func Getgid() int { + return int(libc_getgid()); +} + +// Getegid returns the numeric effective group id of the caller. +func Getegid() int { + return int(libc_getegid()); +} + +// Getgroups returns a list of the numeric ids of groups that the caller belongs to. +func Getgroups() (gids []int, errno int) { + n := libc_getgroups(0, nil); + if n < 0 { + return nil, GetErrno(); + } + if n == 0 { + return nil, 0; + } + + // Sanity check group count. Max is 1<<16 on Linux. + if n < 0 || n > 1<<20 { + return nil, EINVAL; + } + + a := make([]Gid_t, n); + n = libc_getgroups(n, &a[0]); + if n < 0 { + return nil, GetErrno(); + } + gids = make([]int, n); + for i, v := range a[0:n] { + gids[i] = int(v); + } + return; +} + +func Getpagesize() int { + return libc_getpagesize(); +} + +func TimespecToNsec(ts Timespec) int64 { + return int64(ts.Sec)*1e9 + int64(ts.Nsec); +} + +func NsecToTimespec(nsec int64) (ts Timespec) { + ts.Sec = Timespec_sec_t(nsec / 1e9); + ts.Nsec = Timespec_nsec_t(nsec % 1e9); + return; +} + +func TimevalToNsec(tv Timeval) int64 { + return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3; +} + +func NsecToTimeval(nsec int64) (tv Timeval) { + nsec += 999; // round up to microsecond + tv.Sec = Timeval_sec_t(nsec/1e9); + tv.Usec = Timeval_usec_t(nsec%1e9 / 1e3); + return; +} + +func Exit(code int) { + libc_exit(code); +} + +func fcntl(fd, cmd, arg int) (val int, errno int) { + val = libc_fcntl(int(fd), int(cmd), int(arg)); + if val == -1 { errno = GetErrno() } + return; +} + +func Getpid() (pid int) { + return int(libc_getpid()); +} + +func Getppid() (ppid int) { + return int(libc_getppid()); +} + +func Kill(pid int, sig int) (errno int) { + r := libc_kill(Pid_t(pid), sig) + if r < 0 { + errno = GetErrno() + } + return +} diff --git a/gcc-4.6/libgo/syscalls/sysfile_regfile.go b/gcc-4.6/libgo/syscalls/sysfile_regfile.go new file mode 100644 index 000000000..731c59c97 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/sysfile_regfile.go @@ -0,0 +1,13 @@ +// sysfile_regfile.go -- For systems which do not use the large file interface. + +// Copyright 2011 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. + +package syscall + +func libc_pread(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t __asm__ ("pread") +func libc_pwrite(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t __asm__ ("pwrite") +func libc_lseek(int, Offset_t, int) Offset_t __asm__ ("lseek") +func libc_truncate(path *byte, length Offset_t) int __asm__ ("truncate") +func libc_ftruncate(fd int, length Offset_t) int __asm__ ("ftruncate") diff --git a/gcc-4.6/libgo/syscalls/sysfile_stat_largefile.go b/gcc-4.6/libgo/syscalls/sysfile_stat_largefile.go new file mode 100644 index 000000000..1b785f70a --- /dev/null +++ b/gcc-4.6/libgo/syscalls/sysfile_stat_largefile.go @@ -0,0 +1,12 @@ +// sysfile_stat_largefile.go -- For systems which use the large file interface +// for *stat. + +// Copyright 2011 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. + +package syscall + +func libc_stat(name *byte, buf *Stat_t) int __asm__ ("stat64"); +func libc_fstat(fd int, buf *Stat_t) int __asm__ ("fstat64"); +func libc_lstat(name *byte, buf *Stat_t) int __asm__ ("lstat64"); diff --git a/gcc-4.6/libgo/syscalls/sysfile_stat_regfile.go b/gcc-4.6/libgo/syscalls/sysfile_stat_regfile.go new file mode 100644 index 000000000..b3d486413 --- /dev/null +++ b/gcc-4.6/libgo/syscalls/sysfile_stat_regfile.go @@ -0,0 +1,12 @@ +// sysfile_stat_regfile.go -- For systems which do not use the large file +// interface for *stat. + +// Copyright 2011 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. + +package syscall + +func libc_stat(name *byte, buf *Stat_t) int __asm__ ("stat"); +func libc_fstat(fd int, buf *Stat_t) int __asm__ ("fstat"); +func libc_lstat(name *byte, buf *Stat_t) int __asm__ ("lstat"); -- cgit v1.2.3