Access to errno from Python?

user79758 picture user79758 · Mar 19, 2009 · Viewed 10.1k times · Source

I am stuck with a fairly complex Python module that does not return useful error codes (it actually fails disturbingly silently). However, the underlying C library it calls sets errno.

Normally errno comes in over OSError attributes, but since I don't have an exception, I can't get at it.

Using ctypes, libc.errno doesn't work because errno is a macro in GNU libc. Python 2.6 has some affordances but Debian still uses Python 2.5. Inserting a C module into my pure Python program just to read errno disgusts me.

Is there some way to access errno? A Linux-only solution is fine, since the library being wrapped is Linux-only. I also don't have to worry about threads, as I'm only running one thread during the time in which this can fail.

Answer

theller picture theller · Mar 19, 2009

Here is a snippet of code that allows to access errno:

from ctypes import *

libc = CDLL("libc.so.6")

get_errno_loc = libc.__errno_location
get_errno_loc.restype = POINTER(c_int)

def errcheck(ret, func, args):
    if ret == -1:
        e = get_errno_loc()[0]
        raise OSError(e)
    return ret

copen = libc.open
copen.errcheck = errcheck

print copen("nosuchfile", 0)

The important thing is that you check errno as soon as possible after your function call, otherwise it may already be overwritten.