os.popen hangs mutt
Jason R. Mastaler
jason-dated-990201218.0d3ca1 at mastaler.com
Thu May 10 11:53:38 EDT 2001
I need some help debugging a strange problem I'm having with the mutt
mail client on certain BSD UNIX platforms. I think it might be caused
by a bug in os.popen.
Basically, I use a custom Python "injection agent" which sits between
mutt and the mail transport agent (qmail in my case). It accepts the
message from mutt as stdin, does some header manipulation, and hands
it off to qmail-inject for delivery.
mutt --> injection-agent --> qmail-inject --> recipient
The problem is that on certain operating systems (FreeBSD, NetBSD,
OpenBSD), this exchange hangs before reaching qmail-inject so the
message is never delivered. The injection-agent is left hanging
around in the process table until manually killed. For example,
(jason at mail1):(~)$ echo | mutt jason
(this command hangs, and the `ps' output looks like this)
jason 737 0.0 1.1 900 1424 ?? I 10:44AM 0:00.03 python /home/jason/pyinject -- jason
The strange thing is that if I implement the injection-agent using the
popen2 module instead of os.popen, the problem goes away. I've tried
several different Python versions from 1.5.2 to 2.1 with the same
results. So the question is: why does os.popen hang while popen2
doesn't?
Here is a simple prototype of the injection-agent that I use to
reproduce the problem. The program simply accepts the message on
stdin, extracts the "To:" header, opens a pipe to qmail-inject, and
writes the message to it.
============================================
#!/usr/bin/env python
import os
import sys
import rfc822
message = sys.stdin
message_headers = rfc822.Message(message)
to = message_headers['to']
message_body = message.read()
inject = '/var/qmail/bin/qmail-inject ' + to
pipeline = os.popen(inject, 'w')
pipeline.write(str(message_headers))
pipeline.write(message_body)
pipeline.close()
============================================
If I replace the last chunk of the above program with popen2, the
problem goes away. I.e,
[...]
import popen2
pipeline = popen2.popen2(inject)[1]
pipeline.write(str(message_headers))
pipeline.write('\n')
pipeline.write(message_body)
pipeline.close()
P.S - if anyone is brave enough, I have a 400k kernel process trace
log of a hung mutt delivery attempt that might contain the answer.
--
(TMDA - http://tmda.sourceforge.net)
(Python-based SPAM reduction system)
More information about the Python-list
mailing list