[erlang-questions] Trouble with gen_udp:fdopen

David Baird dhbaird@REDACTED
Sun Sep 2 20:08:23 CEST 2007


I am using otp_src_R11B-5 and I have the following code:

    #!/usr/bin/env escript
    main(Args) ->
        io:fwrite("Args = ~p ~n", [Args]),
        case Args of
          [_, "-foofd", FDStr] ->
            FD = erlang:list_to_integer(FDStr),
            io:fwrite("FD = ~p ~n", [FD]),
            Res = gen_udp:fdopen(FD, []),
            io:fwrite("Res = ~p~n", [Res])

When I execute the script using the suid "setuid_socket_wrap.c"
program (provided with the Erlang sources):

    /tmp/setuid_socket_wrap -d -foofd,:123 -- ./client.erl

I get this result:

    Args = ["./client.erl","-foofd","3"]
    FD = 3
    Res = {error,eprotonosupport}

Does anyone know what is going on?  I think the error is being raised
in "otp_src_R11B-5/lib/kernel/src/prim_inet.erl" (but I'm not 100%

    protocol2drv(tcp)  -> tcp_inet;
    protocol2drv(udp)  -> udp_inet;
    protocol2drv(sctp) -> sctp_inet;
    protocol2drv(_) ->

I have a suspicion that it might be an incorrect atom ("dgram" instead
of "udp") in "otp_src_R11B-5/lib/kernel/src/inet_udp.erl:"

    open(Port, Opts) when Port >= 0, Port =< 16#ffff ->
        case inet:udp_options(
               [{port,Port}, {recbuf, ?RECBUF} | Opts],
               inet) of
            {error, Reason} -> exit(Reason);
            {ok, R} ->
                Fd       = R#udp_opts.fd,
                BAddr    = R#udp_opts.ifaddr,
                BPort    = R#udp_opts.port,
                SockOpts = R#udp_opts.opts,
                inet:open(Fd,BAddr,BPort,SockOpts,udp,inet,?MODULE) %
<- good atom

    % <snip>

    fdopen(Fd, Opts) ->
                optuniquify([{recbuf, ?RECBUF} | Opts]),
                dgram, inet, ?MODULE). % <- bad atom here

In "open," the "udp" atom is used as the Protocol (which matches
"protocol2drv(udp)" in "prim_inet.erl").  However, "fdopen" is using a
different atom: "dgram".  I looked at "inet_tcp.erl" and it is
consistent, unlike "inet_udp.erl":

    do_connect({A,B,C,D}, Port, Opts, Time) when ?ip(A,B,C,D),
is_integer(Port) ->
        case inet:connect_options(Opts, inet) of
      {error, Reason} -> exit(Reason);
      {ok, R} ->
          Fd       = R#connect_opts.fd,
          BAddr    = R#connect_opts.ifaddr,
          BPort    = R#connect_opts.port,
          SockOpts = R#connect_opts.opts,
          case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet,?MODULE) of
          % ...

    % <snip>

    fdopen(Fd, Opts) ->
        inet:fdopen(Fd, Opts, tcp, inet, ?MODULE).

Any suggestions?  Is this a bug or am I doing something wrong?


More information about the erlang-questions mailing list