mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
refactor(TerminalShell): changing recursion into loops
This commit is contained in:
@@ -125,33 +125,37 @@ static pid_t getShellInfo(FFShellResult* result, pid_t pid)
|
||||
|
||||
pid_t ppid = 0;
|
||||
|
||||
if(getProcessNameAndPpid(pid, name, &ppid))
|
||||
return 0;
|
||||
while (getProcessNameAndPpid(pid, name, &ppid) == NULL)
|
||||
{
|
||||
//Common programs that are between terminal and own process, but are not the shell
|
||||
if(
|
||||
ffStrEquals(name, "sh") || //This prevents us from detecting things like pipes and redirects, i hope nobody uses plain `sh` as shell
|
||||
ffStrEquals(name, "sudo") ||
|
||||
ffStrEquals(name, "su") ||
|
||||
ffStrEquals(name, "strace") ||
|
||||
ffStrEquals(name, "sshd") ||
|
||||
ffStrEquals(name, "gdb") ||
|
||||
ffStrEquals(name, "lldb") ||
|
||||
ffStrEquals(name, "lldb-mi") ||
|
||||
ffStrEquals(name, "login") ||
|
||||
ffStrEquals(name, "ltrace") ||
|
||||
ffStrEquals(name, "perf") ||
|
||||
ffStrEquals(name, "guake-wrapped") ||
|
||||
ffStrContainsIgnCase(name, "debug") ||
|
||||
ffStrContainsIgnCase(name, "not-found") ||
|
||||
ffStrEndsWith(name, ".sh")
|
||||
)
|
||||
{
|
||||
pid = ppid;
|
||||
continue;
|
||||
}
|
||||
|
||||
//Common programs that are between terminal and own process, but are not the shell
|
||||
if(
|
||||
ffStrEquals(name, "sh") || //This prevents us from detecting things like pipes and redirects, i hope nobody uses plain `sh` as shell
|
||||
ffStrEquals(name, "sudo") ||
|
||||
ffStrEquals(name, "su") ||
|
||||
ffStrEquals(name, "strace") ||
|
||||
ffStrEquals(name, "sshd") ||
|
||||
ffStrEquals(name, "gdb") ||
|
||||
ffStrEquals(name, "lldb") ||
|
||||
ffStrEquals(name, "lldb-mi") ||
|
||||
ffStrEquals(name, "login") ||
|
||||
ffStrEquals(name, "ltrace") ||
|
||||
ffStrEquals(name, "perf") ||
|
||||
ffStrEquals(name, "guake-wrapped") ||
|
||||
ffStrContainsIgnCase(name, "debug") ||
|
||||
ffStrContainsIgnCase(name, "not-found") ||
|
||||
ffStrEndsWith(name, ".sh")
|
||||
)
|
||||
return getShellInfo(result, ppid);
|
||||
|
||||
result->pid = (uint32_t) pid;
|
||||
result->ppid = (uint32_t) ppid;
|
||||
ffStrbufSetS(&result->processName, name);
|
||||
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName);
|
||||
result->pid = (uint32_t) pid;
|
||||
result->ppid = (uint32_t) ppid;
|
||||
ffStrbufSetS(&result->processName, name);
|
||||
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName);
|
||||
break;
|
||||
}
|
||||
return ppid;
|
||||
}
|
||||
|
||||
@@ -162,39 +166,46 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
|
||||
|
||||
pid_t ppid = 0;
|
||||
|
||||
if(getProcessNameAndPpid(pid, name, &ppid))
|
||||
return 0;
|
||||
while (getProcessNameAndPpid(pid, name, &ppid) == NULL)
|
||||
{
|
||||
//Known shells
|
||||
if (
|
||||
ffStrEquals(name, "ash") ||
|
||||
ffStrEquals(name, "bash") ||
|
||||
ffStrEquals(name, "zsh") ||
|
||||
ffStrEquals(name, "ksh") ||
|
||||
ffStrEquals(name, "mksh") ||
|
||||
ffStrEquals(name, "oksh") ||
|
||||
ffStrEquals(name, "csh") ||
|
||||
ffStrEquals(name, "tcsh") ||
|
||||
ffStrEquals(name, "fish") ||
|
||||
ffStrEquals(name, "dash") ||
|
||||
ffStrEquals(name, "pwsh") ||
|
||||
ffStrEquals(name, "nu") ||
|
||||
ffStrEquals(name, "git-shell") ||
|
||||
ffStrEquals(name, "elvish") ||
|
||||
ffStrEquals(name, "oil.ovm") ||
|
||||
(ffStrEquals(name, "python") && getenv("XONSH_VERSION"))
|
||||
)
|
||||
{
|
||||
pid = ppid;
|
||||
continue;
|
||||
}
|
||||
|
||||
//Known shells
|
||||
if (
|
||||
ffStrEquals(name, "ash") ||
|
||||
ffStrEquals(name, "bash") ||
|
||||
ffStrEquals(name, "zsh") ||
|
||||
ffStrEquals(name, "ksh") ||
|
||||
ffStrEquals(name, "mksh") ||
|
||||
ffStrEquals(name, "oksh") ||
|
||||
ffStrEquals(name, "csh") ||
|
||||
ffStrEquals(name, "tcsh") ||
|
||||
ffStrEquals(name, "fish") ||
|
||||
ffStrEquals(name, "dash") ||
|
||||
ffStrEquals(name, "pwsh") ||
|
||||
ffStrEquals(name, "nu") ||
|
||||
ffStrEquals(name, "git-shell") ||
|
||||
ffStrEquals(name, "elvish") ||
|
||||
ffStrEquals(name, "oil.ovm") ||
|
||||
(ffStrEquals(name, "python") && getenv("XONSH_VERSION"))
|
||||
)
|
||||
return getTerminalInfo(result, ppid);
|
||||
#ifdef __APPLE__
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/501
|
||||
if (ffStrEndsWith(name, " (figterm)") || ffStrEndsWith(name, " (cwterm)"))
|
||||
{
|
||||
if (__builtin_expect(getProcessNameAndPpid(ppid, name, &ppid) != NULL, false))
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/501
|
||||
if (ffStrEndsWith(name, " (figterm)") || ffStrEndsWith(name, " (cwterm)"))
|
||||
getProcessNameAndPpid(ppid, name, &ppid);
|
||||
#endif
|
||||
|
||||
result->pid = (uint32_t) pid;
|
||||
ffStrbufSetS(&result->processName, name);
|
||||
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName);
|
||||
result->pid = (uint32_t) pid;
|
||||
ffStrbufSetS(&result->processName, name);
|
||||
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName);
|
||||
break;
|
||||
}
|
||||
return ppid;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,48 +87,50 @@ static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
|
||||
{
|
||||
uint32_t ppid;
|
||||
|
||||
if(pid == 0 || !getProcessInfo(pid, &ppid, &result->processName, &result->exe, &result->exeName))
|
||||
return 0;
|
||||
|
||||
ffStrbufSet(&result->prettyName, &result->processName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
|
||||
|
||||
//Common programs that are between terminal and own process, but are not the shell
|
||||
if(
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "sudo") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "su") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "doas") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "strace") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "sshd") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "gdb") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "lldb") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "guake-wrapped") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "fastfetch") || //scoop warps the real binaries with a "shim" exe
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "flashfetch") ||
|
||||
ffStrbufContainIgnCaseS(&result->prettyName, "debug") ||
|
||||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmu") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
|
||||
) {
|
||||
ffStrbufClear(&result->processName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
ffStrbufClear(&result->exe);
|
||||
result->exeName = NULL;
|
||||
return getShellInfo(result, ppid);
|
||||
}
|
||||
|
||||
ffStrbufClear(&result->version);
|
||||
fftsGetShellVersion(&result->exe, result->prettyName.chars, &result->version);
|
||||
|
||||
result->pid = pid;
|
||||
result->ppid = ppid;
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&result->prettyName, "explorer"))
|
||||
while (pid != 0 && getProcessInfo(pid, &ppid, &result->processName, &result->exe, &result->exeName))
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "Windows Explorer"); // Started without shell
|
||||
// In this case, terminal process will be created by fastfetch itself.
|
||||
ppid = 0;
|
||||
}
|
||||
ffStrbufSet(&result->prettyName, &result->processName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
|
||||
|
||||
//Common programs that are between terminal and own process, but are not the shell
|
||||
if(
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "sudo") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "su") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "doas") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "strace") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "sshd") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "gdb") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "lldb") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "guake-wrapped") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "fastfetch") || //scoop warps the real binaries with a "shim" exe
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "flashfetch") ||
|
||||
ffStrbufContainIgnCaseS(&result->prettyName, "debug") ||
|
||||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmu") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
|
||||
) {
|
||||
ffStrbufClear(&result->processName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
ffStrbufClear(&result->exe);
|
||||
result->exeName = NULL;
|
||||
pid = ppid;
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufClear(&result->version);
|
||||
fftsGetShellVersion(&result->exe, result->prettyName.chars, &result->version);
|
||||
|
||||
result->pid = pid;
|
||||
result->ppid = ppid;
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&result->prettyName, "explorer"))
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "Windows Explorer"); // Started without shell
|
||||
// In this case, terminal process will be created by fastfetch itself.
|
||||
ppid = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return ppid;
|
||||
}
|
||||
|
||||
@@ -296,55 +298,57 @@ static uint32_t getTerminalInfo(FFTerminalResult* result, uint32_t pid)
|
||||
{
|
||||
uint32_t ppid;
|
||||
|
||||
if(pid == 0 || !getProcessInfo(pid, &ppid, &result->processName, &result->exe, &result->exeName))
|
||||
return 0;
|
||||
while (pid != 0 && getProcessInfo(pid, &ppid, &result->processName, &result->exe, &result->exeName))
|
||||
{
|
||||
ffStrbufSet(&result->prettyName, &result->processName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
|
||||
|
||||
ffStrbufSet(&result->prettyName, &result->processName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
|
||||
|
||||
if(
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "pwsh") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "cmd") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "bash") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "zsh") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "fish") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "nu") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "powershell") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "powershell_ise") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "wsl") || // running inside wsl
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "servercoreshell") || // ServerCore Shell Launcher
|
||||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmuC") // wrapper process of ConEmu
|
||||
) {
|
||||
//We are nested shell
|
||||
ffStrbufClear(&result->processName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
ffStrbufClear(&result->exe);
|
||||
result->exeName = "";
|
||||
return getTerminalInfo(result, ppid);
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&result->prettyName, "sihost") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "explorer")
|
||||
) {
|
||||
// A CUI program created by Windows Explorer will spawn a conhost as its child.
|
||||
// However the conhost process is just a placeholder;
|
||||
// The true terminal can be Windows Terminal or others.
|
||||
if (!getTerminalFromEnv(result) && !detectDefaultTerminal(result))
|
||||
{
|
||||
if(
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "pwsh") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "cmd") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "bash") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "zsh") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "fish") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "nu") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "powershell") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "powershell_ise") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "wsl") || // running inside wsl
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "servercoreshell") || // ServerCore Shell Launcher
|
||||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmuC") // wrapper process of ConEmu
|
||||
) {
|
||||
//We are nested shell
|
||||
ffStrbufClear(&result->processName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
ffStrbufClear(&result->exe);
|
||||
result->exeName = "";
|
||||
return 0;
|
||||
pid = ppid;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result->pid = pid;
|
||||
result->ppid = ppid;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&result->prettyName, "sihost") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "explorer")
|
||||
) {
|
||||
// A CUI program created by Windows Explorer will spawn a conhost as its child.
|
||||
// However the conhost process is just a placeholder;
|
||||
// The true terminal can be Windows Terminal or others.
|
||||
if (!getTerminalFromEnv(result) && !detectDefaultTerminal(result))
|
||||
{
|
||||
ffStrbufClear(&result->processName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
ffStrbufClear(&result->exe);
|
||||
result->exeName = "";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result->pid = pid;
|
||||
result->ppid = ppid;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return ppid;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user