Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #5415 > unrolled thread
| Started by | Christoph Scheingraber <chris@spam.org> |
|---|---|
| First post | 2011-05-15 09:44 +0000 |
| Last post | 2011-05-15 14:08 +0100 |
| Articles | 9 — 5 participants |
Back to article view | Back to comp.lang.python
connect SIGINT to custom interrupt handler Christoph Scheingraber <chris@spam.org> - 2011-05-15 09:44 +0000
Re: connect SIGINT to custom interrupt handler Christoph Scheingraber <chris@spam.org> - 2011-05-15 14:32 +0000
Re: connect SIGINT to custom interrupt handler Chris Angelico <rosuav@gmail.com> - 2011-05-16 01:30 +1000
Re: connect SIGINT to custom interrupt handler Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-05-15 17:43 +0200
Re: connect SIGINT to custom interrupt handler Christoph Scheingraber <spam@scheingraber.net> - 2011-05-15 17:05 +0000
Re: connect SIGINT to custom interrupt handler Nobody <nobody@nowhere.com> - 2011-05-16 03:28 +0100
Re: connect SIGINT to custom interrupt handler Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-05-20 09:38 +0200
Re: connect SIGINT to custom interrupt handler Nobody <nobody@nowhere.com> - 2011-05-16 03:53 +0100
Re: connect SIGINT to custom interrupt handler Nobody <nobody@nowhere.com> - 2011-05-15 14:08 +0100
| From | Christoph Scheingraber <chris@spam.org> |
|---|---|
| Date | 2011-05-15 09:44 +0000 |
| Subject | connect SIGINT to custom interrupt handler |
| Message-ID | <slrnisv835.b74.chris@scheingraber.no-ip.org> |
Hi,
I am trying to connect SIGINT (^c) to a custom interrupt handler like
this (no threading, just straightforward):
if __name__ == "__main__":
quit = False
def interrupt_handler(signal, frame):
global quit
if not quit:
print "blabla, i'll finish my task and quit kind of message"
print "Press ^C again to interrupt immediately."
else:
sys.exit(2)
quit = True
signal.signal(signal.SIGINT, interrupt_handler)
# main will use the quit flag to determine if it should quit before next
# task
status = main()
This worked fine in some rare lucky cases, but most of the times, the
module I am using (my university's seismology project) catches the SIGINT
and quits:
select.error: (4, 'Interrupted system call')
How can I prevent the imported module's function from catching the
interrupt signal?
Thanks to anyone that takes the time to help me...
Chris
--
Chris Scheingraber - www.scheingraber.net
[toc] | [next] | [standalone]
| From | Christoph Scheingraber <chris@spam.org> |
|---|---|
| Date | 2011-05-15 14:32 +0000 |
| Message-ID | <slrnisvove.dj0.chris@scheingraber.no-ip.org> |
| In reply to | #5415 |
I now have signal.siginterrupt(signal.SIGINT, False) in the line
below signal.signal(signal.SIGINT, interrupt_handler)
Unfortunately, pressing ^c still results in the same interrupt error. I
also tried putting signal.siginterrupt into the interrupt_handler
function, which gave an interesting result:
File "/usr/local/bin/obspysod", line 586, in interrupt_handler
signal.siginterrupt(signal.SIGINT, False)
AttributeError: 'int' object has no attribute 'siginterrupt'
Could there be a namespace problem?
On 2011-05-15, Nobody <nobody@nowhere.com> wrote:
> On Sun, 15 May 2011 09:44:04 +0000, Christoph Scheingraber wrote:
>
>> signal.signal(signal.SIGINT, interrupt_handler)
>
>> This worked fine in some rare lucky cases, but most of the times, the
>> module I am using (my university's seismology project) catches the SIGINT
>> and quits:
>>
>> select.error: (4, 'Interrupted system call')
>
> After installing the signal handler, call:
>
> signal.siginterrupt(signal.SIGINT, False)
>
> This will cause (most) interrupted system calls to be restarted after the
> signal has been handled.
>
>> How can I prevent the imported module's function from catching the
>> interrupt signal?
>
> It isn't catching the signal. Unless you enable restarting of system
> calls, an interrupted system call will typically fail with EINTR. Python
> typically reports failures via exceptions; failures due to EINTR aren't
> handled differently.
>
--
Chris Scheingraber - www.scheingraber.net
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-05-16 01:30 +1000 |
| Message-ID | <mailman.1595.1305473419.9059.python-list@python.org> |
| In reply to | #5426 |
On Mon, May 16, 2011 at 12:32 AM, Christoph Scheingraber <chris@spam.org> wrote: > I now have signal.siginterrupt(signal.SIGINT, False) in the line > below signal.signal(signal.SIGINT, interrupt_handler) > > Unfortunately, pressing ^c still results in the same interrupt error. I > also tried putting signal.siginterrupt into the interrupt_handler > function, which gave an interesting result: > File "/usr/local/bin/obspysod", line 586, in interrupt_handler > signal.siginterrupt(signal.SIGINT, False) > AttributeError: 'int' object has no attribute 'siginterrupt' > > Could there be a namespace problem? def interrupt_handler(signal, frame): You're using 'signal' as a parameter here. The local int is masking the global module. Chris Angelico
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-05-15 17:43 +0200 |
| Message-ID | <1691845.hkbZ0PkbqX@PointedEars.de> |
| In reply to | #5426 |
Christoph Scheingraber wrote: > I now have signal.siginterrupt(signal.SIGINT, False) in the line > below signal.signal(signal.SIGINT, interrupt_handler) > > Unfortunately, pressing ^c still results in the same interrupt error. I > also tried putting signal.siginterrupt into the interrupt_handler > function, which gave an interesting result: > File "/usr/local/bin/obspysod", line 586, in interrupt_handler > signal.siginterrupt(signal.SIGINT, False) > AttributeError: 'int' object has no attribute 'siginterrupt' > > Could there be a namespace problem? Obviously. `signal' refers to an `int' object, probably by something like signal = 42 before. E.g. `print' or a debugger will tell you, as you have not showed the relevant parts of the code. Please trim your quotes to the relevant minimum; DO NOT top-post. Also, it is not acceptable behavior to use domain namespaces without authorization (chris@spam.org is not a mailbox, yet spam.org is registered to someone else). -- PointedEars Bitte keine Kopien per E-Mail. / Please do not Cc: me.
[toc] | [prev] | [next] | [standalone]
| From | Christoph Scheingraber <spam@scheingraber.net> |
|---|---|
| Date | 2011-05-15 17:05 +0000 |
| Message-ID | <slrnit01vm.hf2.spam@scheingraber.no-ip.org> |
| In reply to | #5429 |
On 2011-05-15, Thomas 'PointedEars' Lahn <PointedEars@web.de> wrote: > > Obviously. `signal' refers to an `int' object, probably by something like > > signal = 42 > > before. E.g. `print' or a debugger will tell you, as you have not showed > the relevant parts of the code. The problem is that I am running someone else's module which seems to use signal, I guess that means I have to create a child method? Is it correct anyway to have signal.siginterrupt(signal.SIGINT, False) in my custom interrupt_handler function or should it be outside but after signal.signal(signal.SIGINT, interrupt_handler)? > > Please trim your quotes to the relevant minimum; DO NOT top-post. > Also, it is not acceptable behavior to use domain namespaces without > authorization (chris@spam.org is not a mailbox, yet spam.org is > registered to someone else). > I am sorry, I changed it to my own domain. -- Chris Scheingraber - www.scheingraber.net
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-05-16 03:28 +0100 |
| Message-ID | <pan.2011.05.16.02.27.52.359000@nowhere.com> |
| In reply to | #5438 |
On Sun, 15 May 2011 17:05:57 +0000, Christoph Scheingraber wrote: > Is it correct anyway to have > > signal.siginterrupt(signal.SIGINT, False) > > in my custom interrupt_handler function No. > or should it be outside but after > signal.signal(signal.SIGINT, interrupt_handler)? Yes.
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2011-05-20 09:38 +0200 |
| Message-ID | <1905065.XAFRqVoOGU@PointedEars.de> |
| In reply to | #5438 |
Christoph Scheingraber wrote: > On 2011-05-15, Thomas 'PointedEars' Lahn <PointedEars@web.de> wrote: >> Obviously. `signal' refers to an `int' object, probably by something >> like >> >> signal = 42 >> >> before. E.g. `print' or a debugger will tell you, as you have not showed >> the relevant parts of the code. > > The problem is that I am running someone else's module which seems to > use signal, I guess that means I have to create a child method? > Is it correct anyway to have > > signal.siginterrupt(signal.SIGINT, False) > > in my custom interrupt_handler function Only if `signal' is not the name of an int argument. > or should it be outside but > after signal.signal(signal.SIGINT, interrupt_handler)? In the meantime, Chris Angelico has pointed out the cause of the problem. Please follow his advice, i.e. rename your argument. -- PointedEars Bitte keine Kopien per E-Mail. / Please do not Cc: me.
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-05-16 03:53 +0100 |
| Message-ID | <pan.2011.05.16.02.52.43.390000@nowhere.com> |
| In reply to | #5426 |
On Sun, 15 May 2011 14:32:13 +0000, Christoph Scheingraber wrote:
> I now have signal.siginterrupt(signal.SIGINT, False) in the line
> below signal.signal(signal.SIGINT, interrupt_handler)
>
> Unfortunately, pressing ^c still results in the same interrupt error.
Sorry; I wasn't paying sufficient attention to the details:
>>> select.error: (4, 'Interrupted system call')
According to Linux' signal(7) manpage, select() is never restarted,
regardless of the siginterrupt() setting.
In general, wait-for-something functions aren't restarted; the caller is
expected to check that the waited-for condition actually happened, so
returning prematurely isn't considered problematic.
EINTR is one of those "special" errors (like EAGAIN) which don't
actually indicate an error. In the context of select(), a return value of
-1 with errno set to EINTR should normally be handled in the same way as a
return value of zero, i.e. "nothing has happened yet, try again".
While the EINTR case isn't identical to the zero-return case, it's much
closer to it than it is to a genuine error. If it's being treated like
genuine errors (i.e. raising an exception), that's a defect in the Python
bindings. In which case, I'd suggest catching the exception and checking
the error code, e.g.:
def myselect(rlist, wlist, xlist, timeout = None):
try:
return select.select(rlist, wlist, xlist, timeout)
except select.error, e:
if e[0] == errno.EINTR:
return 0
raise
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-05-15 14:08 +0100 |
| Message-ID | <pan.2011.05.15.13.08.22.15000@nowhere.com> |
| In reply to | #5415 |
On Sun, 15 May 2011 09:44:04 +0000, Christoph Scheingraber wrote: > signal.signal(signal.SIGINT, interrupt_handler) > This worked fine in some rare lucky cases, but most of the times, the > module I am using (my university's seismology project) catches the SIGINT > and quits: > > select.error: (4, 'Interrupted system call') After installing the signal handler, call: signal.siginterrupt(signal.SIGINT, False) This will cause (most) interrupted system calls to be restarted after the signal has been handled. > How can I prevent the imported module's function from catching the > interrupt signal? It isn't catching the signal. Unless you enable restarting of system calls, an interrupted system call will typically fail with EINTR. Python typically reports failures via exceptions; failures due to EINTR aren't handled differently.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web