Giampaolo Rodola' | e09fb71 | 2014-04-04 15:34:17 +0200 | [diff] [blame^] | 1 | import _signal |
| 2 | from _signal import * |
| 3 | from functools import wraps as _wraps |
| 4 | from enum import IntEnum as _IntEnum |
| 5 | |
| 6 | _globals = globals() |
| 7 | |
| 8 | Signals = _IntEnum( |
| 9 | 'Signals', |
| 10 | {name: value for name, value in _globals.items() |
| 11 | if name.isupper() |
| 12 | and (name.startswith('SIG') and not name.startswith('SIG_')) |
| 13 | or name.startswith('CTRL_')}) |
| 14 | |
| 15 | class Handlers(_IntEnum): |
| 16 | SIG_DFL = _signal.SIG_DFL |
| 17 | SIG_IGN = _signal.SIG_IGN |
| 18 | |
| 19 | _globals.update(Signals.__members__) |
| 20 | _globals.update(Handlers.__members__) |
| 21 | |
| 22 | if 'pthread_sigmask' in _globals: |
| 23 | class Sigmasks(_IntEnum): |
| 24 | SIG_BLOCK = _signal.SIG_BLOCK |
| 25 | SIG_UNBLOCK = _signal.SIG_UNBLOCK |
| 26 | SIG_SETMASK = _signal.SIG_SETMASK |
| 27 | |
| 28 | _globals.update(Sigmasks.__members__) |
| 29 | |
| 30 | |
| 31 | def _int_to_enum(value, enum_klass): |
| 32 | """Convert a numeric value to an IntEnum member. |
| 33 | If it's not a known member, return the numeric value itself. |
| 34 | """ |
| 35 | try: |
| 36 | return enum_klass(value) |
| 37 | except ValueError: |
| 38 | return value |
| 39 | |
| 40 | |
| 41 | def _enum_to_int(value): |
| 42 | """Convert an IntEnum member to a numeric value. |
| 43 | If it's not a IntEnum member return the value itself. |
| 44 | """ |
| 45 | try: |
| 46 | return int(value) |
| 47 | except (ValueError, TypeError): |
| 48 | return value |
| 49 | |
| 50 | |
| 51 | @_wraps(_signal.signal) |
| 52 | def signal(signalnum, handler): |
| 53 | handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) |
| 54 | return _int_to_enum(handler, Handlers) |
| 55 | |
| 56 | |
| 57 | @_wraps(_signal.getsignal) |
| 58 | def getsignal(signalnum): |
| 59 | handler = _signal.getsignal(signalnum) |
| 60 | return _int_to_enum(handler, Handlers) |
| 61 | |
| 62 | |
| 63 | if 'pthread_sigmask' in _globals: |
| 64 | @_wraps(_signal.pthread_sigmask) |
| 65 | def pthread_sigmask(how, mask): |
| 66 | sigs_set = _signal.pthread_sigmask(how, mask) |
| 67 | return set(_int_to_enum(x, Signals) for x in sigs_set) |
| 68 | pthread_sigmask.__doc__ = _signal.pthread_sigmask.__doc__ |
| 69 | |
| 70 | |
| 71 | @_wraps(_signal.sigpending) |
| 72 | def sigpending(): |
| 73 | sigs = _signal.sigpending() |
| 74 | return set(_int_to_enum(x, Signals) for x in sigs) |
| 75 | |
| 76 | |
| 77 | if 'sigwait' in _globals: |
| 78 | @_wraps(_signal.sigwait) |
| 79 | def sigwait(sigset): |
| 80 | retsig = _signal.sigwait(sigset) |
| 81 | return _int_to_enum(retsig, Signals) |
| 82 | sigwait.__doc__ = _signal.sigwait |
| 83 | |
| 84 | del _globals, _wraps |