aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-01-13 05:17:52 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-01-13 05:17:52 +0000
commitcff0c39da10717bec95ae9b1d57d05645f91dea9 (patch)
treee9602dee09986866e66e3bee32d69f8c5d57bf78
parent243ffa47b314724dc9f5c0484e999243c4a25da9 (diff)
downloadgcc-cff0c39da10717bec95ae9b1d57d05645f91dea9.zip
gcc-cff0c39da10717bec95ae9b1d57d05645f91dea9.tar.gz
gcc-cff0c39da10717bec95ae9b1d57d05645f91dea9.tar.bz2
Clean up syscalls, add some Solaris support.
From-SVN: r168738
-rw-r--r--libgo/Makefile.am95
-rw-r--r--libgo/Makefile.in58
-rw-r--r--libgo/syscalls/errstr.go5
-rw-r--r--libgo/syscalls/errstr_rtems.go5
-rw-r--r--libgo/syscalls/sleep_rtems.go17
-rw-r--r--libgo/syscalls/sleep_select.go13
-rw-r--r--libgo/syscalls/socket.go89
-rw-r--r--libgo/syscalls/socket_bsd.go123
-rw-r--r--libgo/syscalls/socket_linux.go129
-rw-r--r--libgo/syscalls/socket_solaris.go76
-rw-r--r--libgo/syscalls/syscall_solaris_386.go2
-rw-r--r--libgo/syscalls/syscall_solaris_amd64.go2
-rw-r--r--libgo/syscalls/syscall_unix.go5
-rw-r--r--libgo/syscalls/sysfile_largefile.go13
-rw-r--r--libgo/syscalls/sysfile_linux.go38
-rw-r--r--libgo/syscalls/sysfile_posix.go6
-rw-r--r--libgo/syscalls/sysfile_regfile.go13
-rw-r--r--libgo/syscalls/sysfile_rtems.go34
18 files changed, 413 insertions, 310 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 46b5924..e2d2158 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -596,10 +596,17 @@ go_mime_files = \
if LIBGO_IS_RTEMS
go_net_fd_os_file = go/net/fd_rtems.go
go_net_newpollserver_file = go/net/newpollserver_rtems.go
-else
+else # !LIBGO_IS_RTEMS
+if LIBGO_IS_LINUX
go_net_fd_os_file = go/net/fd_linux.go
go_net_newpollserver_file = go/net/newpollserver.go
-endif
+else # !LIBGO_IS_LINUX && !LIBGO_IS_RTEMS
+# By default use select with pipes. Most systems should have
+# something better.
+go_net_fd_os_file = go/net/fd_rtems.go
+go_net_newpollserver_file = go/net/newpollserver.go
+endif # !LIBGO_IS_LINUX
+endif # !LIBGO_IS_RTEMS
go_net_files = \
go/net/dial.go \
@@ -1019,33 +1026,92 @@ go_testing_quick_files = \
go_testing_script_files = \
go/testing/script/script.go
+# Define Syscall and Syscall6.
if LIBGO_IS_RTEMS
-syscall_exec_os_file = syscalls/exec_stubs.go
-syscall_socket_os_file = syscalls/socket_bsd.go
-syscall_socket_epoll_file =
-syscall_sysfile_os_file = syscalls/sysfile_rtems.go
syscall_syscall_file = syscalls/syscall_stubs.go
-syscall_errstr_file = syscalls/errstr_rtems.go
-syscall_errstr_decl_file = syscalls/errstr_decl_rtems.go
else
-syscall_exec_os_file = syscalls/exec.go
-syscall_socket_os_file = syscalls/socket_linux.go
-syscall_socket_epoll_file = syscalls/socket_epoll.go
-syscall_sysfile_os_file = syscalls/sysfile_linux.go
syscall_syscall_file = syscalls/syscall.go
+endif
+
+# Declare libc functions that vary for largefile systems.
+if LIBGO_IS_LINUX
+# Always use lseek64 on GNU/Linux.
+syscall_filesize_file = syscalls/sysfile_largefile.go
+else # !LIBGO_IS_LINUX
+if LIBGO_IS_SOLARIS
+if LIBGO_IS_386
+# Use lseek64 on 386 Solaris.
+syscall_filesize_flie = syscalls/sysfile_largefile.go
+else # !LIBGO_IS_LINUX && LIBGO_IS_SOLARIS && !LIBGO_IS_386
+# Use lseek on amd64 Solaris.
+syscall_filesize_flie = syscalls/sysfile_regfile.go
+endif # !LIBGO_IS_386
+else # !LIBGO_IS_LINUX && !LIBGO_IS_SOLARIS
+# Use lseek by default.
+syscall_filesize_file = syscalls/sysfile_regfile.go
+endif # !LIBGO_IS_SOLARIS
+endif # !LIBGO_IS_LINUX
+
+
+# Define ForkExec, PtraceForkExec, Exec, and Wait4.
+if LIBGO_IS_RTEMS
+syscall_exec_os_file = syscalls/exec_stubs.go
+else
+syscall_exec_os_file = syscalls/exec.go
+endif
+
+# Define Sleep.
+if LIBGO_IS_RTEMS
+syscall_sleep_file = syscalls/sleep_rtems.go
+else
+syscall_sleep_file = syscalls/sleep_select.go
+endif
+
+# Define Errstr.
+if LIBGO_IS_RTEMS
+syscall_errstr_file = syscalls/errstr_rtems.go
+else
syscall_errstr_file = syscalls/errstr.go
+endif
+
+# Declare libc_strerror_r which is the Go name for strerror_r.
+if LIBGO_IS_RTEMS
+# RTEMS uses newlib in which strerror_r returns char *.
+syscall_errstr_decl_file = syscalls/errstr_decl_rtems.go
+else
if LIBGO_IS_LINUX
+# In Linux the POSIX strerror_r is called __xpg_strerror_r.
syscall_errstr_decl_file = syscalls/errstr_decl_linux.go
else
+# On other systems we hope strerror_r is just strerror_r.
syscall_errstr_decl_file = syscalls/errstr_decl.go
endif
endif
+# Define socket sizes and types.
+if LIBGO_IS_LINUX
+syscall_socket_os_file = syscalls/socket_linux.go
+else
+if LIBGO_IS_SOLARIS
+syscall_socket_os_file = syscalls/socket_solaris.go
+else
+syscall_socket_os_file = syscalls_socket_bsd.go
+endif
+endif
+
+# Support for epoll.
+if LIBGO_IS_LINUX
+syscall_socket_epoll_file = syscalls/socket_epoll.go
+else
+syscall_socket_epoll_file =
+endif
+
syscall_arch.go: s-syscall_arch; @true
s-syscall_arch: Makefile
rm -f syscall_arch.go.tmp
echo "package syscall" > syscall_arch.go.tmp
echo 'const ARCH = "'$(GOARCH)'"' >> syscall_arch.go.tmp
+ echo 'const OS = "'$(GOOS)'"' >> syscall_arch.go.tmp
$(SHELL) $(srcdir)/../move-if-change syscall_arch.go.tmp syscall_arch.go
$(STAMP) $@
@@ -1054,6 +1120,8 @@ go_syscall_files = \
$(syscall_errstr_decl_file) \
syscalls/exec_helpers.go \
$(syscall_exec_os_file) \
+ $(syscall_filesize_file) \
+ $(syscall_sleep_file) \
syscalls/socket.go \
$(syscall_socket_os_file) \
$(syscall_socket_epoll_file) \
@@ -1063,7 +1131,6 @@ go_syscall_files = \
syscalls/syscall_$(GOOS).go \
syscalls/syscall_$(GOOS)_$(GOARCH).go \
syscalls/sysfile_posix.go \
- $(syscall_sysfile_os_file) \
sysinfo.go \
syscall_arch.go
go_syscall_c_files = \
@@ -2232,7 +2299,7 @@ testing/script/check: $(CHECK_DEPS)
.PHONY: testing/script/check
sysinfo.go: $(srcdir)/mksysinfo.sh config.h
- $(SHELL) $(srcdir)/mksysinfo.sh
+ CC="$(CC)" $(SHELL) $(srcdir)/mksysinfo.sh
syscalls/libsyscall.a: $(go_syscall_files) $(go_syscall_c_files) sync.gox
rm -f syscall.gox syscalls/libsyscall.a
test -d syscalls || $(MKDIR_P) syscalls
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index e54fad2..1b8fd5a 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -938,9 +938,13 @@ go_mime_files = \
go/mime/mediatype.go \
go/mime/type.go
-@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file = go/net/fd_linux.go
+# By default use select with pipes. Most systems should have
+# something better.
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file = go/net/fd_rtems.go
+@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file = go/net/fd_linux.go
@LIBGO_IS_RTEMS_TRUE@go_net_fd_os_file = go/net/fd_rtems.go
-@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file = go/net/newpollserver.go
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file = go/net/newpollserver.go
+@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file = go/net/newpollserver.go
@LIBGO_IS_RTEMS_TRUE@go_net_newpollserver_file = go/net/newpollserver_rtems.go
go_net_files = \
go/net/dial.go \
@@ -1389,26 +1393,56 @@ go_testing_quick_files = \
go_testing_script_files = \
go/testing/script/script.go
-@LIBGO_IS_RTEMS_FALSE@syscall_exec_os_file = syscalls/exec.go
-@LIBGO_IS_RTEMS_TRUE@syscall_exec_os_file = syscalls/exec_stubs.go
-@LIBGO_IS_RTEMS_FALSE@syscall_socket_os_file = syscalls/socket_linux.go
-@LIBGO_IS_RTEMS_TRUE@syscall_socket_os_file = syscalls/socket_bsd.go
-@LIBGO_IS_RTEMS_FALSE@syscall_socket_epoll_file = syscalls/socket_epoll.go
-@LIBGO_IS_RTEMS_TRUE@syscall_socket_epoll_file =
-@LIBGO_IS_RTEMS_FALSE@syscall_sysfile_os_file = syscalls/sysfile_linux.go
-@LIBGO_IS_RTEMS_TRUE@syscall_sysfile_os_file = syscalls/sysfile_rtems.go
@LIBGO_IS_RTEMS_FALSE@syscall_syscall_file = syscalls/syscall.go
+
+# Define Syscall and Syscall6.
@LIBGO_IS_RTEMS_TRUE@syscall_syscall_file = syscalls/syscall_stubs.go
+# Use lseek by default.
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@syscall_filesize_file = syscalls/sysfile_regfile.go
+
+# Declare libc functions that vary for largefile systems.
+# Always use lseek64 on GNU/Linux.
+@LIBGO_IS_LINUX_TRUE@syscall_filesize_file = syscalls/sysfile_largefile.go
+# Use lseek on amd64 Solaris.
+@LIBGO_IS_386_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@syscall_filesize_flie = syscalls/sysfile_regfile.go
+# Use lseek64 on 386 Solaris.
+@LIBGO_IS_386_TRUE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@syscall_filesize_flie = syscalls/sysfile_largefile.go
+@LIBGO_IS_RTEMS_FALSE@syscall_exec_os_file = syscalls/exec.go
+
+# Define ForkExec, PtraceForkExec, Exec, and Wait4.
+@LIBGO_IS_RTEMS_TRUE@syscall_exec_os_file = syscalls/exec_stubs.go
+@LIBGO_IS_RTEMS_FALSE@syscall_sleep_file = syscalls/sleep_select.go
+
+# Define Sleep.
+@LIBGO_IS_RTEMS_TRUE@syscall_sleep_file = syscalls/sleep_rtems.go
@LIBGO_IS_RTEMS_FALSE@syscall_errstr_file = syscalls/errstr.go
+
+# Define Errstr.
@LIBGO_IS_RTEMS_TRUE@syscall_errstr_file = syscalls/errstr_rtems.go
+# On other systems we hope strerror_r is just strerror_r.
@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_RTEMS_FALSE@syscall_errstr_decl_file = syscalls/errstr_decl.go
+# In Linux the POSIX strerror_r is called __xpg_strerror_r.
@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_RTEMS_FALSE@syscall_errstr_decl_file = syscalls/errstr_decl_linux.go
+
+# Declare libc_strerror_r which is the Go name for strerror_r.
+# RTEMS uses newlib in which strerror_r returns char *.
@LIBGO_IS_RTEMS_TRUE@syscall_errstr_decl_file = syscalls/errstr_decl_rtems.go
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@syscall_socket_os_file = syscalls_socket_bsd.go
+@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@syscall_socket_os_file = syscalls/socket_solaris.go
+
+# Define socket sizes and types.
+@LIBGO_IS_LINUX_TRUE@syscall_socket_os_file = syscalls/socket_linux.go
+@LIBGO_IS_LINUX_FALSE@syscall_socket_epoll_file =
+
+# Support for epoll.
+@LIBGO_IS_LINUX_TRUE@syscall_socket_epoll_file = syscalls/socket_epoll.go
go_syscall_files = \
$(syscall_errstr_file) \
$(syscall_errstr_decl_file) \
syscalls/exec_helpers.go \
$(syscall_exec_os_file) \
+ $(syscall_filesize_file) \
+ $(syscall_sleep_file) \
syscalls/socket.go \
$(syscall_socket_os_file) \
$(syscall_socket_epoll_file) \
@@ -1418,7 +1452,6 @@ go_syscall_files = \
syscalls/syscall_$(GOOS).go \
syscalls/syscall_$(GOOS)_$(GOARCH).go \
syscalls/sysfile_posix.go \
- $(syscall_sysfile_os_file) \
sysinfo.go \
syscall_arch.go
@@ -3608,6 +3641,7 @@ s-syscall_arch: Makefile
rm -f syscall_arch.go.tmp
echo "package syscall" > syscall_arch.go.tmp
echo 'const ARCH = "'$(GOARCH)'"' >> syscall_arch.go.tmp
+ echo 'const OS = "'$(GOOS)'"' >> syscall_arch.go.tmp
$(SHELL) $(srcdir)/../move-if-change syscall_arch.go.tmp syscall_arch.go
$(STAMP) $@
@@ -4578,7 +4612,7 @@ testing/script/check: $(CHECK_DEPS)
.PHONY: testing/script/check
sysinfo.go: $(srcdir)/mksysinfo.sh config.h
- $(SHELL) $(srcdir)/mksysinfo.sh
+ CC="$(CC)" $(SHELL) $(srcdir)/mksysinfo.sh
syscalls/libsyscall.a: $(go_syscall_files) $(go_syscall_c_files) sync.gox
rm -f syscall.gox syscalls/libsyscall.a
test -d syscalls || $(MKDIR_P) syscalls
diff --git a/libgo/syscalls/errstr.go b/libgo/syscalls/errstr.go
index 961df40..a95abc6 100644
--- a/libgo/syscalls/errstr.go
+++ b/libgo/syscalls/errstr.go
@@ -6,11 +6,6 @@
package syscall
-const ENONE = 0
-
-func GetErrno() int
-func SetErrno(int)
-
func Errstr(errno int) string {
for len := Size_t(128); ; len *= 2 {
b := make([]byte, len)
diff --git a/libgo/syscalls/errstr_rtems.go b/libgo/syscalls/errstr_rtems.go
index b933360..f6b453b 100644
--- a/libgo/syscalls/errstr_rtems.go
+++ b/libgo/syscalls/errstr_rtems.go
@@ -6,11 +6,6 @@
package syscall
-const ENONE = 0
-
-func GetErrno() int
-func SetErrno(int)
-
func Errstr(errno int) string {
for len := Size_t(128); ; len *= 2 {
b := make([]byte, len+1)
diff --git a/libgo/syscalls/sleep_rtems.go b/libgo/syscalls/sleep_rtems.go
new file mode 100644
index 0000000..443e850
--- /dev/null
+++ b/libgo/syscalls/sleep_rtems.go
@@ -0,0 +1,17 @@
+// 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.
+
+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/libgo/syscalls/sleep_select.go b/libgo/syscalls/sleep_select.go
new file mode 100644
index 0000000..6fc13a0
--- /dev/null
+++ b/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/libgo/syscalls/socket.go b/libgo/syscalls/socket.go
index 5550800..bc3ce69 100644
--- a/libgo/syscalls/socket.go
+++ b/libgo/syscalls/socket.go
@@ -12,10 +12,6 @@ package syscall
import "unsafe"
-const SizeofSockaddrInet4 = 16
-const SizeofSockaddrInet6 = 28
-const SizeofSockaddrUnix = 110
-
type RawSockaddrAny struct {
Addr RawSockaddr;
Pad [12]int8;
@@ -53,6 +49,91 @@ type Linger struct {
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");
diff --git a/libgo/syscalls/socket_bsd.go b/libgo/syscalls/socket_bsd.go
index eaf20f9..c46e24e 100644
--- a/libgo/syscalls/socket_bsd.go
+++ b/libgo/syscalls/socket_bsd.go
@@ -4,13 +4,11 @@
// 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"
+const SizeofSockaddrInet4 = 16
+const SizeofSockaddrInet6 = 28
+const SizeofSockaddrUnix = 110
type RawSockaddrInet4 struct {
Len uint8;
@@ -20,6 +18,11 @@ type RawSockaddrInet4 struct {
Zero [8]uint8;
}
+func (sa *RawSockaddrInet4) setLen() Socklen_t {
+ sa.Len = SizeofSockaddrInet4
+ return SizeofSockaddrInet4
+}
+
type RawSockaddrInet6 struct {
Len uint8;
Family uint8;
@@ -29,108 +32,40 @@ type RawSockaddrInet6 struct {
Scope_id uint32;
}
-type RawSockaddrUnix struct {
- Len uint8;
- Family uint8;
- Path [108]int8;
+func (sa *RawSockaddrInet6) setLen() Socklen_t {
+ sa.raw.Len = SizeofSockaddrInet6
+ return SizeofSockaddrInet6
}
-type RawSockaddr struct {
+type RawSockaddrUnix struct {
Len uint8;
Family uint8;
- Data [14]int8;
+ Path [108]int8;
}
-func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL;
- }
- sa.raw.Len = SizeofSockaddrInet4;
- sa.raw.Family = AF_INET;
- 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)), Socklen_t(sa.raw.Len), 0;
+func (sa *RawsockaddrUnix) setLen(n int) {
+ sa.Len = uint8(3 + n) // 2 for Family, Len; 1 for NUL.
}
-func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL;
- }
- sa.raw.Len = SizeofSockaddrInet6;
- sa.raw.Family = AF_INET6;
- 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];
+func (sa *RawsockaddrUnix) getLen() (int, int) {
+ if sa.Len < 3 || sa.Len > SizeofSockaddrUnix {
+ return 0, EINVAL
}
- return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 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.Len = byte(3 + n); // 2 for Family, Len; 1 for NUL.
- sa.raw.Family = AF_UNIX;
+ n := int(sa.Len) - 3 // subtract leading Family, Len, terminating NUL.
for i := 0; i < n; i++ {
- sa.raw.Path[i] = int8(name[i]);
- }
- if sa.raw.Path[0] == '@' {
- sa.raw.Path[0] = 0;
+ if sa.Path[i] == 0 {
+ // found early NUL; assume Len is overestimating.
+ n = i
+ break
+ }
}
-
- // length is family, name, NUL.
- return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 0;
+ return n, 0
}
-func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
- switch rsa.Addr.Family {
- case AF_UNIX:
- pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
- if pp.Len < 3 || pp.Len > SizeofSockaddrUnix {
- return nil, EINVAL
- }
- sa := new(SockaddrUnix)
- n := int(pp.Len) - 3 // subtract leading Family, Len, terminating NUL.
- for i := 0; i < n; i++ {
- if pp.Path[i] == 0 {
- // found early NUL; assume Len is overestimating.
- n = i
- break
- }
- }
- 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;
+type RawSockaddr struct {
+ Len uint8;
+ Family uint8;
+ Data [14]int8;
}
// BindToDevice binds the socket associated with fd to device.
diff --git a/libgo/syscalls/socket_linux.go b/libgo/syscalls/socket_linux.go
index bc196a2..cdcdf4f 100644
--- a/libgo/syscalls/socket_linux.go
+++ b/libgo/syscalls/socket_linux.go
@@ -4,14 +4,11 @@
// 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"
+const SizeofSockaddrInet4 = 16
+const SizeofSockaddrInet6 = 28
+const SizeofSockaddrUnix = 110
type RawSockaddrInet4 struct {
Family uint16;
@@ -20,6 +17,10 @@ type RawSockaddrInet4 struct {
Zero [8]uint8;
}
+func (sa *RawSockaddrInet4) setLen() Socklen_t {
+ return SizeofSockaddrInet4
+}
+
type RawSockaddrInet6 struct {
Family uint16;
Port uint16;
@@ -28,110 +29,44 @@ type RawSockaddrInet6 struct {
Scope_id uint32;
}
-type RawSockaddrUnix struct {
- Family uint16;
- Path [108]int8;
+func (sa *RawSockaddrInet6) setLen() Socklen_t {
+ return SizeofSockaddrInet6
}
-type RawSockaddr struct {
+type RawSockaddrUnix struct {
Family uint16;
- Data [14]int8;
+ Path [108]int8;
}
-func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL;
- }
- sa.raw.Family = AF_INET;
- 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)), SizeofSockaddrInet4, 0;
+func (sa *RawSockaddrUnix) setLen(int) {
}
-func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, int) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL;
- }
- sa.raw.Family = AF_INET6;
- 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];
+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] = '@';
}
- return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6, 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;
- for i := 0; i < n; i++ {
- sa.raw.Path[i] = int8(name[i]);
- }
- if sa.raw.Path[0] == '@' {
- sa.raw.Path[0] = 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++;
}
- // length is family, name, NUL.
- return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), 1 + Socklen_t(n) + 1, 0;
+ return n, 0
}
-func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
- switch rsa.Addr.Family {
- case AF_UNIX:
- pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa));
- sa := new(SockaddrUnix);
- if pp.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.
- pp.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(pp.Path) - 3 && pp.Path[n] != 0 {
- n++;
- }
- 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;
+type RawSockaddr struct {
+ Family uint16;
+ Data [14]int8;
}
// BindToDevice binds the socket associated with fd to device.
diff --git a/libgo/syscalls/socket_solaris.go b/libgo/syscalls/socket_solaris.go
new file mode 100644
index 0000000..13fe727
--- /dev/null
+++ b/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/libgo/syscalls/syscall_solaris_386.go b/libgo/syscalls/syscall_solaris_386.go
index 20e8b5d..687722d 100644
--- a/libgo/syscalls/syscall_solaris_386.go
+++ b/libgo/syscalls/syscall_solaris_386.go
@@ -8,8 +8,6 @@ package syscall
import "unsafe"
-const ARCH = "386"
-
// 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")
diff --git a/libgo/syscalls/syscall_solaris_amd64.go b/libgo/syscalls/syscall_solaris_amd64.go
index 628e781..f68b596 100644
--- a/libgo/syscalls/syscall_solaris_amd64.go
+++ b/libgo/syscalls/syscall_solaris_amd64.go
@@ -8,8 +8,6 @@ package syscall
import "unsafe"
-const ARCH = "amd64"
-
// 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")
diff --git a/libgo/syscalls/syscall_unix.go b/libgo/syscalls/syscall_unix.go
index 3e9d293..408d0b8 100644
--- a/libgo/syscalls/syscall_unix.go
+++ b/libgo/syscalls/syscall_unix.go
@@ -10,6 +10,11 @@ var (
Stderr = 2
)
+const ENONE = 0
+
+func GetErrno() int
+func SetErrno(int)
+
func libc_uname(buf *Utsname) (errno int) __asm__("uname")
func Uname(buf *Utsname) (errno int) {
diff --git a/libgo/syscalls/sysfile_largefile.go b/libgo/syscalls/sysfile_largefile.go
new file mode 100644
index 0000000..963a624
--- /dev/null
+++ b/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/libgo/syscalls/sysfile_linux.go b/libgo/syscalls/sysfile_linux.go
deleted file mode 100644
index 3e77e90..0000000
--- a/libgo/syscalls/sysfile_linux.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// sysfile_linux.go -- Linux specific 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
-
-const OS = "linux"
-
-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_lseek64(int, Offset_t, int) Offset_t __asm__ ("lseek64")
-func libc_truncate64(path *byte, length Offset_t) int __asm__ ("truncate64")
-func libc_ftruncate64(fd int, length Offset_t) int __asm__ ("ftruncate64")
-func libc_setgroups(size Size_t, list *Gid_t) int __asm__ ("setgroups")
-
-func Sleep(nsec int64) (errno int) {
- tv := NsecToTimeval(nsec);
- n, err := Select(0, nil, nil, nil, &tv);
- return err;
-}
-
-func Setgroups(gids []int) (errno int) {
- if len(gids) == 0 {
- return libc_setgroups(0, nil);
- }
-
- a := make([]Gid_t, len(gids));
- for i, v := range gids {
- a[i] = Gid_t(v);
- }
- return libc_setgroups(Size_t(len(a)), &a[0]);
-}
diff --git a/libgo/syscalls/sysfile_posix.go b/libgo/syscalls/sysfile_posix.go
index 4e44c5b..1458bf5 100644
--- a/libgo/syscalls/sysfile_posix.go
+++ b/libgo/syscalls/sysfile_posix.go
@@ -106,7 +106,7 @@ func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
}
func Seek(fd int, offset int64, whence int) (off int64, errno int) {
- r := libc_lseek64(fd, Offset_t(offset), whence);
+ r := libc_lseek(fd, Offset_t(offset), whence);
if r == -1 { errno = GetErrno() }
off = int64(r);
return;
@@ -300,13 +300,13 @@ func Fchown(fd int, uid int, gid int) (errno int) {
}
func Truncate(path string, length int64) (errno int) {
- r := libc_truncate64(StringBytePtr(path), Offset_t(length));
+ r := libc_truncate(StringBytePtr(path), Offset_t(length));
if r < 0 { errno = GetErrno() }
return;
}
func Ftruncate(fd int, length int64) (errno int) {
- r := libc_ftruncate64(fd, Offset_t(length));
+ r := libc_ftruncate(fd, Offset_t(length));
if r < 0 { errno = GetErrno() }
return;
}
diff --git a/libgo/syscalls/sysfile_regfile.go b/libgo/syscalls/sysfile_regfile.go
new file mode 100644
index 0000000..731c59c
--- /dev/null
+++ b/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/libgo/syscalls/sysfile_rtems.go b/libgo/syscalls/sysfile_rtems.go
deleted file mode 100644
index 3768b6d..0000000
--- a/libgo/syscalls/sysfile_rtems.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// sysfile_rtems.go -- RTEMS specific 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
-
-const (
- OS = "rtems"
- // No support for async I/O in RTEMS.
- O_ASYNC = 0
-)
-
-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_lseek64(int, Offset_t, int) Offset_t __asm__ ("lseek")
-func libc_truncate64(path *byte, length Offset_t) int __asm__ ("truncate")
-func libc_ftruncate64(fd int, length Offset_t) int __asm__ ("ftruncate")
-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
-}