diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-13 05:17:52 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-13 05:17:52 +0000 |
commit | 6b376419aef89630087058acc26f60def53be7b4 (patch) | |
tree | e9602dee09986866e66e3bee32d69f8c5d57bf78 /libgo | |
parent | 36bedd942f1671e50882209288415199fc3b3261 (diff) | |
download | gcc-6b376419aef89630087058acc26f60def53be7b4.tar.gz |
Clean up syscalls, add some Solaris support.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168738 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/Makefile.am | 95 | ||||
-rw-r--r-- | libgo/Makefile.in | 58 | ||||
-rw-r--r-- | libgo/syscalls/errstr.go | 5 | ||||
-rw-r--r-- | libgo/syscalls/errstr_rtems.go | 5 | ||||
-rw-r--r-- | libgo/syscalls/sleep_rtems.go | 17 | ||||
-rw-r--r-- | libgo/syscalls/sleep_select.go | 13 | ||||
-rw-r--r-- | libgo/syscalls/socket.go | 89 | ||||
-rw-r--r-- | libgo/syscalls/socket_bsd.go | 123 | ||||
-rw-r--r-- | libgo/syscalls/socket_linux.go | 129 | ||||
-rw-r--r-- | libgo/syscalls/socket_solaris.go | 76 | ||||
-rw-r--r-- | libgo/syscalls/syscall_solaris_386.go | 2 | ||||
-rw-r--r-- | libgo/syscalls/syscall_solaris_amd64.go | 2 | ||||
-rw-r--r-- | libgo/syscalls/syscall_unix.go | 5 | ||||
-rw-r--r-- | libgo/syscalls/sysfile_largefile.go | 13 | ||||
-rw-r--r-- | libgo/syscalls/sysfile_linux.go | 38 | ||||
-rw-r--r-- | libgo/syscalls/sysfile_posix.go | 6 | ||||
-rw-r--r-- | libgo/syscalls/sysfile_regfile.go | 13 | ||||
-rw-r--r-- | libgo/syscalls/sysfile_rtems.go | 34 |
18 files changed, 413 insertions, 310 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 46b592460f6..e2d2158a8c8 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 e54fad22ae7..1b8fd5a2429 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 961df407549..a95abc686f3 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 b9333608c5b..f6b453bdc73 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 00000000000..443e8508edc --- /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 00000000000..6fc13a0ea5e --- /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 5550800d513..bc3ce694f2c 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 eaf20f9edf0..c46e24e8f56 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 bc196a2ffc6..cdcdf4ff28b 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 00000000000..13fe727c33e --- /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 20e8b5db0bc..687722ddc1d 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 628e781ba3c..f68b596c38b 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 3e9d293d9be..408d0b8b7aa 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 00000000000..963a624bd88 --- /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 3e77e900caf..00000000000 --- 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 4e44c5b959c..1458bf56097 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 00000000000..731c59c97b0 --- /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 3768b6d44a9..00000000000 --- 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 -} |