diff options
author | Hans Nilsson <[email protected]> | 2015-11-24 12:18:47 +0100 |
---|---|---|
committer | Hans Nilsson <[email protected]> | 2015-11-24 12:18:47 +0100 |
commit | 3747f01d19676f6f8d5d8b0a05c9ddbf6d92be49 (patch) | |
tree | 3e68106ae3554e0bdd3d770d0cfd7bf39f56996b /lib/ssh/src/ssh.erl | |
parent | d56fda8a730ff43bdfc15936519effb61fbd03e3 (diff) | |
parent | e6d99a21e905f234d579bd2e64a275fc4fdd5ed9 (diff) | |
download | otp-3747f01d19676f6f8d5d8b0a05c9ddbf6d92be49.tar.gz otp-3747f01d19676f6f8d5d8b0a05c9ddbf6d92be49.tar.bz2 otp-3747f01d19676f6f8d5d8b0a05c9ddbf6d92be49.zip |
Merge branch 'hans/ssh/fd_more/OTP-12966' into maint
* hans/ssh/fd_more/OTP-12966:
ssh: testcases for starting daemon with given fd
ssh: Make it possible for more than one daemon started with option fd
Diffstat (limited to 'lib/ssh/src/ssh.erl')
-rw-r--r-- | lib/ssh/src/ssh.erl | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl index 5bde184070..bb50e436a3 100644 --- a/lib/ssh/src/ssh.erl +++ b/lib/ssh/src/ssh.erl @@ -235,10 +235,27 @@ start_daemon(Host, Port, Options, Inet) -> {error, _Reason} = Error -> Error; {SocketOptions, SshOptions}-> - do_start_daemon(Host, Port,[{role, server} |SshOptions] , [Inet | SocketOptions]) + try + do_start_daemon(Host, Port,[{role, server} |SshOptions] , [Inet | SocketOptions]) + catch + throw:bad_fd -> {error,bad_fd}; + _C:_E -> {error,{cannot_start_daemon,_C,_E}} + end end. -do_start_daemon(Host, Port, Options, SocketOptions) -> +do_start_daemon(Host0, Port0, Options, SocketOptions) -> + {Host,Port} = try + case proplists:get_value(fd, SocketOptions) of + undefined -> + {Host0,Port0}; + Fd when Port0==0 -> + find_hostport(Fd); + _ -> + {Host0,Port0} + end + catch + _:_ -> throw(bad_fd) + end, Profile = proplists:get_value(profile, Options, ?DEFAULT_PROFILE), case ssh_system_sup:system_supervisor(Host, Port, Profile) of undefined -> @@ -272,6 +289,22 @@ do_start_daemon(Host, Port, Options, SocketOptions) -> end end. +find_hostport(Fd) -> + %% Using internal functions inet:open/8 and inet:close/0. + %% Don't try this at home unless you know what you are doing! + {ok,S} = inet:open(Fd, {0,0,0,0}, 0, [], tcp, inet, stream, inet_tcp), + {ok, HostPort} = inet:sockname(S), + ok = inet:close(S), + HostPort. + +%% find_port(Fd) -> +%% %% Hack.... +%% {ok,TmpSock} = gen_tcp:listen(0,[{fd,Fd}]), +%% {ok, {_,ThePort}} = inet:sockname(TmpSock), +%% gen_tcp:close(TmpSock), +%% ThePort. + + handle_options(Opts) -> try handle_option(algs_compatibility(proplists:unfold(Opts)), [], []) of {Inet, Ssh} -> |