import (
"errors"
"os"
+ "syscall"
)
// /sys/include/ape/sys/socket.h:/SOMAXCONN
return f, dest, proto, string(buf[:n]), nil
}
-func dialPlan9(net string, laddr, raddr Addr) (*netFD, error) {
+func netErr(e error) {
+ oe, ok := e.(*OpError)
+ if !ok {
+ return
+ }
+ if pe, ok := oe.Err.(*os.PathError); ok {
+ if _, ok = pe.Err.(syscall.ErrorString); ok {
+ oe.Err = pe.Err
+ }
+ }
+}
+
+func dialPlan9(net string, laddr, raddr Addr) (fd *netFD, err error) {
+ defer func() { netErr(err) }()
f, dest, proto, name, err := startPlan9(net, raddr)
if err != nil {
- return nil, err
+ return nil, &OpError{"dial", net, raddr, err}
}
_, err = f.WriteString("connect " + dest)
if err != nil {
f.Close()
- return nil, err
+ return nil, &OpError{"dial", f.Name(), raddr, err}
}
data, err := os.OpenFile("/net/"+proto+"/"+name+"/data", os.O_RDWR, 0)
if err != nil {
f.Close()
- return nil, err
+ return nil, &OpError{"dial", net, raddr, err}
}
laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
if err != nil {
data.Close()
f.Close()
- return nil, err
- }
- raddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/remote")
- if err != nil {
- data.Close()
- f.Close()
- return nil, err
+ return nil, &OpError{"dial", proto, raddr, err}
}
return newFD(proto, name, f, data, laddr, raddr), nil
}
-func listenPlan9(net string, laddr Addr) (*netFD, error) {
+func listenPlan9(net string, laddr Addr) (fd *netFD, err error) {
+ defer func() { netErr(err) }()
f, dest, proto, name, err := startPlan9(net, laddr)
if err != nil {
- return nil, err
+ return nil, &OpError{"listen", net, laddr, err}
}
_, err = f.WriteString("announce " + dest)
if err != nil {
f.Close()
- return nil, err
+ return nil, &OpError{"announce", proto, laddr, err}
}
laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
if err != nil {
f.Close()
- return nil, err
+ return nil, &OpError{Op: "listen", Net: net, Err: err}
}
return newFD(proto, name, f, nil, laddr, nil), nil
}
return newFD(l.proto, l.name, l.ctl, l.data, l.laddr, l.raddr)
}
-func (l *netFD) acceptPlan9() (*netFD, error) {
+func (l *netFD) acceptPlan9() (fd *netFD, err error) {
+ defer func() { netErr(err) }()
f, err := os.Open(l.dir + "/listen")
if err != nil {
- return nil, err
+ return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
}
var buf [16]byte
n, err := f.Read(buf[:])
if err != nil {
f.Close()
- return nil, err
+ return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
}
name := string(buf[:n])
data, err := os.OpenFile("/net/"+l.proto+"/"+name+"/data", os.O_RDWR, 0)
if err != nil {
f.Close()
- return nil, err
+ return nil, &OpError{"accept", l.proto, l.laddr, err}
}
raddr, err := readPlan9Addr(l.proto, "/net/"+l.proto+"/"+name+"/remote")
if err != nil {
data.Close()
f.Close()
- return nil, err
+ return nil, &OpError{"accept", l.proto, l.laddr, err}
}
return newFD(l.proto, name, f, data, l.laddr, raddr), nil
}
switch net {
case "tcp", "tcp4", "tcp6":
default:
- return nil, UnknownNetworkError(net)
+ return nil, &OpError{"dial", net, raddr, UnknownNetworkError(net)}
}
if raddr == nil {
return nil, &OpError{"dial", net, nil, errMissingAddress}
}
if _, err := l.fd.ctl.WriteString("hangup"); err != nil {
l.fd.ctl.Close()
- return err
+ return &OpError{"close", l.fd.ctl.Name(), l.fd.laddr, err}
}
return l.fd.ctl.Close()
}
switch net {
case "tcp", "tcp4", "tcp6":
default:
- return nil, UnknownNetworkError(net)
+ return nil, &OpError{"listen", net, laddr, UnknownNetworkError(net)}
}
if laddr == nil {
laddr = &TCPAddr{}
package syscall
-import "errors"
-
// Constants
const (
// Invented values to support what package os expects.
// Errors
var (
- EINVAL = errors.New("bad arg in system call")
- ENOTDIR = errors.New("not a directory")
- ENOENT = errors.New("file does not exist")
- EEXIST = errors.New("file already exists")
- EIO = errors.New("i/o error")
- ENAMETOOLONG = errors.New("file name too long")
- EPERM = errors.New("permission denied")
- EPLAN9 = errors.New("not supported by plan 9")
+ EINVAL = NewError("bad arg in system call")
+ ENOTDIR = NewError("not a directory")
+ EISDIR = NewError("file is a directory")
+ ENOENT = NewError("file does not exist")
+ EEXIST = NewError("file already exists")
+ EMFILE = NewError("no free file descriptors")
+ EIO = NewError("i/o error")
+ ENAMETOOLONG = NewError("file name too long")
+ EINTR = NewError("interrupted")
+ EPERM = NewError("permission denied")
+ EBUSY = NewError("no free devices")
+ ETIMEDOUT = NewError("connection timed out")
+ EPLAN9 = NewError("not supported by plan 9")
+
+ // The following errors do not correspond to any
+ // Plan 9 system messages. Invented to support
+ // what package os and others expect.
+ EACCES = NewError("access permission denied")
+ EAFNOSUPPORT = NewError("address family not supported by protocol")
)
package syscall
-import "errors"
-
// Constants
const (
// Invented values to support what package os expects.
// Errors
var (
- EINVAL = errors.New("bad arg in system call")
- ENOTDIR = errors.New("not a directory")
- ENOENT = errors.New("file does not exist")
- EEXIST = errors.New("file already exists")
- EIO = errors.New("i/o error")
- ENAMETOOLONG = errors.New("file name too long")
- EPERM = errors.New("permission denied")
- EPLAN9 = errors.New("not supported by plan 9")
+ EINVAL = NewError("bad arg in system call")
+ ENOTDIR = NewError("not a directory")
+ EISDIR = NewError("file is a directory")
+ ENOENT = NewError("file does not exist")
+ EEXIST = NewError("file already exists")
+ EMFILE = NewError("no free file descriptors")
+ EIO = NewError("i/o error")
+ ENAMETOOLONG = NewError("file name too long")
+ EINTR = NewError("interrupted")
+ EPERM = NewError("permission denied")
+ EBUSY = NewError("no free devices")
+ ETIMEDOUT = NewError("connection timed out")
+ EPLAN9 = NewError("not supported by plan 9")
+
+ // The following errors do not correspond to any
+ // Plan 9 system messages. Invented to support
+ // what package os and others expect.
+ EACCES = NewError("access permission denied")
+ EAFNOSUPPORT = NewError("address family not supported by protocol")
)