diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index e84cb1497..6a41daff2 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -123,76 +123,6 @@ jobs: name: fastfetch-bsd path: ./fastfetch-*.* - msys: - name: MSYS - runs-on: windows-latest - permissions: - security-events: write - contents: read - defaults: - run: - shell: msys2 {0} - steps: - - name: checkout repository - uses: actions/checkout@v3 - - - name: setup-msys2 - uses: msys2/setup-msys2@v2 - with: - msystem: MSYS - update: true - install: git base-devel cmake gcc mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd - - - name: print msys version - run: uname -a - - # https://github.com/msys2/MINGW-packages/issues/13524#event-7555720785 - - name: create OpenCL.pc - run: | - cat > /clang64/lib/pkgconfig/OpenCL.pc << EOF - prefix=/clang64 - exec_prefix=${prefix} - libdir=${exec_prefix}/lib - includedir=${prefix}/include - - Name: OpenCL - Description: Open Computing Language generic Installable Client Driver Loader - Version: 2022.09.30-1 - Libs: -L${libdir} -lOpenCL.dll - Cflags: -I${includedir} - EOF - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: c, cpp - - - name: configure project - run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . - - - name: build project - run: cmake --build . --target fastfetch --target flashfetch # Makes no sense to install exes to /usr/bin for Windows - - - name: perform CodeQL analysis - uses: github/codeql-action/analyze@v2 - - - name: copy necessary dlls - run: cp /usr/bin/msys-2.0.dll /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll . - - - name: run fastfetch - run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all - - - name: run flashfetch - run: ./flashfetch - - - name: upload artifacts - uses: actions/upload-artifact@v3 - with: - name: fastfetch-msys - path: | - ./*.dll - ./*.exe - windows: name: Windows runs-on: windows-latest @@ -241,7 +171,7 @@ jobs: run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . - name: build project - run: cmake --build . --target fastfetch --target flashfetch + run: cmake --build . - name: perform CodeQL analysis uses: github/codeql-action/analyze@v2 @@ -255,13 +185,17 @@ jobs: - name: run flashfetch run: ./flashfetch + - name: run tests + run: ctest + - name: upload artifacts uses: actions/upload-artifact@v3 with: name: fastfetch-windows path: | ./*.dll - ./*.exe + ./fastfetch.exe + ./flashfetch.exe release: if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch' @@ -271,7 +205,6 @@ jobs: - linux - macos - bsd - - msys - windows permissions: contents: write @@ -292,4 +225,4 @@ jobs: tag: ${{ needs.linux.outputs.ffversion }} commit: ${{ github.sha }} artifactErrorsFailBuild: true - artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/* + artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/*,fastfetch-windows/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 25074c595..3f4526855 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,11 +15,11 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*") set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*") set(BSD TRUE CACHE BOOL "..." FORCE) -elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS AND NOT WIN32) +elseif(NOT APPLE AND NOT ANDROID AND NOT WIN32) message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}") endif() -if(MSYS OR WIN32) +if(WIN32) enable_language(CXX) endif() @@ -41,7 +41,7 @@ include(CheckIncludeFile) include(CMakeDependentOption) cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS OR WIN32" OFF) +cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32" OFF) cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF) @@ -60,8 +60,8 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS OR WIN32" OFF) -cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS OR WIN32" OFF) +cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32" OFF) +cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN32" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND AND NOT ANDROID" OFF) @@ -90,7 +90,7 @@ endif() set(CMAKE_C_STANDARD 11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") -if(MSYS OR WIN32) +if(WIN32) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti") endif() @@ -102,7 +102,7 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX}) endif() set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer") -if(NOT MSYS AND NOT WIN32) +if(NOT WIN32) set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") @@ -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 @@ -287,11 +288,10 @@ set(LIBFASTFETCH_SRC if(LINUX OR APPLE OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC - src/detection/users/users_linux.c src/common/processing_linux.c + src/detection/users/users_linux.c src/detection/disk/disk.c src/detection/terminalshell/terminalshell_linux.c - src/detection/kernel/kernel_linux.c src/detection/localip/localip_linux.c ) endif() @@ -345,8 +345,9 @@ if(LINUX OR BSD) ) endif() -if(MSYS OR WIN32) +if(WIN32) list(APPEND LIBFASTFETCH_SRC + src/common/processing_windows.c src/detection/host/host_windows.cpp src/detection/bios/bios_windows.cpp src/detection/board/board_windows.cpp @@ -364,33 +365,18 @@ 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/kernel/kernel_windows.cpp src/detection/localip/localip_windows.c src/detection/uptime/uptime_windows.c - src/util/windows/wmi.cpp - - src/detection/poweradapter/poweradapter_nosupport.c - src/detection/media/media_nosupport.c - ) -endif() - -if(MSYS) - list(APPEND LIBFASTFETCH_SRC - src/common/processing_linux.c - src/detection/terminalshell/terminalshell_linux.c - src/detection/packages/packages_linux.c - ) -endif() - -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/wmi.cpp src/util/windows/getline.c src/util/windows/pwd.c src/util/windows/utsname.c + + src/detection/poweradapter/poweradapter_nosupport.c + src/detection/media/media_nosupport.c ) endif() @@ -528,15 +514,15 @@ if(APPLE) PRIVATE "-framework Cocoa" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" ) -elseif(MSYS OR WIN32) +elseif(WIN32) target_link_libraries(libfastfetch - PRIVATE "wbemuuid" - PRIVATE "ole32" - PRIVATE "oleaut32" PRIVATE "dwmapi" - PRIVATE "opengl32" PRIVATE "gdi32" PRIVATE "iphlpapi" + PRIVATE "ole32" + PRIVATE "oleaut32" + PRIVATE "opengl32" + PRIVATE "wbemuuid" PRIVATE "ws2_32" ) endif() diff --git a/src/common/init.c b/src/common/init.c index 00b3c687a..0427d419b 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -285,7 +285,7 @@ void ffInitInstance(FFinstance* instance) FF_THREAD_ENTRY_DECL_WRAPPER(ffConnectDisplayServer, FFinstance*) -#if !(defined(__APPLE__) || defined(__MSYS__) || defined(_WIN32)) +#if !(defined(__APPLE__) || defined(_WIN32)) #define FF_DETECT_QT_GTK 1 @@ -294,7 +294,7 @@ FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK2, FFinstance*) FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK3, FFinstance*) FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK4, FFinstance*) -#endif //!(defined(__APPLE__) || defined(__MSYS__) || defined(_WIN32)) +#endif //!(defined(__APPLE__) || defined(_WIN32)) #endif //FF_HAVE_THREADS diff --git a/src/common/library.c b/src/common/library.c index 554cc9f39..e771b8d4d 100644 --- a/src/common/library.c +++ b/src/common/library.c @@ -22,7 +22,7 @@ static void* libraryLoad(const char* path, int maxVersion) { void* result = dlopen(path, FF_DLOPEN_FLAGS); - #if defined(_WIN32) || defined(__MSYS__) + #ifdef _WIN32 // libX.dll.1 never exists on Windows, while libX-1.dll may exist FF_UNUSED(maxVersion) diff --git a/src/common/library.h b/src/common/library.h index fd12c0b05..fbbbdac44 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -16,7 +16,7 @@ #include #endif -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 #define FF_LIBRARY_EXTENSION ".dll" #elif defined(__APPLE__) #define FF_LIBRARY_EXTENSION ".dylib" diff --git a/src/common/networking.c b/src/common/networking.c index d3685a543..a5c8ed629 100644 --- a/src/common/networking.c +++ b/src/common/networking.c @@ -1,4 +1,4 @@ -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 #include #include #include @@ -31,7 +31,7 @@ FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout) { - #if defined(_WIN32) || defined(__MSYS__) + #ifdef _WIN32 static INIT_ONCE once = INIT_ONCE_STATIC_INIT; WSADATA* pData; if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData)) diff --git a/src/common/networking.h b/src/common/networking.h index f64288066..0a1b36e5d 100644 --- a/src/common/networking.h +++ b/src/common/networking.h @@ -5,7 +5,7 @@ #include "util/FFstrbuf.h" -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 typedef uintptr_t FFSockType; //SOCKET, unsigned #ifndef INVALID_SOCKET //Don't conflict with #define INVALID_SOCKET ((uintptr_t)~0) diff --git a/src/common/thread.h b/src/common/thread.h index 3c80f84fd..035ff9350 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -14,9 +14,9 @@ typedef SRWLOCK FFThreadMutex; static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); } static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); } - static inline void ffThreadCreateAndDetach(__stdcall unsigned (* func)(void*), void* data) { - uintptr_t newThread = _beginthreadex(func, 0, data, NULL, 0, NULL); - if(newThread != 0) + static inline void ffThreadCreateAndDetach(unsigned (__stdcall* func)(void*), void* data) { + uintptr_t newThread = _beginthreadex(NULL, 0, func, data, 0, NULL); + if(newThread) CloseHandle((HANDLE)newThread); } #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; } diff --git a/src/common/time.h b/src/common/time.h index 7569d40e2..a765e7834 100644 --- a/src/common/time.h +++ b/src/common/time.h @@ -4,7 +4,7 @@ #define FF_INCLUDED_common_time #include -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 #include #include #else @@ -14,7 +14,7 @@ static inline uint64_t ffTimeGetTick() //In msec { - #if defined(_WIN32) || defined(__MSYS__) + #ifdef _WIN32 return GetTickCount64(); #else struct timeval timeNow; @@ -25,7 +25,7 @@ static inline uint64_t ffTimeGetTick() //In msec static inline void ffTimeSleep(uint32_t msec) { - #if defined(_WIN32) || defined(__MSYS__) + #ifdef _WIN32 SleepEx(msec, TRUE); #else nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL); diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h index 4ac03c222..126fc1a8e 100644 --- a/src/detection/cpuUsage/cpuUsage.h +++ b/src/detection/cpuUsage/cpuUsage.h @@ -3,7 +3,7 @@ #ifndef FF_INCLUDED_detection_cpu_cpuUsage #define FF_INCLUDED_detection_cpu_cpuUsage -#if defined(_WIN32) || defined(__MSYS__) +#ifdef _WIN32 // Disabled by default because the result does need some time to generate #define FF_DETECTION_CPUUSAGE_NOWAIT 0 #endif diff --git a/src/detection/kernel/kernel.h b/src/detection/kernel/kernel.h deleted file mode 100644 index 1b29350f3..000000000 --- a/src/detection/kernel/kernel.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#ifndef FF_INCLUDED_detection_kernel_kernel -#define FF_INCLUDED_detection_kernel_kernel - -#include "fastfetch.h" - -typedef struct FFKernelResult -{ - FFstrbuf sysname; - FFstrbuf release; - FFstrbuf version; - FFstrbuf error; -} FFKernelResult; - -void ffDetectKernel(FFinstance* instance, FFKernelResult* result); - -#endif diff --git a/src/detection/kernel/kernel_linux.c b/src/detection/kernel/kernel_linux.c deleted file mode 100644 index 4ab70f027..000000000 --- a/src/detection/kernel/kernel_linux.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "kernel.h" - -void ffDetectKernel(FFinstance* instance, FFKernelResult* result) -{ - ffStrbufInit(&result->error); - ffStrbufInitS(&result->sysname, instance->state.utsname.sysname); - ffStrbufInitS(&result->release, instance->state.utsname.release); - ffStrbufInitS(&result->version, instance->state.utsname.version); -} diff --git a/src/detection/kernel/kernel_windows.cpp b/src/detection/kernel/kernel_windows.cpp deleted file mode 100644 index 94a06d950..000000000 --- a/src/detection/kernel/kernel_windows.cpp +++ /dev/null @@ -1,34 +0,0 @@ -extern "C" { -#include "kernel.h" -} -#include "util/windows/wmi.hpp" - -extern "C" void ffDetectKernel(FFinstance* instance, FFKernelResult* kernel) -{ - FF_UNUSED(instance); - - ffStrbufInit(&kernel->error); - - ffStrbufInitS(&kernel->sysname, "Windows_NT"); - ffStrbufInit(&kernel->release); - ffStrbufInit(&kernel->version); - - IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Version FROM Win32_OperatingSystem", &kernel->error); - if(!pEnumerator) - return; - - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0) - { - ffStrbufInitS(&kernel->error, "No WMI result returned"); - pEnumerator->Release(); - return; - } - - ffGetWmiObjString(pclsObj, L"Version", &kernel->release); - - pclsObj->Release(); - pEnumerator->Release(); -} diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index ccf7da36e..aa04bb976 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -59,10 +59,7 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufClear(&os->variant); } - if(getenv("MSYSTEM")) - ffStrbufAppendS(&os->id, "MSYS2"); - else - ffStrbufAppendF(&os->id, "Windows %*s", os->version.length, os->version.chars); + ffStrbufAppendF(&os->id, "Windows %*s", os->version.length, os->version.chars); ffGetWmiObjString(pclsObj, L"BuildNumber", &os->buildID); ffGetWmiObjString(pclsObj, L"OSArchitecture", &os->architecture); diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 34611328f..1a9fe2ade 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -30,7 +30,8 @@ void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) FF_UNUSED(instance); FFstrbuf scoopPath; - ffStrbufInitF(&scoopPath, "%s/scoop/apps/*", getenv("USERPROFILE")); + ffStrbufInitS(&scoopPath, instance->state.passwd->pw_dir); + ffStrbufAppendS(&scoopPath, "/scoop/apps/*"); result->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); if(result->scoop > 0) result->scoop--; // scoop diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index c79ed7827..4d33bb78b 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -64,7 +64,7 @@ static void detectTTY(FFTerminalFontResult* terminalFont) ffStrbufDestroy(&fontName); } -#if defined(_WIN32) || defined(__MSYS__) || defined(__linux__) +#if defined(_WIN32) || defined(__linux__) #ifdef FF_HAVE_LIBCJSON #include "common/library.h" @@ -241,7 +241,7 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFon } #endif -#endif //defined(_WIN32) || defined(__MSYS__) || defined(__linux__) +#endif //defined(_WIN32) || defined(__linux__) void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); @@ -259,7 +259,7 @@ const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) detectTTY(&result); - #if defined(_WIN32) || defined(__MSYS__) || defined(__linux__) + #if defined(_WIN32) || defined(__linux__) //Used by both Linux (WSL) and Windows else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c new file mode 100644 index 000000000..606d7ad7e --- /dev/null +++ b/src/detection/terminalshell/terminalshell.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; +} diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 534c343c7..e04f41f66 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -28,7 +28,7 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex assert(processName->length > 0); ffStrbufClear(exe); - #if defined(__linux__) || defined(__MSYS__) + #ifdef __linux__ char cmdlineFilePath[64]; snprintf(cmdlineFilePath, sizeof(cmdlineFilePath), "/proc/%d/cmdline", (int)pid); @@ -61,7 +61,7 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid) { const char* error = NULL; - #if defined(__linux__) || defined(__MSYS__) + #ifdef __linux__ char statFilePath[64]; snprintf(statFilePath, sizeof(statFilePath), "/proc/%d/stat", (int)pid); @@ -135,10 +135,14 @@ 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` - getProcessInformation(pid, &result->shellProcessName, &result->shellExe, &result->shellExeName); + if (result->shellProcessName.length == 0) + { + ffStrbufSetS(&result->shellProcessName, name); + getProcessInformation(pid, &result->shellProcessName, &result->shellExe, &result->shellExeName); + } getTerminalShell(result, ppid); return; @@ -160,7 +164,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0 ) return; - char* term = NULL; + const char* term = NULL; //SSH if(getenv("SSH_CONNECTION") != NULL) @@ -179,30 +183,36 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) getenv("ALACRITTY_WINDOW_ID") != NULL )) term = "Alacritty"; + #ifdef __ANDROID__ //Termux if(!ffStrSet(term) && ( getenv("TERMUX_VERSION") != NULL || getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL || getenv("TMUX_TMPDIR") != NULL )) term = "Termux"; + #endif + #ifdef __linux__ //Konsole if(!ffStrSet(term) && ( getenv("KONSOLE_VERSION") != NULL )) term = "konsole"; + #endif //MacOS, mintty if(!ffStrSet(term)) term = getenv("TERM_PROGRAM"); - //We are in WSL but not in Windows Terminal + #ifdef __linux__ if(!ffStrSet(term)) { + //We are in WSL but not in Windows Terminal const FFHostResult* host = ffDetectHost(); if(ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_WSL) == 0 || ffStrbufCompS(&host->productName, FF_HOST_PRODUCT_NAME_MSYS) == 0) //TODO better WSL or MSYS detection term = "conhost"; } + #endif //Normal Terminal if(!ffStrSet(term)) @@ -236,43 +246,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 +268,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); @@ -353,10 +316,21 @@ const FFTerminalShellResult* else ffStrbufSet(&result.userShellVersion, &result.shellVersion); - // https://github.com/LinusDierheimer/fastfetch/discussions/280#discussioncomment-3831734 - ffStrbufInitS(&result.shellPrettyName, result.shellExeName); + if(ffStrbufEqualS(&result.shellProcessName, "pwsh")) + ffStrbufInitS(&result.shellPrettyName, "PowerShell"); + else if(ffStrbufEqualS(&result.shellProcessName, "nu")) + ffStrbufInitS(&result.shellPrettyName, "nushell"); + else + { + // https://github.com/LinusDierheimer/fastfetch/discussions/280#discussioncomment-3831734 + ffStrbufInitS(&result.shellPrettyName, result.shellExeName); + } - if(strncmp(result.terminalExeName, result.terminalProcessName.chars, result.terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName + if(ffStrbufEqualS(&result.terminalProcessName, "iTerm.app")) + ffStrbufInitS(&result.terminalPrettyName, "iTerm"); + else if(ffStrbufEqualS(&result.terminalProcessName, "Apple_Terminal")) + ffStrbufInitS(&result.terminalPrettyName, "Apple Terminal"); + else if(strncmp(result.terminalExeName, result.terminalProcessName.chars, result.terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName ffStrbufInitS(&result.terminalPrettyName, result.terminalExeName); else ffStrbufInitCopy(&result.terminalPrettyName, &result.terminalProcessName); diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index c2e5acf04..a6d02c612 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -1,6 +1,7 @@ extern "C" { #include "terminalshell.h" #include "common/processing.h" +#include "common/thread.h" } #include "util/windows/wmi.hpp" @@ -50,19 +51,13 @@ 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) { uint32_t ppid; - if(!getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe)) + if(pid == 0 || !getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe)) return 0; result->shellExeName = result->shellExe.chars + ffStrbufLastIndexC(&result->shellExe, '\\') + 1; @@ -70,17 +65,19 @@ 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) ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell ISE"); else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "cmd") == 0) ffStrbufSetS(&result->shellPrettyName, "Command Prompt"); + else if(ffStrbufIgnCaseCompS(&result->shellPrettyName, "nu") == 0) + ffStrbufSetS(&result->shellPrettyName, "nushell"); else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "explorer") == 0) { ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); // Started without shell @@ -94,7 +91,7 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; - if(!getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe)) + if(pid == 0 || !getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe)) return 0; result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\'); @@ -102,6 +99,24 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe")) ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4); + if( + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "pwsh") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "cmd") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "bash") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "zsh") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "fish") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "nu") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "powershell") == 0 || + ffStrbufIgnCaseCompS(&result->terminalPrettyName, "powershell_ise") == 0 + ) { + //We are nested shell + ffStrbufClear(&result->terminalProcessName); + ffStrbufClear(&result->terminalPrettyName); + ffStrbufClear(&result->terminalExe); + result->terminalExeName = NULL; + return getTerminalInfo(result, ppid); + } + if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "WindowsTerminal") == 0) ffStrbufSetS(&result->terminalPrettyName, "Windows Terminal"); else if(ffStrbufIgnCaseCompS(&result->terminalPrettyName, "conhost") == 0) @@ -112,27 +127,63 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) return ppid; } -#ifdef __MSYS__ - extern "C" - const FFTerminalShellResult* ffDetectTerminalShellPosix(const FFinstance* instance); -#endif +static void getTerminalFromEnv(FFTerminalShellResult* result) +{ + if( + result->terminalProcessName.length > 0 && + !ffStrbufStartsWithIgnCaseS(&result->terminalProcessName, "login") && + ffStrbufIgnCaseCompS(&result->terminalProcessName, "(login)") != 0 && + ffStrbufIgnCaseCompS(&result->terminalProcessName, "systemd") != 0 && + ffStrbufIgnCaseCompS(&result->terminalProcessName, "init") != 0 && + ffStrbufIgnCaseCompS(&result->terminalProcessName, "(init)") != 0 && + ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0 + ) return; + + const char* term = NULL; + + //SSH + if(getenv("SSH_CONNECTION") != NULL) + term = getenv("SSH_TTY"); + + //Windows Terminal + if(!term && ( + getenv("WT_SESSION") != NULL || + getenv("WT_PROFILE_ID") != NULL + )) term = "Windows Terminal"; + + //Alacritty + if(!term && ( + getenv("ALACRITTY_SOCKET") != NULL || + getenv("ALACRITTY_LOG") != NULL || + getenv("ALACRITTY_WINDOW_ID") != NULL + )) term = "Alacritty"; + + //Normal Terminal + if(!term) + term = getenv("TERM"); + + if(term) + { + ffStrbufSetS(&result->terminalProcessName, term); + ffStrbufSetS(&result->terminalPrettyName, term); + ffStrbufSetS(&result->terminalExe, term); + result->terminalExeName = ""; + } +} 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 + FF_UNUSED(instance); + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; static FFTerminalShellResult result; static bool init = false; + ffThreadMutexLock(&mutex); if(init) + { + ffThreadMutexUnlock(&mutex); return &result; + } init = true; ffStrbufInit(&result.shellProcessName); @@ -152,17 +203,14 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) uint32_t ppid = GetCurrentProcessId(); if(!getProcessInfo(ppid, &ppid, nullptr, nullptr)) - return &result; + goto exit; ppid = getShellInfo(&result, ppid); - if(ppid == 0) - return &result; - - // TODO: handle nested shells - - ppid = getTerminalInfo(&result, ppid); - if(ppid == 0) - return &result; + getTerminalInfo(&result, ppid); + if(result.terminalProcessName.length == 0) + getTerminalFromEnv(&result); +exit: + ffThreadMutexUnlock(&mutex); return &result; } diff --git a/src/modules/cursor.c b/src/modules/cursor.c index e6d50d333..c7285427e 100644 --- a/src/modules/cursor.c +++ b/src/modules/cursor.c @@ -11,7 +11,7 @@ #define FF_CURSOR_MODULE_NAME "Cursor" #define FF_CURSOR_NUM_FORMAT_ARGS 2 -#if !(defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__)) +#if !(defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32)) static void printCursor(FFinstance* instance, FFstrbuf* cursorTheme, const FFstrbuf* cursorSize) { @@ -196,7 +196,7 @@ static bool printCursorFromEnv(FFinstance* instance) void ffPrintCursor(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) FF_UNUSED(instance); ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "Cursor detection is not supported"); diff --git a/src/modules/font.c b/src/modules/font.c index 4223eb799..9ca20b547 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -41,7 +41,7 @@ static void printFont(const FFFontResult* font) printf("%s [User]", font->fonts[1].chars); } -#elif defined(_WIN32) || defined(__MSYS__) +#elif defined(_WIN32) static void printFont(const FFFontResult* font) { diff --git a/src/modules/icons.c b/src/modules/icons.c index c489b9a86..4597cf2e8 100644 --- a/src/modules/icons.c +++ b/src/modules/icons.c @@ -10,7 +10,7 @@ void ffPrintIcons(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) FF_UNUSED(instance); ffPrintError(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons, "Icons detection is not supported"); diff --git a/src/modules/kernel.c b/src/modules/kernel.c index 02cece513..062b04f42 100644 --- a/src/modules/kernel.c +++ b/src/modules/kernel.c @@ -1,38 +1,22 @@ #include "fastfetch.h" #include "common/printing.h" -#include "detection/kernel/kernel.h" #define FF_KERNEL_MODULE_NAME "Kernel" #define FF_KERNEL_NUM_FORMAT_ARGS 3 void ffPrintKernel(FFinstance* instance) { - FFKernelResult result; - ffDetectKernel(instance, &result); - - if(result.error.length > 0) - { - ffPrintError(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, "%*s", result.error.length, result.error.chars); - goto exit; - } - if(instance->config.kernel.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel.key); - ffStrbufPutTo(&result.release, stdout); + puts(instance->state.utsname.release); } else { ffPrintFormat(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result.sysname}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.release}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.version} + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.release}, + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.version} }); } - -exit: - ffStrbufDestroy(&result.error); - ffStrbufDestroy(&result.sysname); - ffStrbufDestroy(&result.release); - ffStrbufDestroy(&result.version); } diff --git a/src/modules/theme.c b/src/modules/theme.c index 5d294c196..5c10ee485 100644 --- a/src/modules/theme.c +++ b/src/modules/theme.c @@ -10,7 +10,7 @@ void ffPrintTheme(FFinstance* instance) { - #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) || defined(__MSYS__) + #if defined(__ANDROID__) || defined(__APPLE__) || defined(_WIN32) FF_UNUSED(instance); ffPrintError(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme, "Theme detection is not supported"); diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 8966b569e..cfe6449d4 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -147,11 +147,21 @@ static inline int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp) return memcmp(strbuf->chars, comp->chars, length + 1); } +static inline FF_C_NODISCARD int ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) +{ + return ffStrbufComp(strbuf, comp) == 0; +} + static inline FF_C_NODISCARD int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp) { return strcmp(strbuf->chars, comp); } +static inline FF_C_NODISCARD int ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp) +{ + return ffStrbufCompS(strbuf, comp) == 0; +} + static inline FF_C_NODISCARD int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp) { return strcasecmp(strbuf->chars, comp);