Compare commits

...

74 Commits

Author SHA1 Message Date
Carter Li 5ede47fede Merge pull request #665 from fastfetch-cli/dev
Release v2.4.0
2023-12-18 23:02:03 +00:00
李通洲 d84ae91f59 Release: v2.4.0 2023-12-18 23:55:11 +08:00
apocelipes 70160d324f fix(DiskIO, PhysicalDisk): fix readlink 2023-12-18 14:31:05 +00:00
李通洲 600f6c7f24 Image: don't dlclose(imageMagick)
Fix: #552
2023-12-18 21:25:15 +08:00
李通洲 11b1b97567 IO: only retry when open() error is ENOENT / ERROR_PATH_NOT_FOUND
Close: #663
2023-12-18 21:08:29 +08:00
李通洲 4ae0c43c6f IO: remove support of FF_PATHTYPE_LINK 2023-12-18 20:49:32 +08:00
李通洲 e89d475a3b Presets: remove flag based config files 2023-12-18 16:13:45 +08:00
李通洲 4f3cd46f96 Presets: rename all flag based files to *.conf 2023-12-18 16:09:24 +08:00
李通洲 c076f5ae98 Github: update issue templates 2023-12-18 16:04:56 +08:00
李通洲 064d7d3c3a Doc: update changelog 2023-12-18 15:58:01 +08:00
李通洲 9937eeab1d Logo (Builtin): add EshanizedOS 2023-12-18 15:57:35 +08:00
李通洲 e8326306f8 Doc: add module physical disk 2023-12-18 15:53:15 +08:00
李通洲 89bc7eb015 DiskIO: move device info detected in PhysicalDisk module 2023-12-18 15:12:52 +08:00
李通洲 3cd81ec3ad PhysicalDisk: add new module 2023-12-18 15:12:52 +08:00
李通洲 0f497a53ad DiskIO (macOS): detect serial number and removable 2023-12-18 09:57:19 +08:00
Carter Li 569883a1a1 DiskIO (FreeBSD): detect disk serial number 2023-12-18 09:01:33 +08:00
李通洲 04a41cbd6b DiskIO (Windows): don't use registry 2023-12-17 21:49:54 +08:00
李通洲 4e4246a46a DiskIO (Windows): fix segfault and memleak 2023-12-17 19:40:24 +08:00
李通洲 c3a28064f6 DiskIO: tidy 2023-12-17 19:29:45 +08:00
李通洲 ce9f9ed7ed Windows: try fixing --no-buffer 2023-12-17 19:04:49 +08:00
李通洲 fb8c7d6e4a DiskIO: add property removable 2023-12-17 18:40:41 +08:00
李通洲 70f39e641c DiskIO (Windows): improve device name detection 2023-12-17 18:24:01 +08:00
李通洲 1dbd8474c2 DiskIO (Linux): fix serial number detection 2023-12-17 17:27:38 +08:00
李通洲 e7c787159a DiskIO: print serial number in json format
Always init serial property
2023-12-17 13:51:17 +08:00
李通洲 9339a0fb4e DiskIO (Windows): detect serial number 2023-12-17 13:43:52 +08:00
Carter Li b692b759c7 DiskIO (Linux): detect interconnect more aggressively 2023-12-17 12:52:34 +08:00
李通洲 529f94c64a DiskIO (Linux): better handling virtual devices 2023-12-17 12:21:12 +08:00
李通洲 e071a1eeb2 Disk (Linux): improve removable type detection 2023-12-17 12:13:28 +08:00
李通洲 3400e40e47 DiskIO (Linux): detect device serial number 2023-12-17 11:48:59 +08:00
李通洲 d32125e988 DiskIO (Linux): improve device name detection 2023-12-17 11:47:05 +08:00
李通洲 b3484088e9 FFPlatform (Linux): tidy 2023-12-17 11:46:28 +08:00
Carter Li f91a8aea4d DiskIO (Linux): improve detection
1. Ignore `dm-*`
2. Add devices that don't have disk ids
3. Fix  device size detection
2023-12-17 10:39:25 +08:00
Carter Li 335022e034 SMBIOS: ignore more meaningless values 2023-12-17 09:10:11 +08:00
Carter Li 8fa073b1e4 DisplayServer (Linux): test for status instead of enabled 2023-12-17 01:00:37 +08:00
李通洲 10e1753c03 DisplayServer (Linux): better handling abnormal situations
Try fix #660
2023-12-17 00:41:59 +08:00
李通洲 224a6a9881 TerminalShell: code cleanup 2023-12-15 14:29:51 +08:00
李通洲 e804dfc49e Memory (macOS): align algo of memory usage counting to stats
Which seems to print the same result of neofetch
2023-12-14 16:13:05 +08:00
李通洲 8048101eca Doc: fix documentation of --ds-force-drm 2023-12-14 16:13:05 +08:00
Horst G. Burkhardt 833727f333 remove unnecessary escaping for Adelie logo 2023-12-14 15:15:52 +08:00
李通洲 8ed5d30b3e Wifi (Windows): use less magic numbers 2023-12-13 19:33:20 +08:00
Carter Li f62cdff924 README: add start history 2023-12-13 02:56:13 -06:00
Carter Li 25a792743b WMDE: tidy 2023-12-12 18:22:20 +08:00
Carter Li b63e6a3053 DE (Linux): add support for CDE
Fix #658
2023-12-12 18:20:02 +08:00
李通洲 a565dcfb9e Doc: update changelog
Fix: #655
2023-12-12 10:12:12 +08:00
Carter Li 453f4757ed DE (FreeBSD): support detection with processes 2023-12-12 10:10:08 +08:00
李通洲 0555fb97e8 TerminalShell (Linux): tidy 2023-12-12 09:51:09 +08:00
李通洲 663d568927 DE (Linux): fix xfce4 version detection 2023-12-11 16:36:12 +08:00
李通洲 165c213ed0 FFstrbuf: don't crash with ffStrbufAppendNC(&str, 0, 'c') 2023-12-11 15:21:16 +08:00
李通洲 a28dc8a9bf DisplayServer (Linux): support --ds-force-drm sysfs-only 2023-12-11 13:25:58 +08:00
李通洲 f20b6d4387 Temps (macOS): support Apple M3 2023-12-08 16:10:10 +08:00
李通洲 4925222dab CI: run basic modules only in FreeBSD 2023-12-08 10:58:11 +08:00
李通洲 77cc0c61d7 Doc: update changelog 2023-12-08 10:28:03 +08:00
李通洲 a19888bb33 CI: don't run cpuusage in FreeBSD, which seems to have issues when running in VM 2023-12-08 10:28:03 +08:00
李通洲 40aa4a60d6 Packages: improve performance of pkg and rpm detection 2023-12-08 09:49:17 +08:00
Carter Li c4824b2b5d Merge pull request #654 from fastfetch-cli/dev
Release v2.3.4
2023-12-08 00:10:31 +08:00
李通洲 dcbda6c0d5 Release: v2.3.4 2023-12-08 00:04:38 +08:00
李通洲 91e4e94aaa CMake: fix --help doesn't work when building without python3 2023-12-07 23:51:56 +08:00
apocelipes 1504e26e38 optimize(Packages): optimize reading large files
Using less syscalls and processing data in memory
makes getNumStringsImpl ~300% faster.

