ArtemGr
ArtemGr

Reputation: 12567

How can I get os.Errno from os.Error? Other ways to use os.Timeout?

The net.Conn interface provides the SetTimeout methods and I am supposed to check the returned error with os.Timeout. However I see no way of calling os.Timeout on the returned os.Error.

(The os.Error I've got is read unix @: Resource temporarily unavailable which seem to consists of two parts: description of the function which timed out and the strerror description of the EAGAIN. I've tried err == os.EAGAIN and it doesn't work, probably because of the extra information in os.Error).

Upvotes: 1

Views: 1999

Answers (2)

ypb
ypb

Reputation: 116

You need to do a type assertion. Let's say kon is type net.Conn and you read into buffer buf. Then:

if numread, err := kon.Read(buf); err != nil {
    if val, ok := err.(os.Errno); ok {
        if val.Timeout() {
            println("Connection to:", kon.RemoteAddr().String(), "timed out.")
        }
    }
}

That's of course only a gist of the idea. In practice you probably want to do something more elegant (aka more RL complexleete) and consider more cases at once with Type switches.

Upvotes: 0

kostix
kostix

Reputation: 55553

The "An I/O Package" section of the Go tutorial has this snippet:

func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) {
  r, e := syscall.Open(name, mode, perm)
  if e != 0 {
    err = os.Errno(e)
  }
  return newFile(r, name), err
}

syscall.Open() has this signature:

func Open(path string, mode int, perm uint32) (fd int, errno int)

So I think it's safe to assume os.Error is still just that integer error code, just with the added fluff and your approach to check it is correct.

To investigate why err == os.EAGAIN did not work for you, I'd print the error as a value of type int and then grepped your platform's errno.h file for the value printed.

Upvotes: 1

Related Questions