Hi,
while testing how my application (which uses dnspython) behaves under a
simulated network outage, I think I found a dnspython bug. For my
testing I use the following pseudo-code:
1. block remote port 53 using "iptables"
2. register a function to SIGALRM that removes the block
3. alarm(...) # raise SIGALRM after x seconds
4. dns.resolver.query(...)
The code should stall initially, but when the SIGALRM handler removes
the network block, it should continue and return However when I
implemented this I got the following exception (the traceback format is
slightly non-standard and is generated by py.test -- only the last part
is included here):
def _wait_for(ir, iw, ix, expiration):
if expiration is None:
timeout = None
else:
timeout = expiration - time.time()
if timeout <= 0.0:
raise dns.exception.Timeout
if timeout is None:
(r, w, x) = select.select(ir, iw, ix)
else:
E (r, w, x) = select.select(ir, iw, ix, timeout)
> error: (4, 'Interrupted system call')
[/usr/lib/python2.5/site-packages/dns/query.py:58]
Error #4 is EINTR and indicates that the select() system call has been
interrupted by a signal. This is the SIGALRM that was generated by
alarm(). In my view this is a bug. Dnspython should not interpret EINTR
as terminal. Instead it should restart the select() with an updated
timeout value that reflects how much time is still left.
For now I will use a thread to remove the block, but I think this may be
an area that needs to be looked into. Blocking system calls can always
return with errno = EINTR, so wherever a blocking system call is used in
dnspython, that should be taken into account.
Regards,
Geert Jansen
_______________________________________________
dnspython-bugs mailing list
[email protected]
http://woof.play-bow.org/mailman/listinfo/dnspython-bugs