The code is much simpler.
2023-12-07 20:32:14 +08:00
李通洲 a9c5c2892c Memory (Linux): Use MemAvailable if available 2023-12-07 16:30:10 +08:00
Carter Li 923997f0a2 Merge pull request #651 from fastfetch-cli/dev
Release v2.3.3
2023-12-07 09:39:07 +08:00
李通洲 0182e32f00 Release: v2.3.3 2023-12-07 09:33:26 +08:00
李通洲 bd40205427 Help: fix json text loading 2023-12-06 23:55:34 +08:00
Carter Li 30b9f95b49 Merge pull request #649 from fastfetch-cli/dev
Release v2.3.2
2023-12-06 11:20:24 +08:00
李通洲 74b9fd01ff CI (macOS): try fixing compiling 2023-12-06 11:06:52 +08:00
李通洲 03f4ffb9d7 Release: v2.3.2 2023-12-06 10:48:06 +08:00
李通洲 a00cb2aede CMake: install fish completion script 2023-12-06 10:38:55 +08:00
李通洲 6799076fa6 Logo (Builtin): fix compiling 2023-12-06 10:30:56 +08:00
李通洲 573a315d61 Help: tweaks 2023-12-06 10:29:28 +08:00
李通洲 0cd6cb841d Completion (Fish): fix fastfetch detection 2023-12-06 10:29:28 +08:00
xray_os af94cf4d0d fixing the name of my distro 2023-12-06 08:51:29 +08:00
Carter Li ac76107940 Merge pull request #647 from fastfetch-cli/dev
Release v2.3.1
2023-12-05 20:52:37 +08:00
李通洲 c25fe53251 Merge remote-tracking branch 'upstream/master' into dev 2023-12-05 20:50:10 +08:00
李通洲 4137b3829a Release v2.3.1 2023-12-05 20:48:09 +08:00
Viorel 0bb08049bf Fix man page install location 2023-12-05 20:41:20 +08:00
76 changed files with 1608 additions and 718 deletions
+2 -5
View File
@@ -1,7 +1,7 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
title: '[BUG] '
labels: bug
assignees: ''
@@ -24,12 +24,9 @@ The content of the configuration file you use (if any)
//paste here
```
Output of `env NO_CONFIG=1 fastfetch --load-config all --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false`:
Output of `fastfetch -c ci.jsonc --format json`:
<!--
Note that this output will contain you public IP. If it is not relevant for the issue, feel free to remove it before uploading.
If you get the following error: `Error: couldn't find config: [...]`, copy the files in [presets](../../presets/) to `/usr/share/fastfetch/presets/` or `~/.local/share/fastfetch/presets/`.
If this isn't possible (or too much work) for you, post the output of `env NO_CONFIG=1 fastfetch --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false && fastfetch --version`.
-->
```
+3 -1
View File
@@ -1,12 +1,14 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
title: '[FEAT] '
labels: enhancement
assignees: ''
---
<!-- Before requesting a new feature, please try `fastfetch -c all.jsonc` to see if it has been supported -->
# Current state:
# Wanted state:
+3 -3
View File
@@ -1,7 +1,7 @@
---
name: Logo request
about: Request a new logo
title: ''
title: '[LOGO] '
labels: logo request
assignees: ''
@@ -9,10 +9,10 @@ assignees: ''
# OS
```
paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
Paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
```
# Ascii
```
paste ascii art here. If you leave this empty, i will try to find the logo myself.
Paste ascii art here.
```
+3 -4
View File
@@ -152,9 +152,8 @@ jobs:
- name: install required packages
run: |
brew uninstall aws-sam-cli azure-cli qemu lima colima gradle kotlin maven pipx aria2 || true
brew update
brew install vulkan-loader vulkan-headers molten-vk imagemagick chafa
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install vulkan-loader vulkan-headers molten-vk imagemagick chafa
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
@@ -216,8 +215,8 @@ jobs:
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc
time ./fastfetch -c presets/ci.jsonc --format json
time ./fastfetch
time ./fastfetch --format json
time ./flashfetch
ldd fastfetch
ctest
+1
View File
@@ -7,3 +7,4 @@
cscope.*
tags
fastfetch.kdev4
*.user
+56 -3
View File
@@ -1,5 +1,60 @@
# 2.4.0
**We are deprecating flags based config files (will be removed in v3.0.0). We suggest you migrate to json based config files.** One may use `-c /path/to/config.conf --gen-config` to migrate existing flag based config files.
Changes:
* All flag based presets are removed
Features:
* Improve performance of detecting rpm and pkg package count (Packages, Linux / FreeBSD)
* Support Apple M3X temperature detection (CPU / GPU, macOS)
* `--ds-force-drm` support a new option `sysfs-only`
* Improve xfce4 version detection
* Detect WM and DE by enumerating running processes (WM / DE, FreeBSD)
* Add a new module `Physical Disk`, which detects product name, full size, serial number and so on.
Bugfixes:
* Fix crashes sometimes when `--logo-padding-top` is not set (Logo)
* Fix memory usage counting algorithm (Memory, macOS)
* Fix the behavior of `--no-buffer` in Windows
* Fix possible segfault in some devices (Display, Linux)
* Fix segfaults on first use of new images with Sixel flag (Image)
Logo:
* Remove unnecessary escaping for Adelie logo
* Add EshanizedOS
# 2.3.4
Bugfixes:
* Fix `--help` doesn't work when built without python
Features:
* Use `MemAvailable` if available (Memory, Linux)
* Improve performance of detecting dpkg package count (Packages, Linux)
# 2.3.3
Bugfixes:
* Fix `--help` doesn't work in Windows and some other platforms
# 2.3.2
Bugfixes:
* Fix fish completion script, and install the script correctly
Logo:
* Fix Xray-OS logo name
# 2.3.1
Bugfixes:
* Fix man page install location
# 2.3.0
**We are deprecating flags based config files (will be removed in v3.0.0). We suggest you migrate to json based config files.**
Config related changes:
* The deprecated flag `--gen-config conf` is removed
* Flag `--gen-config` now does the same thing as `--migrate-config`, which can be used as config migration and default config file generation. Flag `--migrate-config` is removed
@@ -9,8 +64,6 @@ Config related changes:
* Config files will always be loaded before other command line flags being parsed. That is to say, command line flags will always override options defined in config files.
* the value of GPUType `integrated` contained a typo and was fixed. Existing config files may need to be updated.
We are deprecating flags based config files (will be removed in v3.0.0). We suggest you migrate to json based config files.
Features:
* Support Oils and elvish shell version detection (Shell)
* Support Windows Server Core (Windows)
@@ -35,7 +88,7 @@ Bugfixes:
* Fix some memory leaks
* Fix used swap space detection (Swap, FreeBSD)
* Don't leak fds to child processes (Linux)
* Fix possible issues when reading procfs (Linux)
* Fix possible issues when reading procfs (Linux, @apocelipes)
Logos:
* Add Adelie, Ironclad
+22 -7
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.3.0
VERSION 2.4.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -206,7 +206,7 @@ endif()
#############
function(fastfetch_encode_c_string STR OUTVAR)
string(REGEX REPLACE "\n$" "" TEMP "${STR}") # Remove trailing newline
string(REGEX REPLACE "\n$" "" TEMP "${STR}") # Remove trailing newline
string(REPLACE "\\" "\\\\" TEMP "${TEMP}") # Escape backslashes
string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n
string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \"
@@ -221,12 +221,15 @@ endfunction(fastfetch_load_text)
find_package(Python)
if(Python_FOUND)
# Minify JSON string. `io.open(0,encoding='utf-8')` is needed to avoid encoding issues on Windows
execute_process(COMMAND ${Python_EXECUTABLE} -c "import io,json,sys;json.dump(json.load(io.open(0,encoding='utf-8')),sys.stdout,separators=(',', ':'),ensure_ascii=False)"
execute_process(COMMAND ${Python_EXECUTABLE} -c "import json,sys;json.dump(json.load(sys.stdin),sys.stdout,separators=(',',':'))"
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/data/help.json"
OUTPUT_VARIABLE DATATEXT_JSON_HELP)
if(DATATEXT_JSON_HELP STREQUAL "")
message(ERROR "DATATEXT_JSON_HELP is empty, which should not happen!")
endif()
else()
file(READ "src/data/help.json" TEMP)
message(STATUS "Python3 is not found, 'help.json' will not be minified")
file(READ "src/data/help.json" DATATEXT_JSON_HELP)
endif()
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
@@ -337,6 +340,7 @@ set(LIBFASTFETCH_SRC
src/modules/opengl/opengl.c
src/modules/os/os.c
src/modules/packages/packages.c
src/modules/physicaldisk/physicaldisk.c
src/modules/processes/processes.c
src/modules/player/player.c
src/modules/poweradapter/poweradapter.c
@@ -391,6 +395,7 @@ if(LINUX)
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/disk/disk_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
@@ -450,6 +455,7 @@ elseif(ANDROID)
src/detection/cursor/cursor_nosupport.c
src/detection/cpuusage/cpuusage_linux.c
src/detection/disk/disk_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/displayserver_android.c
src/detection/font/font_nosupport.c
@@ -503,6 +509,7 @@ elseif(BSD)
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/physicaldisk/physicaldisk_bsd.c
src/detection/diskio/diskio_bsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
@@ -526,7 +533,7 @@ elseif(BSD)
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
src/detection/packages/packages_linux.c
src/detection/packages/packages_bsd.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_bsd.c
src/detection/gtk_qt/qt.c
@@ -563,6 +570,7 @@ elseif(APPLE)
src/detection/cpuusage/cpuusage_apple.c
src/detection/cursor/cursor_apple.m
src/detection/disk/disk_bsd.c
src/detection/physicaldisk/physicaldisk_apple.c
src/detection/diskio/diskio_apple.c
src/detection/displayserver/displayserver_apple.c
src/detection/font/font_apple.m
@@ -616,6 +624,7 @@ elseif(WIN32)
src/detection/cpuusage/cpuusage_windows.c
src/detection/cursor/cursor_windows.c
src/detection/disk/disk_windows.c
src/detection/physicaldisk/physicaldisk_windows.c
src/detection/diskio/diskio_windows.c
src/detection/displayserver/displayserver_windows.c
src/detection/font/font_windows.c
@@ -1040,6 +1049,12 @@ install(
RENAME "${CMAKE_PROJECT_NAME}"
)
install(
FILES "${CMAKE_SOURCE_DIR}/completions/fish"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/fish/vendor_completions.d"
RENAME "${CMAKE_PROJECT_NAME}.fish"
)
install(
DIRECTORY "${CMAKE_SOURCE_DIR}/presets"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}"
@@ -1052,7 +1067,7 @@ install(
install(
FILES "${PROJECT_BINARY_DIR}/fastfetch.1"
DESTINATION "${CMAKE_INSTALL_MANDIR}"
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
)
##################
+12
View File
@@ -89,3 +89,15 @@ Q: Why do you need a very performant version of neofetch?
Q: It does not display [*] correctly for me, what can I do?
> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
## Star History
Give it a star to support us!
<a href="https://star-history.com/#fastfetch-cli/fastfetch&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date" />
</picture>
</a>
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env fish
if not test -x fastfetch
if not type -q fastfetch
return
end
+45 -2
View File
@@ -251,8 +251,24 @@
"description": "Set the path to the file containing OS information. Linux only"
},
"dsForceDrm": {
"type": "boolean",
"description": "Force display detection to use `/sys/class/drm`. Linux only",
"description": "Force display detection to use DRM. Linux only",
"oneOf": [
{
"type": "bool",
"const": false,
"description": "Try `wayland`, then `x11`, then `drm`"
},
{
"type": "string",
"description": "Use `/sys/class/drm` only.",
"const": "sysfs-only"
},
{
"type": "bool",
"const": true,
"description": "Try `libdrm` first, then `sysfs` if libdrm failed"
}
],
"default": false
},
"wmiTimeout": {
@@ -584,6 +600,7 @@
"opengl",
"os",
"packages",
"physicaldisk",
"player",
"poweradapter",
"processes",
@@ -1353,6 +1370,32 @@
}
}
},
{
"title": "Physical Disk",
"properties": {
"type": {
"description": "Print physical disk information",
"const": "physicaldisk"
},
"namePrefix": {
"description": "Show disks with given name prefix only",
"type": "string"
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
},
"additionalProperties": false
},
{
"title": "Public IP",
"properties": {
-1
View File
@@ -1 +0,0 @@
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:NetIO:DiskIO:Version:Break:Colors
+1
View File
@@ -53,6 +53,7 @@
"weather",
"netio",
"diskio",
"physicaldisk",
"version",
"break",
"colors"
-3
View File
@@ -1,3 +0,0 @@
--logo arch
--os-format "Arch Linux ({12})"
--packages-format "{} (pacman)"
+1
View File
@@ -62,6 +62,7 @@
},
"netio",
"diskio",
"physicaldisk",
"version",
"break",
"colors"
-1
View File
@@ -1 +0,0 @@
# Load with --load-config examples/1
-24
View File
@@ -1,24 +0,0 @@
# Load with --load-config examples/2
# Note that you must replace the image path to an existing image to display it.
--kitty /home/linus/Bilder/Gentoo.png
--logo-width 28
--separator "  "
--set-keyless HardwareStart=┌───────── \e[1mHardware Information\e[0m ─────────┐
--set-keyless SoftwareStart=├───────── \e[1mSoftware Information\e[0m ─────────┤
--set-keyless InformationEnd=└────────────────────────────────────────┘
--set-keyless Colors= \e[38m \e[37m \e[36m \e[35m \e[34m \e[33m \e[32m \e[31m
--structure HardwareStart:Host:CPU:GPU:SoftwareStart:OS:Kernel:WM:Shell:Terminal:TerminalFont:Packages:InformationEnd:Colors
--host-key " "
--cpu-key " "
--gpu-key " ﬙"
--os-key " "
--kernel-key " "
--wm-key " "
--shell-key " "
--terminal-key " "
--terminalfont-key " "
--packages-key " "
-7
View File
@@ -1,7 +0,0 @@
# Load with --load-config example/3
--logo debian_small
--structure Vulkan:OpenGL:OpenCL:Memory:Disk:LocalIP
--binary-prefix si
--localip-show-loop false
--disk-folders /:/home:/boot:/efi
-7
View File
@@ -1,7 +0,0 @@
# Load with --load-config examples/4
--color blue
--logo arch_small
--logo-padding-right 1
--separator "  "
--structure DateTime:Break:Player:Media
-11
View File
@@ -1,11 +0,0 @@
# Load with --load-config examples/5
--logo none
--color reset_magenta
--structure Theme:Icons:Font:Cursor
--theme-key T
--theme-format {7}
--icons-key I
--icons-format {5}
--font-key F
--cursor-key C
-4
View File
@@ -1,4 +0,0 @@
--structure Host:Display:CPU:GPU:Memory:Disk:Battery
--memory-format "{?2}{2}{?}"
--disk-format "{?2}{2}{?}"
--battery-format "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
-9
View File
@@ -1,9 +0,0 @@
--structure "Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Terminal:TerminalFont:CPU:GPU:Memory:Break:Colors"
--host-format "{/2}{-}{/}{2}{?3} {3}{?}"
--os-format "{3} {12}"
--display-key Resolution
--display-compact-type original
--de-format "{2} {3}"
--theme-format "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
--terminalfont-format "{/2}{-}{/}{2}{?3} {3}{?}"
--memory-format "{/1}{-}{/}{/2}{-}{/}{} / {}"
-5
View File
@@ -1,5 +0,0 @@
--structure Title:Separator:OS:Host:Kernel:Uptime:Battery:Break:Packages:Shell:Display:Terminal:Break:CPU:GPU:Memory:Break:Colors
--host-format "{/2}{-}{/}{2}{?3} {3}{?}"
--battery-format "{/4}{-}{/}{4}%{?5} [{5}]{?}"
--display-key "Display"
--gpu-key "GPU"
-1
View File
@@ -1 +0,0 @@
--structure OS:Kernel:Shell:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont
+4 -1
View File
@@ -94,7 +94,10 @@ void ffStart(void)
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
#ifdef _WIN32
setvbuf(stdout, NULL, _IOFBF, instance.config.display.noBuffer ? 0 : 4096);
if (instance.config.display.noBuffer)
setvbuf(stdout, NULL, _IONBF, 0);
else
setvbuf(stdout, NULL, _IOFBF, 4096);
SetConsoleCtrlHandler(consoleHandler, TRUE);
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode = 0;
+37 -6
View File
@@ -10,6 +10,7 @@
#else
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
typedef int FFNativeFD;
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
// one safe way to read correct data is reading the whole file in a single read syscall
@@ -75,15 +76,45 @@ static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
//Bit flags, combine with |
typedef enum FFPathType
{
FF_PATHTYPE_REGULAR = 1,
FF_PATHTYPE_LINK = 2,
FF_PATHTYPE_DIRECTORY = 4
FF_PATHTYPE_FILE = 1 << 0,
FF_PATHTYPE_DIRECTORY = 1 << 1,
FF_PATHTYPE_ANY = FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY,
} FFPathType;
#define FF_PATHTYPE_FILE (FF_PATHTYPE_REGULAR | FF_PATHTYPE_LINK)
#define FF_PATHTYPE_ANY (FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY)
static inline bool ffPathExists(const char* path, FFPathType pathType)
{
#ifdef _WIN32
DWORD attr = GetFileAttributesA(path);
if(attr == INVALID_FILE_ATTRIBUTES)
return false;
if(pathType & FF_PATHTYPE_FILE && !(attr & FILE_ATTRIBUTE_DIRECTORY))
return true;
if(pathType & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
return true;
#else
struct stat fileStat;
if(stat(path, &fileStat) != 0)
return false;
unsigned int mode = fileStat.st_mode & S_IFMT;
if(pathType & FF_PATHTYPE_FILE && mode == S_IFREG)
return true;
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
return true;
#endif
return false;
}
bool ffPathExists(const char* path, FFPathType pathType);
bool ffPathExpandEnv(const char* in, FFstrbuf* out);
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
+9 -24
View File
@@ -3,10 +3,10 @@
#include "util/unused.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <termios.h>
#include <poll.h>
#include <dirent.h>
#include <errno.h>
#if __has_include(<wordexp.h>)
#include <wordexp.h>
@@ -33,9 +33,14 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
if(fd == -1)
{
createSubfolders(fileName);
fd = open(fileName, openFlagsModes, openFlagsRights);
if(fd == -1)
if (errno == ENOENT)
{
createSubfolders(fileName);
fd = open(fileName, openFlagsModes, openFlagsRights);
if(fd == -1)
return false;
}
else
return false;
}
@@ -103,26 +108,6 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
return ffAppendFDBuffer(fd, buffer);
}
bool ffPathExists(const char* path, FFPathType type)
{
struct stat fileStat;
if(stat(path, &fileStat) != 0)
return false;
unsigned int mode = fileStat.st_mode & S_IFMT;
if(type & FF_PATHTYPE_REGULAR && mode == S_IFREG)
return true;
if(type & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
return true;
if(type & FF_PATHTYPE_LINK && mode == S_IFLNK)
return true;
return false;
}
bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* out)
{
bool result = false;
+10 -23
View File
@@ -18,11 +18,16 @@ static void createSubfolders(const char* fileName)
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
{
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle == INVALID_HANDLE_VALUE)
if (handle == INVALID_HANDLE_VALUE)
{
createSubfolders(fileName);
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle == INVALID_HANDLE_VALUE)
if (GetLastError() == ERROR_PATH_NOT_FOUND)
{
createSubfolders(fileName);
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE)
return false;
}
else
return false;
}
@@ -37,7 +42,7 @@ bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer)
LARGE_INTEGER fileSize;
if(!GetFileSizeEx(handle, &fileSize))
fileSize.QuadPart = 0;
if (fileSize.QuadPart > 0)
{
// optimize for files has a fixed length,
@@ -87,24 +92,6 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
return ffAppendFDBuffer(handle, buffer);
}
bool ffPathExists(const char* path, FFPathType type)
{
DWORD attr = GetFileAttributesA(path);
if(attr == INVALID_FILE_ATTRIBUTES)
return false;
if(type & FF_PATHTYPE_REGULAR && !(attr & FILE_ATTRIBUTE_DIRECTORY))
return true;
if(type & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
return true;
if(type & FF_PATHTYPE_LINK && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
return true;
return false;
}
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
{
DWORD length = ExpandEnvironmentStringsA(in, NULL, 0);
+1
View File
@@ -96,6 +96,7 @@ static FFModuleBaseInfo* O[] = {
static FFModuleBaseInfo* P[] = {
(void*) &instance.config.modules.packages,
(void*) &instance.config.modules.physicalDisk,
(void*) &instance.config.modules.player,
(void*) &instance.config.modules.powerAdapter,
(void*) &instance.config.modules.processes,
+25 -13
View File
@@ -124,9 +124,14 @@
"desc": "Set if only DRM should be used to detect displays",
"remark": "Use this option if you encountered problems with other detection method. Linux only",
"arg": {
"type": "bool",
"type": "enum",
"optional": true,
"default": false
"default": "false",
"enum": {
"true": "Try `libdrm` first, then `sysfs` if libdrm failed",
"sysfs-only": "Use `/sys/class/drm` only",
"false": "Try `wayland`, then `x11`, then `drm`"
}
}
}
],
@@ -545,15 +550,15 @@
},
{
"long": "bar-char-elapsed",
"desc": "Set the character to use in elapsed part",
"desc": "Set the character to use in elapsed part of percentage bars",
"arg": {
"type": "str",
"default": ""
"default": "\u25a0"
}
},
{
"long": "bar-char-total",
"desc": "Set the character to use in total part",
"desc": "Set the character to use in total part of percentage bars",
"arg": {
"type": "str",
"default": "-"
@@ -561,7 +566,7 @@
},
{
"long": "bar-width",
"desc": "Set the width of the bar, in number of characters",
"desc": "Set the width of percentage bars, in number of characters",
"arg": {
"type": "num",
"default": 10
@@ -569,7 +574,7 @@
},
{
"long": "bar-border",
"desc": "Whether to show a border around the bar",
"desc": "Whether to show a border around percentage bars",
"arg": {
"type": "bool",
"optional": true,
@@ -942,6 +947,13 @@
"type": "str"
}
},
{
"long": "physicaldisk-name-prefix",
"desc": "Show disks with given name prefix only",
"arg": {
"type": "str"
}
},
{
"long": "bluetooth-show-disconnected",
"desc": "Set if disconnected bluetooth devices should be printed",
@@ -1290,12 +1302,12 @@
"arg": {
"type": "enum",
"enum": {
"block": "███",
"circle": "",
"diamond": "",
"triangle": "",
"square": "",
"star": ""
"block": "\u2588\u2588\u2588",
"circle": "\u25cf",
"diamond": "\u25c6",
"triangle": "\u25b2",
"square": "\u25a0",
"star": "\u2605"
},
"default": "block"
}
+10 -4
View File
@@ -7,10 +7,16 @@ static double detectCpuTemp(const FFstrbuf* cpuName)
double result = 0;
const char* error = NULL;
if(ffStrbufStartsWithS(cpuName, "Apple M1"))
error = ffDetectCoreTemps(FF_TEMP_CPU_M1X, &result);
else if(ffStrbufStartsWithS(cpuName, "Apple M2"))
error = ffDetectCoreTemps(FF_TEMP_CPU_M2X, &result);
if (ffStrbufStartsWithS(cpuName, "Apple M"))
{
switch (strtol(cpuName->chars + strlen("Apple M"), NULL, 10))
{
case 1: error = ffDetectCoreTemps(FF_TEMP_CPU_M1X, &result); break;
case 2: error = ffDetectCoreTemps(FF_TEMP_CPU_M2X, &result); break;
case 3: error = ffDetectCoreTemps(FF_TEMP_CPU_M3X, &result); break;
default: error = "Unsupported Apple Silicon CPU";
}
}
else // PPC?
error = ffDetectCoreTemps(FF_TEMP_CPU_X64, &result);
+13 -20
View File
@@ -1,6 +1,7 @@
#include "de.h"
#include "common/io/io.h"
#include "common/library.h"
#include "common/parsing.h"
#include "common/properties.h"
#include "common/processing.h"
@@ -87,26 +88,18 @@ static void getMate(FFstrbuf* result, FFDEOptions* options)
}
}
static const char* getXfce4ByLib(FFstrbuf* result)
{
const char* xfce_version_string(void); // from `xfce4/libxfce4util/xfce-misutils.h
FF_LIBRARY_LOAD(xfce4util, NULL, "dlopen libxfce4util" FF_LIBRARY_EXTENSION "failed", "libxfce4util" FF_LIBRARY_EXTENSION, 7);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xfce4util, xfce_version_string);
ffStrbufSetS(result, ffxfce_version_string());
return NULL;
}
static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
{
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", result);
#ifdef __FreeBSD__
if(result->length == 0)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
if (dirp)
{
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
continue;
ffStrbufAppendS(result, &entry->d_name[5]);
}
}
}
#endif
getXfce4ByLib(result);
if(result->length == 0 && options->slowVersionDetection)
{
@@ -117,8 +110,8 @@ static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
NULL
});
ffStrbufSubstrBeforeFirstC(result, '(');
ffStrbufSubstrAfterFirstC(result, ' ');
ffStrbufSubstrBeforeFirstC(result, ')');
ffStrbufSubstrAfterLastC(result, ' ');
ffStrbufTrim(result, ' ');
}
}
+6 -20
View File
@@ -106,14 +106,6 @@ static void detectName(FFDisk* disk)
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate();
//Detect USB devices. Code is put here to reuse deviceStat
//https://stackoverflow.com/a/73302717
ffStrbufAppendS(&basePath, "/dev/disk/by-id/");
detectNameFromPath(disk, &deviceStat, &basePath);
if (ffStrbufStartsWithS(&disk->name, "usb-"))
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
ffStrbufClear(&disk->name);
//Try label first
ffStrbufSetS(&basePath, "/dev/disk/by-label/");
detectNameFromPath(disk, &deviceStat, &basePath);
@@ -197,9 +189,6 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
static bool isRemovable(FFDisk* currentDisk)
{
// https://stackoverflow.com/a/73302025
// Note my USB mobile hard disk isn't detected as removable, but my USB flash disk does.
// USB devices should be handled in detectName
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreateS("/sys/block/");
FF_AUTO_CLOSE_DIR DIR* dir = opendir(basePath.chars);
@@ -218,11 +207,10 @@ static bool isRemovable(FFDisk* currentDisk)
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
// /sys/block/sdx/removable
// /sys/block/sdx/device/delete
ffStrbufAppendS(&basePath, entry->d_name);
ffStrbufAppendS(&basePath, "/removable");
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
return ffReadFileBuffer(basePath.chars, &buffer) && ffStrbufEqualS(&buffer, "1");
ffStrbufAppendS(&basePath, "/device/delete");
return ffPathExists(basePath.chars, FF_PATHTYPE_FILE);
}
return false;
@@ -230,14 +218,12 @@ static bool isRemovable(FFDisk* currentDisk)
static void detectType(const FFlist* disks, FFDisk* currentDisk)
{
if(currentDisk->type != FF_DISK_VOLUME_TYPE_NONE) return;
if(isRemovable(currentDisk))
if(ffStrbufStartsWithS(&currentDisk->mountpoint, "/boot") || ffStrbufStartsWithS(&currentDisk->mountpoint, "/efi"))
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else if(isRemovable(currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else if(isSubvolume(disks, currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
else if(ffStrbufStartsWithS(&currentDisk->mountpoint, "/boot") || ffStrbufStartsWithS(&currentDisk->mountpoint, "/efi"))
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
}
+2 -2
View File
@@ -47,8 +47,8 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
{
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
if (!ffStrbufEqual(&icPrev->name, &icCurr->name))
return "Network interface name changed";
if (!ffStrbufEqual(&icPrev->devPath, &icCurr->devPath))
return "Physical disk device path changed";
static_assert(sizeof(FFDiskIOResult) - offsetof(FFDiskIOResult, bytesRead) == sizeof(uint64_t) * 4, "Unexpected struct FFDiskIOResult layout");
for (size_t off = offsetof(FFDiskIOResult, bytesRead); off < sizeof(FFDiskIOResult); off += sizeof(uint64_t))
-10
View File
@@ -2,19 +2,9 @@
#include "fastfetch.h"
typedef enum FFDiskIOPhysicalType
{
FF_DISKIO_PHYSICAL_TYPE_UNKNOWN,
FF_DISKIO_PHYSICAL_TYPE_HDD,
FF_DISKIO_PHYSICAL_TYPE_SSD,
} FFDiskIOPhysicalType;
typedef struct FFDiskIOResult
{
FFstrbuf name;
FFstrbuf interconnect;
FFDiskIOPhysicalType type;
uint64_t size;
FFstrbuf devPath;
uint64_t bytesRead;
uint64_t readCount;
-30
View File
@@ -48,8 +48,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInit(&device->devPath);
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
device->size = 0;
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
@@ -62,34 +60,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
ffCfStrGetString(bsdName, &device->devPath);
ffStrbufPrependS(&device->devPath, "/dev/");
}
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
if (mediaSize)
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
else
device->size = 0;
ffStrbufInit(&device->interconnect);
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
{
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (protocolCharacteristics)
ffCfDictGetString(protocolCharacteristics, CFSTR("Physical Interconnect"), &device->interconnect);
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (deviceCharacteristics)
{
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
if (mediumType)
{
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
device->type = FF_DISKIO_PHYSICAL_TYPE_SSD;
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
device->type = FF_DISKIO_PHYSICAL_TYPE_HDD;
}
}
}
}
return NULL;
+3 -13
View File
@@ -32,35 +32,25 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
if (provider->lg_geom->lg_rank != 1)
continue;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
FFDiskIOPhysicalType type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
{
if (ffStrEquals(ptr->lg_name, "descr"))
ffStrbufSetS(&name, ptr->lg_val);
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
type = ffStrEquals(ptr->lg_val, "0") ? FF_DISKIO_PHYSICAL_TYPE_SSD : FF_DISKIO_PHYSICAL_TYPE_HDD;
}
if (name.length == 0)
ffStrbufSetS(&name, provider->lg_name);
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
ffStrbufInit(&device->interconnect);
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
{
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
}
device->bytesRead = snapIter->bytes[DEVSTAT_READ];
device->readCount = snapIter->operations[DEVSTAT_READ];
device->bytesWritten = snapIter->bytes[DEVSTAT_WRITE];
device->writeCount = snapIter->operations[DEVSTAT_WRITE];
device->size = (uint64_t) provider->lg_mediasize;
ffStrbufInitMove(&device->name, &name);
device->type = type;
}
geom_stats_snapshot_free(snap);
+52 -83
View File
@@ -1,5 +1,6 @@
#include "diskio.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "util/stringUtils.h"
#include <ctype.h>
@@ -7,107 +8,75 @@
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS("/dev/disk/by-id/");
uint32_t baseDirLength = baseDir.length;
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
if(sysBlockDirp == NULL)
return "opendir(\"/sys/block/\") == NULL";
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
if(dirp == NULL)
return "opendir(batteryDir) == NULL";
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
struct dirent* sysBlockEntry;
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
{
if (entry->d_name[0] == '.')
const char* const devName = sysBlockEntry->d_name;
if (devName[0] == '.')
continue;
char* part = strstr(entry->d_name, "-part");
if (part && isdigit(part[strlen("-part")]))
continue;
if (ffStrStartsWith(entry->d_name, "nvme-eui.")) // NVMe drive identifier
continue;
// Other exceptions?
ffStrbufAppendS(&baseDir, entry->d_name);
char pathDev[PATH_MAX];
ssize_t pathLen = readlink(baseDir.chars, pathDev, PATH_MAX);
ffStrbufSubstrBefore(&baseDir, baseDirLength);
if (pathLen < 0) continue;
pathDev[pathLen] = '\0'; // ../../nvme0n1
char pathDev1[PATH_MAX];
const char* devName = basename(pathDev);
snprintf(pathDev1, PATH_MAX, "/dev/%s", devName);
// Avoid duplicated disks
bool flag = false;
FF_LIST_FOR_EACH(FFDiskIOResult, disk, *result)
{
if (ffStrbufEqualS(&disk->devPath, pathDev1))
{
flag = true;
break;
}
}
if (flag) continue;
char pathSysBlock[PATH_MAX];
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
FF_AUTO_CLOSE_FILE FILE* sysBlockStat = fopen(pathSysBlock, "r");
if (!sysBlockStat) continue;
char pathSysDeviceReal[PATH_MAX];
ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
if (pathLength < 0)
continue;
pathSysDeviceReal[pathLength] = '\0';
// I/Os merges sectors ticks ...
uint64_t nRead, sectorRead, nWritten, sectorWritten;
if (fscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, &sectorRead, &nWritten, &sectorWritten) == 0)
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
continue;
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
char* slash = strchr(entry->d_name, '-');
if (slash)
{
char* slash2 = strchr(slash + 1, '-');
if (slash2)
ffStrbufInitNS(&device->name, (uint32_t) (slash2 - slash - 1), slash + 1);
else
ffStrbufInitS(&device->name, slash + 1);
ffStrbufInitNS(&device->interconnect, (uint32_t) (slash - entry->d_name), entry->d_name);
}
else
{
ffStrbufInitS(&device->name, entry->d_name);
ffStrbufInit(&device->interconnect);
}
ffStrbufReplaceAllC(&device->name, '_', ' ');
ffStrbufInit(&device->name);
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->interconnect);
result->length--;
continue;
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
ffAppendFileBuffer(pathSysBlock, &device->name);
if (device->name.length > 0)
ffStrbufAppendC(&device->name, ' ');
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
ffAppendFileBuffer(pathSysBlock, &device->name);
ffStrbufTrim(&device->name, ' ');
if (device->name.length == 0)
ffStrbufSetS(&device->name, devName);
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
}
}
ffStrbufInitS(&device->devPath, pathDev1);
// I/Os merges sectors ticks ...
uint64_t nRead, sectorRead, nWritten, sectorWritten;
{
char sysBlockStat[PROC_FILE_BUFFSIZ];
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(sysBlockStat) - 1, sysBlockStat);
if (fileSize <= 0) continue;
sysBlockStat[fileSize] = '\0';
if (sscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, &sectorRead, &nWritten, &sectorWritten) <= 0)
continue;
}
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
device->bytesRead = sectorRead * 512;
device->bytesWritten = sectorWritten * 512;
device->readCount = nRead;
device->writeCount = nWritten;
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffReadFileBuffer(pathSysBlock, &buffer))
device->type = ffStrbufEqualS(&buffer, "1") ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
else
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
if (ffReadFileBuffer(pathSysBlock, &buffer))
device->size = ffStrbufToUInt(&buffer, 0);
else
device->size = 0;
}
return NULL;
+58 -77
View File
@@ -1,101 +1,82 @@
#include "diskio.h"
#include "common/io/io.h"
#include "util/windows/registry.h"
#include "util/windows/unicode.h"
#include <windows.h>
#include <winioctl.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
FF_HKEY_AUTO_DESTROY hKey = NULL;
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", &hKey, NULL))
return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum\") failed";
uint32_t nDevices;
if (!ffRegReadUint(hKey, L"Count", &nDevices, NULL))
return "ffRegReadUint(hKey, L\"Count\", &nDevices) failed";
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
for (uint32_t idev = 0; idev <= nDevices; ++idev) {
for (uint32_t idev = 0; ; ++idev)
{
_ultow(idev, pNum, 10);
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
break;
DWORD retSize;
char sddBuffer[4096];
if(!DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&sddBuffer,
sizeof(sddBuffer),
&retSize,
NULL
) || retSize == 0)
continue;
DISK_PERFORMANCE diskPerformance;
DWORD ioctrlSize = sizeof(diskPerformance);
DWORD dwSize;
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, ioctrlSize, &dwSize, NULL))
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
ffStrbufInit(&device->name);
if (sdd->VendorIdOffset != 0)
{
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInit(&device->name);
ffStrbufInit(&device->interconnect);
if (ffRegReadStrbuf(hKey, pNum, &device->name, NULL))
{
// SCSI\Disk&Ven_NVMe&Prod_WDC_PC_SN810_SDC\5&19cebb7&0&000000
uint32_t index = ffStrbufFirstIndexC(&device->name, '\\');
if (index != device->name.length)
{
ffStrbufAppendNS(&device->interconnect, index, device->name.chars); // SCSI
ffStrbufSubstrAfter(&device->name, index);
}
ffStrbufSubstrBeforeLastC(&device->name, '\\');
ffStrbufSubstrAfterFirstS(&device->name, "&Ven_");
ffStrbufRemoveS(&device->name, "&Prod");
ffStrbufReplaceAllC(&device->name, '_', ' ');
ffStrbufTrim(&device->name, ' ');
}
else
ffStrbufSetWS(&device->name, szDevice);
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
ffStrbufTrim(&device->name, ' ');
}
if (sdd->ProductIdOffset != 0)
{
if (device->name.length)
ffStrbufAppendC(&device->name, ' ');
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->interconnect);
result->length--;
continue;
}
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
ffStrbufTrimRight(&device->name, ' ');
}
ffStrbufInitWS(&device->devPath, szDevice);
device->bytesRead = (uint64_t) diskPerformance.BytesRead.QuadPart;
device->readCount = (uint64_t) diskPerformance.ReadCount;
device->bytesWritten = (uint64_t) diskPerformance.BytesWritten.QuadPart;
device->writeCount = (uint64_t) diskPerformance.WriteCount;
if (!device->name.length)
ffStrbufAppendF(&device->name, "PhysicalDrive%u", (unsigned) idev);
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
DWORD retSize = 0;
if(DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceSeekPenaltyProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&dspd,
sizeof(dspd),
&retSize,
NULL
) && retSize == sizeof(dspd))
device->type = dspd.IncursSeekPenalty ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
else
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
}
DISK_GEOMETRY_EX dge = {};
if(DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
NULL,
0,
&dge,
sizeof(dge),
&retSize,
NULL))
device->size = (uint64_t) dge.DiskSize.QuadPart;
else
device->size = 0;
ffStrbufInitWS(&device->devPath, szDevice);
DISK_PERFORMANCE dp = {};
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &dp, sizeof(dp), &retSize, NULL))
{
device->bytesRead = (uint64_t) dp.BytesRead.QuadPart;
device->readCount = (uint64_t) dp.ReadCount;
device->bytesWritten = (uint64_t) dp.BytesWritten.QuadPart;
device->writeCount = (uint64_t) dp.WriteCount;
}
else
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
}
}
@@ -11,6 +11,7 @@
#define FF_DE_PRETTY_LXDE "LXDE"
#define FF_DE_PRETTY_LXQT "LXQT"
#define FF_DE_PRETTY_BUDGIE "Budgie"
#define FF_DE_PRETTY_CDE "CDE"
#define FF_DE_PRETTY_UNITY "Unity"
#define FF_WM_PRETTY_KWIN "KWin"
@@ -32,6 +33,7 @@
#define FF_WM_PRETTY_HERBSTLUFTWM "herbstluftwm"
#define FF_WM_PRETTY_ICEWM "IceWM"
#define FF_WM_PRETTY_SPECTRWM "spectrwm"
#define FF_WM_PRETTY_DTWM "dtwm"
#define FF_WM_PROTOCOL_TTY "TTY"
@@ -10,7 +10,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
ffStrbufInit(&ds->dePrettyName);
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
if (!instance.config.general.dsForceDrm)
if (instance.config.general.dsForceDrm == FF_DS_FORCE_DRM_TYPE_FALSE)
{
//We try wayland as our preferred display server, as it supports the most features.
//This method can't detect the name of our WM / DE
+133 -50
View File
@@ -27,10 +27,10 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
ffStrbufAppendS(&drmDir, entry->d_name);
uint32_t drmDirWithDnameLength = drmDir.length;
ffStrbufAppendS(&drmDir, "/enabled");
char enabled = 'd'; // disabled
ffReadFileData(drmDir.chars, sizeof(enabled), &enabled);
if (enabled != 'e') // enabled
ffStrbufAppendS(&drmDir, "/status");
char status = 'd'; // disconnected
ffReadFileData(drmDir.chars, sizeof(status), &status);
if (status != 'c') // connected
{
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
@@ -152,6 +152,49 @@ static inline const char* drmType2Name(uint32_t connector_type)
}
}
static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name)
{
const char* drmDirPath = "/sys/class/drm/";
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
if(dirp == NULL)
return "opendir(drmDirPath) failed";
FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64);
ffStrbufAppendS(&drmDir, drmDirPath);
uint32_t drmDirLength = drmDir.length;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
continue;
ffStrbufAppendS(&drmDir, entry->d_name);
uint32_t drmDirWithDnameLength = drmDir.length;
ffStrbufAppendS(&drmDir, "/connector_id");
ffReadFileBuffer(drmDir.chars, name);
if (ffStrbufToUInt(name, 0) != connId)
{
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
}
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
ffStrbufClear(name);
ffStrbufAppendS(&drmDir, "/edid");
uint8_t edidData[128];
if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData))
ffEdidGetName(edidData, name);
return NULL;
}
ffStrbufClear(name);
return "Failed to match connector ID";
}
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen(libdrm)" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
@@ -162,6 +205,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetEncoder)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetProperty)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetPropertyBlob)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeResources)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeCrtc)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeEncoder)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeConnector)
@@ -196,18 +240,56 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
if (!conn)
continue;
if (conn->connection != DRM_MODE_CONNECTED)
goto next_conn;
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
if (!encoder)
goto next_conn;
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
if (!crtc)
goto next_encoder;
if (conn->connection == DRM_MODE_CONNECTED)
{
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
uint32_t width = 0, height = 0, refreshRate = 0;
if (encoder)
{
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
if (crtc)
{
width = crtc->mode.vdisplay;
height = crtc->mode.hdisplay;
refreshRate = crtc->mode.vrefresh;
if (refreshRate == 0)
{
// There are weird cases that we can't get the refresh rate from the CRTC but from the modes
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
{
drmModeModeInfo* mode = &conn->modes[iMode];
if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
{
refreshRate = mode->vrefresh;
break;
}
}
}
ffdrmModeFreeCrtc(crtc);
}
ffdrmModeFreeEncoder(encoder);
}
if (width == 0 || height == 0)
{
// NVIDIA DRM driver seems incomplete and conn->encoder_id == 0
// Assume preferred resolution is used as what we do in drmParseSys
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
{
drmModeModeInfo* mode = &conn->modes[iMode];
if (mode->type & DRM_MODE_TYPE_PREFERRED)
{
width = mode->hdisplay;
height = mode->vdisplay;
refreshRate = mode->vrefresh;
break;
}
}
}
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
for (int iProp = 0; iProp < conn->count_props; ++iProp)
@@ -219,60 +301,58 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
uint32_t type = prop->flags & (DRM_MODE_PROP_LEGACY_TYPE | DRM_MODE_PROP_EXTENDED_TYPE);
if (type == DRM_MODE_PROP_BLOB && ffStrEquals(prop->name, "EDID"))
{
// Stangely, prop->count_blobs is 0 and prop->blob_ids is NULL
drmModePropertyBlobPtr blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
if (blob->length >= 128)
ffEdidGetName(blob->data, &name);
ffdrmModeFreePropertyBlob(blob);
drmModePropertyBlobPtr blob = NULL;
if (prop->count_blobs > 0 && prop->blob_ids != NULL)
blob = ffdrmModeGetPropertyBlob(fd, prop->blob_ids[0]);
else
blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
if (blob)
{
if (blob->length >= 128)
ffEdidGetName(blob->data, &name);
ffdrmModeFreePropertyBlob(blob);
}
break;
}
ffdrmModeFreeProperty(prop);
}
if (name.length == 0)
{
drmGetNameByConnId(conn->connector_id, &name);
}
if (name.length == 0)
{
const char* connectorTypeName = drmType2Name(conn->connector_type);
if (connectorTypeName == NULL)
connectorTypeName = "Unknown";
ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn);
ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn + 1);
}
uint32_t refreshRate = crtc->mode.vrefresh;
if (refreshRate == 0)
{
// There are weird cases that we can't get the refresh rate from the CRTC but from the modes
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
{
drmModeModeInfo* mode = &conn->modes[iMode];
if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
{
refreshRate = mode->vrefresh;
break;
}
}
}
ffdsAppendDisplay(
result,
crtc->width, crtc->height,
ffdsAppendDisplay(result,
width,
height,
refreshRate,
0, 0,
0,
0,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
conn->connector_type == DRM_MODE_CONNECTOR_eDP
? FF_DISPLAY_TYPE_BUILTIN
: conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB
? FF_DISPLAY_TYPE_EXTERNAL : FF_DISPLAY_TYPE_UNKNOWN,
false,
0
conn->connector_id
);
}
ffdrmModeFreeCrtc(crtc);
next_encoder:
ffdrmModeFreeEncoder(encoder);
next_conn:
ffdrmModeFreeConnector(conn);
}
ffdrmModeFreeResources(res);
}
ffdrmFreeDevices(devices, nDevices);
@@ -285,8 +365,11 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
void ffdsConnectDrm(FFDisplayServerResult* result)
{
#ifdef FF_HAVE_DRM
if (drmConnectLibdrm(result) == NULL)
return;
if (instance.config.general.dsForceDrm != FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY)
{
if (drmConnectLibdrm(result) == NULL)
return;
}
#endif
drmParseSysfs(result);
+111 -67
View File
@@ -1,14 +1,20 @@
#include "displayserver_linux.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "common/processing.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#ifdef __FreeBSD__
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/user.h>
#else
#include "common/io/io.h"
#endif
static const char* parseEnv(void)
{
@@ -46,10 +52,12 @@ static const char* parseEnv(void)
if(getenv("TDE_FULL_SESSION") != NULL)
return "Trinity";
#ifdef __linux__
if(
getenv("WAYLAND_DISPLAY") != NULL &&
ffPathExists("/mnt/wslg/", FF_PATHTYPE_DIRECTORY)
) return "WSLg";
#endif
return NULL;
}
@@ -60,52 +68,54 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
return;
if(
strcasecmp(name, "kwin_wayland") == 0 ||
strcasecmp(name, "kwin_wayland_wrapper") == 0 ||
strcasecmp(name, "kwin_x11") == 0 ||
strcasecmp(name, "kwin_x11_wrapper") == 0 ||
strcasecmp(name, "kwin") == 0
ffStrEqualsIgnCase(name, "kwin_wayland") ||
ffStrEqualsIgnCase(name, "kwin_wayland_wrapper") ||
ffStrEqualsIgnCase(name, "kwin_x11") ||
ffStrEqualsIgnCase(name, "kwin_x11_wrapper") ||
ffStrEqualsIgnCase(name, "kwin")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN);
else if(
strcasecmp(name, "gnome-shell") == 0 ||
strcasecmp(name, "gnome shell") == 0 ||
strcasecmp(name, "gnome-session-binary") == 0 ||
strcasecmp(name, "Mutter") == 0
ffStrEqualsIgnCase(name, "gnome-shell") ||
ffStrEqualsIgnCase(name, "gnome shell") ||
ffStrEqualsIgnCase(name, "gnome-session-binary") ||
ffStrEqualsIgnCase(name, "Mutter")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER);
else if(
strcasecmp(name, "cinnamon-session") == 0 ||
strcasecmp(name, "Muffin") == 0 ||
strcasecmp(name, "Mutter (Muffin)") == 0
ffStrEqualsIgnCase(name, "cinnamon-session") ||
ffStrEqualsIgnCase(name, "Muffin") ||
ffStrEqualsIgnCase(name, "Mutter (Muffin)")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN);
else if(strcasecmp(name, "sway") == 0)
else if(ffStrEqualsIgnCase(name, "sway"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_SWAY);
else if(strcasecmp(name, "weston") == 0)
else if(ffStrEqualsIgnCase(name, "weston"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WESTON);
else if(strcasecmp(name, "wayfire") == 0)
else if(ffStrEqualsIgnCase(name, "wayfire"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WAYFIRE);
else if(strcasecmp(name, "openbox") == 0)
else if(ffStrEqualsIgnCase(name, "openbox"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_OPENBOX);
else if(strcasecmp(name, "xfwm4") == 0)
else if(ffStrEqualsIgnCase(name, "xfwm4"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XFWM4);
else if(strcasecmp(name, "Marco") == 0 ||
strcasecmp(name, "Metacity (Marco)") == 0)
else if(ffStrEqualsIgnCase(name, "Marco") ||
ffStrEqualsIgnCase(name, "Metacity (Marco)"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MARCO);
else if(strcasecmp(name, "xmonad") == 0)
else if(ffStrEqualsIgnCase(name, "xmonad"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XMONAD);
else if(strcasecmp(name, "WSLg") == 0)
else if(ffStrEqualsIgnCase(name, "WSLg"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WSLG);
else if(strcasecmp(name, "dwm") == 0)
else if(ffStrEqualsIgnCase(name, "dwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DWM);
else if(strcasecmp(name, "bspwm") == 0)
else if(ffStrEqualsIgnCase(name, "bspwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_BSPWM);
else if(strcasecmp(name, "tinywm") == 0)
else if(ffStrEqualsIgnCase(name, "tinywm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_TINYWM);
else if(strcasecmp(name, "qtile") == 0)
else if(ffStrEqualsIgnCase(name, "qtile"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_QTILE);
else if(strcasecmp(name, "herbstluftwm") == 0)
else if(ffStrEqualsIgnCase(name, "herbstluftwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HERBSTLUFTWM);
else if(strcasecmp(name, "icewm") == 0)
else if(ffStrEqualsIgnCase(name, "icewm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM);
else if(ffStrEqualsIgnCase(name, "dtwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM);
}
static void applyNameIfWM(FFDisplayServerResult* result, const char* processName)
@@ -136,10 +146,10 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
return;
else if(
strcasecmp(name, "KDE") == 0 ||
strcasecmp(name, "plasma") == 0 ||
strcasecmp(name, "plasmashell") == 0 ||
strcasecmp(name, "plasmawayland") == 0
ffStrEqualsIgnCase(name, "KDE") ||
ffStrEqualsIgnCase(name, "plasma") ||
ffStrEqualsIgnCase(name, "plasmashell") ||
ffStrEqualsIgnCase(name, "plasmawayland")
) {
ffStrbufSetStatic(&result->deProcessName, "plasmashell");
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
@@ -147,10 +157,10 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
}
else if(
strcasecmp(name, "Gnome") == 0 ||
strcasecmp(name, "ubuntu:GNOME") == 0 ||
strcasecmp(name, "ubuntu") == 0 ||
strcasecmp(name, "gnome-shell") == 0
ffStrEqualsIgnCase(name, "Gnome") ||
ffStrEqualsIgnCase(name, "ubuntu:GNOME") ||
ffStrEqualsIgnCase(name, "ubuntu") ||
ffStrEqualsIgnCase(name, "gnome-shell")
) {
ffStrbufSetStatic(&result->deProcessName, "gnome-shell");
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
@@ -161,37 +171,37 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
}
else if(
strcasecmp(name, "X-Cinnamon") == 0 ||
strcasecmp(name, "Cinnamon") == 0
ffStrEqualsIgnCase(name, "X-Cinnamon") ||
ffStrEqualsIgnCase(name, "Cinnamon")
) {
ffStrbufSetS(&result->deProcessName, "cinnamon");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
}
else if(
strcasecmp(name, "XFCE") == 0 ||
strcasecmp(name, "X-XFCE") == 0 ||
strcasecmp(name, "XFCE4") == 0 ||
strcasecmp(name, "X-XFCE4") == 0 ||
strcasecmp(name, "xfce4-session") == 0
ffStrEqualsIgnCase(name, "XFCE") ||
ffStrEqualsIgnCase(name, "X-XFCE") ||
ffStrEqualsIgnCase(name, "XFCE4") ||
ffStrEqualsIgnCase(name, "X-XFCE4") ||
ffStrEqualsIgnCase(name, "xfce4-session")
) {
ffStrbufSetS(&result->deProcessName, "xfce4-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
}
else if(
strcasecmp(name, "MATE") == 0 ||
strcasecmp(name, "X-MATE") == 0 ||
strcasecmp(name, "mate-session") == 0
ffStrEqualsIgnCase(name, "MATE") ||
ffStrEqualsIgnCase(name, "X-MATE") ||
ffStrEqualsIgnCase(name, "mate-session")
) {
ffStrbufSetS(&result->deProcessName, "mate-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
}
else if(
strcasecmp(name, "LXQt") == 0 ||
strcasecmp(name, "X-LXQT") == 0 ||
strcasecmp(name, "lxqt-session") == 0
ffStrEqualsIgnCase(name, "LXQt") ||
ffStrEqualsIgnCase(name, "X-LXQT") ||
ffStrEqualsIgnCase(name, "lxqt-session")
) {
ffStrbufSetS(&result->deProcessName, "lxqt-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
@@ -201,14 +211,21 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
}
else if(
strcasecmp(name, "Budgie") == 0 ||
strcasecmp(name, "X-Budgie") == 0 ||
strcasecmp(name, "budgie-desktop") == 0 ||
strcasecmp(name, "Budgie:GNOME") == 0
ffStrEqualsIgnCase(name, "Budgie") ||
ffStrEqualsIgnCase(name, "X-Budgie") ||
ffStrEqualsIgnCase(name, "budgie-desktop") ||
ffStrEqualsIgnCase(name, "Budgie:GNOME")
) {
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
}
else if(
ffStrEqualsIgnCase(name, "dtsession")
) {
ffStrbufSetS(&result->deProcessName, "dtsession");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CDE);
}
}
static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
@@ -219,9 +236,9 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
const char* env = getenv("XDG_SESSION_TYPE");
if(ffStrSet(env))
{
if(strcasecmp(env, "x11") == 0)
if(ffStrEqualsIgnCase(env, "x11"))
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
else if(strcasecmp(env, "tty") == 0)
else if(ffStrEqualsIgnCase(env, "tty"))
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
else
ffStrbufSetS(&result->wmProtocolName, env);
@@ -237,30 +254,56 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
}
env = getenv("TERM");
if(ffStrSet(env) && strcasecmp(env, "linux") == 0)
if(ffStrSet(env) && ffStrEqualsIgnCase(env, "linux"))
{
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
return;
}
}
static void getFromProcDir(FFDisplayServerResult* result)
static const char* getFromProcesses(FFDisplayServerResult* result)
{
DIR* proc = opendir("/proc");
if(proc == NULL)
return;
uint32_t userId = getuid();
#ifdef __FreeBSD__
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_UID, (int) userId};
size_t length = 0;
if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0)
return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_UID}, NULL) failed";
FF_AUTO_FREE struct kinfo_proc* procs = (struct kinfo_proc*) malloc(length);
if(sysctl(request, sizeof(request) / sizeof(*request), procs, &length, NULL, 0) != 0)
return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_UID}, procs) failed";
length /= sizeof(*procs);
for (struct kinfo_proc* proc = procs; proc < procs + length; ++proc)
{
if(result->dePrettyName.length == 0)
applyPrettyNameIfDE(result, proc->ki_comm);
if(result->wmPrettyName.length == 0)
applyNameIfWM(result, proc->ki_comm);
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
break;
}
#else
FF_AUTO_CLOSE_DIR DIR* procdir = opendir("/proc");
if(procdir == NULL)
return "opendir(\"/proc\") failed";
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreateA(64);
ffStrbufAppendS(&procPath, "/proc/");
uint32_t procPathLength = procPath.length;
FF_STRBUF_AUTO_DESTROY userID = ffStrbufCreateF("%i", getuid());
FF_STRBUF_AUTO_DESTROY loginuid = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY processName = ffStrbufCreateA(256); //Some processes have large command lines (looking at you chrome)
struct dirent* dirent;
while((dirent = readdir(proc)) != NULL)
while((dirent = readdir(procdir)) != NULL)
{
//Match only folders starting with a number (the pid folders)
if(dirent->d_type != DT_DIR || !isdigit(dirent->d_name[0]))
@@ -272,7 +315,7 @@ static void getFromProcDir(FFDisplayServerResult* result)
//Don't check for processes not owend by the current user.
ffStrbufAppendS(&procPath, "/loginuid");
ffReadFileBuffer(procPath.chars, &loginuid);
if(ffStrbufComp(&userID, &loginuid) != 0)
if(ffStrbufToUInt(&loginuid, (uint64_t) -1) != userId)
{
ffStrbufSubstrBefore(&procPath, procPathLength);
continue;
@@ -297,8 +340,9 @@ static void getFromProcDir(FFDisplayServerResult* result)
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
break;
}
#endif
closedir(proc);
return NULL;
}
void ffdsDetectWMDE(FFDisplayServerResult* result)
@@ -338,7 +382,7 @@ void ffdsDetectWMDE(FFDisplayServerResult* result)
return;
//Get missing WM / DE from processes.
getFromProcDir(result);
getFromProcesses(result);
//Return if both wm and de are set, or if env doesn't contain anything
if(
+14 -8
View File
@@ -9,20 +9,26 @@
static double detectGpuTemp(const FFstrbuf* gpuName)
{
double result = 0;
const char* error;
const char* error = NULL;
if(ffStrbufStartsWithS(gpuName, "Apple M1"))
error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result);
else if(ffStrbufStartsWithS(gpuName, "Apple M2"))
error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result);
else if(ffStrbufStartsWithS(gpuName, "Intel"))
if (ffStrbufStartsWithS(gpuName, "Apple M"))
{
switch (strtol(gpuName->chars + strlen("Apple M"), NULL, 10))
{
case 1: error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result); break;
case 2: error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result); break;
case 3: error = ffDetectCoreTemps(FF_TEMP_GPU_M3X, &result); break;
default: error = "Unsupported Apple Silicon GPU";
}
}
else if (ffStrbufStartsWithS(gpuName, "Intel"))
error = ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &result);
else if(ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
else if (ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
error = ffDetectCoreTemps(FF_TEMP_GPU_AMD, &result);
else
error = ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &result);
if(error)
if (error)
return FF_GPU_TEMP_UNSET;
return result;
+10 -1
View File
@@ -16,7 +16,16 @@ const char* ffDetectMemory(FFMemoryResult* ram)
if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS)
return "Failed to read host_statistics64";
ram->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * instance.state.platform.pageSize;
// https://github.com/exelban/stats/blob/master/Modules/RAM/readers.swift#L56
ram->bytesUsed = ((uint64_t)
+ vmstat.active_count
+ vmstat.inactive_count
+ vmstat.speculative_count
+ vmstat.wire_count
+ vmstat.compressor_page_count
- vmstat.purgeable_count
- vmstat.external_page_count
) * instance.state.platform.pageSize;
return NULL;
}
+25 -15
View File
@@ -13,33 +13,43 @@ const char* ffDetectMemory(FFMemoryResult* ram)
buf[nRead] = '\0';
uint64_t memTotal = 0,
memAvailable = 0,
shmem = 0,
memFree = 0,
buffers = 0,
cached = 0,
sReclaimable = 0;
char *token = NULL;
if((token = strstr(buf, "MemTotal:")) != NULL)
memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10);
else
return "MemTotal not found in /proc/meminfo";
if((token = strstr(buf, "MemFree:")) != NULL)
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
if((token = strstr(buf, "MemAvailable:")) != NULL)
memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10);
else
{
if((token = strstr(buf, "MemFree:")) != NULL)
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
if((token = strstr(buf, "Buffers:")) != NULL)
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
if((token = strstr(buf, "Cached:")) != NULL)
cached = strtoul(token + strlen("Cached:"), NULL, 10);
if((token = strstr(buf, "Shmem:")) != NULL)
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
if((token = strstr(buf, "SReclaimable:")) != NULL)
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
if((token = strstr(buf, "Buffers:")) != NULL)
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
if((token = strstr(buf, "Cached:")) != NULL)
cached = strtoul(token + strlen("Cached:"), NULL, 10);
if((token = strstr(buf, "Shmem:")) != NULL)
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
if((token = strstr(buf, "SReclaimable:")) != NULL)
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
memAvailable = memFree + buffers + cached + sReclaimable - shmem;
}
ram->bytesTotal = memTotal * 1024lu;
ram->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * 1024lu;
ram->bytesUsed = (memTotal - memAvailable) * 1024lu;
return NULL;
}
+8
View File
@@ -0,0 +1,8 @@
#include "packages.h"
#include "common/settings.h"
void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
{
result->pkg = (uint32_t) ffSettingsGetSQLite3Int(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg/local.sqlite", "SELECT count(*) FROM packages");
}
+10 -20
View File
@@ -11,7 +11,7 @@
static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
{
DIR* dirp = opendir(dirname);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
if(dirp == NULL)
return 0;
@@ -26,8 +26,6 @@ static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
if(type == DT_DIR && num_elements >= 2)
num_elements -= 2; // accounting for . and ..
closedir(dirp);
return num_elements;
}
@@ -42,26 +40,19 @@ static uint32_t getNumElements(FFstrbuf* baseDir, const char* dirname, unsigned
static uint32_t getNumStringsImpl(const char* filename, const char* needle)
{
FILE* file = fopen(filename, "r");
if(file == NULL)
FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate();
if (!ffReadFileBuffer(filename, &content))
return 0;
uint32_t count = 0;
char* line = NULL;
size_t len = 0;
while(getline(&line, &len, file) != EOF)
char *iter = content.chars;
size_t needleLength = strlen(needle);
while ((iter = memmem(iter, content.length - (size_t)(iter - content.chars), needle, needleLength)) != NULL)
{
if(strstr(line, needle) != NULL)
++count;
++count;
iter += needleLength;
}
if(line != NULL)
free(line);
fclose(file);
return count;
}
@@ -272,9 +263,8 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts)
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system");
packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR);
packageCounts->pkg += getSQLite3Int(baseDir, "/var/db/pkg/local.sqlite", "SELECT count(id) FROM packages");
packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG);
packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(blob) FROM Packages");
packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages");
packageCounts->snap += getSnap(baseDir);
packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps");
packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", DT_DIR);
@@ -288,7 +278,7 @@ static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* package
getPackageCounts(baseDir, packageCounts);
uint32_t baseDirLength = baseDir->length;
ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC"/pacman-mirrors.conf");
ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC "/pacman-mirrors.conf");
if(ffParsePropFile(baseDir->chars, "Branch =", &packageCounts->pacmanBranch) && packageCounts->pacmanBranch.length == 0)
ffStrbufAppendS(&packageCounts->pacmanBranch, "stable");
ffStrbufSubstrBefore(baseDir, baseDirLength);
+25
View File
@@ -0,0 +1,25 @@
#include "fastfetch.h"
typedef enum FFPhysicalDiskType
{
FF_PHYSICALDISK_TYPE_NONE = 0,
// If neither is set, it's unknown
FF_PHYSICALDISK_TYPE_HDD = 1 << 0,
FF_PHYSICALDISK_TYPE_SSD = 1 << 1,
FF_PHYSICALDISK_TYPE_FIXED = 1 << 2,
FF_PHYSICALDISK_TYPE_REMOVABLE = 1 << 3,
} FFPhysicalDiskType;
typedef struct FFPhysicalDiskResult
{
FFstrbuf name;
FFstrbuf interconnect;
FFstrbuf serial;
FFstrbuf devPath;
FFPhysicalDiskType type;
uint64_t size;
} FFPhysicalDiskResult;
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options);
@@ -0,0 +1,93 @@
#include "physicaldisk.h"
#include "util/apple/cf_helpers.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOBlockStorageDriver.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
static inline void wrapIoObjectRelease(io_service_t* service)
{
assert(service);
if (*service)
IOObjectRelease(*service);
}
#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
while((registryEntry = IOIteratorNext(iterator)) != 0)
{
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry;
io_name_t deviceName;
if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS)
continue;
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0;
if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS)
continue;
if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only
continue;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInit(&device->serial);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInit(&device->devPath);
ffStrbufInit(&device->interconnect);
device->type = FF_PHYSICALDISK_TYPE_NONE;
device->size = 0;
FF_CFTYPE_AUTO_RELEASE CFBooleanRef removable = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaRemovableKey), kCFAllocatorDefault, kNilOptions);
device->type |= CFBooleanGetValue(removable) ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
if (bsdName)
{
ffCfStrGetString(bsdName, &device->devPath);
ffStrbufPrependS(&device->devPath, "/dev/");
}
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
if (mediaSize)
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
else
device->size = 0;
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
{
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (protocolCharacteristics)
ffCfDictGetString(protocolCharacteristics, CFSTR(kIOPropertyPhysicalInterconnectTypeKey), &device->interconnect);
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (deviceCharacteristics)
{
ffCfDictGetString(deviceCharacteristics, CFSTR(kIOPropertyProductSerialNumberKey), &device->serial);
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
if (mediumType)
{
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
device->type |= FF_PHYSICALDISK_TYPE_SSD;
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
device->type |= FF_PHYSICALDISK_TYPE_HDD;
}
}
}
}
return NULL;
}
@@ -0,0 +1,70 @@
#include "physicaldisk.h"
#include "util/stringUtils.h"
#include <devstat.h>
#include <memory.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/disk.h>
#include <libgeom.h>
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
struct gmesh geomTree;
if (geom_gettree(&geomTree) < 0)
return "geom_gettree() failed";
if (geom_stats_open() < 0)
return "geom_stats_open() failed";
void* snap = geom_stats_snapshot_get();
struct devstat* snapIter;
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
{
if (snapIter->device_type & DEVSTAT_TYPE_PASS)
continue;
struct gident* geomId = geom_lookupid(&geomTree, snapIter->id);
if (geomId == NULL)
continue;
if (geomId->lg_what != ISPROVIDER)
continue;
struct gprovider* provider = (struct gprovider*) geomId->lg_ptr;
if (provider->lg_geom->lg_rank != 1)
continue;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
FF_STRBUF_AUTO_DESTROY identifier = ffStrbufCreate();
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
{
if (ffStrEquals(ptr->lg_name, "descr"))
ffStrbufSetS(&name, ptr->lg_val);
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
type |= ffStrEquals(ptr->lg_val, "0") ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
else if (ffStrEquals(ptr->lg_name, "ident"))
ffStrbufSetS(&identifier, ptr->lg_val);
}
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
continue;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
ffStrbufInitMove(&device->serial, &identifier);
ffStrbufInit(&device->interconnect);
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
{
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
}
device->size = (uint64_t) provider->lg_mediasize;
ffStrbufInitMove(&device->name, &name);
device->type = type;
}
geom_stats_snapshot_free(snap);
geom_stats_close();
return NULL;
}
@@ -0,0 +1,117 @@
#include "physicaldisk.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <limits.h>
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
if(sysBlockDirp == NULL)
return "opendir(\"/sys/block/\") == NULL";
struct dirent* sysBlockEntry;
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
{
const char* const devName = sysBlockEntry->d_name;
if (devName[0] == '.')
continue;
char pathSysBlock[PATH_MAX];
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
char pathSysDeviceReal[PATH_MAX];
ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
if (pathLength < 0)
continue;
pathSysDeviceReal[pathLength] = '\0';
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
continue;
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
continue;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
device->type = FF_PHYSICALDISK_TYPE_NONE;
ffStrbufInit(&device->name);
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
ffAppendFileBuffer(pathSysBlock, &device->name);
if (device->name.length > 0)
ffStrbufAppendC(&device->name, ' ');
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
ffAppendFileBuffer(pathSysBlock, &device->name);
ffStrbufTrim(&device->name, ' ');
if (device->name.length == 0)
ffStrbufSetS(&device->name, devName);
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
}
}
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
{
ffStrbufInit(&device->interconnect);
if (strstr(pathSysDeviceReal, "/usb") != NULL)
ffStrbufSetS(&device->interconnect, "usb");
else
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName);
if (!ffAppendFileBuffer(pathSysBlock, &device->interconnect))
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/uevent", devName);
if (ffParsePropFile(pathSysBlock, "DEVTYPE=", &device->interconnect))
ffStrbufSubstrBeforeLastC(&device->interconnect, '_');
}
}
}
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
char isRotationalChar = '1';
if (ffReadFileData(pathSysBlock, 1, &isRotationalChar) > 0)
device->type |= isRotationalChar == '1' ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
}
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
char blkSize[32];
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blkSize) - 1, blkSize);
if (fileSize > 0)
{
blkSize[fileSize] = 0;
device->size = (uint64_t) strtoul(blkSize, NULL, 10) * 512;
}
else
device->size = 0;
}
{
char removableChar = '0';
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/removable", devName);
if (ffReadFileData(pathSysBlock, 1, &removableChar) > 0)
device->type |= removableChar == '1' ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
}
{
ffStrbufInit(&device->serial);
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName);
ffReadFileBuffer(pathSysBlock, &device->serial);
}
}
return NULL;
}
@@ -0,0 +1,131 @@
#include "physicaldisk.h"
#include "common/io/io.h"
#include "util/windows/unicode.h"
#include <windows.h>
#include <winioctl.h>
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
for (uint32_t idev = 0; ; ++idev)
{
_ultow(idev, pNum, 10);
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
break;
DWORD retSize;
char sddBuffer[4096];
if(!DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&sddBuffer,
sizeof(sddBuffer),
&retSize,
NULL
) || retSize == 0)
continue;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
device->type = FF_PHYSICALDISK_TYPE_NONE;
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
ffStrbufInit(&device->name);
if (sdd->VendorIdOffset != 0)
{
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
ffStrbufTrim(&device->name, ' ');
}
if (sdd->ProductIdOffset != 0)
{
if (device->name.length)
ffStrbufAppendC(&device->name, ' ');
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
ffStrbufTrimRight(&device->name, ' ');
}
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
}
ffStrbufInitWS(&device->devPath, szDevice);
ffStrbufInit(&device->serial);
if (sdd->SerialNumberOffset != 0)
{
ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset);
ffStrbufTrim(&device->serial, ' ');
}
device->type |= sdd->RemovableMedia ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
ffStrbufInit(&device->interconnect);
switch (sdd->BusType)
{
case BusTypeUnknown: ffStrbufSetStatic(&device->interconnect, "Unknown"); break;
case BusTypeScsi: ffStrbufSetStatic(&device->interconnect, "Scsi"); break;
case BusTypeAtapi: ffStrbufSetStatic(&device->interconnect, "Atapi"); break;
case BusTypeAta: ffStrbufSetStatic(&device->interconnect, "Ata"); break;
case BusType1394: ffStrbufSetStatic(&device->interconnect, "1394"); break;
case BusTypeSsa: ffStrbufSetStatic(&device->interconnect, "Ssa"); break;
case BusTypeFibre: ffStrbufSetStatic(&device->interconnect, "Fibra"); break;
case BusTypeUsb: ffStrbufSetStatic(&device->interconnect, "Usb"); break;
case BusTypeRAID: ffStrbufSetStatic(&device->interconnect, "RAID"); break;
case BusTypeiScsi: ffStrbufSetStatic(&device->interconnect, "iScsi"); break;
case BusTypeSas: ffStrbufSetStatic(&device->interconnect, "Sas"); break;
case BusTypeSata: ffStrbufSetStatic(&device->interconnect, "Sata"); break;
case BusTypeSd: ffStrbufSetStatic(&device->interconnect, "Sd"); break;
case BusTypeMmc: ffStrbufSetStatic(&device->interconnect, "Mmc"); break;
case BusTypeVirtual: ffStrbufSetStatic(&device->interconnect, "Virtual"); break;
case BusTypeFileBackedVirtual: ffStrbufSetStatic(&device->interconnect, "FileBackedVirtual"); break;
case BusTypeSpaces: ffStrbufSetStatic(&device->interconnect, "Spaces"); break;
case BusTypeNvme: ffStrbufSetStatic(&device->interconnect, "Nvme"); break;
case BusTypeSCM: ffStrbufSetStatic(&device->interconnect, "SCM"); break;
case BusTypeUfs: ffStrbufSetStatic(&device->interconnect, "Ufs"); break;
default: ffStrbufSetF(&device->interconnect, "Unknown (%d)", (int) sdd->BusType); break;
}
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
if(DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceSeekPenaltyProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&dspd,
sizeof(dspd),
&retSize,
NULL
) && retSize == sizeof(dspd))
device->type |= dspd.IncursSeekPenalty ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
DISK_GEOMETRY_EX dge = {};
if(DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
NULL,
0,
&dge,
sizeof(dge),
&retSize,
NULL))
device->size = (uint64_t) dge.DiskSize.QuadPart;
else
device->size = 0;
}
return NULL;
}
+35 -1
View File
@@ -333,6 +333,25 @@ const char *ffDetectCoreTemps(enum FFTempType type, double *result)
count += detectTemp(conn, "Tp09", result); // CPU core 8
break;
case FF_TEMP_CPU_M3X:
count += detectTemp(conn, "Te05", result); // CPU efficiency core 1
count += detectTemp(conn, "Te0L", result); // CPU efficiency core 2
count += detectTemp(conn, "Te0P", result); // CPU efficiency core 3
count += detectTemp(conn, "Te0S", result); // CPU efficiency core 4
count += detectTemp(conn, "Tf04", result); // CPU performance core 1
count += detectTemp(conn, "Tf09", result); // CPU performance core 2
count += detectTemp(conn, "Tf0A", result); // CPU performance core 3
count += detectTemp(conn, "Tf0B", result); // CPU performance core 4
count += detectTemp(conn, "Tf0D", result); // CPU performance core 5
count += detectTemp(conn, "Tf0E", result); // CPU performance core 6
count += detectTemp(conn, "Tf44", result); // CPU performance core 7
count += detectTemp(conn, "Tf49", result); // CPU performance core 8
count += detectTemp(conn, "Tf4A", result); // CPU performance core 9
count += detectTemp(conn, "Tf4B", result); // CPU performance core 10
count += detectTemp(conn, "Tf4D", result); // CPU performance core 11
count += detectTemp(conn, "Tf4E", result); // CPU performance core 12
break;
case FF_TEMP_GPU_INTEL:
count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
goto gpu_unknown;
@@ -359,12 +378,27 @@ const char *ffDetectCoreTemps(enum FFTempType type, double *result)
count += detectTemp(conn, "Tg0j", result); // GPU 2
break;
case FF_TEMP_GPU_M3X:
count += detectTemp(conn, "Tf14", result); // GPU 1
count += detectTemp(conn, "Tf18", result); // GPU 2
count += detectTemp(conn, "Tf19", result); // GPU 3
count += detectTemp(conn, "Tf1A", result); // GPU 4
count += detectTemp(conn, "Tf24", result); // GPU 5
count += detectTemp(conn, "Tf28", result); // GPU 6
count += detectTemp(conn, "Tf29", result); // GPU 7
count += detectTemp(conn, "Tf2A", result); // GPU 8
break;
case FF_TEMP_BATTERY:
count += detectTemp(conn, "TB1T", result); // Battery
count += detectTemp(conn, "TB2T", result); // Battery
break;
case FF_TEMP_MEMORY:
count += detectTemp(conn, "Tm02", result); // Memory
count += detectTemp(conn, "Tm02", result); // Memory 1
count += detectTemp(conn, "Tm06", result); // Memory 2
count += detectTemp(conn, "Tm08", result); // Memory 3
count += detectTemp(conn, "Tm09", result); // Memory 4
break;
}
+2
View File
@@ -15,12 +15,14 @@ enum FFTempType
FF_TEMP_CPU_X64,
FF_TEMP_CPU_M1X,
FF_TEMP_CPU_M2X,
FF_TEMP_CPU_M3X,
FF_TEMP_GPU_INTEL,
FF_TEMP_GPU_AMD,
FF_TEMP_GPU_UNKNOWN,
FF_TEMP_GPU_M1X,
FF_TEMP_GPU_M2X,
FF_TEMP_GPU_M3X,
FF_TEMP_BATTERY,
+25 -1
View File
@@ -4,6 +4,8 @@
#include "common/properties.h"
#include "util/stringUtils.h"
#include <ctype.h>
#ifdef _WIN32
#include "util/mallocHelper.h"
@@ -162,6 +164,28 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
NULL
}) == NULL;
}
#else
static bool getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
{
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate();
ffStrbufAppendS(&command, "printf \"%s\" \"$");
ffStrbufAppendTransformS(&command, exeName, toupper);
ffStrbufAppendS(&command, "_VERSION\"");
if (ffProcessAppendStdOut(version, (char* const[]) {
"env",
"-i",
exe->chars,
"-c",
command.chars,
NULL
}) != NULL)
return false;
ffStrbufSubstrBeforeFirstC(version, '(');
ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" });
return true;
}
#endif
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
@@ -198,7 +222,7 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
return getFileVersion(exe->chars, version);
#else
return false;
return getShellVersionGeneric(exe, exeName, version);
#endif
}
@@ -5,7 +5,6 @@
#include "common/thread.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
@@ -68,8 +67,6 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex
static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
{
const char* error = NULL;
#ifdef __linux__
char statFilePath[64];
@@ -86,20 +83,18 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
!ffStrSet(name) ||
*ppid == 0
)
error = "sscanf(stat) failed";
return "sscanf(stat) failed";
#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
}
return "proc_pidinfo(pid) failed";
#else
*ppid = (pid_t)proc.pbsi_ppid;
strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars
#elif defined(__FreeBSD__)
struct kinfo_proc proc;
size_t size = sizeof(proc);
@@ -108,16 +103,18 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
&proc, &size,
NULL, 0
))
error = "sysctl(KERN_PROC_PID) failed";
else
{
*ppid = (pid_t)proc.ki_ppid;
strncpy(name, proc.ki_comm, COMMLEN);
}
return "sysctl(KERN_PROC_PID) failed";
*ppid = (pid_t)proc.ki_ppid;
strncpy(name, proc.ki_comm, COMMLEN);
#else
return "Unsupported platform";
#endif
return error;
return NULL;
}
static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
@@ -286,34 +283,8 @@ static void getUserShellFromEnv(FFTerminalShellResult* result)
}
}
static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
{
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate();
ffStrbufAppendS(&command, "printf \"%s\" \"$");
ffStrbufAppendTransformS(&command, exeName, toupper);
ffStrbufAppendS(&command, "_VERSION\"");
ffProcessAppendStdOut(version, (char* const[]) {
"env",
"-i",
exe->chars,
"-c",
command.chars,
NULL
});
ffStrbufSubstrBeforeFirstC(version, '(');
ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" });
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
{
ffStrbufClear(version);
if(!fftsGetShellVersion(exe, exeName, version))
getShellVersionGeneric(exe, exeName, version);
}
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
const FFTerminalShellResult* ffDetectTerminalShell()
@@ -350,7 +321,8 @@ const FFTerminalShellResult* ffDetectTerminalShell()
getTerminalFromEnv(&result);
getUserShellFromEnv(&result);
getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
ffStrbufClear(&result.shellVersion);
fftsGetShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
if(ffStrbufEqualS(&result.shellProcessName, "pwsh"))
ffStrbufInitStatic(&result.shellPrettyName, "PowerShell");
+11 -11
View File
@@ -18,22 +18,22 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result)
ffStrbufAppendS(result, "Connected");
break;
case wlan_interface_state_ad_hoc_network_formed:
ffStrbufAppendS(result, "First node in a ad hoc network");
ffStrbufAppendS(result, "Ad hoc network formed");
break;
case wlan_interface_state_disconnecting:
ffStrbufAppendS(result, "Disconnecting");
break;
case wlan_interface_state_disconnected:
ffStrbufAppendS(result, "Not connected");
ffStrbufAppendS(result, "Disconnected");
break;
case wlan_interface_state_associating:
ffStrbufAppendS(result, "Attempting to associate with a network");
ffStrbufAppendS(result, "Associating");
break;
case wlan_interface_state_discovering:
ffStrbufAppendS(result, "Auto configuration is discovering settings for the network");
ffStrbufAppendS(result, "Discovering");
break;
case wlan_interface_state_authenticating:
ffStrbufAppendS(result, "In process of authenticating");
ffStrbufAppendS(result, "Authenticating");
break;
default:
ffStrbufAppendS(result, "Unknown");
@@ -133,16 +133,16 @@ const char* ffDetectWifi(FFlist* result)
case dot11_phy_type_ht:
ffStrbufAppendS(&item->conn.protocol, "802.11n (Wi-Fi 4)");
break;
case 8 /*dot11_phy_type_vht*/:
case dot11_phy_type_vht:
ffStrbufAppendS(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
break;
case 9 /*dot11_phy_type_dmg*/:
case dot11_phy_type_dmg:
ffStrbufAppendS(&item->conn.protocol, "802.11ad (WiGig)");
break;
case 10 /*dot11_phy_type_he*/:
case dot11_phy_type_he:
ffStrbufAppendS(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
break;
case 11 /*dot11_phy_type_eht*/:
case dot11_phy_type_eht:
ffStrbufAppendS(&item->conn.protocol, "802.11be (Wi-Fi 7)");
break;
default:
@@ -179,10 +179,10 @@ const char* ffDetectWifi(FFlist* result)
case DOT11_AUTH_ALGO_RSNA_PSK:
ffStrbufAppendS(&item->conn.security, "WPA2-PSK");
break;
case 8 /* DOT11_AUTH_ALGO_WPA3 */:
case DOT11_AUTH_ALGO_WPA3:
ffStrbufAppendS(&item->conn.security, "WPA3");
break;
case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */:
case DOT11_AUTH_ALGO_WPA3_SAE:
ffStrbufAppendS(&item->conn.security, "WPA3-SAE");
break;
case 10 /* DOT11_AUTH_ALGO_OWE */:
+14 -14
View File
@@ -1,16 +1,16 @@
${c3} ,-^-___
${c3} /\\\\\\///
${c2}refined.${c1} /\\\\\\\\//
${c2}reliable.${c1} /\\\\\\///
${c2}ready.${c1} /\\\\/////\\
__///\\\\\\\\/////\\
${c3} _//////\\\\\\\\\\\\\\////
${c1} ///////${c3}\\\\\\\\\\\\\\\\\\\\//
//////${c1}\\\\\\\\\\/
/////\\\\\\\\\\/
/////${c3}\\\\\\\\/
/\\\\///\\\\\\/
/\\\\\\/${c1}\\\/
/\\\\\\\\//
${c3} /\\\///
${c2}refined.${c1} /\\\\//
${c2}reliable.${c1} /\\\///
${c2}ready.${c1} /\\/////\
__///\\\\/////\
${c3} _//////\\\\\\\////
${c1} ///////${c3}\\\\\\\\\\//
//////${c1}\\\\\/
/////\\\\\/
/////${c3}\\\\/
/\\///\\\/
/\\\/${c1}\\/
/\\\\//
//////
/// ${c3}\\\\\\\\\\
/// ${c3}\\\\\
+27
View File
@@ -0,0 +1,27 @@
.:-==++++++++++++++++++++++-.
.:=+##############################+
.=*###################################-
:+######################################:
:+######################################*-
.+#############*+--:::::::::::::::::::::.
:*##########*=:
-###########=
:##########+.
*#########=
=*********+ .::::::::::::::::.
**********. -*###################+:
:********** =#######################=
-*********+ +************************
:*********+ :***********************:
.********** .=******************+-
+*********-
.**********.
=**********:
+**********=.
=***********=:
-*************+-.
:+****************+++++++++++++++++++++==:
:+**************************************+.
-+************************************-
.-+*********************************.
:-==+*************************=.
+12 -3
View File
@@ -1348,6 +1348,15 @@ static const FFlogo E[] = {
.colorKeys = FF_COLOR_FG_WHITE,
.colorTitle = FF_COLOR_FG_WHITE,
},
// EshanizedOS
{
.names = {"EshanizedOS"},
.lines = FASTFETCH_DATATEXT_LOGO_ESHANIZEDOS,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
},
},
// EuroLinux
{
.names = {"EuroLinux"},
@@ -4279,10 +4288,10 @@ static const FFlogo X[] = {
FF_COLOR_FG_CYAN,
},
},
//XrayOS
//Xray_OS
{
.names = {"XrayOS"},
.lines = FASTFETCH_DATATEXT_LOGO_XRAYOS,
.names = {"Xray_OS"},
.lines = FASTFETCH_DATATEXT_LOGO_XRAY_OS,
.colors = {
FF_COLOR_FG_256 "15",
FF_COLOR_FG_256 "14",
+4 -1
View File
@@ -17,10 +17,13 @@ FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData)
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
return ffLogoPrintImageImpl(requestData, &(FFIMData) {
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
.resizeFunc = logoResize,
.library = imageMagick,
});
imageMagick = NULL; // leak imageMagick to prevent fastfetch from crashing #552
return result;
}
#endif
+4 -1
View File
@@ -21,10 +21,13 @@ FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData)
)
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
return ffLogoPrintImageImpl(requestData, &(FFIMData) {
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
.resizeFunc = logoResize,
.library = imageMagick,
});
imageMagick = NULL; // leak imageMagick to prevent fastfetch from crashing #552
return result;
}
#endif
+2 -45
View File
@@ -6,7 +6,7 @@
#include "util/stringUtils.h"
#define FF_DISKIO_DISPLAY_NAME "Disk IO"
#define FF_DISKIO_NUM_FORMAT_ARGS 11
#define FF_DISKIO_NUM_FORMAT_ARGS 8
static int sortDevices(const FFDiskIOResult* left, const FFDiskIOResult* right)
{
@@ -17,10 +17,7 @@ static void formatKey(const FFDiskIOOptions* options, FFDiskIOResult* dev, uint3
{
if(options->moduleArgs.key.length == 0)
{
if(!dev->name.length)
ffStrbufSetF(&dev->name, "unknown %u", (unsigned) index);
ffStrbufSetF(key, FF_DISKIO_DISPLAY_NAME " (%s)", dev->name.chars);
ffStrbufSetF(key, FF_DISKIO_DISPLAY_NAME " (%s)", dev->name.length ? dev->name.chars : dev->devPath.chars);
}
else
{
@@ -74,34 +71,15 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
ffParseSize(dev->bytesWritten, &buffer2);
ffStrbufAppendS(&buffer2, "/s");
const char* physicalType;
switch(dev->type)
{
case FF_DISKIO_PHYSICAL_TYPE_HDD:
physicalType = "HDD";
break;
case FF_DISKIO_PHYSICAL_TYPE_SSD:
physicalType = "SSD";
break;
default:
physicalType = "Unknown";
break;
}
FF_STRBUF_AUTO_DESTROY sizePretty = ffStrbufCreate();
ffParseSize(dev->size, &sizePretty);
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISKIO_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer2},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->interconnect},
{FF_FORMAT_ARG_TYPE_STRING, physicalType},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesRead},
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesWritten},
{FF_FORMAT_ARG_TYPE_UINT64, &dev->readCount},
{FF_FORMAT_ARG_TYPE_UINT64, &dev->writeCount},
{FF_FORMAT_ARG_TYPE_STRBUF, &sizePretty},
});
}
++index;
@@ -110,7 +88,6 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
{
ffStrbufDestroy(&dev->name);
ffStrbufDestroy(&dev->interconnect);
ffStrbufDestroy(&dev->devPath);
}
}
@@ -181,33 +158,16 @@ void ffGenerateDiskIOJsonResult(FFDiskIOOptions* options, yyjson_mut_doc* doc, y
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
yyjson_mut_obj_add_strbuf(doc, obj, "interconnectType", &dev->interconnect);
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
switch(dev->type)
{
case FF_DISKIO_PHYSICAL_TYPE_HDD:
yyjson_mut_obj_add_str(doc, obj, "physicalType", "HDD");
break;
case FF_DISKIO_PHYSICAL_TYPE_SSD:
yyjson_mut_obj_add_str(doc, obj, "physicalType", "SSD");
break;
default:
yyjson_mut_obj_add_null(doc, obj, "physicalType");
break;
}
yyjson_mut_obj_add_uint(doc, obj, "bytesRead", dev->bytesRead);
yyjson_mut_obj_add_uint(doc, obj, "bytesWritten", dev->bytesWritten);
yyjson_mut_obj_add_uint(doc, obj, "readCount", dev->readCount);
yyjson_mut_obj_add_uint(doc, obj, "writeCount", dev->writeCount);
yyjson_mut_obj_add_uint(doc, obj, "size", dev->size);
}
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
{
ffStrbufDestroy(&dev->name);
ffStrbufDestroy(&dev->interconnect);
ffStrbufDestroy(&dev->devPath);
}
}
@@ -218,14 +178,11 @@ void ffPrintDiskIOHelpFormat(void)
"Size of data read per second (formatted)",
"Size of data written per second (formatted)",
"Device name",
"Device interconnect type",
"Device physical type (SSD / HDD)",
"Device raw file path",
"Size of data read per second (in bytes)",
"Size of data written per second (in bytes)",
"Number of reads",
"Number of writes",
"Device size (formatted)",
});
}
+1
View File
@@ -37,6 +37,7 @@
#include "modules/opencl/opencl.h"
#include "modules/os/os.h"
#include "modules/packages/packages.h"
#include "modules/physicaldisk/physicaldisk.h"
#include "modules/player/player.h"
#include "modules/poweradapter/poweradapter.h"
#include "modules/processes/processes.h"
+1
View File
@@ -37,6 +37,7 @@
#include "modules/opencl/option.h"
#include "modules/os/option.h"
#include "modules/packages/option.h"
#include "modules/physicaldisk/option.h"
#include "modules/player/option.h"
#include "modules/poweradapter/option.h"
#include "modules/processes/option.h"
+13
View File
@@ -0,0 +1,13 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
typedef struct FFPhysicalDiskOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
FFstrbuf namePrefix;
} FFPhysicalDiskOptions;
+241
View File
@@ -0,0 +1,241 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "common/parsing.h"
#include "detection/physicaldisk/physicaldisk.h"
#include "modules/physicaldisk/physicaldisk.h"
#include "util/stringUtils.h"
#define FF_PHYSICALDISK_DISPLAY_NAME "Physical Disk"
#define FF_PHYSICALDISK_NUM_FORMAT_ARGS 7
static int sortDevices(const FFPhysicalDiskResult* left, const FFPhysicalDiskResult* right)
{
return ffStrbufComp(&left->name, &right->name);
}
static void formatKey(const FFPhysicalDiskOptions* options, FFPhysicalDiskResult* dev, uint32_t index, FFstrbuf* key)
{
if(options->moduleArgs.key.length == 0)
{
ffStrbufSetF(key, FF_PHYSICALDISK_DISPLAY_NAME " (%s)", dev->name.length ? dev->name.chars : dev->devPath.chars);
}
else
{
ffStrbufClear(key);
ffParseFormatString(key, &options->moduleArgs.key, 2, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT, &index},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
});
}
}
void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalDiskResult));
const char* error = ffDetectPhysicalDisk(&result, options);
if(error)
{
ffPrintError(FF_PHYSICALDISK_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error);
return;
}
ffListSort(&result, (const void*) sortDevices);
uint32_t index = 0;
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
{
formatKey(options, dev, result.length == 1 ? 0 : index + 1, &key);
ffStrbufClear(&buffer);
ffParseSize(dev->size, &buffer);
const char* physicalType = dev->type & FF_PHYSICALDISK_TYPE_HDD
? "HDD"
: dev->type & FF_PHYSICALDISK_TYPE_SSD
? "SSD"
: "";
const char* removableType = dev->type & FF_PHYSICALDISK_TYPE_REMOVABLE
? "Removable"
: dev->type & FF_PHYSICALDISK_TYPE_FIXED
? "Fixed"
: "";
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
if (physicalType[0] || removableType[0])
{
ffStrbufAppendS(&buffer, " [");
if (physicalType[0])
ffStrbufAppendS(&buffer, physicalType);
if (removableType[0])
{
if (physicalType[0])
ffStrbufAppendS(&buffer, ", ");
ffStrbufAppendS(&buffer, removableType);
}
ffStrbufAppendC(&buffer, ']');
}
ffStrbufPutTo(&buffer, stdout);
}
else
{
ffParseSize(dev->size, &buffer);
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_PHYSICALDISK_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->interconnect},
{FF_FORMAT_ARG_TYPE_STRING, physicalType},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->serial},
{FF_FORMAT_ARG_TYPE_STRING, removableType},
});
}
++index;
}
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
{
ffStrbufDestroy(&dev->name);
ffStrbufDestroy(&dev->interconnect);
ffStrbufDestroy(&dev->devPath);
ffStrbufDestroy(&dev->serial);
}
}
bool ffParsePhysicalDiskCommandOptions(FFPhysicalDiskOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_PHYSICALDISK_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
{
ffOptionParseString(key, value, &options->namePrefix);
return true;
}
return false;
}
void ffParsePhysicalDiskJsonObject(FFPhysicalDiskOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (ffStrEqualsIgnCase(key, "namePrefix"))
{
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
continue;
}
ffPrintError(FF_PHYSICALDISK_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
void ffGeneratePhysicalDiskJsonConfig(FFPhysicalDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyPhysicalDiskOptions))) FFPhysicalDiskOptions defaultOptions;
ffInitPhysicalDiskOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
if (!ffStrbufEqual(&options->namePrefix, &defaultOptions.namePrefix))
yyjson_mut_obj_add_strbuf(doc, module, "namePrefix", &options->namePrefix);
}
void ffGeneratePhysicalDiskJsonResult(FFPhysicalDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalDiskResult));
const char* error = ffDetectPhysicalDisk(&result, options);
if(error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
yyjson_mut_obj_add_strbuf(doc, obj, "interconnect", &dev->interconnect);
if (dev->type & FF_PHYSICALDISK_TYPE_HDD)
yyjson_mut_obj_add_str(doc, obj, "kind", "HDD");
else if (dev->type & FF_PHYSICALDISK_TYPE_SSD)
yyjson_mut_obj_add_str(doc, obj, "kind", "SSD");
else
yyjson_mut_obj_add_null(doc, obj, "kind");
yyjson_mut_obj_add_uint(doc, obj, "size", dev->size);
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &dev->serial);
if (dev->type & FF_PHYSICALDISK_TYPE_REMOVABLE)
yyjson_mut_obj_add_bool(doc, obj, "removable", true);
else if (dev->type & FF_PHYSICALDISK_TYPE_FIXED)
yyjson_mut_obj_add_bool(doc, obj, "removable", false);
else
yyjson_mut_obj_add_null(doc, obj, "removable");
}
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
{
ffStrbufDestroy(&dev->name);
ffStrbufDestroy(&dev->interconnect);
ffStrbufDestroy(&dev->devPath);
}
}
void ffPrintPhysicalDiskHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_PHYSICALDISK_MODULE_NAME, "{1}", FF_PHYSICALDISK_NUM_FORMAT_ARGS, (const char* []) {
"Device size (formatted)",
"Device name",
"Device interconnect type",
"Device raw file path",
"Serial number",
"Device kind (SSD or HDD)",
"Device kind (Removable or Fixed)",
});
}
void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_PHYSICALDISK_MODULE_NAME,
"Print physical disk information",
ffParsePhysicalDiskCommandOptions,
ffParsePhysicalDiskJsonObject,
ffPrintPhysicalDisk,
ffGeneratePhysicalDiskJsonResult,
ffPrintPhysicalDiskHelpFormat,
ffGeneratePhysicalDiskJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs);
ffStrbufInit(&options->namePrefix);
}
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
ffStrbufDestroy(&options->namePrefix);
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_PHYSICALDISK_MODULE_NAME "PhysicalDisk"
void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options);
void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options);
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options);
+41 -4
View File
@@ -30,7 +30,24 @@ const char* ffOptionsParseGeneralJsonConfig(FFOptionsGeneral* options, yyjson_va
else if (ffStrEqualsIgnCase(key, "osFile"))
ffStrbufSetS(&options->osFile, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "dsForceDrm"))
options->dsForceDrm = yyjson_get_bool(val);
{
if (yyjson_is_str(val))
{
int value;
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
{ "sysfs-only", FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY },
{ "false", FF_DS_FORCE_DRM_TYPE_FALSE },
{ "true", FF_DS_FORCE_DRM_TYPE_TRUE },
{},
});
if (error)
return "Invalid enum value of `dsForceDrm`";
else
options->dsForceDrm = (FFDsForceDrmType) value;
}
else
options->dsForceDrm = yyjson_get_bool(val) ? FF_DS_FORCE_DRM_TYPE_TRUE : FF_DS_FORCE_DRM_TYPE_FALSE;
}
#elif defined(_WIN32)
else if (ffStrEqualsIgnCase(key, "wmiTimeout"))
options->wmiTimeout = (int32_t) yyjson_get_int(val);
@@ -65,7 +82,14 @@ bool ffOptionsParseGeneralCommandLine(FFOptionsGeneral* options, const char* key
else if (ffStrEqualsIgnCase(key, "--os-file"))
ffOptionParseString(key, value, &options->osFile);
else if(ffStrEqualsIgnCase(key, "--ds-force-drm"))
options->dsForceDrm = ffOptionParseBoolean(value);
{
if (ffOptionParseBoolean(value))
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_TRUE;
else if (ffStrEqualsIgnCase(value, "sysfs-only"))
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY;
else
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE;
}
#elif defined(_WIN32)
else if (ffStrEqualsIgnCase(key, "--wmi-timeout"))
options->wmiTimeout = ffOptionParseInt32(key, value);
@@ -86,7 +110,7 @@ void ffOptionsInitGeneral(FFOptionsGeneral* options)
options->escapeBedrock = true;
ffStrbufInit(&options->playerName);
ffStrbufInit(&options->osFile);
options->dsForceDrm = false;
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE;
#elif defined(_WIN32)
options->wmiTimeout = 5000;
#endif
@@ -125,7 +149,20 @@ void ffOptionsGenerateGeneralJsonConfig(FFOptionsGeneral* options, yyjson_mut_do
yyjson_mut_obj_add_strbuf(doc, obj, "osFile", &options->osFile);
if (options->dsForceDrm != defaultOptions.dsForceDrm)
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", options->dsForceDrm);
{
switch (options->dsForceDrm)
{
case FF_DS_FORCE_DRM_TYPE_FALSE:
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", false);
break;
case FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY:
yyjson_mut_obj_add_str(doc, obj, "dsForceDrm", "sysfs-only");
break;
case FF_DS_FORCE_DRM_TYPE_TRUE:
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", true);
break;
}
}
#elif defined(_WIN32)
+8 -1
View File
@@ -2,6 +2,13 @@
#include "util/FFstrbuf.h"
typedef enum FFDsForceDrmType
{
FF_DS_FORCE_DRM_TYPE_FALSE = 0, // Disable
FF_DS_FORCE_DRM_TYPE_TRUE = 1, // Try `libdrm`, then `sysfs` if libdrm failed
FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY, // Use `/sys/class/drm` only
} FFDsForceDrmType;
typedef struct FFOptionsGeneral
{
bool multithreading;
@@ -12,7 +19,7 @@ typedef struct FFOptionsGeneral
FFstrbuf playerName;
FFstrbuf osFile;
bool escapeBedrock;
bool dsForceDrm;
FFDsForceDrmType dsForceDrm;
#elif defined(_WIN32)
int32_t wmiTimeout;
#endif
+2
View File
@@ -38,6 +38,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitOpenCLOptions(&options->openCL);
ffInitOpenGLOptions(&options->openGL);
ffInitPackagesOptions(&options->packages);
ffInitPhysicalDiskOptions(&options->physicalDisk);
ffInitPlayerOptions(&options->player);
ffInitPowerAdapterOptions(&options->powerAdapter);
ffInitProcessesOptions(&options->processes);
@@ -98,6 +99,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyOSOptions(&options->os);
ffDestroyOpenCLOptions(&options->openCL);
ffDestroyOpenGLOptions(&options->openGL);
ffDestroyPhysicalDiskOptions(&options->physicalDisk);
ffDestroyPackagesOptions(&options->packages);
ffDestroyPlayerOptions(&options->player);
ffDestroyPowerAdapterOptions(&options->powerAdapter);
+1
View File
@@ -39,6 +39,7 @@ typedef struct FFOptionsModules
FFOpenCLOptions openCL;
FFOpenGLOptions openGL;
FFPackagesOptions packages;
FFPhysicalDiskOptions physicalDisk;
FFPlayerOptions player;
FFPowerAdapterOptions powerAdapter;
FFProcessesOptions processes;
+5 -3
View File
@@ -59,9 +59,9 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
uint32_t oldFree = ffStrbufGetFree(strbuf);
if (oldFree >= free && !(strbuf->allocated == 0 && strbuf->length > 0))
return;
uint32_t newCap = strbuf->allocated + (free - oldFree);
if(strbuf->allocated == 0)
{
newCap += strbuf->length + 1; // +1 for the NUL
@@ -74,7 +74,7 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
}
else
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
strbuf->allocated = newCap;
}
@@ -99,6 +99,8 @@ void ffStrbufAppendC(FFstrbuf* strbuf, char c)
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c)
{
if (num == 0) return;
ffStrbufEnsureFree(strbuf, num);
memset(&strbuf->chars[strbuf->length], c, num);
strbuf->length += num;
+1 -1
View File
@@ -20,7 +20,7 @@ static void getExePath(FFPlatform* platform)
FFstrbuf* const exePath = &platform->exePath;
ffStrbufEnsureFree(exePath, PATH_MAX);
#ifdef __linux__
ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated);
ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated - 1);
#elif defined(__APPLE__)
int exePathLen = proc_pidpath((int) getpid(), exePath->chars, exePath->allocated);
#elif defined(__FreeBSD__)
+2
View File
@@ -18,6 +18,8 @@ bool ffIsSmbiosValueSet(FFstrbuf* value)
!ffStrbufIgnCaseEqualS(value, "Undefined") &&
!ffStrbufIgnCaseEqualS(value, "Not Specified") &&
!ffStrbufIgnCaseEqualS(value, "Not Applicable") &&
!ffStrbufIgnCaseEqualS(value, "Not Defined") &&
!ffStrbufIgnCaseEqualS(value, "Not Available") &&
!ffStrbufIgnCaseEqualS(value, "INVALID") &&
!ffStrbufIgnCaseEqualS(value, "Type1ProductConfigId") &&
!ffStrbufIgnCaseEqualS(value, "All Series") &&