From patchwork Thu Jan 13 05:17:54 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: libgo patch committed: Clean up syscalls, add some Solaris support Date: Wed, 12 Jan 2011 19:17:54 -0000 From: Ian Taylor X-Patchwork-Id: 78656 Message-Id: To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Cc: Rainer Orth This patch, partly due to Rainer Orth, cleans up the libgo syscalls directory a bit to remove some redundancy, and adds Solaris support. Bootstrapped and ran libgo testsuite on x86_64-unknown-linux-gnu in both 32-bit and 64-bit mode. Committed to mainline. Ian diff -r 169c58c802a1 libgo/Makefile.am --- a/libgo/Makefile.am Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/Makefile.am Wed Jan 12 18:09:18 2011 -0800 @@ -596,10 +596,17 @@ 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_script_files = \ go/testing/script/script.go +# Define Syscall and Syscall6. +if LIBGO_IS_RTEMS +syscall_syscall_file = syscalls/syscall_stubs.go +else +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 -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 +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 -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 -syscall_errstr_file = syscalls/errstr.go 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 @@ $(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 @@ 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 @@ .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 -r 169c58c802a1 libgo/syscalls/errstr.go --- a/libgo/syscalls/errstr.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/errstr.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 -r 169c58c802a1 libgo/syscalls/errstr_rtems.go --- a/libgo/syscalls/errstr_rtems.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/errstr_rtems.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 -r 169c58c802a1 libgo/syscalls/sleep_rtems.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgo/syscalls/sleep_rtems.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 -r 169c58c802a1 libgo/syscalls/sleep_select.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgo/syscalls/sleep_select.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 -r 169c58c802a1 libgo/syscalls/socket.go --- a/libgo/syscalls/socket.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/socket.go Wed Jan 12 18:09:18 2011 -0800 @@ -12,10 +12,6 @@ import "unsafe" -const SizeofSockaddrInet4 = 16 -const SizeofSockaddrInet6 = 28 -const SizeofSockaddrUnix = 110 - type RawSockaddrAny struct { Addr RawSockaddr; Pad [12]int8; @@ -53,6 +49,91 @@ 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 -r 169c58c802a1 libgo/syscalls/socket_bsd.go --- a/libgo/syscalls/socket_bsd.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/socket_bsd.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 @@ Zero [8]uint8; } +func (sa *RawSockaddrInet4) setLen() Socklen_t { + sa.Len = SizeofSockaddrInet4 + return SizeofSockaddrInet4 +} + type RawSockaddrInet6 struct { Len uint8; Family uint8; @@ -29,110 +32,42 @@ Scope_id uint32; } +func (sa *RawSockaddrInet6) setLen() Socklen_t { + sa.raw.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; } -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 *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]; - } - 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; - 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, name, NUL. - return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), Socklen_t(sa.raw.Len), 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; -} - // BindToDevice binds the socket associated with fd to device. func BindToDevice(fd int, device string) (errno int) { return ENOSYS diff -r 169c58c802a1 libgo/syscalls/socket_linux.go --- a/libgo/syscalls/socket_linux.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/socket_linux.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 @@ Zero [8]uint8; } +func (sa *RawSockaddrInet4) setLen() Socklen_t { + return SizeofSockaddrInet4 +} + type RawSockaddrInet6 struct { Family uint16; Port uint16; @@ -28,112 +29,46 @@ 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; } -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 *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]; - } - 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; - } - - // length is family, name, NUL. - return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), 1 + 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); - 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; -} - // 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 -r 169c58c802a1 libgo/syscalls/socket_solaris.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgo/syscalls/socket_solaris.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 -r 169c58c802a1 libgo/syscalls/syscall_solaris_386.go --- a/libgo/syscalls/syscall_solaris_386.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/syscall_solaris_386.go Wed Jan 12 18:09:18 2011 -0800 @@ -8,8 +8,6 @@ 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 -r 169c58c802a1 libgo/syscalls/syscall_solaris_amd64.go --- a/libgo/syscalls/syscall_solaris_amd64.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/syscall_solaris_amd64.go Wed Jan 12 18:09:18 2011 -0800 @@ -8,8 +8,6 @@ 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 -r 169c58c802a1 libgo/syscalls/syscall_unix.go --- a/libgo/syscalls/syscall_unix.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/syscall_unix.go Wed Jan 12 18:09:18 2011 -0800 @@ -10,6 +10,11 @@ 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 -r 169c58c802a1 libgo/syscalls/sysfile_largefile.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgo/syscalls/sysfile_largefile.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 -r 169c58c802a1 libgo/syscalls/sysfile_linux.go --- a/libgo/syscalls/sysfile_linux.go Wed Jan 12 15:04:36 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 -r 169c58c802a1 libgo/syscalls/sysfile_posix.go --- a/libgo/syscalls/sysfile_posix.go Wed Jan 12 15:04:36 2011 -0800 +++ b/libgo/syscalls/sysfile_posix.go Wed Jan 12 18:09:18 2011 -0800 @@ -106,7 +106,7 @@ } 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 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 -r 169c58c802a1 libgo/syscalls/sysfile_regfile.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgo/syscalls/sysfile_regfile.go Wed Jan 12 18:09:18 2011 -0800 @@ -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 -r 169c58c802a1 libgo/syscalls/sysfile_rtems.go --- a/libgo/syscalls/sysfile_rtems.go Wed Jan 12 15:04:36 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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 -}