File: ctypes_errno.py

package info (click to toggle)
python-ptrace 0.7-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, stretch
  • size: 680 kB
  • ctags: 1,002
  • sloc: python: 6,659; ansic: 263; makefile: 13; sh: 1
file content (71 lines) | stat: -rw-r--r-- 1,964 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
"""
Function get_errno(): get the current errno value.

Try different implementations:
 - ctypes_support.get_errno() function
 - __errno_location_sym symbol from the C library
 - PyErr_SetFromErrno() from the C Python API
"""

get_errno = None
try:
    from ctypes_support import get_errno
except ImportError:
    pass

if not get_errno:
    from ctypes import POINTER, c_int

    def _errno_location():
        """
        Try to get errno integer from libc using __errno_location_sym function.

        This function is specific to OS with "libc.so.6" and may fails for
        thread-safe libc.
        """
        from ctypes import cdll
        try:
            libc = cdll.LoadLibrary("libc.so.6")
        except OSError:
            # Unable to open libc dynamic library
            return None
        try:
            __errno_location = libc.__errno_location_sym
        except AttributeError:
            # libc doesn't have __errno_location
            return None
        __errno_location.restype = POINTER(c_int)
        return __errno_location()[0]

    errno = _errno_location()
    if errno is not None:
        def get_errno():
            # pyflakes warn about "undefined name",
            # but that's wrong: errno is defined!
            return errno
    else:
        del errno

if not get_errno:
    from ctypes import pythonapi, py_object

    # Function from pypy project:
    # File pypy/dist/pypy/rpython/rctypes/aerrno.py
    def _pythonapi_geterrno():
        """
        Read errno using Python C API: raise an exception with PyErr_SetFromErrno
        and then read error code 'errno'.

        This function may raise an RuntimeError.
        """
        try:
            pythonapi.PyErr_SetFromErrno(py_object(OSError))
        except OSError as err:
            return err.errno
        else:
            raise RuntimeError("get_errno() is unable to get error code")

    get_errno = _pythonapi_geterrno

__all__ = ["get_errno"]