[rabbitmq-discuss] Creating an auth plugin (Kerberos)

Tim Watson tim at rabbitmq.com
Mon Dec 3 11:21:55 GMT 2012


On 12/03/2012 11:01 AM, Simon MacMullen wrote:
> On 29/11/12 16:46, Simon Lundström wrote:
>> Sorry to revisit an old message, but it's kind of related...
>
>> When trying to handle when password is undefined I have found that
>> the {'EXIT', Port, normal} message is only sent when a user logs in
>> via AMQP (and probably STOMP).
>
> Well, the {'EXIT', Port, Reason} message is sent by the Erlang 
> runtime, so whatever is determining whether it gets sent or not is 
> down to the interaction between the runtime and kinit.
>
> It's worth noting at this point that I have never written anything 
> that uses open_port, so we really are reaching the limits of my 
> ability to help you. According to the docs:
>
> "During use of a port opened using {spawn, Name}, {spawn_driver, Name} 
> or {spawn_executable, Name}, errors arising when sending messages to 
> it are reported to the owning process using signals of the form 
> {'EXIT', Port, PosixCode}. See file(3) for possible values of PosixCode."
> So it sounds like the messages might be optional.
>

This all depends what arguments you've passed in `Options' when you 
called erlang:open_port/2 and whether or not your process is trapping 
exits. For example, if you pass the exit_status option, then you'll get 
a `{Port,{exit_status,Status}}' message when the port exits. If you're 
trapping exits, then you will get 'EXIT' messages from the port (as 
you're the controlling process if you called open_port) and you'll need 
to handle these too.

Normally what will happen is when stdio for the port detects `eof' then 
it will close (and the exit signal will be generated). If you want to 
avoid getting the exit signals, you can pass 'eof' in the options which 
(as per the open_port/2 docs) will change this behaviour such that:

"The port will not be closed at the end of the file and produce an exit 
signal. Instead, it will remain open and a {Port, eof} message will be 
sent to the process holding the port."

Either way you're going to end up getting some messages from the port 
and you need to learn about the port protocol (from 
http://erlang.org/doc/man/erlang.html#open_port-2 and 
http://www.erlang.org/doc/tutorial/c_port.html) and make sure you're 
handling all of them.

>> I never receive an EXIT-message when a user logs in via the
>> API/mgmt.
>>
>> Why is that? How can I handle the EXIT-message "sometimes"?
>
> If you really are only getting them sometimes, then "after 0" should 
> be fine as long as you have received everything else you expect from 
> the port by that point.
>

I would suggest making sure your port isn't 'hanging' by receiving until 
you've got either 'EXIT' or a combination of 'eof' and 'exit_status' 
messages - iirc the ordering guarantees with these allows you to write a 
shutdown loop like so (you might want to ignore or use the stdout during 
shutdown/close for your own purposes, I don't know how your app works):

shutdown_loop(Port, Acc) ->
     receive
         {Port, {exit_status, 0}}       -> {ok, Acc};
         {Port, {exit_status, Rc}}     -> {error, Rc, Acc};
         {Port, {data, {eol, Line}}} -> shutdown_loop(Port, [Line|Acc]);
         {Port, {data, {eol, []}}}     -> shutdown_loop(Port, Acc);
         {Port, {data, Data}}           -> shutdown_loop(Port,
                                                                                   [io_lib:format("~p~n", [Data])|Acc])
     end.

If you want to avoid blocking (the reader! yes you do I would've 
thought) then you might consider using an 'insulator' process in which 
to open and interact with the port. This allows you to timeout and/or 
terminate the port without blocking the reader process - some port 
commands are blocking and if your C code (or external application or 
whatever) gets stuck then you could be in trouble.

HTH

Cheers,
Tim


More information about the rabbitmq-discuss mailing list