aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/syscall
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-01-29 20:52:43 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-01-29 20:52:43 +0000
commitd6f2922e91928b5191a5c5f1b3a6b320712b5ce3 (patch)
tree4f2fad1f4b778519bdd5941185c7e1d032af055b /libgo/go/syscall
parent91bfca59095b1cca9d4364996866848eaaf76c26 (diff)
downloadgcc-d6f2922e91928b5191a5c5f1b3a6b320712b5ce3.zip
gcc-d6f2922e91928b5191a5c5f1b3a6b320712b5ce3.tar.gz
gcc-d6f2922e91928b5191a5c5f1b3a6b320712b5ce3.tar.bz2
libgo: Update Go library to master revision 15489/921e53d4863c.
From-SVN: r195560
Diffstat (limited to 'libgo/go/syscall')
-rw-r--r--libgo/go/syscall/exec_bsd.go14
-rw-r--r--libgo/go/syscall/exec_linux.go17
-rw-r--r--libgo/go/syscall/exec_unix.go8
-rw-r--r--libgo/go/syscall/libcall_linux.go31
-rw-r--r--libgo/go/syscall/netlink_linux.go170
-rw-r--r--libgo/go/syscall/sockcmsg_linux.go26
-rw-r--r--libgo/go/syscall/sockcmsg_unix.go76
7 files changed, 174 insertions, 168 deletions
diff --git a/libgo/go/syscall/exec_bsd.go b/libgo/go/syscall/exec_bsd.go
index f1f7a18..c8eed53 100644
--- a/libgo/go/syscall/exec_bsd.go
+++ b/libgo/go/syscall/exec_bsd.go
@@ -223,3 +223,17 @@ childerror:
// and this shuts up the compiler.
panic("unreached")
}
+
+// Try to open a pipe with O_CLOEXEC set on both file descriptors.
+func forkExecPipe(p []int) error {
+ err := Pipe(p)
+ if err != nil {
+ return err
+ }
+ _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC)
+ if err != nil {
+ return err
+ }
+ _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
+ return err
+}
diff --git a/libgo/go/syscall/exec_linux.go b/libgo/go/syscall/exec_linux.go
index 75c61f0..e29878a 100644
--- a/libgo/go/syscall/exec_linux.go
+++ b/libgo/go/syscall/exec_linux.go
@@ -250,3 +250,20 @@ childerror:
// and this shuts up the compiler.
panic("unreached")
}
+
+// Try to open a pipe with O_CLOEXEC set on both file descriptors.
+func forkExecPipe(p []int) (err error) {
+ err = Pipe2(p, O_CLOEXEC)
+ // pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
+ // might not be implemented.
+ if err == ENOSYS {
+ if err = Pipe(p); err != nil {
+ return
+ }
+ if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
+ return
+ }
+ _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
+ }
+ return
+}
diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go
index e51878e..d4aa959 100644
--- a/libgo/go/syscall/exec_unix.go
+++ b/libgo/go/syscall/exec_unix.go
@@ -219,13 +219,7 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
ForkLock.Lock()
// Allocate child status pipe close on exec.
- if err = Pipe(p[0:]); err != nil {
- goto error
- }
- if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
- goto error
- }
- if _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC); err != nil {
+ if err = forkExecPipe(p[:]); err != nil {
goto error
}
diff --git a/libgo/go/syscall/libcall_linux.go b/libgo/go/syscall/libcall_linux.go
index 482a23f..7d780e6 100644
--- a/libgo/go/syscall/libcall_linux.go
+++ b/libgo/go/syscall/libcall_linux.go
@@ -166,6 +166,24 @@ func Reboot(cmd int) (err error) {
return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
}
+//sys accept4(fd int, sa *RawSockaddrAny, len *Socklen_t, flags int) (nfd int, err error)
+//accept4(fd _C_int, sa *RawSockaddrAny, len *Socklen_t, flags _C_int) _C_int
+
+func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ var len Socklen_t = SizeofSockaddrAny
+ nfd, err = accept4(fd, &rsa, &len, flags)
+ if err != nil {
+ return -1, nil, err
+ }
+ sa, err = anyToSockaddr(&rsa)
+ if err != nil {
+ Close(nfd)
+ return -1, nil, err
+ }
+ return nfd, sa, nil
+}
+
//sys Acct(path string) (err error)
//acct(path *byte) int
@@ -271,6 +289,19 @@ func ParseDirent(buf []byte, max int, names []string) (consumed int, count int,
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//mknodat(dirfd int, path *byte, mode Mode_t, dev _dev_t) int
+//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//pipe2(p *[2]_C_int, flags _C_int) _C_int
+func Pipe2(p []int, flags int) (err error) {
+ if len(p) != 2 {
+ return EINVAL
+ }
+ var pp [2]_C_int
+ err = pipe2(&pp, flags)
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ return
+}
+
//sys PivotRoot(newroot string, putold string) (err error)
//pivot_root(newroot *byte, putold *byte) int
diff --git a/libgo/go/syscall/netlink_linux.go b/libgo/go/syscall/netlink_linux.go
index d535713..49550ea 100644
--- a/libgo/go/syscall/netlink_linux.go
+++ b/libgo/go/syscall/netlink_linux.go
@@ -6,9 +6,7 @@
package syscall
-import (
- "unsafe"
-)
+import "unsafe"
// Round the length of a netlink message up to align it properly.
func nlmAlignOf(msglen int) int {
@@ -21,8 +19,8 @@ func rtaAlignOf(attrlen int) int {
return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
}
-// NetlinkRouteRequest represents the request message to receive
-// routing and link states from the kernel.
+// NetlinkRouteRequest represents a request message to receive routing
+// and link states from the kernel.
type NetlinkRouteRequest struct {
Header NlMsghdr
Data RtGenmsg
@@ -49,167 +47,131 @@ func newNetlinkRouteRequest(proto, seq, family int) []byte {
return rr.toWireFormat()
}
-// NetlinkRIB returns routing information base, as known as RIB,
-// which consists of network facility information, states and
-// parameters.
+// NetlinkRIB returns routing information base, as known as RIB, which
+// consists of network facility information, states and parameters.
func NetlinkRIB(proto, family int) ([]byte, error) {
- var (
- lsanl SockaddrNetlink
- tab []byte
- )
-
- s, e := Socket(AF_NETLINK, SOCK_RAW, 0)
- if e != nil {
- return nil, e
+ s, err := Socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
+ if err != nil {
+ return nil, err
}
defer Close(s)
-
- lsanl.Family = AF_NETLINK
- e = Bind(s, &lsanl)
- if e != nil {
- return nil, e
+ lsa := &SockaddrNetlink{Family: AF_NETLINK}
+ if err := Bind(s, lsa); err != nil {
+ return nil, err
}
-
- seq := 1
- wb := newNetlinkRouteRequest(proto, seq, family)
- e = Sendto(s, wb, 0, &lsanl)
- if e != nil {
- return nil, e
+ wb := newNetlinkRouteRequest(proto, 1, family)
+ if err := Sendto(s, wb, 0, lsa); err != nil {
+ return nil, err
}
-
+ var tab []byte
+done:
for {
- var (
- rb []byte
- nr int
- lsa Sockaddr
- )
-
- rb = make([]byte, Getpagesize())
- nr, _, e = Recvfrom(s, rb, 0)
- if e != nil {
- return nil, e
+ rb := make([]byte, Getpagesize())
+ nr, _, err := Recvfrom(s, rb, 0)
+ if err != nil {
+ return nil, err
}
if nr < NLMSG_HDRLEN {
return nil, EINVAL
}
rb = rb[:nr]
tab = append(tab, rb...)
-
- msgs, _ := ParseNetlinkMessage(rb)
+ msgs, err := ParseNetlinkMessage(rb)
+ if err != nil {
+ return nil, err
+ }
for _, m := range msgs {
- if lsa, e = Getsockname(s); e != nil {
- return nil, e
+ lsa, err := Getsockname(s)
+ if err != nil {
+ return nil, err
}
switch v := lsa.(type) {
case *SockaddrNetlink:
- if m.Header.Seq != uint32(seq) || m.Header.Pid != v.Pid {
+ if m.Header.Seq != 1 || m.Header.Pid != v.Pid {
return nil, EINVAL
}
default:
return nil, EINVAL
}
if m.Header.Type == NLMSG_DONE {
- goto done
+ break done
}
if m.Header.Type == NLMSG_ERROR {
return nil, EINVAL
}
}
}
-
-done:
return tab, nil
}
-// NetlinkMessage represents the netlink message.
+// NetlinkMessage represents a netlink message.
type NetlinkMessage struct {
Header NlMsghdr
Data []byte
}
-// ParseNetlinkMessage parses buf as netlink messages and returns
-// the slice containing the NetlinkMessage structs.
-func ParseNetlinkMessage(buf []byte) ([]NetlinkMessage, error) {
- var (
- h *NlMsghdr
- dbuf []byte
- dlen int
- e error
- msgs []NetlinkMessage
- )
-
- for len(buf) >= NLMSG_HDRLEN {
- h, dbuf, dlen, e = netlinkMessageHeaderAndData(buf)
- if e != nil {
- break
+// ParseNetlinkMessage parses b as an array of netlink messages and
+// returns the slice containing the NetlinkMessage structures.
+func ParseNetlinkMessage(b []byte) ([]NetlinkMessage, error) {
+ var msgs []NetlinkMessage
+ for len(b) >= NLMSG_HDRLEN {
+ h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
+ if err != nil {
+ return nil, err
}
- m := NetlinkMessage{}
- m.Header = *h
- m.Data = dbuf[:int(h.Len)-NLMSG_HDRLEN]
+ m := NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len)-NLMSG_HDRLEN]}
msgs = append(msgs, m)
- buf = buf[dlen:]
+ b = b[dlen:]
}
-
- return msgs, e
+ return msgs, nil
}
-func netlinkMessageHeaderAndData(buf []byte) (*NlMsghdr, []byte, int, error) {
- h := (*NlMsghdr)(unsafe.Pointer(&buf[0]))
- if int(h.Len) < NLMSG_HDRLEN || int(h.Len) > len(buf) {
+func netlinkMessageHeaderAndData(b []byte) (*NlMsghdr, []byte, int, error) {
+ h := (*NlMsghdr)(unsafe.Pointer(&b[0]))
+ if int(h.Len) < NLMSG_HDRLEN || int(h.Len) > len(b) {
return nil, nil, 0, EINVAL
}
- return h, buf[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
+ return h, b[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
}
-// NetlinkRouteAttr represents the netlink route attribute.
+// NetlinkRouteAttr represents a netlink route attribute.
type NetlinkRouteAttr struct {
Attr RtAttr
Value []byte
}
-// ParseNetlinkRouteAttr parses msg's payload as netlink route
-// attributes and returns the slice containing the NetlinkRouteAttr
-// structs.
-func ParseNetlinkRouteAttr(msg *NetlinkMessage) ([]NetlinkRouteAttr, error) {
- var (
- buf []byte
- a *RtAttr
- alen int
- vbuf []byte
- e error
- attrs []NetlinkRouteAttr
- )
-
- switch msg.Header.Type {
+// ParseNetlinkRouteAttr parses m's payload as an array of netlink
+// route attributes and returns the slice containing the
+// NetlinkRouteAttr structures.
+func ParseNetlinkRouteAttr(m *NetlinkMessage) ([]NetlinkRouteAttr, error) {
+ var b []byte
+ switch m.Header.Type {
case RTM_NEWLINK, RTM_DELLINK:
- buf = msg.Data[SizeofIfInfomsg:]
+ b = m.Data[SizeofIfInfomsg:]
case RTM_NEWADDR, RTM_DELADDR:
- buf = msg.Data[SizeofIfAddrmsg:]
+ b = m.Data[SizeofIfAddrmsg:]
case RTM_NEWROUTE, RTM_DELROUTE:
- buf = msg.Data[SizeofRtMsg:]
+ b = m.Data[SizeofRtMsg:]
default:
return nil, EINVAL
}
-
- for len(buf) >= SizeofRtAttr {
- a, vbuf, alen, e = netlinkRouteAttrAndValue(buf)
- if e != nil {
- break
+ var attrs []NetlinkRouteAttr
+ for len(b) >= SizeofRtAttr {
+ a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
+ if err != nil {
+ return nil, err
}
- ra := NetlinkRouteAttr{}
- ra.Attr = *a
- ra.Value = vbuf[:int(a.Len)-SizeofRtAttr]
+ ra := NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-SizeofRtAttr]}
attrs = append(attrs, ra)
- buf = buf[alen:]
+ b = b[alen:]
}
-
return attrs, nil
}
-func netlinkRouteAttrAndValue(buf []byte) (*RtAttr, []byte, int, error) {
- h := (*RtAttr)(unsafe.Pointer(&buf[0]))
- if int(h.Len) < SizeofRtAttr || int(h.Len) > len(buf) {
+func netlinkRouteAttrAndValue(b []byte) (*RtAttr, []byte, int, error) {
+ a := (*RtAttr)(unsafe.Pointer(&b[0]))
+ if int(a.Len) < SizeofRtAttr || int(a.Len) > len(b) {
return nil, nil, 0, EINVAL
}
- return h, buf[SizeofRtAttr:], rtaAlignOf(int(h.Len)), nil
+ return a, b[SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
}
diff --git a/libgo/go/syscall/sockcmsg_linux.go b/libgo/go/syscall/sockcmsg_linux.go
index 0b4caa1..a2e26a1 100644
--- a/libgo/go/syscall/sockcmsg_linux.go
+++ b/libgo/go/syscall/sockcmsg_linux.go
@@ -6,33 +6,31 @@
package syscall
-import (
- "unsafe"
-)
+import "unsafe"
// UnixCredentials encodes credentials into a socket control message
// for sending to another process. This can be used for
// authentication.
func UnixCredentials(ucred *Ucred) []byte {
- buf := make([]byte, CmsgSpace(SizeofUcred))
- cmsg := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
- cmsg.Level = SOL_SOCKET
- cmsg.Type = SCM_CREDENTIALS
- cmsg.SetLen(CmsgLen(SizeofUcred))
- *((*Ucred)(cmsgData(cmsg))) = *ucred
- return buf
+ b := make([]byte, CmsgSpace(SizeofUcred))
+ h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
+ h.Level = SOL_SOCKET
+ h.Type = SCM_CREDENTIALS
+ h.SetLen(CmsgLen(SizeofUcred))
+ *((*Ucred)(cmsgData(h))) = *ucred
+ return b
}
// ParseUnixCredentials decodes a socket control message that contains
// credentials in a Ucred structure. To receive such a message, the
// SO_PASSCRED option must be enabled on the socket.
-func ParseUnixCredentials(msg *SocketControlMessage) (*Ucred, error) {
- if msg.Header.Level != SOL_SOCKET {
+func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
+ if m.Header.Level != SOL_SOCKET {
return nil, EINVAL
}
- if msg.Header.Type != SCM_CREDENTIALS {
+ if m.Header.Type != SCM_CREDENTIALS {
return nil, EINVAL
}
- ucred := *(*Ucred)(unsafe.Pointer(&msg.Data[0]))
+ ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
return &ucred, nil
}
diff --git a/libgo/go/syscall/sockcmsg_unix.go b/libgo/go/syscall/sockcmsg_unix.go
index 943ebdd..fc83df1 100644
--- a/libgo/go/syscall/sockcmsg_unix.go
+++ b/libgo/go/syscall/sockcmsg_unix.go
@@ -8,9 +8,7 @@
package syscall
-import (
- "unsafe"
-)
+import "unsafe"
// Round the length of a raw sockaddr up to align it propery.
func cmsgAlignOf(salen int) int {
@@ -38,77 +36,69 @@ func CmsgSpace(datalen int) int {
return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)
}
-func cmsgData(cmsg *Cmsghdr) unsafe.Pointer {
- return unsafe.Pointer(uintptr(unsafe.Pointer(cmsg)) + SizeofCmsghdr)
+func cmsgData(h *Cmsghdr) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + SizeofCmsghdr)
}
+// SocketControlMessage represents a socket control message.
type SocketControlMessage struct {
Header Cmsghdr
Data []byte
}
-func ParseSocketControlMessage(buf []byte) ([]SocketControlMessage, error) {
- var (
- h *Cmsghdr
- dbuf []byte
- e error
- cmsgs []SocketControlMessage
- )
-
- for len(buf) >= CmsgLen(0) {
- h, dbuf, e = socketControlMessageHeaderAndData(buf)
- if e != nil {
- break
+// ParseSocketControlMessage parses b as an array of socket control
+// messages.
+func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
+ var msgs []SocketControlMessage
+ for len(b) >= CmsgLen(0) {
+ h, dbuf, err := socketControlMessageHeaderAndData(b)
+ if err != nil {
+ return nil, err
}
- m := SocketControlMessage{}
- m.Header = *h
- m.Data = dbuf[:int(h.Len)-cmsgAlignOf(SizeofCmsghdr)]
- cmsgs = append(cmsgs, m)
- buf = buf[cmsgAlignOf(int(h.Len)):]
+ m := SocketControlMessage{Header: *h, Data: dbuf[:int(h.Len)-cmsgAlignOf(SizeofCmsghdr)]}
+ msgs = append(msgs, m)
+ b = b[cmsgAlignOf(int(h.Len)):]
}
-
- return cmsgs, e
+ return msgs, nil
}
-func socketControlMessageHeaderAndData(buf []byte) (*Cmsghdr, []byte, error) {
- h := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
- if h.Len < SizeofCmsghdr || int(h.Len) > len(buf) {
+func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
+ h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
+ if h.Len < SizeofCmsghdr || int(h.Len) > len(b) {
return nil, nil, EINVAL
}
- return h, buf[cmsgAlignOf(SizeofCmsghdr):], nil
+ return h, b[cmsgAlignOf(SizeofCmsghdr):], nil
}
// UnixRights encodes a set of open file descriptors into a socket
// control message for sending to another process.
func UnixRights(fds ...int) []byte {
datalen := len(fds) * 4
- buf := make([]byte, CmsgSpace(datalen))
- cmsg := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
- cmsg.Level = SOL_SOCKET
- cmsg.Type = SCM_RIGHTS
- cmsg.SetLen(CmsgLen(datalen))
-
- data := uintptr(cmsgData(cmsg))
+ b := make([]byte, CmsgSpace(datalen))
+ h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
+ h.Level = SOL_SOCKET
+ h.Type = SCM_RIGHTS
+ h.SetLen(CmsgLen(datalen))
+ data := uintptr(cmsgData(h))
for _, fd := range fds {
*(*int32)(unsafe.Pointer(data)) = int32(fd)
data += 4
}
-
- return buf
+ return b
}
// ParseUnixRights decodes a socket control message that contains an
// integer array of open file descriptors from another process.
-func ParseUnixRights(msg *SocketControlMessage) ([]int, error) {
- if msg.Header.Level != SOL_SOCKET {
+func ParseUnixRights(m *SocketControlMessage) ([]int, error) {
+ if m.Header.Level != SOL_SOCKET {
return nil, EINVAL
}
- if msg.Header.Type != SCM_RIGHTS {
+ if m.Header.Type != SCM_RIGHTS {
return nil, EINVAL
}
- fds := make([]int, len(msg.Data)>>2)
- for i, j := 0, 0; i < len(msg.Data); i += 4 {
- fds[j] = int(*(*int32)(unsafe.Pointer(&msg.Data[i])))
+ fds := make([]int, len(m.Data)>>2)
+ for i, j := 0, 0; i < len(m.Data); i += 4 {
+ fds[j] = int(*(*int32)(unsafe.Pointer(&m.Data[i])))
j++
}
return fds, nil