Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #5415 > unrolled thread

connect SIGINT to custom interrupt handler

Started byChristoph Scheingraber <chris@spam.org>
First post2011-05-15 09:44 +0000
Last post2011-05-15 14:08 +0100
Articles 9 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  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

#5415 — connect SIGINT to custom interrupt handler

FromChristoph Scheingraber <chris@spam.org>
Date2011-05-15 09:44 +0000
Subjectconnect 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]


#5426

FromChristoph Scheingraber <chris@spam.org>
Date2011-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]


#5428

FromChris Angelico <rosuav@gmail.com>
Date2011-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]


#5429

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-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]


#5438

FromChristoph Scheingraber <spam@scheingraber.net>
Date2011-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]


#5463

FromNobody <nobody@nowhere.com>
Date2011-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]


#5837

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-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]


#5467

FromNobody <nobody@nowhere.com>
Date2011-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]


#5435

FromNobody <nobody@nowhere.com>
Date2011-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