[erlang-questions] open_port confusing (concerning qmail-inject) UPDATE
Kevin
q2h46uw02@REDACTED
Thu Apr 30 04:48:50 CEST 2009
Kevin q2h46uw02-at-sneakemail.com |erlang| wrote:
> 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
>
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
>
I'm beginning to thing there is no solution to this other than writing a
wrapper for qmail-inject. The main problem
is that, according to my research, there is no way to tell qmail-inject
that it has reached the "end of file" without
port_close(Port), which, when called, will prevent any exit codes from
being sent, so I'll never know if qmail-inject
succeeded.
-ks
More information about the erlang-questions
mailing list