From 851f61719985651e769f8df8246d5ddb855cc022 Mon Sep 17 00:00:00 2001 From: Aleksandr Vinokurov Date: Thu, 8 Nov 2012 13:59:12 +0400 Subject: Fix deep list argument error under Windows in os:cmd/1 Because of leeway in implementing os:cmd/1 under different OS there is a difference in results when calling it with deep list argument. os:cmd/1 specifies io_lib:chars() type for its argument and io_lib functions can produce deep lists inspite of io_lib:chars() result type specification. This commit flattens the argument for erlang:open_port/2 (which is used under Windows) and expands the os_SUITE to regress the bug. --- lib/kernel/src/os.erl | 5 ++++- lib/kernel/test/os_SUITE.erl | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'lib/kernel') diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl index 742c000cc1..2bded77fc4 100644 --- a/lib/kernel/src/os.erl +++ b/lib/kernel/src/os.erl @@ -187,11 +187,14 @@ cmd(Cmd) -> {unix, _} -> unix_cmd(Cmd); {win32, Wtype} -> - Command = case {os:getenv("COMSPEC"),Wtype} of + Command0 = case {os:getenv("COMSPEC"),Wtype} of {false,windows} -> lists:concat(["command.com /c", Cmd]); {false,_} -> lists:concat(["cmd /c", Cmd]); {Cspec,_} -> lists:concat([Cspec," /c",Cmd]) end, + %% open_port/2 awaits string() in Command, but io_lib:chars() can be + %% deep lists according to io_lib module description. + Command = lists:flatten(Command0), Port = open_port({spawn, Command}, [stream, in, eof, hide]), get_data(Port, []) end. diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl index 382fd6f6a9..e302bf7378 100644 --- a/lib/kernel/test/os_SUITE.erl +++ b/lib/kernel/test/os_SUITE.erl @@ -29,7 +29,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [space_in_cwd, quoting, space_in_name, bad_command, - find_executable, unix_comment_in_command, evil]. + find_executable, unix_comment_in_command, deep_list_command, + evil]. groups() -> []. @@ -237,6 +238,20 @@ unix_comment_in_command(Config) when is_list(Config) -> ?line test_server:timetrap_cancel(Dog), ok. +deep_list_command(doc) -> + "Check that a deep list in command works equally on unix and on windows."; +deep_list_command(suite) -> []; +deep_list_command(Config) when is_list(Config) -> + %% As a 'io_lib' module description says: "There is no guarantee that the + %% character lists returned from some of the functions are flat, they can + %% be deep lists." + %% That's why os:cmd/1 can have arguments that are deep lists. + %% It is not a problem for unix, but for windows it is (in R15B02 for ex.). + ?line os:cmd([$e, $c, "ho"]), + %% FYI: [$e, $c, "ho"] =:= io_lib:format("ec~s", ["ho"]) + ok. + + -define(EVIL_PROCS, 100). -define(EVIL_LOOPS, 100). -define(PORT_CREATOR, os_cmd_port_creator). -- cgit v1.2.3