Mailing List Archive

^C and os.system()
Greetings. Is it considered a bug or a feature that if I type ^C at a
Python program that is in the middle of executing a call to
os.system(), the Python program never seems to see the SIGINT signal?
Instead, only the process created by os.system() receives the signal.
Consequently, if I have a Python script that executes a program
repeatedly for a list of files, for instance, I can't kill the Python
script with ^C.

Personally, I find this kind of annoying. This is using Python 1.5.1
under Solaris 2.6. Please forgive me if this a bug that has already
been fixed under 1.5.2.

Also, when I have the Python program check the return status of a
command invoked via os.system() and subsequently killed with ^C,
instead of getting back 0x0002, as would be expected from a process
killed by SIGINT, I usually get back 0x8200. Sometimes I get back
0xd000. Only infrequently do I get back the 0x0002 that I would
expect.

None of these problems occur if I use commands.getstatusoutput()
instead of os.system(), so I guess I will stick with getstatusoutput()
for the time being.

|>oug
http://space.mit.edu/~nessus
^C and os.system() [ In reply to ]
Douglas Alan <nessus@mit.edu> writes:
| Greetings. Is it considered a bug or a feature that if I type ^C at a
| Python program that is in the middle of executing a call to
| os.system(), the Python program never seems to see the SIGINT signal?
| Instead, only the process created by os.system() receives the signal.
| Consequently, if I have a Python script that executes a program
| repeatedly for a list of files, for instance, I can't kill the Python
| script with ^C.

It's neither bug nor feature, it's just the implementation of the
C system() function. In the NetBSD source, I see system() ignores
SIGINT and SIGQUIT in the parent fork while calling waitpid(), and
I imagine Solaris 2.6 may do something similar. Can't explain why.

| Also, when I have the Python program check the return status of a
| command invoked via os.system() and subsequently killed with ^C,
| instead of getting back 0x0002, as would be expected from a process
| killed by SIGINT, I usually get back 0x8200. Sometimes I get back
| 0xd000. Only infrequently do I get back the 0x0002 that I would
| expect.

Now that looks like a bug in the Solaris 2.6 system(). I don't get
this effect on Digital UNIX, for example. You might try a little
C program, it should look the same as Python.

| None of these problems occur if I use commands.getstatusoutput()
| instead of os.system(), so I guess I will stick with getstatusoutput()
| for the time being.

Uses popen(), which doesn't have the same signal handling. You
can also roll your own system() with fork() and exec*().

Donn Cave, University Computing Services, University of Washington
donn@u.washington.edu