Skip to content

Commit

Permalink
yet another executor fix
Browse files Browse the repository at this point in the history
  • Loading branch information
alabuzhev committed Jun 11, 2016
1 parent 1a36a26 commit b8c3d57
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 38 deletions.
4 changes: 4 additions & 0 deletions far/changelog
@@ -1,3 +1,7 @@
drkns 11.06.2016 22:55:07 +0200 - build 4702

1. Ещё одно уточнение работы запускателя.

drkns 11.06.2016 20:05:25 +0200 - build 4701

1. Рефакторинг.
Expand Down
4 changes: 2 additions & 2 deletions far/cmdline.cpp
Expand Up @@ -848,7 +848,7 @@ void CommandLine::ShowViewEditHistory()
{
execute_info Info;
Info.Command = strStr;
Info.WaitMode = Type == HR_EXTERNAL_WAIT? Info.wait_finish : Info.no_wait;
Info.WaitMode = Type == HR_EXTERNAL_WAIT? execute_info::wait_mode::wait_finish : execute_info::wait_mode::no_wait;

ExecString(Info);
break;
Expand Down Expand Up @@ -1057,7 +1057,7 @@ void CommandLine::ExecString(execute_info& Info)

FarChDir(m_CurDir);

if (Info.ExecMode != Info.direct)
if (Info.ExecMode != execute_info::exec_mode::direct && Info.SourceMode != execute_info::source_mode::known)
{
if (!Info.Command.empty() && Info.Command[0] == L'@')
{
Expand Down
14 changes: 8 additions & 6 deletions far/cmdline.hpp
Expand Up @@ -40,14 +40,16 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

struct execute_info
{
enum wait_mode { no_wait, wait_idle, wait_finish };
enum exec_mode { detect, direct, external };
enum class wait_mode { no_wait, wait_idle, wait_finish };
enum class exec_mode { detect, direct, external };
enum class source_mode { unknown, known };

string Command;
wait_mode WaitMode = no_wait;
bool NewWindow = false;
exec_mode ExecMode = detect;
bool RunAs = false;
wait_mode WaitMode{ wait_mode::no_wait };
bool NewWindow{};
exec_mode ExecMode{ exec_mode::detect };
source_mode SourceMode{ source_mode::unknown };
bool RunAs{};
};

class execution_context;
Expand Down
49 changes: 30 additions & 19 deletions far/execute.cpp
Expand Up @@ -194,7 +194,12 @@ static bool FindObject(const string& Module, string &strDest, bool &Internal)
{
auto strFullName = Module;
const auto ModuleExt = wcsrchr(PointToName(Module), L'.');
const auto strPathExt = os::env::get_pathext() + L";;"; // ";;" to also try no extension if nothing else matches
auto strPathExt = os::env::get_pathext();
if (Global->Opt->UseRegisteredTypes)
{
// ";;" to also try no extension if nothing else matches
strPathExt += L";;";
}
const auto PathExtList = split<std::vector<string>>(strPathExt, STLF_UNIQUE | STLF_ALLOWEMPTY);

for (const auto& i: PathExtList) // первый проход - в текущем каталоге
Expand Down Expand Up @@ -600,7 +605,8 @@ void OpenFolderInShell(const string& Folder)
execute_info Info;
Info.Command = Folder;
Info.NewWindow = true;
Info.ExecMode = Info.direct;
Info.ExecMode = execute_info::exec_mode::direct;
Info.SourceMode = execute_info::source_mode::known;

Execute(Info, true, true);
}
Expand All @@ -611,11 +617,15 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio
string strNewCmdStr;
string strNewCmdPar;

if (!PartCmdLine(Info.Command, strNewCmdStr, strNewCmdPar))
if (Info.SourceMode == execute_info::source_mode::known)
{
strNewCmdStr = Info.Command;
}
else if (!PartCmdLine(Info.Command, strNewCmdStr, strNewCmdPar))
{
// Complex expression (pipe or redirection): fallback to comspec as is
strNewCmdStr = Info.Command;
Info.ExecMode = Info.external;
Info.ExecMode = execute_info::exec_mode::external;
}

bool IsDirectory = false;
Expand All @@ -642,18 +652,19 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio
{
strNewCmdStr = Unquoted;
ConvertNameToFull(strNewCmdStr, strNewCmdStr);
Info.ExecMode = Info.direct;
Info.ExecMode = execute_info::exec_mode::direct;
Info.SourceMode = execute_info::source_mode::known;
FolderRun=true;
}
}

string Verb;

if (FolderRun && Info.ExecMode == Info.direct)
if (FolderRun && Info.ExecMode == execute_info::exec_mode::direct)
{
AddEndSlash(strNewCmdStr); // НАДА, иначе ShellExecuteEx "возьмет" BAT/CMD/пр.ересь, но не каталог
}
else if (Info.ExecMode == Info.detect)
else if (Info.ExecMode == execute_info::exec_mode::detect)
{
auto GetAssociatedImageType = [&Verb](const string& Str, image_type& ImageType)
{
Expand Down Expand Up @@ -701,18 +712,18 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio

auto ImageType = image_type::unknown;

if (FindObject(ModuleName, FoundModuleName, Internal))
if (Info.SourceMode == execute_info::source_mode::known || FindObject(ModuleName, FoundModuleName, Internal))
{
if (Internal)
{
// Internal comspec command (one of ExcludeCmds): fallback to comspec as is
Info.ExecMode = Info.external;
Info.ExecMode = execute_info::exec_mode::external;
strNewCmdStr = Info.Command;
}
else if (GetImageType(FoundModuleName, ImageType) || GetAssociatedImageType(FoundModuleName, ImageType) || GetImageTypeFallback(ImageType))
{
// We can run it directly
Info.ExecMode = Info.direct;
Info.ExecMode = execute_info::exec_mode::direct;
strNewCmdStr = FoundModuleName;
strNewCmdPar = os::env::expand_strings(strNewCmdPar);

Expand All @@ -726,12 +737,12 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio
else
{
// Found nothing: fallback to comspec as is
Info.ExecMode = Info.external;
Info.ExecMode = execute_info::exec_mode::external;
strNewCmdStr = Info.Command;
}
}

if (Info.WaitMode == Info.wait_finish)
if (Info.WaitMode == execute_info::wait_mode::wait_finish)
{
// It's better to show console rather than non-responding panels
Silent = false;
Expand Down Expand Up @@ -775,18 +786,18 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio

// ShellExecuteEx Win8.1+ wrongly opens symlinks in a separate console window
// Workaround: execute through %comspec%
if (Info.ExecMode == Info.direct && !Info.NewWindow && IsWindows8Point1OrGreater())
if (Info.ExecMode == execute_info::exec_mode::direct && !Info.NewWindow && IsWindows8Point1OrGreater())
{
os::fs::file_status fstatus(strNewCmdStr);
if (os::fs::is_file(fstatus) && fstatus.check(FILE_ATTRIBUTE_REPARSE_POINT))
{
Info.ExecMode = Info.external;
Info.ExecMode = execute_info::exec_mode::external;
}
}

string strComspec, ComSpecParams;

if (Info.ExecMode == Info.direct)
if (Info.ExecMode == execute_info::exec_mode::direct)
{
seInfo.lpFile = strNewCmdStr.data();
if(!strNewCmdPar.empty())
Expand Down Expand Up @@ -867,7 +878,7 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio
{
if (Process)
{
if (Info.WaitMode == Info.wait_finish || !Info.NewWindow)
if (Info.WaitMode == execute_info::wait_mode::wait_finish || !Info.NewWindow)
{
if (Global->Opt->ConsoleDetachKey.empty())
{
Expand Down Expand Up @@ -955,7 +966,7 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio
}
}
}
if(Info.WaitMode == Info.wait_idle)
if(Info.WaitMode == execute_info::wait_mode::wait_idle)
{
WaitForInputIdle(Process.native_handle(), INFINITE);
}
Expand Down Expand Up @@ -991,7 +1002,7 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio
if (!Result)
{
std::vector<string> Strings;
if (Info.ExecMode == Info.direct)
if (Info.ExecMode == execute_info::exec_mode::direct)
Strings = { MSG(MCannotExecute), strNewCmdStr };
else
Strings = { MSG(MCannotInvokeComspec), strComspec, MSG(MCheckComspecVar) };
Expand All @@ -1003,7 +1014,7 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio
L"ErrCannotExecute",
nullptr,
nullptr,
{ Info.ExecMode == Info.direct? strNewCmdStr : strComspec });
{ Info.ExecMode == execute_info::exec_mode::direct? strNewCmdStr : strComspec });
}

return Result;
Expand Down
10 changes: 3 additions & 7 deletions far/filelist.cpp
Expand Up @@ -2681,15 +2681,11 @@ void FileList::ProcessEnter(bool EnableExec,bool SeparateWindow,bool EnableAssoc
{
execute_info Info;
Info.Command = strFileName;
Info.WaitMode = PluginMode? Info.wait_finish : Info.no_wait;
Info.WaitMode = PluginMode? execute_info::wait_mode::wait_finish : execute_info::wait_mode::no_wait;
Info.NewWindow = SeparateWindow;
Info.SourceMode = execute_info::source_mode::known;
Info.RunAs = RunAs;

// Here we definitely know that we're about to launch an actual file,
// (as manually typed commands are processed elsewhere), so launcher shall NOT try to search for it.
// However, we can't simply set ExecMode to 'direct' as we need to know image type anyway
// to launch it silently or in console mode.
// So, to avoid introducing some new additional weird flags, we just use the full file name:
ConvertNameToFull(Info.Command, Info.Command);
QuoteSpace(Info.Command);

Expand Down Expand Up @@ -4928,7 +4924,7 @@ bool FileList::ApplyCommand()

execute_info Info;
Info.Command = strConvertedCommand;
Info.WaitMode = ListFileUsed? Info.wait_idle : Info.no_wait;
Info.WaitMode = ListFileUsed? execute_info::wait_mode::wait_idle : execute_info::wait_mode::no_wait;

Parent()->GetCmdLine()->ExecString(Info);
//if (!(Global->Opt->ExcludeCmdHistory&EXCLUDECMDHISTORY_NOTAPPLYCMD))
Expand Down
4 changes: 2 additions & 2 deletions far/filetype.cpp
Expand Up @@ -185,7 +185,7 @@ bool ProcessLocalFileTypes(const string& Name, const string& ShortName, FILETYPE

execute_info Info;
Info.Command = strCommand;
Info.WaitMode = AlwaysWaitFinish? Info.wait_finish : ListFileUsed? Info.wait_idle : Info.no_wait;
Info.WaitMode = AlwaysWaitFinish? execute_info::wait_mode::wait_finish : ListFileUsed? execute_info::wait_mode::wait_idle : execute_info::wait_mode::no_wait;

Global->CtrlObject->CmdLine()->ExecString(Info);

Expand Down Expand Up @@ -299,7 +299,7 @@ void ProcessExternal(const string& Command, const string& Name, const string& Sh

execute_info Info;
Info.Command = strExecStr;
Info.WaitMode = AlwaysWaitFinish? Info.wait_finish : ListFileUsed? Info.wait_idle : Info.no_wait;
Info.WaitMode = AlwaysWaitFinish? execute_info::wait_mode::wait_finish : ListFileUsed? execute_info::wait_mode::wait_idle : execute_info::wait_mode::no_wait;

Global->CtrlObject->CmdLine()->ExecString(Info);

Expand Down
2 changes: 1 addition & 1 deletion far/usermenu.cpp
Expand Up @@ -801,7 +801,7 @@ int UserMenu::ProcessSingleMenu(std::list<UserMenuItem>& Menu, int MenuPos, std:

execute_info Info;
Info.Command = strCommand;
Info.WaitMode = ListFileUsed? Info.wait_idle : Info.no_wait;
Info.WaitMode = ListFileUsed? execute_info::wait_mode::wait_idle : execute_info::wait_mode::no_wait;

Global->CtrlObject->CmdLine()->ExecString(Info);
}
Expand Down
2 changes: 1 addition & 1 deletion far/vbuild.m4
@@ -1 +1 @@
m4_define(BUILD,4701)m4_dnl
m4_define(BUILD,4702)m4_dnl

0 comments on commit b8c3d57

Please sign in to comment.