[erlang-questions] open_port confusing (concerning qmail-inject)
Kevin
q2h46uw02@REDACTED
Thu Apr 30 01:12:08 CEST 2009
Hello, qmail-inject is just a command line program that takes a message
from stdin and dumps it into the mail queue
example to deliver a very short message to kevin@REDACTED:
prompt> echo "subject:it worked" | qmail-inject kevin@REDACTED
If successful it exits with a code of 0, all other numbers are errors.
I'm writing an erlang function that will eventually, **line-by-line**,
feed a message to qmail-inject.
Here is my attempt:
start() ->
From = "somebody@REDACTED",
To = "kevin@REDACTED",
Command = "/var/qmail/bin/qmail-inject -a -f " ++ From ++ " " ++ To,
Port = open_port({spawn, Command}, [stream, exit_status]),
Port ! {self(), {command, "Subject:It worked!\n"}},
Port ! {self(), {command, "From:from@REDACTED\n"}},
Port ! {self(), {command, "To:to@REDACTED\n"}},
Port ! {self(), close},
receive
{Port, {exit_status, 0}} -> %% exited without a result
{ok, worked};
{Port, {exit_status, R}} -> %% dig program missing?
{error, inject_error, R};
Unknown -> Unknown
end.
I was confused by the docs for port_command and port_close so I just
stuck with the standard erlang message passing.
It works fine, but because I'm a little obsessive and I tried hiding the
qmail-inject program by renaming it and breaking the whole thing.
By playing around I figured out the behavior of a broken command:
14> open_port({spawn, "/asdf"}, [stream, exit_status]).
#Port<0.444>
15> flush().
Shell got {#Port<0.444>,{exit_status,126}}
Ok, so I now see I can received the message of a broken command.
And here is a successful command:
16> open_port({spawn, "/usr/local/bin/date"}, [stream, exit_status]).
#Port<0.445>
17> flush().
Shell got {#Port<0.445>,{data,"Wed Apr 29 18:56:27 EDT 2009\n"}}
Shell got {#Port<0.445>,{exit_status,0}}
ok
But with a command like qmail-inject, there is nothing to flush until
the message is finished, and I'm assuming it will
be sent when send it a close signal. And with all this flushing, is
there a chance of a race condition?
17> open_port({spawn, "/usr/local/bin/date"}, [stream, exit_status]).
#Port<0.1830>
18> flush().
ok
19>
So how do I tell if the port successfully opened to a waiting
qmail-inject without blocking on a message that will only
come until after I fed it the message and closed the port? And then be
certain that the qmail-inject program returned
a success code of 0? And avoid race conditions?
I would take my grandma 5 minutes to figure out how to open a pipe to a
command line program in a scripting language like perl or ruby, but here
I don't even know if I'm going in the right direction.
Thanks for any help,
Kevin
More information about the erlang-questions
mailing list