TerminalShell: unify shell version detection code

This commit is contained in:
李通洲
2022-10-14 16:28:03 +08:00
parent 622f84c971
commit 11ad7a8a3d
4 changed files with 75 additions and 77 deletions
+2 -1
View File
@@ -237,6 +237,7 @@ set(LIBFASTFETCH_SRC
src/detection/font/font.c
src/detection/displayserver/displayserver.c
src/detection/terminalfont/terminalfont.c
src/detection/terminalshell/terminalshell.c
src/detection/media/media.c
src/detection/packages/packages.c
src/modules/break.c
@@ -363,7 +364,6 @@ if(MSYS OR WIN32)
src/detection/cpuUsage/cpuUsage_nowait_windows.cpp
src/detection/memory/memory_windows.cpp
src/detection/font/font_windows.cpp
src/detection/terminalshell/terminalshell_windows.cpp
src/detection/terminalfont/terminalfont_windows.c
src/detection/localip/localip_windows.c
src/detection/uptime/uptime_windows.c
@@ -386,6 +386,7 @@ if(WIN32)
list(APPEND LIBFASTFETCH_SRC
src/common/processing_windows.c
src/detection/packages/packages_windows.c
src/detection/terminalshell/terminalshell_windows.cpp
src/util/windows/getline.c
src/util/windows/pwd.c
src/util/windows/utsname.c
@@ -0,0 +1,64 @@
#include "fastfetch.h"
#include "common/processing.h"
static void getShellVersionBash(FFstrbuf* exe, FFstrbuf* version)
{
ffProcessAppendStdOut(version, (char* const[]) {
"env",
"-i",
exe->chars,
"--norc",
"--noprofile",
"-c",
"printf \"%s\" \"$BASH_VERSION\"",
NULL
});
ffStrbufSubstrBeforeFirstC(version, '(');
}
static void getShellVersionZsh(FFstrbuf* exe, FFstrbuf* version)
{
ffProcessAppendStdOut(version, (char* const[]) {
exe->chars,
"--version",
NULL
});
ffStrbufSubstrBeforeLastC(version, ' ');
ffStrbufSubstrAfterFirstC(version, ' ');
}
static void getShellVersionFishPwsh(FFstrbuf* exe, FFstrbuf* version)
{
ffProcessAppendStdOut(version, (char* const[]) {
exe->chars,
"--version",
NULL
});
ffStrbufTrimRight(version, '\n');
ffStrbufSubstrAfterLastC(version, ' ');
}
static void getShellVersionNu(FFstrbuf* exe, FFstrbuf* version)
{
ffProcessAppendStdOut(version, (char* const[]) {
exe->chars,
"--version",
NULL
});
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
{
bool ok = true;
if(strcasecmp(exeName, "bash") == 0 || strcasecmp(exeName, "sh") == 0)
getShellVersionBash(exe, version);
else if(strcasecmp(exeName, "zsh") == 0)
getShellVersionZsh(exe, version);
else if(strcasecmp(exeName, "fish") == 0 || strcasecmp(exeName, "pwsh") == 0)
getShellVersionFishPwsh(exe, version);
else if(strcasecmp(exeName, "nu") == 0)
getShellVersionNu(exe, version);
else
ok = false;
return ok;
}
@@ -135,6 +135,7 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
strcasecmp(name, "fish") == 0 ||
strcasecmp(name, "dash") == 0 ||
strcasecmp(name, "pwsh") == 0 ||
strcasecmp(name, "nu") == 0 ||
strcasecmp(name, "git-shell") == 0
) {
ffStrbufSetS(&result->shellProcessName, name); // prevent from `fishbash`
@@ -236,43 +237,6 @@ static void getUserShellFromEnv(FFTerminalShellResult* result)
}
}
static void getShellVersionBash(FFstrbuf* exe, FFstrbuf* version)
{
ffProcessAppendStdOut(version, (char* const[]) {
"env",
"-i",
exe->chars,
"--norc",
"--noprofile",
"-c",
"printf \"%s\" \"$BASH_VERSION\"",
NULL
});
ffStrbufSubstrBeforeFirstC(version, '(');
}
static void getShellVersionZsh(FFstrbuf* exe, FFstrbuf* version)
{
ffProcessAppendStdOut(version, (char* const[]) {
exe->chars,
"--version",
NULL
});
ffStrbufSubstrBeforeLastC(version, ' ');
ffStrbufSubstrAfterFirstC(version, ' ');
}
static void getShellVersionFish(FFstrbuf* exe, FFstrbuf* version)
{
ffProcessAppendStdOut(version, (char* const[]) {
exe->chars,
"--version",
NULL
});
ffStrbufTrimRight(version, '\n');
ffStrbufSubstrAfterLastC(version, ' ');
}
static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
{
FFstrbuf command;
@@ -295,26 +259,16 @@ static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf*
ffStrbufDestroy(&command);
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
{
ffStrbufClear(version);
if(strcasecmp(exeName, "bash") == 0)
getShellVersionBash(exe, version);
else if(strcasecmp(exeName, "zsh") == 0)
getShellVersionZsh(exe, version);
else if(strcasecmp(exeName, "fish") == 0 || strcasecmp(exeName, "pwsh") == 0)
getShellVersionFish(exe, version);
else
if(!fftsGetShellVersion(exe, exeName, version))
getShellVersionGeneric(exe, exeName, version);
}
const FFTerminalShellResult*
#if defined(__MSYS__) || defined(_WIN32)
ffDetectTerminalShellPosix
#else
ffDetectTerminalShell
#endif
(const FFinstance* instance)
const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
{
FF_UNUSED(instance);
@@ -50,13 +50,7 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb
return true;
}
static void getShellVersion(FFstrbuf* exe, FFstrbuf* version)
{
char* const argv[] = { exe->chars, (char*)"--version", NULL };
ffProcessAppendStdOut(version, argv);
ffStrbufTrimRight(version, '\n');
ffStrbufSubstrAfterLastC(version, ' ');
}
extern "C" bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
{
@@ -70,11 +64,11 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
if(ffStrbufEndsWithIgnCaseS(&result->shellPrettyName, ".exe"))
ffStrbufSubstrBefore(&result->shellPrettyName, result->shellPrettyName.length - 4);
ffStrbufClear(&result->shellVersion);
fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion);
if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "pwsh") == 0)
{
ffStrbufSetS(&result->shellPrettyName, "PowerShell");
getShellVersion(&result->shellExe, &result->shellVersion);
}
else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell") == 0)
ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell");
else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "powershell_ise") == 0)
@@ -112,23 +106,8 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid)
return ppid;
}
#ifdef __MSYS__
extern "C"
const FFTerminalShellResult* ffDetectTerminalShellPosix(const FFinstance* instance);
#endif
const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
{
#ifdef __MSYS__
// This is hacky.
// When running inside of MSYS2, the real Windows parent process doesn't exist and we must find it in Linux way ( /proc/self/xxx )
// When running outside of MSYS2, /proc/self/xxx doesn't exist and we must find it in Windows way
if(getenv("MSYSTEM"))
return ffDetectTerminalShellPosix(instance);
#else
FF_UNUSED(instance);
#endif
static FFTerminalShellResult result;
static bool init = false;
if(init)