diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index ae492a408..6b532c563 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -123,6 +123,71 @@ jobs: name: fastfetch-bsd path: ./fastfetch-*.* + windows: + name: Windows + runs-on: windows-latest + permissions: + security-events: write + contents: read + outputs: + ffversion: ${{ steps.ffversion.outputs.ffversion }} + 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: 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: copy necessary dlls + run: cp /usr/bin/msys-2.0.dll /clang64/bin/*.dll . + + # Crashes on start for some reason, but it provides binaries at least. Needs investigation. + # - 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-windows + path: | + ./*.dll + ./*.exe + release: if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch' name: Release diff --git a/CMakeLists.txt b/CMakeLists.txt index 1684259d4..639f25dad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,10 +98,12 @@ endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}") set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG} -rdynamic") -include(CheckIPOSupported) -check_ipo_supported(RESULT IPO_SUPPORTED) -if(IPO_SUPPORTED) - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) +if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + include(CheckIPOSupported) + check_ipo_supported(RESULT IPO_SUPPORTED) + if(IPO_SUPPORTED) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + endif() endif() ####################### diff --git a/src/detection/memory/memory.c b/src/detection/memory/memory.c index f777554c3..62be6197e 100644 --- a/src/detection/memory/memory.c +++ b/src/detection/memory/memory.c @@ -11,7 +11,7 @@ static void calculatePercentage(FFMemoryStorage* storage) if(storage->bytesTotal == 0) storage->percentage = 0; else - storage->percentage = (uint8_t) ((storage->bytesUsed / (long double) storage->bytesTotal) * 100.0); + storage->percentage = (uint8_t) (((long double) storage->bytesUsed / (long double) storage->bytesTotal) * 100.0); } const FFMemoryResult* ffDetectMemory() diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 53d45d351..994a3e333 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -36,6 +36,10 @@ void ffDetectPackages(FFinstance* instance, FFPackageCounts* counts) FFstrbuf scoopPath; ffStrbufInitF(&scoopPath, "%s/scoop/apps/*", getenv("USERPROFILE")); - counts->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY) - 3; // . .. scoop + counts->scoop = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY); + if(counts->scoop >= 3) + counts->scoop -= 3; // . .. scoop + else + counts->scoop = 0; ffStrbufDestroy(&scoopPath); } diff --git a/src/detection/processes/processes_apple.c b/src/detection/processes/processes_apple.c index 32a251b1a..bbed0db2d 100644 --- a/src/detection/processes/processes_apple.c +++ b/src/detection/processes/processes_apple.c @@ -11,7 +11,7 @@ uint32_t ffDetectProcesses(FFinstance* instance, FFstrbuf* error) if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0) { - ffStrbufAppend(error, "sysctl() failed"); + ffStrbufAppendS(error, "sysctl() failed"); return 0; } return (uint32_t)(length / sizeof(struct kinfo_proc)); diff --git a/src/detection/temps/temps_apple.c b/src/detection/temps/temps_apple.c index b952e720b..015546ecf 100644 --- a/src/detection/temps/temps_apple.c +++ b/src/detection/temps/temps_apple.c @@ -207,7 +207,7 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl uint64_t tmp = 0; for (uint32_t i = 0; i < val.dataSize; i++) tmp += (uint64_t)((uint8_t)(val.bytes[i]) * pow(256, val.dataSize - 1 - i)); - *value = tmp; + *value = (double)tmp; } else if (strcmp(val.dataType, kDataTypeFlt) == 0) { diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 48e5e2c38..b5f68c58f 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -11,6 +11,10 @@ #include #include +#ifdef __APPLE__ + #include +#endif + static void setExeName(FFstrbuf* exe, const char** exeName) { assert(exe->length > 0); @@ -19,64 +23,92 @@ static void setExeName(FFstrbuf* exe, const char** exeName) *exeName = exe->chars + lastSlashIndex + 1; } -static void getProcessInformation(const char* pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName) +static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName) { assert(processName->length > 0); - - FFstrbuf cmdlineFilePath; - ffStrbufInit(&cmdlineFilePath); - ffStrbufAppendS(&cmdlineFilePath, "/proc/"); - ffStrbufAppendS(&cmdlineFilePath, pid); - ffStrbufAppendS(&cmdlineFilePath, "/cmdline"); - ffStrbufClear(exe); - if(ffAppendFileBuffer(cmdlineFilePath.chars, exe)) + + #if defined(__linux__) || defined(__MSYS__) + + char cmdlineFilePath[64]; + snprintf(cmdlineFilePath, sizeof(cmdlineFilePath), "/proc/%d/cmdline", (int)pid); + + if(ffAppendFileBuffer(cmdlineFilePath, exe)) { ffStrbufSubstrBeforeFirstC(exe, '\0'); //Trim the arguments ffStrbufTrimLeft(exe, '-'); //Happens in TTY } + #elif defined(__APPLE__) + + int length = proc_pidpath((int)pid, exe->chars, exe->allocated); + if(length > 0) + exe->length = (uint32_t)length; + + #else + + //TODO: support bsd (https://www.freebsd.org/cgi/man.cgi?query=kinfo_getproc) + + #endif + if(exe->length == 0) ffStrbufSet(exe, processName); setExeName(exe, exeName); - - ffStrbufDestroy(&cmdlineFilePath); } -static void getTerminalShell(FFTerminalShellResult* result, const char* pid) +static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid) { - FFstrbuf statFilePath; - ffStrbufInit(&statFilePath); - ffStrbufAppendS(&statFilePath, "/proc/"); - ffStrbufAppendS(&statFilePath, pid); - ffStrbufAppendS(&statFilePath, "/stat"); + const char* error = NULL; - FILE* stat = fopen(statFilePath.chars, "r"); - - ffStrbufDestroy(&statFilePath); + #if defined(__linux__) || defined(__MSYS__) + char statFilePath[64]; + snprintf(statFilePath, sizeof(statFilePath), "/proc/%d/stat", (int)pid); + FILE* stat = fopen(statFilePath, "r"); if(stat == NULL) - return; + return "fopen(statFilePath, \"r\") failed"; + *ppid = 0; + if( + fscanf(stat, "%*s (%255[^)]) %*c %d", name, ppid) != 2 || //stat (comm) state ppid + !ffStrSet(name) || + *ppid == 0 + ) + error = "fscanf(stat) failed"; + + fclose(stat); + + #elif defined(__APPLE__) + + struct proc_bsdshortinfo proc; + if(proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) <= 0) + error = "proc_pidinfo(pid) failed"; + else + { + *ppid = (pid_t)proc.pbsi_ppid; + strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars + } + + #else + + //TODO: support bsd (https://www.freebsd.org/cgi/man.cgi?query=kinfo_getproc) + error = "unimplemented"; + + #endif + + return error; +} + +static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) +{ char name[256]; name[0] = '\0'; - char ppid[256]; - ppid[0] = '\0'; + pid_t ppid = 0; - if( - fscanf(stat, "%*s (%255[^)]) %*c %255s", name, ppid) != 2 || //stat (comm) state ppid - !ffStrSet(name) || - !ffStrSet(ppid) || - *ppid == '-' || - strcasecmp(ppid, "0") == 0 - ) { - fclose(stat); + if(getProcessNameAndPpid(pid, name, &ppid)) return; - } - - fclose(stat); //Common programs that are between terminal and own process, but are not the shell if( @@ -86,7 +118,9 @@ static void getTerminalShell(FFTerminalShellResult* result, const char* pid) strcasecmp(name, "strace") == 0 || strcasecmp(name, "sshd") == 0 || strcasecmp(name, "gdb") == 0 || - strcasecmp(name, "guake-wrapped") == 0 + strcasecmp(name, "lldb") == 0 || + strcasecmp(name, "guake-wrapped") == 0 || + strcasestr(name, "debug") != NULL ) { getTerminalShell(result, ppid); return; @@ -308,9 +342,7 @@ const FFTerminalShellResult* result.userShellExeName = result.userShellExe.chars; ffStrbufInit(&result.userShellVersion); - char ppid[32]; - snprintf(ppid, sizeof(ppid) - 1, "%i", getppid()); - getTerminalShell(&result, ppid); + getTerminalShell(&result, getppid()); getTerminalFromEnv(&result); getUserShellFromEnv(&result); diff --git a/src/modules/disk.c b/src/modules/disk.c index 8f97f54ba..07903c496 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -24,7 +24,7 @@ static void printFolder(FFinstance* instance, FFDiskResult* folder) }); } - uint8_t percentage = (uint8_t) ((folder->used / (long double) folder->total) * 100.0); + uint8_t percentage = (uint8_t) (((long double) folder->used / (long double) folder->total) * 100.0); FFstrbuf usedPretty; ffStrbufInit(&usedPretty); diff --git a/src/modules/font.c b/src/modules/font.c index 176243adf..4223eb799 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -23,6 +23,7 @@ static void printFont(const FFFontResult* font) } ffStrbufWriteTo(>k, stdout); + ffStrbufDestroy(>k); } #elif defined(__APPLE__) diff --git a/src/util/windows/wmi.cpp b/src/util/windows/wmi.cpp index 845a3dda4..cff1c9a97 100644 --- a/src/util/windows/wmi.cpp +++ b/src/util/windows/wmi.cpp @@ -142,6 +142,11 @@ IEnumWbemClassObject* ffQueryWmi(const wchar_t* queryStr, FFstrbuf* error) void ffBstrToStrbuf(BSTR bstr, FFstrbuf* strbuf) { int len = (int)SysStringLen(bstr); + if(len <= 0) + { + ffStrbufClear(strbuf); + return; + } int size_needed = WideCharToMultiByte(CP_UTF8, 0, bstr, len, nullptr, 0, nullptr, nullptr); ffStrbufEnsureFree(strbuf, (uint32_t)size_needed); WideCharToMultiByte(CP_UTF8, 0, bstr, len, strbuf->chars, size_needed, nullptr, nullptr);