Compare commits

..

432 Commits

Author SHA1 Message Date
Carter Li 4a1037d2b6 Merge pull request #1509 from fastfetch-cli/dev
Release: v2.34.1
2025-01-13 15:57:52 +08:00
Carter Li dbcd5b922a Sound: fix a memleak 2025-01-13 15:39:16 +08:00
Carter Li 8982b860f9 Chore: fix spelling 2025-01-13 15:15:28 +08:00
Carter Li 373b4353bb CPU (BSD): improve base freq detection 2025-01-13 15:06:18 +08:00
Carter Li ace336dfa9 Release: v2.34.1 2025-01-13 14:55:53 +08:00
CELESTIFYX Team 4060626382 fix(logo): Rename *_LOGO_SMARTOS to *_LOGO_SNIGDHAOS (#1502) 2025-01-13 13:48:02 +08:00
李通洲 9f9e3dd931 Logo (Builtin): add Oreon 2025-01-13 13:42:20 +08:00
李通洲 3ed5a250a4 Logo (Builtin): add HeliumOS 2025-01-13 13:39:07 +08:00
carterli fc969b01c7 Memory (NetBSD): change formula to be consistant with other systems 2025-01-13 10:47:25 +08:00
carterli 41e22ea866 Memory (OpenBSD): update formula to be consistant with other systems 2025-01-13 10:47:25 +08:00
李通洲 0b4a6055c6 Logo (Builtin): add netbsd_small 2025-01-13 10:41:11 +08:00
Carter Li b340d4e149 CI: fix build 2025-01-12 12:10:10 +08:00
Carter Li 878e516880 DisplayServer (Linux): upgrade wayland protocol kde-output-device-v2
Ref: #1504
2025-01-12 11:23:42 +08:00
Carter Li 4e3673a2bb DisplayServer (Linux): check HDR support with xx_color_manager_v4_interface (WIP) 2025-01-11 13:10:07 +08:00
李通洲 10c8c1b4bf Media (Linux): use file name as media name if song title is not available 2025-01-10 22:17:36 +08:00
李通洲 17e3853f38 CPU (FreeBSD): bind process to the first 2 cores 2025-01-10 21:14:51 +08:00
李通洲 1bc41dfa54 chore: remove unnecessary NULL checks
Fix #1494
2025-01-10 14:01:48 +08:00
李通洲 8c227ae4b8 TerminalFont (macOS): fix Ghostty termfont detection
`~/Library/Application Support/com.mitchellh.ghostty/config` is generated as an empty file if the settings dialog is opened

Fix #1495
2025-01-10 09:41:19 +08:00
李通洲 c5c2589f4d GPU: set GPU vendor string when using OpenGL backend 2025-01-10 08:48:29 +08:00
Carter Li b273693842 Packaging: update debian stuff [ci skip] 2025-01-09 09:06:41 +08:00
Carter Li 52de8df1f9 Merge pull request #1492 from fastfetch-cli/dev
Release: v2.34.0
2025-01-09 09:02:12 +08:00
李通洲 be99c4ca6e Media (Linux): remove unused variables 2025-01-09 08:50:56 +08:00
李通洲 8133c3365f Doc: update JSON schema [ci skip] 2025-01-08 22:29:49 +08:00
李通洲 6226ccc70e Processing (Windows): fix get current process 2025-01-08 20:37:35 +08:00
李通洲 88917cb14f OpenGL (EGL): try GLES 2.0+; then fallback to 1.1 if failed 2025-01-08 20:13:01 +08:00
Carter Li a93e2aafdb Release: v2.34.0 2025-01-08 16:26:06 +08:00
李通洲 5848b5fc24 OpenGL (Android): enable support 2025-01-08 16:09:41 +08:00
李通洲 934b6291e3 OpenGL (Android): request GLES 2+ 2025-01-08 15:38:55 +08:00
李通洲 90068ab474 Battery (NetBSD): fix battery percentage detection 2025-01-08 13:46:08 +08:00
Carter Li 5567e6cc5e Packages (Linux): rename am-user to appman 2025-01-08 10:56:55 +08:00
Carter Li 8b3017c0d9 Packages (Linux): remove possible final newlines in am config 2025-01-08 10:28:13 +08:00
Carter Li f9f15ba844 General: don't suppress the output of preRun
Fix #1489
2025-01-08 09:46:41 +08:00
Carter Li b282ac5d47 Packages (Linux): support am-user
Fix #771
2025-01-08 09:46:12 +08:00
Carter Li 6577884417 WMDE: detect Sway by env variables 2025-01-08 08:50:53 +08:00
李通洲 c4ee606955 CPU (Android): check for MTK D9X00 SOCs 2025-01-08 08:39:09 +08:00
Bahar KURT 59c80820f2 feat: Add Rhino Linux ASCII (#1487)
Cramp all additions into one commit because I like to do it that
way. xD

Co-authored-by: Bahar KURT <kurtbahartr@users.noreply.github.com>
2025-01-07 21:30:22 +08:00
李通洲 c11e14f7e1 CMake (Android): set rpath for system Android libs
So that Vulkan & OpenCL can find them
2025-01-07 15:38:47 +08:00
Carter Li ab6a770155 Sound: detect platform API
Ref: #1454
2025-01-07 15:38:38 +08:00
李通洲 0e99486efe Processing (Windows): early return if OpenProcess failed 2025-01-07 08:35:57 +08:00
Eshan Roy f82f3002e4 Logo (Builtin): add snigdhaos ascii (#1485)
* feat: add snigdhaos ascii

* feat: insert builtin data
2025-01-06 23:49:48 +08:00
Angel Gustavo Lopez 0bed182784 fixing fastfetch wrong colors for xray_os logo (#1486) 2025-01-06 19:54:38 +08:00
Carter Li d39be955b1 Doc: update changelog [ci skip] 2025-01-06 14:39:29 +08:00
CaKrome 3b2790cccc CI (Linux): add Linux ppc64le platform (#1484) 2025-01-06 13:55:13 +08:00
Carter Li 3ea0406b69 CPU (Linux): fix var content was unexpectedly modified 2025-01-06 10:57:29 +08:00
李通洲 6429c20466 OS: prefer pretty names
Hopefully we can end the controversy.

Fix #1483 #1038
2025-01-06 08:58:14 +08:00
李通洲 88ebeb21e2 CPU: fix core count output in multi-package platforms
Fix #1413
2025-01-05 19:38:16 +08:00
Carter Li f28f5e2874 CPU (Linux): detect TZ temp if CPU temp is not available 2025-01-05 17:28:01 +08:00
Carter Li 637c37e81c Packages (macOS): remove redundant tokens 2025-01-05 17:28:01 +08:00
Simon Quigley b2c779dea9 Logo (Builtin): add the Lubuntu logo (#1481)
* Add the Lubuntu logo

* Lubuntu uses LXQt, not LXDE
2025-01-05 11:08:27 +08:00
李通洲 89d636447b Doc: update README [ci skip] 2025-01-03 13:56:48 +08:00
Carter Li 3dc51d5f88 FFstrbuf: improve performance of copying static strings 2025-01-03 10:59:01 +08:00
Carter Li 60ff89c794 Terminal (Linux): fix detection of pk-command-not-found
Fix #1467
2025-01-03 10:32:16 +08:00
Carter Li f973572c5a TerminalShell (Linux): relax detection of terminals in NixOS
Fix #1479
2025-01-03 10:18:44 +08:00
Carter Li ea78665971 Doc: update README.md 2025-01-03 10:16:38 +08:00
Carter Li 80b48dd2d1 Logo (Image): mark ghostty supports kitty image protocol 2025-01-03 09:55:38 +08:00
Carter Li df6eed7a02 TerminalSize (Linux): enable fast path when stdout is redirected. 2025-01-03 09:50:59 +08:00
李通洲 c9ac09f9eb WM (Linux): detect WM version 2025-01-02 20:19:15 +08:00
Carter Li 67597e4566 WM (Linux): add sway version detection 2025-01-02 16:36:31 +08:00
李通洲 611de77980 Terminal (macOS): improve performance of kitty version 2025-01-02 16:35:53 +08:00
李通洲 0fde835629 WM (Windows): detect version of DWM 2025-01-02 16:35:53 +08:00
李通洲 f373e07847 WM (Linux): don't crash if no wm is detected 2025-01-02 16:35:53 +08:00
李通洲 89e4403cc8 WM (macOS): add WindowServer version detection 2025-01-02 16:35:53 +08:00
李通洲 c68d21e215 WM: report version field in custom and JSON output 2025-01-02 16:35:53 +08:00
Christopher Kaster f14cd2c6e8 WM: Add support for detecting window manager versions, add support for Hyprland version (#1472) 2025-01-02 10:13:28 +08:00
Carter Li d58d786c83 Logo (Image): add --kitty-icat; honor --logo-height if set 2024-12-31 15:43:01 +08:00
Carter Li 9f37557177 Logo (Image): support generate image data via kitten icat 2024-12-31 15:30:26 +08:00
李通洲 aa63c4f5f2 Revert "GPU: support detection by EGLext"
Works only for NVIDIA GPUs

This reverts commits 9ef8580d93 and 9342d74c93.
2024-12-31 13:57:06 +08:00
李通洲 a378d2ad62 Brightness (FreeBSD): fix backlight name detection 2024-12-30 11:12:06 +08:00
Carter Li 2ab2dd4d48 TerminalFont (macOS): fix ghostty font detection; default to JetBrains Mono
Ref: https://github.com/fastfetch-cli/fastfetch/issues/1466#issuecomment-2564379883
2024-12-30 10:43:28 +08:00
Peter Zmanovsky 2a83b86ba4 Platform (Linux): fix exe path detection (#1468)
On error, -1 is returned from readlink()
2024-12-29 09:53:20 +08:00
李通洲 d967d05019 Bluetooth (DragonFly): disable module to fix build 2024-12-28 22:13:49 +08:00
李通洲 9ef8580d93 GPU (EGLext): fix build on old systems 2024-12-28 21:50:08 +08:00
Carter Li 813b80c5a8 TerminalFont: support Ghostty
Fix #1466
2024-12-28 15:34:41 +08:00
Carter Li ddce9b2357 GPU: rename ffGetGPUVendorString to ffGPUGetVendorString 2024-12-28 15:26:17 +08:00
Carter Li 9342d74c93 GPU: support detection by EGLext
Support multi-gpus
2024-12-28 15:25:22 +08:00
Carter Li d6028370e7 Bluetooth (FreeBSD): add support (not tested) 2024-12-27 14:49:15 +08:00
李通洲 e425d7df63 CI: update *BSD versions 2024-12-27 14:11:53 +08:00
李通洲 a4a2ae7d67 Host (macOS): fix thunderbolt version of new MBPs
Fix #1465
2024-12-27 14:07:17 +08:00
Carter Li 99aa0638cc Packaging: update debian stuff [ci skip] 2024-12-26 09:47:44 +08:00
Carter Li 1a9e637134 Merge pull request #1464 from fastfetch-cli/dev
Release: v2.33.0
2024-12-26 09:37:25 +08:00
李通洲 f322405c04 Release: v2.33.0 2024-12-26 09:08:33 +08:00
Carter Li e4202635af Doc: update changelog [ci skip] 2024-12-25 10:47:36 +08:00
Carter Li 2f13ee3814 Media (Linux): set player name manually for musikcube 2024-12-25 10:47:36 +08:00
Carter Li 2bfde87f84 Logo (Builtin): add GoralixOS
Fix #1462
2024-12-25 10:47:36 +08:00
Carter Li f38a51c9bc Media: make it able to print player info in custom format 2024-12-25 09:04:10 +08:00
Carter Li 28ec935c42 Media (Linux): report player name 2024-12-25 08:50:28 +08:00
李通洲 d939f95c69 Vulkan (Android): hard code path of libvulkan.so, so that users don't need to install vulkan-loader wrapper of termux 2024-12-24 21:20:03 +08:00
李通洲 e0fd5111fe Media (Linux): Fix #1461 (WIP) 2024-12-24 19:38:43 +08:00
李通洲 4736031538 Doc: update changelog [ci skip] 2024-12-22 22:19:02 +08:00
李通洲 66085c087e Logo (Builtin): add NurOS
Fix #1456
2024-12-22 21:48:18 +08:00
李通洲 e0253d71c0 Doc: add comments for running fastfetch in root 2024-12-22 20:45:51 +08:00
李通洲 dadd4bfab6 DiskIO (OpenBSD): remove debug output 2024-12-22 20:43:36 +08:00
李通洲 2f3861e732 PhysicalMemory: clean up garbage data 2024-12-22 20:27:27 +08:00
李通洲 851f271ed5 CPU (NetBSD): fix typo 2024-12-22 14:20:32 +08:00
Carter Li d3e40f625b Battery (OpenBSD): fix build 2024-12-22 09:30:42 +08:00
Carter Li 7c1991c2e3 Battery (NetBSD): add support 2024-12-21 23:54:30 +08:00
李通洲 b8048ee488 Bluetooth (BSD): disable
bluez is Linux specific
2024-12-21 23:54:30 +08:00
李通洲 b99f54b9f4 CPU (NetBSD): trim CPU vendor 2024-12-21 23:54:30 +08:00
Carter Li b38d7a4919 Brightness (NetBSD): don't error out if the screen idx isn't 0 2024-12-21 23:54:30 +08:00
李通洲 45f7e2c0b2 Version (NetBSD): report sysname 2024-12-21 23:54:30 +08:00
李通洲 5a8dda27ff CPU (NetBSD): support temp and frequency detection 2024-12-21 23:54:30 +08:00
李通洲 1ea3264b13 SMBIOS (NetBSD): add more data 2024-12-21 23:54:30 +08:00
Carter Li 852a729581 Battary (NetBSD): some basic investigation of acpi battery detection 2024-12-21 23:54:30 +08:00
Carter Li 0f454b7140 Battery (OpenBSD): add support 2024-12-21 23:54:30 +08:00
Carter Li 9c47a3a9e7 Brightness (OpenBSD): add support
Requires root permission. Not tested
2024-12-21 23:54:30 +08:00
李通洲 4adf7fda28 Brightness (NetBSD): add support for builtin display 2024-12-21 23:54:30 +08:00
李通洲 e2fc83fd48 Bluetooth (Windows): silence compiler warnings 2024-12-21 23:54:30 +08:00
Robin Candau dd41dfa000 CMake: Add a cmake option to make flashfetch target optional (#1455)
Introduces the `-DBUILD_FLASHFETCH='ON'/'OFF'` build option so one can skip the `flashfetch` target (both from executable and install targets, option at `ON` by default to preserve compatibility with the current default behavior).
This is useful when distributing pre-built downstream packages (e.g. for Linux distributions packaging `fastfetch`) as building and shipping the `flashfetch` binary in such pre-built packages serves little to no purpose.
2024-12-21 23:53:02 +08:00
Carter Li 14d6157901 PhysicalDisk (Linux): fix interconnect type detection
Regression of b5a9d64

Fix #1453
2024-12-20 16:38:30 +08:00
Carter Li 74586a9df1 Bluetooth (Linux): improve performance
1. ignore unpaired devices
2. ignore disconnected devices when `showDisconnected == false`
2024-12-20 15:57:17 +08:00
Carter Li c5d4b20729 TerminalShell (Android): ignore proot 2024-12-20 15:57:17 +08:00
李通洲 b152b383a2 Bluetooth (Windows): optimise
1. don't report disconnected devices if `showDisconnected == false`
2. don't report unknown devices
3. don't report errors when no devices found
2024-12-20 15:57:17 +08:00
李通洲 ae26692ef6 Bluetooth (macOS): don't report disconnected devices if showDisconnected == false 2024-12-20 15:57:17 +08:00
Carter Li 4f807f26a9 Bluetooth (Linux): improve performance when showDisconnected == false
If no connected devices found, no dbus calls will be emitted

Fix #1450
2024-12-20 15:57:02 +08:00
Carter Li 4bef801337 BluetoothRadio (Linux): improve performance by reducing size of dbus response 2024-12-20 15:56:48 +08:00
李通洲 41240e9460 FFlist: fix return value of ffListPop 2024-12-20 11:12:14 +08:00
JohnTheCoolingFan 3bb82423b3 OS (Linux): Refactor Armbian version detection and add support for ubuntu-based armbian detection (#1447)
* Add support for detection of Armbian as Ubuntu flavor

Ubuntu can be used to build Armbian, it is one of the official bases for
Armbian. This allows the detection of Armbian in case it is based on
Ubuntu.

* Refactor Armbian detection

* Armbian: set idLike to id before setting id to "armbian"

* Tidy up detectArmbianVersion
2024-12-19 16:18:42 +08:00
李通洲 b87df82d58 Shell (Windows): use $POWERSHELL_VERSION if available 2024-12-19 11:00:16 +08:00
Carter Li c145ce49a5 Merge pull request #1446 from fastfetch-cli/dev
Release: v2.32.1
2024-12-18 14:41:21 +08:00
李通洲 8c4fb5d6d4 Release: v2.32.1 2024-12-18 14:25:44 +08:00
李通洲 eae0fee032 Packages (OpenBSD): fix a typo that prevents package counting from working 2024-12-18 14:24:13 +08:00
Carter Li 4472a13f41 Packaging: update debian stuff 2024-12-18 14:22:56 +08:00
Carter Li 5b001d6bd6 Merge pull request #1445 from fastfetch-cli/dev
Release: v2.32.0
2024-12-18 10:38:44 +08:00
Carter Li 1b52029fce Release: v2.32.0 2024-12-18 09:58:46 +08:00
Carter Li 2176ea2937 Revert "Display (Linux): prefer detecting physical size from EDID"
Try fixing #1444

This reverts commit 5f3ce50022.
2024-12-18 09:28:42 +08:00
李通洲 ac2266c72f Wifi (FreeBSD): early break if the interface is not associated 2024-12-17 20:55:33 +08:00
Eva 0dc40a2632 WM (Linux): added ratpoison window manager (#1442) 2024-12-17 10:49:55 +08:00
李通洲 ca975f8e81 Version: fix format parameter name
Fix #1443
2024-12-17 10:24:18 +08:00
Kevin c4c6fe6668 Logo (Builtin): improved debian ascii logo (#1441) 2024-12-16 12:05:18 +08:00
Carter Li 0a00f5721e OpenGL (NetBSD): try fixing build 2024-12-14 22:22:35 +08:00
李通洲 69f180beea Display (FreeBSD): don't try to use /sys on FreeBSD 2024-12-14 22:22:35 +08:00
李通洲 0e9cdf75b5 WM (FreeBSD): improve WM detection for Wayland 2024-12-14 22:22:35 +08:00
Carter Li 7d7e219c0a OpenGL (NetBSD): fix build 2024-12-14 13:34:42 +08:00
Carter Li 4937ccfa81 OpenGL (EGL): prefer surfaceless display 2024-12-14 12:56:40 +08:00
JohnTheCoolingFan d0d29c163b Add Armbian-unofficial detection (#1436) 2024-12-14 12:56:13 +08:00
Carter Li 901e0eb177 Logo (Builtin): add Ultramarine Small
Fix #1438
2024-12-14 12:00:33 +08:00
Carter Li 87446e6eef WM (OpenBSD): fix process enumeration 2024-12-14 00:18:41 +08:00
Carter Li bfaa73a2c7 Display (Linux): clean up 2024-12-14 00:05:28 +08:00
Carter Li 373e288d03 WM: add support for fvwm (OpenBSD) and ctwm (NetBSD) 2024-12-14 00:05:02 +08:00
李通洲 82170ceab0 Scripts: fix typo 2024-12-13 16:05:37 +08:00
Carter Li 009a7888b5 OpenGL (Linux): suppress IO
Fix #1435
2024-12-13 15:40:36 +08:00
Carter Li ab1a11c9fa CPU (ARM): add more apple cores 2024-12-13 15:29:24 +08:00
Carter Li 68746275f8 CPU (Linux): detect Virtualized Apple Silicon 2024-12-13 15:28:59 +08:00
李通洲 491cfb94b6 Doc: update changelog [ci skip] 2024-12-12 16:01:56 +08:00
李通洲 79c8919431 Logo (Builtin): add Serpent OS
Ref: https://github.com/serpent-os/recipes/blob/main/f/fastfetch/pkg/0001-logo-Port-our-neofetch-Serpent-OS-logo-from-ermo.patch
2024-12-12 15:43:43 +08:00
李通洲 e98afa8315 JsonSchema: fix typo 2024-12-11 16:41:48 +08:00
李通洲 86783c033b OS (Linux): detect Linux Lite
Fix #1434
2024-12-11 16:40:02 +08:00
李通洲 f01944de41 JsonSchema: add documentation of format args 2024-12-11 16:12:55 +08:00
李通洲 ebfdeef25c Fastfetch: add -h format-json 2024-12-11 16:12:03 +08:00
李通洲 9a36d63d18 Global: refactor code of -h <module>-format 2024-12-11 10:47:02 +08:00
李通洲 e45ff546ed Host: silence compiler warnings 2024-12-10 09:35:52 +08:00
李通洲 2700390371 Host (Sun): fix build 2024-12-09 23:07:24 +08:00
Carter Li 5c01685d69 Host: detect mac model in FreeBSD & Windows 2024-12-09 21:44:31 +08:00
Carter Li d897472572 Edid: use screen size in DTD if make sense 2024-12-06 19:20:06 +08:00
Carter Li 8410a66277 Host (Linux): report mac product name 2024-12-06 18:31:33 +08:00
Carter Li 856d229b36 Wifi (Linux): fix bssid formatting 2024-12-06 09:14:30 +08:00
李通洲 b33692aa7d Logo: randomly select one if the logo source expands to multiple files
Fix #1426
2024-12-05 14:16:30 +08:00
李通洲 e90c5cb241 GPU (OpenBSD): fix pci.ids file location 2024-12-05 08:37:41 +08:00
Carter Li 03cd283755 Packaging: update debian stuff [ci skip] 2024-12-04 08:43:33 +08:00
Carter Li 58a1d965cb Merge pull request #1425 from fastfetch-cli/dev
Release: v2.31.0
2024-12-03 15:00:54 +08:00
Carter Li 6edf763f2b Display (Linux): detect bit depth when libdrm is used 2024-12-03 10:55:00 +08:00
Carter Li ab200d7e4a Terminal: Support sakura version & font detection
Fix #1424
2024-12-02 19:10:47 +08:00
Carter Li dfe36daf79 Release: v2.31.0 2024-12-02 16:36:12 +08:00
李通洲 e9ab67b380 Processing (Linux): interrupt poll & read syscalls when the child process is exited
Fix #1418
2024-12-02 16:02:04 +08:00
Carter Li f073f4882c Wifi (Linux): detect Wifi-7 2024-12-01 18:16:05 +08:00
李通洲 692ad502df Wifi (Windows): make unit of bitrates be consistant
Also fix a copy & paste bug
2024-11-30 23:50:06 +08:00
Raymond Kemboi 3004ce8565 Completion (Zsh): fix syntax error in completion file (#1421)
A syntax error in the file caused the following output when trying to trigger completions in `zsh` (pressing <TAB>):

```zsh
$ fastfetch    File "<stdin>", line 15
    command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
                                               ^^^^
SyntaxError: f-string: unmatched '['
```
This fix replaces single quotes with double quotes in the f-strings in lines 37 and 41.
2024-11-29 10:25:58 +08:00
Ryan ee8801b54d WM (Linux): fix wl-restart parsing (#1422)
Make the WM name in `wl-restart -n 5 Hyprland` parse as "Hyprland"
instead of "-n".
2024-11-29 08:34:40 +08:00
李通洲 bbe239647b Logo (Builtin): add Windows Server 2025
Fix #1420
2024-11-28 21:55:21 +08:00
Carter Li 77c06193d6 GPU (Linux): detect GPU NV type 2024-11-28 21:28:35 +08:00
李通洲 90bbefe11a CPU (Windows): code cleanup 2024-11-26 22:02:57 +08:00
Carter Li 69a7e64e48 CPU (Linux): support up to 128-socket boards 2024-11-26 21:49:28 +08:00
Carter Li ee564de461 CPU: change cpuCount to packages; support custom format
Fix #1413
2024-11-26 21:37:15 +08:00
Carter Li 9955e9da02 CPU: remove duplicate whitespaces in CPU name
Eg. `Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz`
2024-11-26 21:27:36 +08:00
Carter Li 8b41cbd508 CPU (Linux): refactor; fix cpu count detection 2024-11-26 16:05:01 +08:00
AzimovParviz 7535ce8a18 Support for dual CPU systems (#1417)
* [macOS] Added support for dual CPUs on Mac computers

Signed-off-by: Koneko <azimovp17@gmail.com>

* Change how number of cores is displayed when the system is dual CPU

* Support for dual CPU on Windows

* Dual CPU detection on Linux basic implementation

---------

Signed-off-by: Koneko <azimovp17@gmail.com>
2024-11-26 08:53:01 +08:00
李通洲 b76eb87510 CI: fix building on macOS 2024-11-25 22:46:57 +08:00
李通洲 0cd7aeac19 Display (macOS): don't crash with NULL pointer references
Fix #1393
2024-11-25 22:23:24 +08:00
Carter Li 04088b5b2c Logo (Builtin): update MidOS
Fix #1409
2024-11-25 14:31:07 +08:00
Carter Li e77c3119ca OS (Linux): check for lmde
Fix #1415
2024-11-25 14:20:52 +08:00
Carlos Henrique Lima Melara 3463fc331f Scripts: use datetime to get date and set timezone to UTC (#1410)
This will ensure the package is reproducible even in different
timezones.
2024-11-24 10:22:57 +08:00
李通洲 64287eed21 Display: change physical size detection to use basic display parameters
Some monitor report invalid data in DTD.
Ref: #1406
2024-11-24 01:02:06 +08:00
李通洲 1b835544b6 Users: fix invalid var name
Fix #1408
2024-11-23 22:44:45 +08:00
Carter Li 55352be0cc Wifi (FreeBSD): support channel & frequency detection 2024-11-23 12:21:48 +08:00
Carter Li c0be2637a8 Wifi (Android): silence compiler warnings 2024-11-22 15:37:01 +08:00
Carter Li 864fb918bc Chore: silence some warnings 2024-11-22 14:20:50 +08:00
Carter Li 2197cfb06d Wifi (Android): report more props 2024-11-22 13:53:04 +08:00
Carter Li 94f8ff938b Wifi: print channel band 2024-11-22 11:01:54 +08:00
Carter Li 7000317841 Wifi (Linux): detect frequency & channel number 2024-11-22 10:31:12 +08:00
李通洲 06055cc6c3 Wifi (macOS): fix build on old OS version 2024-11-21 22:03:25 +08:00
李通洲 601b9706b5 Display: report ppi to 0 if screen size is not available 2024-11-21 21:44:05 +08:00
李通洲 d48c76b597 Wifi: detect channel and frequency 2024-11-21 21:37:30 +08:00
李通洲 9a1d18556d Display: don't report screen size when display is mirrored
Fix #1406
2024-11-21 15:29:14 +08:00
李通洲 71b073e1bf CMake: fix possible linking errors in BINARY_LINK_TYPE=dynamic mode 2024-11-20 22:13:10 +08:00
Carter Li a567268ca1 Display (Linux): fix preferred resolution detection for wayland 2024-11-20 21:38:18 +08:00
李通洲 8b62ad72f7 Display (FreeBSD): fix build 2024-11-20 16:39:01 +08:00
李通洲 cee880cb83 Display: print preferred resolution & refresh rate in custom format
Fix #1406
2024-11-20 16:39:01 +08:00
李通洲 925c3471c2 Display: add scale factor in custom format 2024-11-20 16:39:01 +08:00
李通洲 7948e627b0 Display (Android): fix build 2024-11-20 16:39:01 +08:00
李通洲 4cca63a299 Display (Windows): detect preferred resolution & refresh rate 2024-11-20 16:39:01 +08:00
李通洲 21a35769a7 Display (macOS): detect maximum resolution & refresh rate 2024-11-20 16:39:01 +08:00
Carter Li fa9290088d Display (Linux): detect preferred resolution and refresh rate 2024-11-20 16:38:53 +08:00
Carter Li 3d5133eaba DisplayServer (Linux): remove support of xcb & xlib
They don't support multi-monitors. Prefer libdrm.
2024-11-20 09:37:32 +08:00
Carter Li 4cbcd0f107 Wifi (Linux): improve performance 2024-11-20 08:43:41 +08:00
Carter Li fdc9bee4b3 DBus: use general.processingTimeout as its timeout instead hard coding 2024-11-20 08:43:41 +08:00
Carter Li 16b7a4a1be Media (Linux): improve performance of dbus communication 2024-11-20 08:43:41 +08:00
R0CKSTAR 465170428f mtgpu: header file cleanup for forward compatibility (#1405)
Signed-off-by: Xiaodong Ye <yeahdongcn@gmail.com>
2024-11-19 19:36:12 +08:00
Carter Li e953ed9d88 Packaging: update debian stuff [ci skip] 2024-11-18 15:47:48 +08:00
Carter Li 6d45fe61b5 Merge pull request #1404 from fastfetch-cli/dev
Release: v2.30.1
2024-11-18 14:57:05 +08:00
李通洲 efc8504607 CMake: check return code of python scripts 2024-11-18 14:08:53 +08:00
李通洲 a9a08d8a80 Release: v2.30.1 2024-11-18 13:40:08 +08:00
李通洲 7f63ec1315 CMake: fix the destination where fastfetch_pciids.c.inc is generated 2024-11-18 13:36:31 +08:00
Masato TOYOSHIMA 6cbbe334b5 CMake: Fixed the destination where fastfetch.1 is generated. (#1403)
* Fixed the destination where fastfetch.1 is generated.

* Update CMakeLists.txt

Reappend trailing new line

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-11-18 13:32:49 +08:00
Carter Li 4bde8d3fb3 Packaging: update debian stuff [ci skip] 2024-11-18 09:36:46 +08:00
Carter Li 62dcd1257e Merge pull request #1401 from fastfetch-cli/dev
Release: v2.30.0
2024-11-18 09:21:24 +08:00
Carter Li dbb6a4b265 Release: v2.30.0 2024-11-18 09:04:17 +08:00
Carter Li a73a3089af Doc: remove guix package installer as it's outdated [ci skip] 2024-11-18 08:40:45 +08:00
李通洲 dcdf2b570e Display: concat flags 2024-11-15 20:01:56 +08:00
李通洲 ba7d3ed27b GPU (Windows): fix a bad assignment 2024-11-15 19:47:24 +08:00
Carter Li b7a9fe58b4 Terminal (Linux): support tilix version detection 2024-11-15 16:18:43 +08:00
李通洲 e5451b6826 NetIO (BSD): remove unnecessary checks
Seems...
2024-11-15 15:13:09 +08:00
李通洲 9f314a208b NetIO (BSD): add txDrops detection if supported 2024-11-15 15:13:09 +08:00
李通洲 56eb8b80c6 NetIO (macOS): fix 32bit trancation 2024-11-15 15:11:55 +08:00
Dariqq 563ed58b4f Scripts: gen-man.py honors SOURCE_DATE_EPOCH. (#1400) 2024-11-15 08:50:47 +08:00
李通洲 b8ec07092a Logo (Builtin): update openSUSE Tumbleweed
Fix #1398
2024-11-15 08:41:14 +08:00
李通洲 e77a4e8262 Doc: update changelog [ci skip] 2024-11-14 16:40:45 +08:00
李通洲 782af250ff Percent: in custom format, only set num and bar string if enabled in percent config
Also fix `percentage-bar` printing in Brightness module
2024-11-14 15:45:25 +08:00
李通洲 6801fe3d9c Doc: update schema for percent type config 2024-11-14 14:26:18 +08:00
李通洲 1c41c6ccb1 Percent: allow use enum to set type value in JSON config 2024-11-14 14:21:55 +08:00
李通洲 c9e3f8d95c Global: support percent type config in module level 2024-11-14 13:52:02 +08:00
李通洲 97e1b987dd Global: pack all enums and make flag enums unsigned 2024-11-14 11:00:44 +08:00
Carter Li e821a99873 CPU (Linux): add more Apple SOC code names 2024-11-13 16:44:24 +08:00
李通洲 bad85a557a Host (Android): detect marketing name of vivo smartphone 2024-11-13 15:53:14 +08:00
李通洲 1d92bf864a IO (macOS): fix logo fails to load from symlinked files
Fix #1395
2024-11-13 15:15:50 +08:00
李通洲 2cfc8ec0db Processing (macOS): fix exe path detection 2024-11-13 10:46:30 +08:00
李通洲 5efb87997b Util (macOS): cleanup cf_helpers.c 2024-11-13 10:38:40 +08:00
李通洲 d7fa0417ed CMake: use gen-man.py to generate man file 2024-11-13 10:24:57 +08:00
李通洲 fe57b28581 Scripts: clean up gen-man.py 2024-11-13 10:18:11 +08:00
李通洲 5a1be2535b Scripts: make gen-pciids.py executable 2024-11-13 10:17:06 +08:00
Tibo bccf241816 Scripts: Add python script to generate man page (#1392)
*  Add man generating script

*  Add arguments and description

* 🐛 Add shebang

* 📝 Add documentation & text for sections

* 🐛 Fix italic text (italic is not supported for man pages)

* 🗑️ Remove .1 generated file

* ✏️ Fix type "abbreviation" gen-man.py:24

* 🐛 Fix invalid escape sequence

*  Add version finder

*  Example & config sections

* 🗑️ Delete generated .1 file

---------

Co-authored-by: tgallone <thibaut.gallone@etu.unistra.fr>
2024-11-13 09:13:13 +08:00
李通洲 c70c37c50c GPU (macOS): apply the same logic as CPU just in case 2024-11-12 22:58:22 +08:00
李通洲 644458bc74 CPU (macOS): try fixing CPU freq detection on Apple M4
Fix #1394
2024-11-12 22:34:57 +08:00
李通洲 e618303343 Media (macOS): try fixing error CFStringGetCString() failed 2024-11-12 21:52:12 +08:00
李通洲 748b7df0d7 Smbios: clean up more garbage values
Ref: #1391
2024-11-12 10:45:09 +08:00
李通洲 7c8250c68c StringUtil: rename ffStrCopy and correctly reflect its usage 2024-11-11 18:02:23 +08:00
Carter Li c368908b7d Shell (macOS): try fixing segfault in old macOS
Ref: #1388
2024-11-11 17:49:49 +08:00
李通洲 830c71ddc4 DisplayServer (NetBSD): detect WM / DE by process name 2024-11-11 17:37:01 +08:00
李通洲 5e7d9ed45e Packages (Linux): add qi support 2024-11-11 17:37:01 +08:00
Carter Li 4799f9277e Revert "IO: optimize createSubfolders (#1382)" (#1390)
This reverts commit 0284e4ccc4.
2024-11-11 17:33:22 +08:00
apocelipes 0a61031463 tests: add FFstrbuf smallest allocation test & minor fix (#1387) 2024-11-11 07:58:24 +08:00
Tibo G 07d0743a18 Logo (Builtin): add cosmicDE logo (#1386)
* add cosmicDE logo

* Update cosmic.txt

* Update builtin.c

---------

Co-authored-by: tgallone <thibaut.gallone@etu.unistra.fr>
Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-11-11 00:43:43 +08:00
Emily Astranova f989a1a982 Doc: fix typo in README (#1385) [ci skip]
Changed "deserved" to "derived"
2024-11-10 23:37:29 +08:00
李通洲 f9713d5ee2 OS (Android): display android icon 2024-11-10 13:57:57 +08:00
李通洲 4f9645e7ff Logo (Builtin): add Unifi 2024-11-10 13:35:22 +08:00
Carter Li 08a92a4324 CPU (OpenBSD): support CPU temp detection 2024-11-10 13:28:48 +08:00
李通洲 d10c14721a Disk: be able to print disk indices 2024-11-10 13:07:30 +08:00
李通洲 4534f18525 Battery: don't print index in multi-battery device 2024-11-10 13:07:12 +08:00
Carter Li f98e6c9d4e Sound (BSD): trim device names 2024-11-10 12:47:26 +08:00
Carter Li 59c666515a Version (MidnightBSD): support libc version detection 2024-11-10 12:47:26 +08:00
李通洲 7fab6f27ee Packages (BSD): support mport 2024-11-10 12:47:26 +08:00
李通洲 7d406bbae1 Logo (Builtin): add MidnightBSD 2024-11-10 12:47:26 +08:00
apocelipes 7b81ffc8e4 FFstrbuf: fix small FFstrbuf allocations in ffStrbufEnsureFree (#1383) 2024-11-10 08:27:57 +08:00
apocelipes 0284e4ccc4 IO: optimize createSubfolders (#1382) 2024-11-10 08:27:34 +08:00
Carter Li 837903e845 DisplayServer: fix deprecation warnings 2024-11-09 21:36:48 +08:00
xiaoran007 3fa0d1ab19 Host (macOS): add HwModel support for new Mac (2024) (#1381)
* host(macOS): add HwModel support for new Mac (iMac, Mac mini and Macbook Pro 2024)

* Update host_apple.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-11-09 20:32:35 +08:00
李通洲 07f2a71b3c Bluetooth (Windows): detect battery level 2024-11-09 20:23:25 +08:00
李通洲 acb38fa3ee Bluetooth (Windows): detect battery (WIP) 2024-11-06 08:25:54 +08:00
李通洲 7396208809 Logo (Builtin): fix Lilidog
Fix #1373
2024-11-06 08:25:48 +08:00
李通洲 2389d7b580 FFstrbuf: correct definition of StrStrIA 2024-11-06 08:25:06 +08:00
李通洲 8f750da559 Bluetooth (Windows): fix mac address detection 2024-11-06 08:25:06 +08:00
Lucas Holt f69a9dab33 CMake: Add initial support for MidnightBSD (#1377)
* Add initial support for MidnightBSD

* Cleanup some issues identified through code review.

Add libzfs check as MidnightBSD does have zfs.

* Add MidnightBSD check to the version.c detection

* Remove `OR MidnightBSD` tests

* Clean up

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-11-06 00:17:23 +08:00
李通洲 9a34cb98dc Bluetooth (macOS): normalize mac address strings 2024-11-05 16:39:04 +08:00
李通洲 ef974ef8c0 Bluetooth (macOS): support battery level detection 2024-11-05 11:06:54 +08:00
李通洲 40671c78f1 Monitor: don't display () if display name is not available 2024-11-05 10:01:43 +08:00
李通洲 211fd4b197 Display: add hdr-compatible
Fix #1376
2024-11-05 09:59:25 +08:00
Carter Li 722063401c Packaging: update debian stuff [ci skip] 2024-11-04 15:06:33 +08:00
Carter Li 9be70a73d3 Merge pull request #1374 from fastfetch-cli/dev
Release: v2.29.0
2024-11-04 15:02:18 +08:00
李通洲 55909c480e CMake (OpenBSD): enable bluetooth detection
I don't think it work, though
2024-11-04 14:47:38 +08:00
李通洲 7ceabcc03e CMake (NetBSD): add /usr/pkg/lib to rpath 2024-11-04 14:28:16 +08:00
Carter Li e4b98b3494 GPU: fix build if libpciaccess is not available 2024-11-04 21:59:41 +08:00
Carter Li 991ebfbc4a Camera (OpenBSD): add support (?) 2024-11-04 13:30:50 +08:00
Carter Li 02e133bf35 OpenGL (NetBSD): use correct so file 2024-11-04 13:30:50 +08:00
李通洲 3c6214d90f Release: 2.29.0 2024-11-04 10:48:38 +08:00
李通洲 7f56928cf0 OS (BSD): don't check for debian and ubuntu variants 2024-11-04 10:47:52 +08:00
李通洲 1487c91f3f OS (Linux): fix build
oops
2024-11-04 10:42:51 +08:00
李通洲 47b9d0a3a4 Library (Windows): load dlls at current exe path 2024-11-04 10:32:17 +08:00
李通洲 17d6153353 Vulkan: drop windows-i686 support 2024-11-04 09:30:13 +08:00
李通洲 b5545c926f Logo (Builtin): add Lilidog
Fix #1373
2024-11-04 09:20:38 +08:00
李通洲 a7f881522b OS (Linux): detect Lilidog 2024-11-04 09:19:53 +08:00
李通洲 91fdc8114f CI: remove windows-i686 2024-11-04 09:08:10 +08:00
Carter Li 8f2d51c698 Doc: update changelog 2024-11-03 18:09:18 +08:00
Carter Li 534aa09d86 CI (DragonFly): build with chafa & libelf 2024-11-03 18:09:08 +08:00
Carter Li d216391278 Libc (BSD): always initialize variables 2024-11-03 18:00:45 +08:00
李通洲 743babda10 Libc (DragonFly): add support 2024-11-03 11:58:23 +08:00
李通洲 9610912c1f CI: build on DragonFly 2024-11-03 11:15:24 +08:00
李通洲 282ed9b40b Netif (SunOS): fix compiling 2024-11-03 11:01:27 +08:00
Carter Li d1ef454ae8 Sound (DragonFly): add support 2024-11-03 18:40:59 +08:00
Carter Li 5c21931a09 DiskIO (DragonFly): add support 2024-11-03 18:10:36 +08:00
李通洲 3c04b0ae65 Doc: update changelog 2024-11-03 09:54:04 +08:00
李通洲 dab02f176f OS (Linux): improve performance of proxmox version detection
Fix #1370
2024-11-03 09:53:54 +08:00
Carter Li f7288fec01 Global: support DragonFly BSD 2024-11-03 08:35:11 +08:00
李通洲 540239fe03 Brightness (NetBSD): disable 2024-11-01 22:33:28 +08:00
李通洲 fe8595a054 Doc: update changelog 2024-11-01 22:18:59 +08:00
李通洲 efe0676831 Logo (Builtin): update OpenSUSE Leap 2024-11-01 22:16:29 +08:00
李通洲 565afa1e51 CI (NetBSD): release NetBSD 2024-11-01 22:05:36 +08:00
李通洲 7ffffda504 CI: remove libv4l
We need libv4l2 instead of libv4l(1)
2024-11-01 22:00:21 +08:00
Carter Li 0110584e39 NetIO (*BSD): support OpenBSD & NetBSD 2024-11-01 18:51:59 +08:00
Carter Li 254f1216ec Users (OpenBSD): add support 2024-11-01 18:44:34 +08:00
Carter Li 090b6d741c DiskIO (SunOS): remove dev path 2024-11-01 15:31:54 +08:00
Carter Li b05023fb8b DiskIO (OpenBSD): add support 2024-11-01 15:21:47 +08:00
Carter Li 0f3ce426e9 DiskIO (NetBSD): add support 2024-11-01 15:21:17 +08:00
李通洲 7d46b2ada5 Logo (Builtin): make aperture colorable
Fix #1368
2024-11-01 08:47:26 +08:00
李通洲 e0acce9646 CI (OpenBSD / NetBSD): embed pci.ids 2024-11-01 00:21:19 +08:00
Carter Li b410710903 Processes (NetBSD): add support 2024-11-01 00:20:51 +08:00
Carter Li cb403be8e5 GPU: use pciaccess to enumerate PCI devices 2024-10-31 23:51:58 +08:00
Carter Li 2bc66d7f27 CMake (NetBSD): set rpath 2024-10-31 22:39:25 +08:00
李通洲 d4c7b53ded CPU (Android): add QS8E 2024-10-31 09:33:23 +08:00
Carter Li c693e5ab5f Bios (NetBSD): try detecting boot method 2024-10-31 00:40:29 +08:00
Carter Li cae8286621 Shell / Terminal: fix proc path detection 2024-10-31 00:25:40 +08:00
Carter Li c3d04d067d Platform (NetBSD): fix exe path detection 2024-10-31 00:13:34 +08:00
Carter Li 49902d8c2f Disk (NetBSD): fix disk size detection 2024-10-30 23:46:40 +08:00
Carter Li 229d5f899c CPU (NetBSD): add support 2024-10-30 23:29:05 +08:00
Carter Li 3f41306c91 Packages (NetBSD): add support 2024-10-30 22:42:46 +08:00
李通洲 6ccc6124d0 Keyboard (Linux): silence compiler warnings 2024-10-30 09:28:18 +08:00
Carter Li c6c6803403 CMake (*BSD): detect videodev2 2024-10-29 09:22:09 +08:00
Carter Li e22b58b26e CI (NetBSD): try fixing build 2024-10-29 09:13:59 +08:00
Carter Li 0406f5c2b2 CI (NetBSD): add more dependencies 2024-10-29 09:08:32 +08:00
Carter Li 5443334156 DisplayServer (Linux): silense compiler warnings 2024-10-29 09:08:28 +08:00
Carter Li a3a042f02b Global: remove stb_printf
Doesn't gain any performance boost
2024-10-29 08:51:17 +08:00
Carter Li bc550a5ea7 Disk (OpenBSD): fix build 2024-10-28 16:27:29 +08:00
Carter Li 82fc27f259 CMake (NetBSD): detect X11 and other packages 2024-10-28 16:12:23 +08:00
Carter Li 081e8ea39f Disk: support NetBSD, improve hidden partition detection 2024-10-28 16:11:37 +08:00
Carter Li e7630aef34 NetBSD: support CPUUsage / Memory / Swap 2024-10-28 16:10:20 +08:00
Carter Li e19ed4c8f6 CMake: allow to replace native *printf to stb_*printf 2024-10-28 14:47:08 +08:00
Carter Li 332ddfc6ed CI: fix a copy-paste error 2024-10-27 14:05:18 +08:00
李通洲 32939eabab Uptime (NetBSD): fix invalid result 2024-10-27 12:19:48 +08:00
李通洲 bdd87a6ce7 CI: try adding netbsd 2024-10-27 12:09:27 +08:00
李通洲 4665fdd145 Global: make it compile on NetBSD
Doesn't work yet.
2024-10-27 11:43:36 +08:00
ferrreo 2fe6e60d98 Logo (Builtin): update PikaOS (#1361) 2024-10-27 09:40:49 +08:00
李通洲 26920d49f5 Logo (Builtin): add SummitOS
Fix #1352
2024-10-26 22:45:32 +08:00
李通洲 2dc8ac6a51 Logo (Builtin): add XCP-ng
Fix #1359
2024-10-26 22:27:09 +08:00
李通洲 20f9ff9bae Logo (Builtin): update OpenSuse Tumbleweed
Fix #1357
2024-10-26 11:42:08 +08:00
李通洲 fd26373c8f Global: overall optimization 2024-10-26 11:42:07 +08:00
李通洲 6dc6fd8b24 3rdparty: add stb_sprintf 2024-10-26 11:42:07 +08:00
apocelipes 53e0861b03 Editor: fix the Vim version detection (#1356) 2024-10-26 11:08:18 +08:00
李通洲 19902fa18c CMake: define NOMINMAX on Windows 2024-10-24 15:21:40 +08:00
李通洲 f3f8601a60 CMake: use 64bit time_t on Linux 2024-10-24 15:21:40 +08:00
apocelipes 0bdb097592 Editor: optimize editor version parsing (#1355) 2024-10-24 09:43:23 +08:00
Carter Li b57766522d Packaging: update debian stuff [ci skip] 2024-10-23 14:36:12 +08:00
Carter Li 18d530103f Merge pull request #1353 from fastfetch-cli/dev
Release: v2.28.0
2024-10-23 09:55:23 +08:00
李通洲 4d235a9fe9 Release: v2.28.0 2024-10-23 09:24:42 +08:00
李通洲 5c06d34b49 Windows: use system provided CM_Get_Device_Interface_PropertyW 2024-10-23 09:21:30 +08:00
Carter Li 6cd7f6c2f6 Doc: update changelog [ci skip] 2024-10-22 14:50:38 +08:00
李通洲 c8521b55b9 CPUUsage / DiskIO / NetIO: add option waitTime 2024-10-22 11:08:44 +08:00
李通洲 40b8023ff9 CI: fix build for old compilers 2024-10-18 21:07:50 +08:00
李通洲 7a3afa4adf PhysicalDisk (Linux): don't report obviously invalid temp 2024-10-18 16:49:36 +08:00
李通洲 b257134d74 Chore: introduce macro ARRAY_SIZE 2024-10-18 16:44:41 +08:00
李通洲 5497cb64c2 Processing (Windows): generate unique pipe name
Fix #1346
2024-10-18 14:08:55 +08:00
李通洲 bd4bc87c38 CMake: add comments 2024-10-17 22:34:37 +08:00
李通洲 188dbde595 Chore: remove all #ifndef guards 2024-10-17 22:33:52 +08:00
李通洲 48bb5b8746 Chore: use ffStrCopyN instead of strlcpy 2024-10-17 22:29:38 +08:00
Carter Li 9bd692dffb Presets: add showAllIps to all.jsonc 2024-10-17 19:39:26 +08:00
李通洲 dee5f1b339 CMake: enable fortify if available 2024-10-17 19:38:48 +08:00
Carter Li ecd73667df DiskIO (Linux): fix multi-namespace nvme drive detection 2024-10-17 19:38:48 +08:00
李通洲 993902916d Chore: don't use strncpy in favor of strlcpy
strncpy doesn't require target to be NUL terminated
2024-10-17 16:16:04 +08:00
李通洲 8f79d6ab1d Chore: silence some warnings 2024-10-17 15:39:11 +08:00
李通洲 6500cddc09 Disk (Android): fix compiling 2024-10-17 15:25:54 +08:00
李通洲 4146bb6731 OS (Windows): hard linking winbrand 2024-10-17 09:30:48 +08:00
李通洲 9188715efd TPM (Windows): use system headers 2024-10-17 09:20:17 +08:00
李通洲 bf1cd3388d Battery (macOS): fix remaining time detection 2024-10-16 09:15:04 +08:00
李通洲 a0ad38d1d4 Disk: check for mntopt instead of statvfs when detecting read only flags
Ref: #1343
2024-10-15 23:08:10 +08:00
李通洲 cc86c2c428 CI (Linux): try fixing build 2024-10-15 21:43:55 +08:00
李通洲 67a35c92ff Chore (Linux): code cleanup 2024-10-15 21:43:41 +08:00
李通洲 ae76d2d032 IO (Linux): improve performance of ffPathExists 2024-10-15 19:40:03 +08:00
Carter Li 2b2c223d22 Btrfs (Linux): simplify 2024-10-15 11:11:11 +08:00
Carter Li d6fa03d9e6 Fastfetch: don't use invalid paths when printing preset files 2024-10-15 10:31:37 +08:00
Carter Li 21ab56ad00 DiskIO (Linux): simplify 2024-10-15 10:30:58 +08:00
Carter Li b5a9d64e75 PhysicalDisk (Linux): simplify 2024-10-15 10:29:50 +08:00
Carter Li e73d6db2e5 Battery (Linux): improve performance by specifying O_PATH 2024-10-15 10:18:26 +08:00
Carter Li 1c598add39 Chore (Linux): always ignore hidden files when enumerating directories 2024-10-15 10:16:58 +08:00
XeroArch f87f345918 Fixing wrong color in the XeroArch ASCII logo (#1342)
* putting xeroarch logo in askii

* updating logo

* updating

* updating

* uploading xeroarch ascii logo

* upgrading fetch ascii logo

* fixing a very small issue

* removing unecessary line

* removing trailing lines

* fixing erroneous colors in the logo

---------

Co-authored-by: xeroarch <xeroarch.os@gmail.com>
2024-10-15 08:52:42 +08:00
李通洲 fba33df1d3 Kernel: don't print ( - 2024-10-14 16:28:53 +08:00
李通洲 a11b10fb37 Doc: update changelog 2024-10-14 16:07:01 +08:00
李通洲 c73b5914ab Battery (macOS): report time remaining only when discharging 2024-10-14 15:58:31 +08:00
李通洲 e70589483d Kernel (Windows): detect wine 2024-10-14 15:52:12 +08:00
Carter Li 71a8978f41 Display: report platform api used for detection 2024-10-14 14:42:11 +08:00
apocelipes 0f1ad5750d Netif (Linux): fix unused-result warning (#1340) 2024-10-14 12:30:39 +08:00
apocelipes bbc9cf4980 Processing(Linux, SunOS): little optimizations (#1341) 2024-10-14 11:35:29 +08:00
李通洲 fbed730dac Netif (Linux): don't use fseek
Turns out that `fseek` generates two extra syscalls, which causes unnecessary overhead.
2024-10-13 21:32:17 +08:00
李通洲 f847a23fb9 CI: remove musl-aarch64 2024-10-13 18:54:46 +08:00
Carter Li c5527fa4e6 Zpool: don't report invalid fragmentation 2024-10-13 17:18:53 +08:00
Carter Li c92d6f9eb6 CI: fix spellcheck errors 2024-10-13 17:07:01 +08:00
李通洲 3a914f2d27 LocalIP (Linux): simplify ffNetifGetDefaultRouteImpl
Fix #1336
2024-10-13 08:55:03 +08:00
Shu Niu 986d36c028 fix build in ancient MacOS (#1334) 2024-10-12 19:45:14 +08:00
李通洲 746cff471f IO (Windows): fix build 2024-10-12 19:44:30 +08:00
Carter Li 08cdeb3bcf PhysicalDisk (Linux): simplify code 2024-10-12 13:29:58 +08:00
Carter Li b5a8d6b86d PowerAdapter (Linux): simplify 2024-10-12 10:42:13 +08:00
Carter Li 29dd6d88c9 IO: add function ffReadFileDataRelative 2024-10-12 10:41:58 +08:00
Carter Li 49076ec69d Battery (Linux): simplify 2024-10-12 10:41:25 +08:00
李通洲 15fc3bcc92 IO (Windows): add ffAppendFileBufferRelative 2024-10-12 10:13:23 +08:00
Carter Li 1178f46aac Battery (Linux): check if AC is connected 2024-10-12 09:38:19 +08:00
Carter Li 68406cd044 IO (Linux): use openat to simplify code 2024-10-11 16:36:08 +08:00
Carter Li 782474b068 Battery (Linux): revert back not to use uevent
Reading `uevent` is slow...
2024-10-11 16:24:19 +08:00
李通洲 cd9cfa5d99 Memory (SunOS): simplify 2024-10-11 14:48:56 +08:00
李通洲 ded38efb1a Memory (OpenBSD): fix detection of used memory size
Fix #1331
2024-10-11 14:48:11 +08:00
Carter Li e2474d1238 OpenCL: print more detailed error messages 2024-10-11 13:28:10 +08:00
Carter Li ec7c1855b3 Battery (FreeBSD): fix time remaining detection
oops
2024-10-11 00:23:04 +08:00
red-magic 99c0e9e719 run.sh: Improve compatibility with other systems (#1332)
* run.sh: Improve compatibility with other systems

For example $OSTYPE is empty in OpenBSD and the script fallsback to Linux option, with nproc isn't present it fails to build.

* Update run.sh

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-10-10 23:38:49 +08:00
李通洲 af09de319b Battery (Android): better status detection 2024-10-10 21:03:27 +08:00
李通洲 ff21dabfb7 Battery (FreeBSD): detect time remaining 2024-10-10 21:01:12 +08:00
Carter Li 27910cf6ec Battery (Linux): calcuate time remaining with current & charge if time_to_empty is unavailable 2024-10-10 08:38:58 +00:00
Carter Li daab70fafc Battery (Linux): rewrite with uevent, add remaining time support 2024-10-10 16:04:27 +08:00
李通洲 4dccb92bb2 Battery: support time remaining detection 2024-10-10 15:57:17 +08:00
李通洲 8c74745076 CI (SunOS): fix build 2024-10-10 10:06:54 +08:00
李通洲 3eb081561d Gamepad: report joystick too 2024-10-10 09:42:56 +08:00
Carter Li 9dcfdcae83 Mouse / Keyboard (FreeBSD): add support 2024-10-10 09:30:20 +08:00
李通洲 4dbc9566da Keyboard: fix CI 2024-10-09 23:22:45 +08:00
李通洲 492010b325 Mouse / Keyboard: try fixing x86 link errors 2024-10-09 23:14:52 +08:00
李通洲 6647d36f85 Mouse / Keyboard (macOS): don't detect vendor name 2024-10-09 21:46:49 +08:00
李通洲 ee29f767a0 Mouse / Keyboard: try harder to get device name 2024-10-09 21:43:33 +08:00
李通洲 aece7cb550 Mouse / Keyboard: add placeholders for unsupported platforms
Fix #1327
2024-10-09 16:41:52 +08:00
李通洲 6f0e6587ac Mouse / Keyboard (Windows): add support 2024-10-09 16:33:47 +08:00
李通洲 bf9963cf85 Gamepad (Windows): fix invalid handle testing 2024-10-09 16:26:00 +08:00
Carter Li a2b32ef564 Mouse / Keyboard: add new modules 2024-10-09 14:36:09 +08:00
李通洲 dbe7aaaa1b CI: use mingw32 for windows-i686 2024-10-08 20:55:55 +08:00
Carter Li d0f52162f3 Logo (Builtin): add MidOS
Fix #1304
2024-10-08 15:31:15 +08:00
Yukari Chiba c624c36754 Logo (Builtin): add eweOS (#1328)
* Logo (Builtin): add eweOS

* Update eweos.txt

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-10-08 15:20:51 +08:00
apocelipes 84cc9e3b15 Chore: fix some unused paramater/function warnings (#1324) 2024-10-06 23:01:49 +08:00
Carter Li 8855c0b851 Packaging: update debian stuff [ci skip] 2024-10-06 12:57:17 +08:00
Carter Li 4059bca941 Merge pull request #1323 from fastfetch-cli/dev
Release: v2.27.1
2024-10-06 12:35:51 +08:00
Carter Li bb94ac7832 Release: v2.27.1 2024-10-06 12:31:47 +08:00
Carter Li d5d935a658 DisplayServer (Linux): fix invalid display name detection 2024-10-06 12:27:49 +08:00
420 changed files with 10739 additions and 4901 deletions
+1 -1
View File
@@ -2,4 +2,4 @@
check-filenames =
builtin = clear,rare,usage,informal
skip = */.git,*/cmake-build-*,*/.idea,*/completions,*/presets,*/screenshots,*/tests,*/3rdparty,*/logo/ascii
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,slave,sur,doas,conexant
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,slave,sur,doas,conexant,ags
+115 -119
View File
@@ -232,6 +232,41 @@ jobs:
name: fastfetch-linux-riscv64
path: ./fastfetch-*.*
linux-ppc64le:
name: Linux-ppc64le
runs-on: ubuntu-22.04
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: run VM
uses: uraimo/run-on-arch-action@v2
id: runcmd
with:
arch: ppc64le
distro: ubuntu20.04
githubToken: ${{ github.token }}
run: |
uname -a
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-linux-ppc64le
path: ./fastfetch-*.*
musl-amd64:
name: Musl-amd64
runs-on: ubuntu-latest
@@ -272,50 +307,9 @@ jobs:
name: fastfetch-musl-amd64
path: ./fastfetch-*.*
musl-aarch64:
name: Musl-aarch64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: setup alpine linux
uses: jirutka/setup-alpine@master
with:
branch: v3.19
arch: aarch64
- name: install dependencies
run: |
cat /etc/alpine-release
uname -a
apk add cmake samurai vulkan-loader-dev libxcb-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
shell: alpine.sh --root {0}
- name: build
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -GNinja .
cmake --build . --target package --verbose -j4
shell: alpine.sh {0}
- name: run
run: |
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
shell: alpine.sh {0}
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-musl-aarch64
path: ./fastfetch-*.*
macos-universal:
name: macOS-universal
runs-on: macos-12
runs-on: macos-latest
permissions:
security-events: write
contents: read
@@ -418,11 +412,11 @@ jobs:
architecture: x86-64
cpu_count: 4
shell: bash
version: '14.1'
version: '14.2'
run: |
uname -a
sudo pkg update
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm libelf glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py311-requests
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py311-requests chafa
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
@@ -438,6 +432,41 @@ jobs:
name: fastfetch-freebsd-amd64
path: ./fastfetch-*.*
dragonfly-amd64:
name: DragonFly-amd64
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: run VM
uses: vmactions/dragonflybsd-vm@v1
with:
usesh: yes
prepare: |
uname -a
pkg update
pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py39-requests chafa libelf
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-dragonfly-amd64
path: ./fastfetch-*.*
openbsd-amd64:
name: OpenBSD-amd64
runs-on: ubuntu-latest
@@ -455,11 +484,11 @@ jobs:
architecture: x86-64
cpu_count: 4
shell: bash
version: '7.5'
version: '7.6'
run: |
uname -a
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa pulseaudio
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa pulseaudio hwdata py3-requests
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=ON .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -474,6 +503,42 @@ jobs:
name: fastfetch-openbsd-amd64
path: ./fastfetch-*.*
netbsd-amd64:
name: NetBSD-amd64
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: run VM
uses: cross-platform-actions/action@master
with:
operating_system: netbsd
architecture: x86-64
cpu_count: 4
shell: bash
version: '10.0'
run: |
uname -a
sudo pkgin -y install cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick pulseaudio opencl-headers ocl-icd py312-requests
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=ON .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-netbsd-amd64
path: ./fastfetch-*.*
windows-amd64:
name: Windows-amd64
runs-on: windows-latest
@@ -539,76 +604,6 @@ jobs:
name: fastfetch-windows-amd64
path: ./fastfetch-windows-amd64.*
windows-i686:
name: Windows-i686
runs-on: windows-latest
permissions:
security-events: write
contents: read
defaults:
run:
shell: msys2 {0}
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: setup-msys2
uses: msys2/setup-msys2@v2
with:
msystem: CLANG32
update: true
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd mingw-w64-clang-i686-opencl-headers
- name: print msys version
run: uname -a
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: c, cpp
- name: configure project
run: env PKG_CONFIG_PATH=/clang32/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
- name: build project
run: cmake --build . --verbose -j4
- name: perform CodeQL analysis
uses: github/codeql-action/analyze@v3
- name: copy necessary dlls
run: cp /clang32/bin/{OpenCL,vulkan-1}.dll .
- name: download amd_ags
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x86.dll
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: ldd fastfetch
- name: run tests
run: ctest
- name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-i686.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-i686.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-windows-i686
path: ./fastfetch-windows-i686.*
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
name: Release
@@ -618,14 +613,15 @@ jobs:
- linux-aarch64
- linux-armv7
- linux-riscv64
- linux-ppc64le
- musl-amd64
- musl-aarch64
- macos-universal
- freebsd-amd64
- openbsd-amd64
- netbsd-amd64
- dragonfly-amd64
- sunos-amd64
- windows-amd64
- windows-i686
permissions:
contents: write
steps:
+1
View File
@@ -9,3 +9,4 @@ tags
fastfetch.kdev4
*.user
*.user.*
*.swp
+267 -2
View File
@@ -1,9 +1,274 @@
# 2.34.1
An early release to fix KDE Plasma 6.3 compatibility. Hopefully it can be accepted by package managers before KDE 6.3 is officially released.
To package managers: if you find fastfetch bugs, it's highly appreciated if you can report them to the upstream, so that all users can benefit from the fix, instead of maintaining out-of-tree patches. Thanks!
Features:
* Report vendor name when detecting GPUs by OpenGL
* Note: the vendor name is actually the creator of the OpenGL driver (such as `Mesa`) and may not be the same as the GPU vendor.
Bugfixes:
* Fix Ghostty termfont detection (#1495, TerminalFont, macOS)
* Fix compatibility with KDE Plasma 6.3 (#1504, Display, Linux)
* Make memory usage detection logic consistent with other systems (Memory, OpenBSD / NetBSD)
* Report media file name if media title is not available (Media)
* Fix max frequency detection for CPUs with both performance and efficiency cores (CPU, FreeBSD)
Logo:
* Add HeliumOS
* Add Oreon
* Update SnigdhaOS
# 2.34.0
Changes:
* We now print distro pretty name if available (OS)
* This is a long requested feature. However, it may break some distros. File a bug with the content of `/etc/os-release` if it breaks your distro.
Bugfixes:
* Fix thunderbolt version of new MBPs (#1465, Host, macOS)
* Fix backlight name detection on FreeBSD (Brightness, FreeBSD)
* Fix Terminal detection when running fastfetch in `pk-command-not-found` (#1467, Terminal, Linux)
* Relax detection of terminals in NixOS (#1479, Terminal, Linux)
* Should fix konsole, ghostty and maybe others
* Fix core count output in multi-package platforms (CPU)
* Don't suppress the output of `preRun` (#1489)
* Fix battery percentage detection (Battery, NetBSD)
Features:
* Support ghostty terminal font detection (TerminalFont, Linux / macOS)
* Support `kitty-icat` image protocol, which uses `kitten icat` to generate image data
* Pros: support tmux; support gif animations; good performance
* Cons: due to the limitation of `kitten icat`, we need to clear the screen before displaying the image logo
* Support WM version detection (WM)
* In Linux, Hyprland & sway are supported currently
* Improve performance when stdout is redirected (TerminalSize)
* Report thermal zone temp if CPU temp is not available (CPU, Linux)
* Report sound server (Pipewire or PulseAudio) if available (#1454, Sound, Linux)
* Enable OpenGL & OpenCL detection on Android (OpenGL / OpenCL, Android)
* Detect & report MediaTek Dimensity 9000+ SOC name (CPU, Android)
* Support appman (am-user) package manager detection (Packages, Linux)
Logo:
* Add Lubuntu
* Update Xray_os
* Add SnigdhaOS
* Add Rhino Linux
# 2.33.0
Changes:
* Introduce a new CMake flag `-DBUILD_FLASHFETCH=OFF` to disable building flashfetch binaries
* Package managers are encouraged to enable it. See <https://github.com/fastfetch-cli/fastfetch/discussions/627> for detail
Bugfixes:
* Fix interconnect type detection (#1453, PhysicalDisk, Linux)
* Regression of v2.28
* Don't report `proot` as terminal (Terminal, Android)
* Remove a debug output (DiskIO, OpenBSD)
* Fix media detection for some players (#1461, Media, Linux)
* Regression of v2.32
Features:
* Use `$POWERSHELL_VERSION` as PowerShell version if available (Shell, Windows)
* Fetching Windows PowerShell version can be very slow. Add `$env:POWERSHELL_VERSION = $PSVersionTable.PSVersion.ToString()` in `$PROFILE` before running `fastfetch` to improve the performance of `Shell` module
* Add support for ubuntu-based armbian detection (#1447, OS, Linux)
* Improve performance of Bluetooth detection (Bluetooth)
* We no longer report disconnected bluetooth devices in `--format json` when `--bluetooth-show-disconnected` isn't specified
* Support brightness level detection for builtin displays (Brightness, OpenBSD / NetBSD)
* Requires root permission on OpenBSD
* Support battery level detection (Battery, OpenBSD / NetBSD)
* Support CPU temperature detection in NetBSD (CPU, NetBSD)
* Hard code path of `libvulkan.so` for Android
* So that users don't need to install the vulkan-loader wrapper of termux
Logo:
* Add NurOS
* Add GoralixOS
# 2.32.1
A hotfix for OpenBSD. No changes to other platforms.
Bugfixes:
* Fix package count detection on OpenBSD (Packages, OpenBSD)
# 2.32.0
Bugfixes:
* Fix `pci.ids` file location on OpenBSD (GPU, OpenBSD)
* It's normally unused because enumerating PCI devices on OpenBSD requires root privileges
* Fix bssid formatting (Wifi, Linux)
* Fix Linux Lite distro detection (#1434, OS, Linux)
* Suppress XE driver warnings from Mesa (#1435, OpenGL, Linux)
* Fix format parameter name (#1443, Version)
* Don't report useless information when Wifi is disabled (Wifi, FreeBSD)
* Currently there are issues when the SSID contains whitespaces. More fixes are expected in the future.
* Always use physical size reported by X11 server to avoid inconsistent results (#1444, Display, Linux)
Features:
* Randomly select one if the logo source expands to multiple files (#1426, Logo)
* Report mac product name when running Linux in MacBook (Host, Linux / FreeBSD)
* Use screen size reported in DTD if make sense (Display)
* Detect Virtualized Apple Silicon CPUs (CPU, Linux)
* Add detection support for fvwm and ctwm (WM, OpenBSD / NetBSD)
* Add Armbian-unofficial detection (OS, Linux)
* Prefer surfaceless display when connect EGL (OpenGL)
* Improve accuracy of WM detection on FreeBSD (WM, FreeBSD)
* Add ratpoison window manager (WM, Linux)
Logo:
* Update Linux Lite
* Add Serpent OS
* Add Ultramarine Small
* Update Debian
# 2.31.0
Bugfixes:
* Improve performance of media detection; fix musikcube detection (Media, Linux)
* After the change, `general.processingTimeout` will also control the timeout of dbus remote calls
* Fix invalid variable names (#1408, Users)
* Change physical size detection to use basic display parameters (#1406)
* Fix possible sigfaults when detecting displays (#1393)
* Fix Nvidia card type detection
* Fix wl-restart parsing (#1422, WM, Linux)
* Fix syntax error in completion file (#1421)
* Fix hunging when using `ssh-agent` as command text (#1418, Command, macOS)
Features:
* Remove support of xcb & xlib and xrandr extension is always required (Display)
* Support preferred resolution & refresh rate detection
* On macOS there is no preferred resolution reported and maximum available resolution is reported instead.
* `--display-format {preferred-width}x{preferred-height}@{preferred-refresh-rate}`
* Report scale factor in custom format (Display)
* `--display-format {scale-factor}`
* Detect current Wi-Fi channel and maximum frequency (Wifi)
* Report processor package count (#1413, CPU)
* Remove duplicate whitespaces in CPU name
* Support sakura terminal version & font detection (Terminal / TerminalFont, Linux)
Logo:
* Fix LMDE
* Update MidOS
* Add Windows Server 2025
# 2.30.1
Bugfixes:
* Fix the destination where `fastfetch.1` is generated (#1403)
# 2.30.0
Changes:
* Percent: bar type must be enabled in `percent.type` before using percent bar in custom format
Features:
* Port to MidnightBSD; add mport package manager support
* Support bluetooth battery detection for macOS and Windows (Bluetooth, macOS / Windows)
* Support M4 model detection (Host, macOS)
* Support CPU temperature detection on OpenBSD (CPU, OpenBSD)
* Display Android icon in Android devices (OS, Android)
* Support qi package manager detection (Packages, Linux)
* Detect WM / DE by enumerating running processes (WM / DE, NetBSD)
* Generate manual pages from `help.json` (Doc)
* Detect marketing name of vivo smartphone (Host, Android)
* Add txDrops detection if supported (NetIO, *BSD)
* Support tilix version detection (Terminal, Linux)
* Support percent type config in module level. Example:
```json
{
"type": "memory",
"percent": {
"green": 20, // [0%, 20%) will be displayed in green
"yellow": 40, // [20, 40) will be displayed in yellow and [40, 100] will be displayed in red
"type": [ // Display percent value in monochrome bar, same as 10
"bar",
"bar-monochrome"
]
}
}
```
Bugfixes:
* Don't display `()` in key if display name is not available (Display)
* Fix & normalize bluetooth mac address detection (Bluetooth, macOS / Windows)
* Don't print index in multi-battery devices (Battery)
* Fix segfault in macOS (#1388, macOS)
* Fix `CFStringGetCString() failed` errors (#1394, Media, macOS)
* Fix CPU frequency detection on Apple M4 (#1394, CPU, macOS)
* Fix exe path detection on macOS (Shell / Terminal, macOS)
* Fix logo fails to load from symlinked files on macOS (#1395, Logo, macOS)
* Fix 32-bit truncation (NetIO, macOS)
Logos:
* Fix Lilidog
* Add MidnightBSD
* Add Unifi
* Add Cosmic DE
* Update openSUSE Tumbleweed
# 2.29.0
Changes:
* Due to [the upstream removal of MSYS2 CLANG32 environment](https://www.msys2.org/news/#2024-09-23-starting-to-drop-the-clang32-environment), we dropped fastfetch-windows-i686 support. v2.27.1 was the last version supporting it.
* Note: fastfetch built with MSVCRT has known bug that DateTime module doesn't work because of its bad support of [strftime](https://en.cppreference.com/w/c/chrono/strftime). Don't use it.
Features:
* Port to NetBSD and DragonFly BSD
* Fastfetch now supports all major BSD variants
* Support DiskIO, NetIO, GPU and Users module on OpenBSD
* Report SD8E SOC name (CPU, Android)
* On Windows, try loading dlls from current exe path (Windows)
* Fix Media module when installed with winget
Bugfixes:
* Fix the VIM version detection on Ubuntu (Editor, Linux)
* Improve performance of OS version detection on Proxmox (#1370, OS, Linux)
Logo:
* Update OpenSuse Tumbleweed
* Add XCP-ng
* Add SummitOS
* Add Lilidog
* Update PikaOS
* Update OpenSUSE Leap
* Update aperture
# 2.28.0
Features:
* Add new module `Mouse` and `Keyboard` which display connected mice and keyboards
* Support remaining time detection (Battery)
* Report if AC is connected (Battery, Linux)
* Report platform API used for display detection for debugging (Display)
* Report Wine version when running in Wine (Kernel, Windows)
* Add option `waitTime` in modules `CPUUsage`, `DiskIO` and `NetIO`
Bugfixes:
* Fix used memory size detection (Memory, OpenBSD)
* Don't report invalid fragmentation percentage when fails to detect it (Zpool)
* Fix unexpected errors when running fastfetch in parallel (#1346, Windows)
* Don't report obviously invalid temperature values (PhysicalDisk, Linux)
Logos:
* Add eweOS
* Add MidOS
* Update XeroArch
# 2.27.1
Bugfixes:
* Fix invalid display name detection on GNOME, wayland (Display, Linux)
# 2.27.0
Changes:
* We now print `"` instead of `″` when displaying diagonal length in inches, so that the character can be correctly displayed in Linux console (Display)
* All detection code of `monitor` module is merged into `display` module. Now `monitor` just prints the same information as `display` with different format. Notably:
* The resolution reported by `monitor` module is now current resolution instead of native / maximum resolution. PPI is calcuated based on current resolution too.
* The resolution reported by `monitor` module is now current resolution instead of native / maximum resolution. PPI is calculated based on current resolution too.
* The refresh rate reported by `monitor` module is the current refresh rate.
Features:
@@ -19,7 +284,7 @@ Bugfixes:
* Remove trailing newline in GPU name for Raspberry pi (#1303, GPU, Linux)
* Fix a possible buffer overflow (GPU, Linux)
* Fix CPU temp incorrectly reported as 0 celsius (#1308, CPU, Linux)
* Corrently report `TPM device is not found` error (#1314, TPM, Windows)
* Correctly report `TPM device is not found` error (#1314, TPM, Windows)
* Fix errors when triggering shell completion with python3 uninstalled (#1310)
* To package managers: as shell completion scripts of fastfetch use python3, it should be added as an optional dependency of fastfetch
* Fix possible crashes when detecting term font of kitty (#1321, TerminalFont, Linux)
+297 -83
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.27.0
VERSION 2.34.1
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -20,6 +20,14 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
set(FreeBSD TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
set(OpenBSD TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "MidnightBSD")
set(FreeBSD TRUE CACHE BOOL "..." FORCE)
set(MidnightBSD TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "NetBSD")
set(NetBSD TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")
set(FreeBSD TRUE CACHE BOOL "..." FORCE)
set(DragonFly TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
set(SunOS TRUE CACHE BOOL "..." FORCE)
elseif(NOT APPLE AND NOT WIN32)
@@ -46,39 +54,39 @@ include(CheckIncludeFile)
include(CMakeDependentOption)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_X11 "Enable x11" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR APPLE OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR APPLE OR SunOS" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS" OFF)
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR OpenBSD OR SunOS" OFF)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
option(BUILD_FLASHFETCH "Build flashfetch" ON) # Also build the flashfetch binary
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
@@ -247,6 +255,7 @@ endfunction(fastfetch_load_text)
find_package(Python)
if(Python_FOUND)
message(STATUS "Minifying 'help.json'")
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)
@@ -254,20 +263,39 @@ if(Python_FOUND)
message(ERROR "DATATEXT_JSON_HELP is empty, which should not happen!")
endif()
else()
message(STATUS "Python3 is not found, 'help.json' will not be minified")
message(WARNING "Python3 is not found, 'help.json' will not be minified")
file(READ "src/data/help.json" DATATEXT_JSON_HELP)
endif()
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "fastfetch_pciids.c.inc")
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc")
if(Python_FOUND)
message(STATUS "Generating 'fastfetch_pciids.c.inc'")
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-pciids.py"
OUTPUT_FILE "fastfetch_pciids.c.inc")
OUTPUT_FILE "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc"
RESULT_VARIABLE PYTHON_PCIIDS_RETCODE)
if(NOT PYTHON_PCIIDS_RETCODE EQUAL 0)
message(FATAL_ERROR "Failed to generate 'fastfetch_pciids.c.inc'")
endif()
else()
message(STATUS "Python3 is not found, 'fastfetch_pciids.c.inc' will not be generated")
message(WARNING "Python3 is not found, 'fastfetch_pciids.c.inc' will not be generated")
set(ENABLE_EMBEDDED_PCIIDS OFF)
endif()
endif()
if(Python_FOUND)
message(STATUS "Generating 'fastfetch.1'")
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-man.py"
OUTPUT_FILE "${PROJECT_BINARY_DIR}/fastfetch.1"
RESULT_VARIABLE PYTHON_MANPAGE_RETCODE)
if(NOT PYTHON_MANPAGE_RETCODE EQUAL 0)
message(FATAL_ERROR "Failed to generate 'fastfetch.1'")
endif()
else()
message(WARNING "Python3 is not found, use basic 'fastfetch.1.in' instead")
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC)
configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY)
endif()
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
fastfetch_load_text(src/data/help_footer.txt DATATEXT_HELP_FOOTER)
@@ -280,9 +308,6 @@ if(APPLE)
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
endif()
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC)
configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY)
####################
# Ascii image data #
####################
@@ -379,6 +404,7 @@ set(LIBFASTFETCH_SRC
src/modules/initsystem/initsystem.c
src/modules/gamepad/gamepad.c
src/modules/kernel/kernel.c
src/modules/keyboard/keyboard.c
src/modules/lm/lm.c
src/modules/loadavg/loadavg.c
src/modules/locale/locale.c
@@ -402,6 +428,7 @@ set(LIBFASTFETCH_SRC
src/modules/sound/sound.c
src/modules/swap/swap.c
src/modules/media/media.c
src/modules/mouse/mouse.c
src/modules/terminal/terminal.c
src/modules/terminaltheme/terminaltheme.c
src/modules/terminalfont/terminalfont.c
@@ -476,8 +503,10 @@ if(LINUX)
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/host/host_mac.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_linux.c
src/detection/libc/libc_linux.c
src/detection/lm/lm_linux.c
src/detection/loadavg/loadavg_linux.c
@@ -486,6 +515,7 @@ if(LINUX)
src/detection/gamepad/gamepad_linux.c
src/detection/media/media_linux.c
src/detection/memory/memory_linux.c
src/detection/mouse/mouse_linux.c
src/detection/netio/netio_linux.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
@@ -504,7 +534,7 @@ if(LINUX)
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_linux.c
src/detection/wm/wm_nosupport.c
src/detection/wm/wm_linux.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
@@ -542,6 +572,7 @@ elseif(ANDROID)
src/detection/host/host_android.c
src/detection/icons/icons_nosupport.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_nosupport.c
src/detection/libc/libc_android.c
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_linux.c
@@ -550,6 +581,7 @@ elseif(ANDROID)
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_nosupport.c
src/detection/memory/memory_linux.c
src/detection/mouse/mouse_nosupport.c
src/detection/netio/netio_linux.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_android.c
@@ -585,8 +617,7 @@ elseif(FreeBSD)
src/common/sysctl.c
src/detection/battery/battery_bsd.c
src/detection/bios/bios_bsd.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/bluetoothradio/bluetoothradio_linux.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_bsd.c
src/detection/bootmgr/bootmgr_bsd.c
src/detection/brightness/brightness_bsd.c
@@ -619,9 +650,11 @@ elseif(FreeBSD)
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_bsd.c
src/detection/host/host_mac.c
src/detection/lm/lm_linux.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_bsd.c
src/detection/libc/libc_bsd.c
src/detection/loadavg/loadavg_bsd.c
src/detection/locale/locale_linux.c
@@ -629,6 +662,7 @@ elseif(FreeBSD)
src/detection/gamepad/gamepad_bsd.c
src/detection/media/media_linux.c
src/detection/memory/memory_bsd.c
src/detection/mouse/mouse_bsd.c
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
@@ -655,7 +689,16 @@ elseif(FreeBSD)
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(OpenBSD)
if(DragonFly)
list(APPEND LIBFASTFETCH_SRC
src/detection/bluetooth/bluetooth_nosupport.c
)
else()
list(APPEND LIBFASTFETCH_SRC
src/detection/bluetooth/bluetooth_bsd.c
)
endif()
elseif(NetBSD)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
@@ -663,16 +706,16 @@ elseif(OpenBSD)
src/common/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
src/detection/battery/battery_nosupport.c
src/detection/bios/bios_nosupport.c
src/detection/battery/battery_nbsd.c
src/detection/bios/bios_nbsd.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_nosupport.c
src/detection/board/board_nbsd.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_nosupport.c
src/detection/brightness/brightness_nbsd.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_obsd.c
src/detection/chassis/chassis_nbsd.c
src/detection/cpu/cpu_nbsd.c
src/detection/cpucache/cpucache_nosupport.c
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
@@ -680,7 +723,7 @@ elseif(OpenBSD)
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_nosupport.c
src/detection/physicalmemory/physicalmemory_nosupport.c
src/detection/diskio/diskio_nosupport.c
src/detection/diskio/diskio_nbsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
@@ -695,12 +738,96 @@ elseif(OpenBSD)
src/detection/displayserver/linux/xcb.c
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_nosupport.c
src/detection/gpu/gpu_general.c
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_nbsd.c
src/detection/lm/lm_linux.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_nosupport.c
src/detection/libc/libc_nosupport.c
src/detection/loadavg/loadavg_bsd.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_linux.c
src/detection/memory/memory_nbsd.c
src/detection/mouse/mouse_nosupport.c
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_nbsd.c
src/detection/packages/packages_obsd.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_nbsd.c
src/detection/gtk_qt/qt.c
src/detection/sound/sound_linux.c
src/detection/swap/swap_obsd.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_linux.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(OpenBSD)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_bsd.c
src/common/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
src/detection/battery/battery_obsd.c
src/detection/bios/bios_nosupport.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_nosupport.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_obsd.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_obsd.c
src/detection/cpucache/cpucache_nosupport.c
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_nosupport.c
src/detection/physicalmemory/physicalmemory_nosupport.c
src/detection/diskio/diskio_obsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
src/detection/displayserver/linux/wayland/global-output.c
src/detection/displayserver/linux/wayland/zwlr-output.c
src/detection/displayserver/linux/wayland/kde-output.c
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c
src/detection/displayserver/linux/wmde.c
src/detection/displayserver/linux/xcb.c
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_pci.c
src/detection/gpu/gpu_general.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_obsd.c
src/detection/lm/lm_nosupport.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_nosupport.c
src/detection/libc/libc_nosupport.c
src/detection/loadavg/loadavg_bsd.c
src/detection/locale/locale_linux.c
@@ -708,7 +835,8 @@ elseif(OpenBSD)
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_linux.c
src/detection/memory/memory_obsd.c
src/detection/netio/netio_nosupport.c
src/detection/mouse/mouse_nosupport.c
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_obsd.c
src/detection/packages/packages_obsd.c
@@ -723,13 +851,13 @@ elseif(OpenBSD)
src/detection/theme/theme_linux.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_nosupport.c
src/detection/users/users_obsd.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_nosupport.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
@@ -764,8 +892,10 @@ elseif(APPLE)
src/detection/gpu/gpu_apple.c
src/detection/gpu/gpu_apple.m
src/detection/host/host_apple.c
src/detection/host/host_mac.c
src/detection/icons/icons_nosupport.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_apple.c
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_bsd.c
src/detection/libc/libc_apple.c
@@ -774,7 +904,8 @@ elseif(APPLE)
src/detection/gamepad/gamepad_apple.c
src/detection/media/media_apple.m
src/detection/memory/memory_apple.c
src/detection/netio/netio_bsd.c
src/detection/mouse/mouse_apple.c
src/detection/netio/netio_apple.c
src/detection/opengl/opengl_apple.c
src/detection/os/os_apple.m
src/detection/packages/packages_apple.c
@@ -791,7 +922,7 @@ elseif(APPLE)
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_apple.m
src/detection/wifi/wifi_apple.m
src/detection/wm/wm_apple.c
src/detection/wm/wm_apple.m
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.m
src/detection/camera/camera_apple.m
@@ -811,6 +942,7 @@ elseif(WIN32)
src/detection/battery/battery_windows.c
src/detection/bios/bios_windows.c
src/detection/bluetooth/bluetooth_windows.c
src/detection/bluetooth/bluetooth_windows.cpp
src/detection/bluetoothradio/bluetoothradio_windows.c
src/detection/board/board_windows.c
src/detection/bootmgr/bootmgr_windows.c
@@ -829,9 +961,11 @@ elseif(WIN32)
src/detection/dns/dns_windows.c
src/detection/font/font_windows.c
src/detection/gpu/gpu_windows.c
src/detection/host/host_mac.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/initsystem/initsystem_nosupport.c
src/detection/keyboard/keyboard_windows.c
src/detection/libc/libc_windows.cpp
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_nosupport.c
@@ -840,10 +974,11 @@ elseif(WIN32)
src/detection/gamepad/gamepad_windows.c
src/detection/media/media_windows.c
src/detection/memory/memory_windows.c
src/detection/mouse/mouse_windows.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/netio/netio_windows.c
src/detection/opengl/opengl_windows.c
src/detection/os/os_windows.cpp
src/detection/os/os_windows.c
src/detection/packages/packages_windows.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_windows.c
@@ -868,6 +1003,7 @@ elseif(WIN32)
src/util/windows/registry.c
src/util/windows/unicode.c
src/util/windows/wmi.cpp
src/util/windows/version.c
src/util/platform/FFPlatform_windows.c
src/util/binary_windows.c
)
@@ -916,6 +1052,7 @@ elseif(SunOS)
src/detection/host/host_windows.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_nosupport.c
src/detection/libc/libc_nosupport.c
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_sunos.c
@@ -924,6 +1061,7 @@ elseif(SunOS)
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_linux.c
src/detection/memory/memory_sunos.c
src/detection/mouse/mouse_nosupport.c
src/detection/netio/netio_sunos.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_sunos.c
@@ -1004,6 +1142,14 @@ else()
endif()
endif()
if(ANDROID)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/vendor/lib64 -Wl,-rpath,/system/lib64")
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/vendor/lib -Wl,-rpath,/system/lib")
endif()
endif()
if(LINUX AND EXISTS "/lib/ld-musl-${CMAKE_HOST_SYSTEM_PROCESSOR}.so.1")
execute_process(COMMAND "/lib/ld-musl-${CMAKE_HOST_SYSTEM_PROCESSOR}.so.1"
ERROR_VARIABLE LD_MUSL_RESULT)
@@ -1018,24 +1164,58 @@ if(APPLE AND EXISTS "/usr/bin/otool")
target_compile_definitions(libfastfetch PUBLIC FF_LIBSYSTEM_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
if(FreeBSD AND EXISTS "/usr/local/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[^ )]*' -o | sort -Vru | head -1"
if(MidnightBSD AND EXISTS "/usr/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1"
OUTPUT_VARIABLE OBJDUMP_T_RESULT)
if("${OBJDUMP_T_RESULT}" MATCHES "FBSD_([0-9]+\\.[0-9]+)")
message(STATUS "Found FBSD ${CMAKE_MATCH_1}")
target_compile_definitions(libfastfetch PUBLIC FF_FBSD_VERSION="${CMAKE_MATCH_1}")
endif()
elseif(FreeBSD AND EXISTS "/usr/local/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1"
OUTPUT_VARIABLE OBJDUMP_T_RESULT)
if("${OBJDUMP_T_RESULT}" MATCHES "FBSD_([0-9]+\\.[0-9]+)")
message(STATUS "Found FBSD ${CMAKE_MATCH_1}")
target_compile_definitions(libfastfetch PUBLIC FF_FBSD_VERSION="${CMAKE_MATCH_1}")
endif()
elseif(DragonFly AND EXISTS "/usr/local/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'DF[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1"
OUTPUT_VARIABLE OBJDUMP_T_RESULT)
if("${OBJDUMP_T_RESULT}" MATCHES "DF([0-9]+\\.[0-9]+)")
message(STATUS "Found DF ${CMAKE_MATCH_1}")
target_compile_definitions(libfastfetch PUBLIC FF_DF_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
if(LINUX OR ANDROID)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1 _FILE_OFFSET_BITS=64)
if(LINUX)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE _ATFILE_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 _TIME_BITS=64) # "$<$<CONFIG:Release>:_FORTIFY_SOURCE=3>"
elseif(ANDROID)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE _FILE_OFFSET_BITS=64 "$<$<CONFIG:DEBUG>:__BIONIC_FORTIFY>" "$<$<CONFIG:DEBUG>:__BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED>")
elseif(WIN32)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN=1 _WIN32_WINNT=0x0A00)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00 NOMINMAX UNICODE) # "$<$<CONFIG:Release>:_FORTIFY_SOURCE=3>"
elseif(APPLE)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 _DARWIN_C_SOURCE)
elseif(OpenBSD)
target_compile_definitions(libfastfetch PUBLIC _XOPEN_SOURCE=700 _FILE_OFFSET_BITS=64 _BSD_SOURCE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/usr/X11R6/lib") # detect x11 lib path automatically
elseif(DragonFly)
target_compile_definitions(libfastfetch PUBLIC __FreeBSD__)
elseif(SunOS)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 __EXTENSIONS__ _POSIX_C_SOURCE)
elseif(NetBSD)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-char-subscripts")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/usr/X11R7/lib -Wl,-rpath,/usr/pkg/lib") # ditto
endif()
if(FreeBSD OR OpenBSD OR NetBSD)
include(CheckStructHasMember)
set(CMAKE_REQUIRED_DEFINITIONS "-D_IFI_OQDROPS=1")
CHECK_STRUCT_HAS_MEMBER("struct if_data" ifi_oqdrops net/if.h HAVE_IFI_OQDROPS LANGUAGE C)
if(HAVE_IFI_OQDROPS)
target_compile_definitions(libfastfetch PUBLIC _IFI_OQDROPS FF_HAVE_IFI_OQDROPS)
endif()
unset(CMAKE_REQUIRED_DEFINITIONS)
endif()
if(HAVE_STATX)
@@ -1062,6 +1242,9 @@ endif()
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
message(STATUS "Enabling custom link type: ${BINARY_LINK_TYPE}")
target_compile_definitions(libfastfetch PRIVATE FF_DISABLE_DLOPEN=1)
if(NOT WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--copy-dt-needed-entries")
endif()
endif()
function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
@@ -1117,18 +1300,10 @@ ff_lib_enable(XCB_RANDR
"xcb-randr"
"XcbRandr"
)
ff_lib_enable(XCB
"xcb"
"Xcb"
)
ff_lib_enable(XRANDR
"xrandr"
"XRandr"
)
ff_lib_enable(X11
"x11"
"X11"
)
ff_lib_enable(DRM
"libdrm"
"Libdrm"
@@ -1181,7 +1356,7 @@ ff_lib_enable(EGL
"egl"
"EGL"
)
if(NOT OpenBSD)
if(NOT OpenBSD AND NOT NetBSD)
ff_lib_enable(GLX
"glx"
"GLX"
@@ -1220,6 +1395,10 @@ ff_lib_enable(DIRECTX_HEADERS
"DirectX-Headers"
"DirectX-Headers"
)
ff_lib_enable(PCIACCESS
"pciaccess"
"pciaccess"
)
# The system <libzfs.h> is only usable on SunOS. We provide our local copy of it so it's always available.
if(ENABLE_LIBZFS)
if(BINARY_LINK_TYPE STREQUAL "dlopen")
@@ -1298,18 +1477,35 @@ elseif(WIN32)
PRIVATE "hid"
PRIVATE "wtsapi32"
PRIVATE "imagehlp"
PRIVATE "cfgmgr32"
PRIVATE "winbrand"
PRIVATE "propsys"
)
elseif(FreeBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "usbhid"
PRIVATE "geom"
PRIVATE "bluetooth"
)
if(NOT DragonFly)
target_link_libraries(libfastfetch
PRIVATE "geom"
)
else()
target_link_libraries(libfastfetch
PRIVATE "devstat"
)
endif()
elseif(OpenBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "kvm"
)
elseif(NetBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "prop"
)
elseif(SunOS)
target_link_libraries(libfastfetch
PRIVATE "m"
@@ -1362,9 +1558,9 @@ if(WIN32)
set(CMAKE_CXX_STANDARD 17)
endif()
if(FreeBSD)
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
endif()
if(LINUX OR FreeBSD)
if(LINUX OR FreeBSD OR OpenBSD OR NetBSD)
CHECK_INCLUDE_FILE("linux/videodev2.h" HAVE_LINUX_VIDEODEV2)
if(HAVE_LINUX_VIDEODEV2)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_VIDEODEV2=1)
@@ -1435,41 +1631,52 @@ target_link_libraries(fastfetch
PRIVATE libfastfetch
)
add_executable(flashfetch
src/flashfetch.c
)
target_compile_definitions(flashfetch
PRIVATE FASTFETCH_TARGET_BINARY_NAME=flashfetch
)
target_link_libraries(flashfetch
PRIVATE libfastfetch
)
# Prevent fastfetch from linking to libstdc++
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C)
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
if(WIN32)
target_sources(fastfetch
PRIVATE src/util/windows/version.rc
)
target_sources(flashfetch
PRIVATE src/util/windows/version.rc
)
elseif(APPLE)
target_link_options(fastfetch
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
)
target_link_options(flashfetch
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
)
endif()
if(BINARY_LINK_TYPE STREQUAL "static")
target_link_options(fastfetch PRIVATE "-static")
target_link_options(flashfetch PRIVATE "-static")
endif()
# Apply all above parameters to flashfetch if it is built
if (BUILD_FLASHFETCH)
add_executable(flashfetch
src/flashfetch.c
)
target_compile_definitions(flashfetch
PRIVATE FASTFETCH_TARGET_BINARY_NAME=flashfetch
)
target_link_libraries(flashfetch
PRIVATE libfastfetch
)
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
if(WIN32)
target_sources(flashfetch
PRIVATE src/util/windows/version.rc
)
elseif(APPLE)
target_link_options(flashfetch
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
)
endif()
if(BINARY_LINK_TYPE STREQUAL "static")
target_link_options(flashfetch PRIVATE "-static")
endif()
endif()
###################
@@ -1511,10 +1718,17 @@ endif()
include(GNUInstallDirs)
install(
TARGETS fastfetch flashfetch
TARGETS fastfetch
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
if (TARGET flashfetch)
install(
TARGETS flashfetch
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
endif()
if (TARGET ffwinrt)
install(
TARGETS ffwinrt
@@ -1614,4 +1828,4 @@ fastfetch is a neofetch-like tool for fetching system information and displaying
It is written mostly in C to achieve much better performance.\
")
include(CPack)
include(CPack)
+34 -2
View File
@@ -40,7 +40,6 @@ Some distros package an outdated fastfetch version. Older versions receive no su
* openSUSE: `zypper install fastfetch`
* ALT Linux: `apt-get install fastfetch`
* Exherbo: `cave resolve --execute app-misc/fastfetch`
* GNU Guix: `guix install fastfetch`
* Solus: `eopkg install fastfetch`
* Slackware: `sbopkg -i fastfetch`
* Void Linux: `xbps-install fastfetch`
@@ -194,16 +193,49 @@ See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096).
Neofetch incorrectly counts `rc` packages ( the package has been removed, but that the configuration files remain ). Bug https://github.com/dylanaraps/neofetch/issues/2278
### Q: I use Debian / Ubuntu / Debian deserved distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is it a bug?
### Q: I use Debian / Ubuntu / Debian derived distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is it a bug?
Try upgrading `pci.ids`: Download <https://pci-ids.ucw.cz/v2.2/pci.ids> and overwrite file `/usr/share/hwdata/pci.ids`. For AMD GPUs, you should also upgrade `amdgpu.ids`: Download <https://gitlab.freedesktop.org/mesa/drm/-/raw/main/data/amdgpu.ids> and overwrite file `/usr/share/libdrm/amdgpu.ids`
Alternatively, you may try to use `fastfetch --gpu-driver-specific`, so that `fastfetch` will try to ask the driver for GPU name if supported.
### Q: I get error `Authorization required, but no authorization protocol specified` when running fastfetch in root
Try `export XAUTHORITY=$HOME/.Xauthority`
### Q: Fastfetch cannot detect my awesome 3rd-party macOS window manager!
Try `fastfetch --wm-detect-plugin`. See also [#984](https://github.com/fastfetch-cli/fastfetch/issues/984)
### Q: How can I change the colors of my ASCII logo?
Try `fastfetch --logo-color-[1-9] <color>`. `[1-9]` is the index of color placeholders.
For example: `fastfetch --logo-color-1 red --logo-color-2 green`.
In JSONC, you can use:
```jsonc
{
"logo": {
"color": {
"1": "red",
"2": "green"
}
}
}
```
### Q: How to hide a key?
Set the key to a white space.
```jsonc
{
"key": " "
}
```
### Q: I want feature A / B / C. Will fastfetch support it?
Fastfetch is a system information tool. We only accept hardware or system level software feature requests. For most personal uses, I recommend using `Command` module to detect it yourself, which can be used to grab output from a custom shell script:
+3 -3
View File
@@ -26,7 +26,7 @@ def main():
for flag in data[key]:
if flag["long"] == "logo-color-[1-9]":
for i in range(1, 10):
command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
command_prefix = f"--logo-color-{i}[{flag['desc']} ({i})]"
print_command(command_prefix, flag)
continue
@@ -34,11 +34,11 @@ def main():
continue
if "short" in flag:
command_prefix = f"-{flag["short"]}[{flag["desc"]}]"
command_prefix = f"-{flag['short']}[{flag['desc']}]"
print_command(command_prefix, flag)
if "long" in flag:
command_prefix = f"--{flag["long"]}[{flag["desc"]}]"
command_prefix = f"--{flag['long']}[{flag['desc']}]"
print_command(command_prefix, flag)
+54
View File
@@ -1,3 +1,57 @@
fastfetch (2.34.0) jammy; urgency=medium
* Update to 2.34.0
-- Carter Li <zhangsongcui@live.cn> Thu, 09 Jan 2025 09:03:17 +0800
fastfetch (2.33.0) jammy; urgency=medium
* Update to 2.33.0
-- Carter Li <zhangsongcui@live.cn> Thu, 26 Dec 2024 09:42:27 +0800
fastfetch (2.32.0) jammy; urgency=medium
* Update to 2.32.0
-- Carter Li <zhangsongcui@live.cn> Wed, 18 Dec 2024 10:39:06 +0800
fastfetch (2.31.0) jammy; urgency=medium
* Update to 2.31.0
-- Carter Li <zhangsongcui@live.cn> Wed, 04 Dec 2024 08:41:40 +0800
fastfetch (2.30.1) jammy; urgency=medium
* Update to 2.30.1
-- Carter Li <zhangsongcui@live.cn> Mon, 18 Nov 2024 15:40:48 +0800
fastfetch (2.30.0) jammy; urgency=medium
* Update to 2.30.0
-- Carter Li <zhangsongcui@live.cn> Mon, 18 Nov 2024 09:30:58 +0800
fastfetch (2.29.0) jammy; urgency=medium
* Update to 2.29.0
-- Carter Li <zhangsongcui@live.cn> Mon, 04 Nov 2024 15:05:02 +0800
fastfetch (2.28.0) jammy; urgency=medium
* Update to 2.28.0
-- Carter Li <zhangsongcui@live.cn> Wed, 23 Oct 2024 10:18:59 +0800
fastfetch (2.27.1) jammy; urgency=medium
* Update to 2.27.1
-- Carter Li <zhangsongcui@live.cn> Sun, 06 Oct 2024 12:55:18 +0800
fastfetch (2.26.1ubuntu1) jammy; urgency=medium
* Update correct code
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.26.1ubuntu1_source.buildinfo universe/utils optional
fastfetch_2.34.0_source.buildinfo universe/utils optional
+1462 -248
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -74,7 +74,8 @@
"showSpeed": true,
"showMtu": true,
"showLoop": true,
"showFlags": true
"showFlags": true,
"showAllIps": true
},
"dns",
"wifi",
+4 -3
View File
@@ -76,7 +76,8 @@
"showSpeed": true,
"showMtu": true,
"showLoop": true,
"showFlags": true
"showFlags": true,
"showAllIps": true
},
"dns",
"wifi",
@@ -86,8 +87,8 @@
"opengl",
"opencl",
"users",
"bluetooth",
"bluetoothradio",
// "bluetooth", // doesn't work on macOS because it requires bluetooth permissions
// "bluetoothradio",
"sound",
"camera",
"gamepad",
+16 -12
View File
@@ -5,18 +5,22 @@ set -e
mkdir -p build/
cd build/
if [ -z "${CMAKE_BUILD_TYPE}" ]; then
CMAKE_BUILD_TYPE=Release
fi
cmake "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" ..
cmake ..
if [ -z "$OSTYPE" ] || [ "$OSTYPE" = "linux-gnu" ]; then
cmake_build_args="-j$(nproc)"
elif [ "$OSTYPE" = "darwin" ]; then
cmake_build_args="-j$(sysctl -n hw.ncpu)"
else
cmake_build_args=""
fi
cmake --build . --target fastfetch ${cmake_build_args}
kernel_name="$(uname -s)"
case "${kernel_name}" in
"Linux" | "MINGW"*)
cmake_build_args="-j$(nproc)"
;;
"Darwin" | *"BSD" | "DragonFly")
cmake_build_args="-j$(sysctl -n hw.ncpu)"
;;
*)
cmake_build_args=""
;;
esac
cmake --build . --target fastfetch "${cmake_build_args}"
./fastfetch "$@"
+258
View File
@@ -0,0 +1,258 @@
#!/usr/bin/env python3
"""
Python script to generate a man page for the command `fastfetch`.
The man content will be printed to stdout so you will need to
pipe it to a file if you want to save it.
The command options will be generated using a JSON file.
For the format of the JSON file, see https://github.com/fastfetch-cli/fastfetch/blob/dev/src/data/help.json
"""
from json import load
from datetime import datetime, timezone
from time import time
from re import search
from os import environ, path
###### Text Decorations Tags ######
startUnderline = r"\fI" # start underline text tag
endUnderline = r"\fR" # end underline text tag
startBold = r"\fB" # start bold text tag
endBold = r"\fR" # end bold text tag
###### Parameters ######
# path to the current directory
pathToCurrentDir = path.dirname(__file__)
# path to the JSON option file
pathToHelpFile = path.join(pathToCurrentDir, "../src/data/help.json")
# man page section
manSection = 1
# title (center header)
titlePage = "Fastfetch man page"
# date (center footer)
# format : "Month (abbreviation) Day Year"
todayDate = datetime.fromtimestamp(
int(environ.get("SOURCE_DATE_EPOCH", time())),
tz=timezone.utc,
).strftime("%b %d %Y")
# file to fastfetch version (left footer)
pathToVersionFile = path.join(pathToCurrentDir, "../CMakeLists.txt")
###### Sections Text ######
# text displayed in the "NAME" section
nameSection = r"fastfetch \- A maintained, feature\-rich and performance oriented, neofetch like system information tool"
# text displayed at the beginning of the "OPTIONS" section
optionSection = r"""
Parsing is not case sensitive. E.g. \fB--logo-type\fR is
equal to \fB--LOGO-TYPE\fR.
If a value is between square brackets, it is optional.
An optional boolean value defaults to true if not specified.
More detailed help messages for each options can be printed
with \fB-h <option_without_dash_prefix>\fR.
All options can be made permanent with command
\fBfastfetch <options> --gen-config\fR.
"""
# text displayed in the "CONFIGURATION"
configurationSection = f"""
.SS Fetch Structure
The structure of a fetch describes the modules that should
be included in the output. It consists of a string of modules,
separated by a colon (:). To list all available modules,
use --list-modules.
.SS Config Files
Fastfetch uses JSONC based format for configuration.
Fastfetch doesn't generate config file automatically;
it should be generated manually by {startBold}--gen-config{endBold}.
The config file will be saved in
{startBold}~/.config/fastfetch/config.jsonc{endBold} by default.
A JSONC config file is a JSON file that also supports comments
with (// and /* */). Those files must have the extension '.jsonc'.
The specified configuration/preset files are searched in the following order:
{startBold}1.{endBold} relative to the current working directory
{startBold}2.{endBold} relative to ~/.local/share/fastfetch/presets/
{startBold}3.{endBold} relative to /usr/share/fastfetch/presets/
Fastfetch provides some default presets. List them with --list-presets.
"""
# text displayed in the "EXAMPLE" section
exampleSection = """
.SS Config files:
.nf
// ~/.config/fastfetch/config.jsonc
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"modules": [
"title",
"separator",
"module1",
{
"type": "module2",
"module2-option": "value"
}
]
}
.fi
"""
# text displayed in the "BUGS" section
bugSection = "Please report bugs to : \
https://github.com/fastfetch-cli/fastfetch/issues"
# text displayed in the "WIKI" section
wikiSection = "Fastfetch github wiki : https://github.com/fastfetch-cli/fastfetch/wiki/Configuration"
###### Argument decoration ######
### optional arguments tags ###
# if an optional argument is displayed as [?optArg] (with "optArg" underlined)
# this value should be f"[?{startUnderline}"
startOptionalArgument = f"[{startUnderline}?"
# if an optional argument is displayed as [?optArg] (with "optArg underlined")
# this value should be f"{endUnderline}]"
endOptionalArgument = f"{endUnderline}]"
### mandatory arguments tags ###
startMandatoryArgument = f"{startUnderline}"
endMandatoryArgument = f"{endUnderline}"
def main():
# importing the JSON file
with open(pathToHelpFile, 'r') as jsonFile:
helpFileData = load(jsonFile) # json.load
######## Start printing the generated .1 file ########
###### header, footer & config #####
print(f".TH FASTFETCH {manSection} ", end=" ")
print(f"\"{todayDate}\"", end=" ")
# version number
with open(pathToVersionFile, 'r') as versionFile:
# research version number in file with regex
for line in versionFile:
researchVersion = search(r"^\s*VERSION (\d+\.\d+\.\d+)$", line)
if (researchVersion):
print(f"\"{researchVersion.group(1)}\"", end=" ")
break
print(f"\"{titlePage}\"")
###### Name ######
print(".SH NAME")
print(nameSection)
##### Synopsis ######
print(".SH SYNOPSIS")
print(".B fastfetch")
print(f"[{startUnderline}OPTIONS{endUnderline}]")\
###### Wiki ######
print(".SH WIKI")
print(wikiSection)
###### Configuration ######
print(".SH CONFIGURATION")
print(configurationSection)
###### Options ######
print(".SH OPTIONS")
print(optionSection)
print()
# loop through every options sections
for key, value in helpFileData.items():
# print new subsection
print(f".SS {key}:")
# loop through every option in a section
for option in value:
# list of existing keys for this option
keyList = option.keys()
# start a new "option" entry
print(".TP")
print(startBold, end="")
# short option (-opt)
if "short" in keyList:
print(fr"\-{ option['short'] }", end="")
# if also have a long option, print a comma
if "long" in keyList:
print(", ", end="")
# long option (--option)
if "long" in keyList:
print(fr"\-\-{ option['long'] }", end="")
print(endBold, end=" ")
# arguments
if "arg" in keyList:
# if argument is optional, print "[arg]"
if "optional" in option["arg"].keys() and option["arg"]["optional"]:
print(startOptionalArgument + option['arg']['type'] + endOptionalArgument, end="")
# if argument is mandatory, print "arg"
else:
print(startMandatoryArgument + option['arg']['type'] + endMandatoryArgument, end="")
# description
print(f"\n {option['desc']} \n")
###### Examples ######
print(".SH EXAMPLES")
print(exampleSection)
###### Bugs ######
print(".SH BUGS")
print(bugSection)
if __name__ == "__main__":
main()
Regular → Executable
+2
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env python3
from requests import get as http_get
class PciDeviceModel:
+2 -2
View File
@@ -171,7 +171,7 @@ DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const c
if (arg)
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, FF_DBUS_TIMEOUT_MILLISECONDS, NULL);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
dbus->lib->ffdbus_message_unref(message);
@@ -189,7 +189,7 @@ DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char
DBUS_TYPE_STRING, &property,
DBUS_TYPE_INVALID);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, FF_DBUS_TIMEOUT_MILLISECONDS, NULL);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
dbus->lib->ffdbus_message_unref(message);
+5 -2
View File
@@ -6,8 +6,6 @@
#include "util/FFstrbuf.h"
#include "common/library.h"
#define FF_DBUS_TIMEOUT_MILLISECONDS 100
typedef struct FFDBusLibrary
{
FF_LIBRARY_SYMBOL(dbus_bus_get)
@@ -38,4 +36,9 @@ DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char
bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result);
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result);
static inline DBusMessage* ffDBusGetAllProperties(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface)
{
return ffDBusGetMethodReply(dbus, busName, objectPath, "org.freedesktop.DBus.Properties", "GetAll", interface);
}
#endif // FF_HAVE_DBUS
+5 -5
View File
@@ -51,7 +51,7 @@ static void fontInitPretty(FFfont* font)
for(uint32_t i = 0; i < font->styles.length; i++)
{
ffStrbufAppend(&font->pretty, ffListGet(&font->styles, i));
ffStrbufAppend(&font->pretty, FF_LIST_GET(FFstrbuf, font->styles, i));
if(i < font->styles.length - 1)
ffStrbufAppendS(&font->pretty, ", ");
@@ -86,7 +86,7 @@ void ffFontInitQt(FFfont* font, const char* data)
{
do
{
FFstrbuf* style = ffListAdd(&font->styles);
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInit(style);
data = ffStrbufAppendSUntilC(style, data, ' ');
if (data) data++;
@@ -142,7 +142,7 @@ static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* altern
) {
if(alternativeBuffer == NULL)
{
alternativeBuffer = ffListAdd(&font->styles);
alternativeBuffer = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInit(alternativeBuffer);
}
@@ -215,7 +215,7 @@ void ffFontDestroy(FFfont* font)
ffStrbufDestroy(&font->name);
ffStrbufDestroy(&font->size);
for(uint32_t i = 0; i < font->styles.length; i++)
ffStrbufDestroy(ffListGet(&font->styles, i));
FF_LIST_FOR_EACH(FFstrbuf, str, font->styles)
ffStrbufDestroy(str);
ffListDestroy(&font->styles);
}
+3 -3
View File
@@ -42,10 +42,10 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
break;
case FF_FORMAT_ARG_TYPE_LIST:
{
const FFlist* list = formatarg->value;
const FFlist* list = (const FFlist*) formatarg->value;
for(uint32_t i = 0; i < list->length; i++)
{
ffStrbufAppend(buffer, ffListGet(list, i));
ffStrbufAppend(buffer, FF_LIST_GET(FFstrbuf, *list, i));
if(i < list->length - 1)
ffStrbufAppendS(buffer, ", ");
}
@@ -110,7 +110,7 @@ static inline bool formatArgSet(const FFformatarg* arg)
(arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value > 0.0) || //Also is false for NaN
(arg->type == FF_FORMAT_ARG_TYPE_INT && *(int*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_STRBUF && ((FFstrbuf*)arg->value)->length > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet(arg->value)) ||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet((char*)arg->value)) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) ||
+3 -5
View File
@@ -2,7 +2,7 @@
#include "util/FFstrbuf.h"
typedef enum FFformatArgType
typedef enum __attribute__((__packed__)) FFformatArgType
{
FF_FORMAT_ARG_TYPE_NULL = 0,
FF_FORMAT_ARG_TYPE_UINT,
@@ -42,7 +42,5 @@ typedef struct FFformatarg
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PARSE_FORMAT_STRING_CHECKED(buffer, formatstr, numArgs, arguments) do {\
static_assert(sizeof(arguments) / sizeof(*(arguments)) == (numArgs), "Invalid number of format arguments");\
ffParseFormatString((buffer), (formatstr), (numArgs), (arguments));\
} while (0)
#define FF_PARSE_FORMAT_STRING_CHECKED(buffer, formatstr, arguments) \
ffParseFormatString((buffer), (formatstr), sizeof(arguments) / sizeof(*arguments), (arguments));
+8 -11
View File
@@ -76,19 +76,21 @@ static void resetConsole(void)
}
#ifdef _WIN32
BOOL WINAPI consoleHandler(DWORD signal)
BOOL WINAPI consoleHandler(FF_MAYBE_UNUSED DWORD signal)
{
FF_UNUSED(signal);
resetConsole();
exit(0);
}
#else
static void exitSignalHandler(int signal)
static void exitSignalHandler(FF_MAYBE_UNUSED int signal)
{
FF_UNUSED(signal);
resetConsole();
exit(0);
}
static void chldSignalHandler(FF_MAYBE_UNUSED int signal)
{
// empty; used to interrupt the poll and read syscalls
}
#endif
void ffStart(void)
@@ -118,6 +120,7 @@ void ffStart(void)
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
sigaction(SIGQUIT, &action, NULL);
sigaction(SIGCHLD, &(struct sigaction) { .sa_handler = chldSignalHandler }, NULL);
#endif
//reset everything to default before we start printing
@@ -179,15 +182,9 @@ void ffListFeatures(void)
#if FF_HAVE_XCB_RANDR
"xcb-randr\n"
#endif
#if FF_HAVE_XCB
"xcb\n"
#endif
#if FF_HAVE_XRANDR
"xrandr\n"
#endif
#if FF_HAVE_X11
"x11\n"
#endif
#if FF_HAVE_DRM
"drm\n"
#endif
@@ -245,7 +242,7 @@ void ffListFeatures(void)
#if FF_HAVE_DDCUTIL
"libddcutil\n"
#endif
#if FF_HAVE_ELF || __sun || __FreeBSD__ || __OpenBSD__
#if FF_HAVE_ELF || __sun || (__FreeBSD__ && !__DragonFly__) || __OpenBSD__ || __NetBSD__
"libelf\n"
#endif
#if FF_HAVE_LIBZFS
+36 -1
View File
@@ -13,6 +13,8 @@
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
#include <limits.h>
typedef int FFNativeFD;
#define FF_INVALID_FD (-1)
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
@@ -66,9 +68,11 @@ static inline ssize_t ffReadFDData(FFNativeFD fd, size_t dataSize, void* data)
}
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data);
ssize_t ffReadFileDataRelative(FFNativeFD dfd, const char* fileName, size_t dataSize, void* data);
bool ffAppendFDBuffer(FFNativeFD fd, FFstrbuf* buffer);
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer);
bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer);
static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
{
@@ -76,12 +80,19 @@ static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
return ffAppendFileBuffer(fileName, buffer);
}
static inline bool ffReadFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer)
{
ffStrbufClear(buffer);
return ffAppendFileBufferRelative(dfd, fileName, buffer);
}
//Bit flags, combine with |
typedef enum FFPathType
typedef enum __attribute__((__packed__)) FFPathType
{
FF_PATHTYPE_FILE = 1 << 0,
FF_PATHTYPE_DIRECTORY = 1 << 1,
FF_PATHTYPE_ANY = FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY,
FF_PATHTYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFPathType;
static inline bool ffPathExists(const char* path, FFPathType pathType)
@@ -108,6 +119,7 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
}
else
{
#if __APPLE__ // #1395
struct stat fileStat;
if(stat(path, &fileStat) != 0)
return false;
@@ -119,6 +131,24 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
return true;
#else
size_t len = strlen(path);
assert(len < PATH_MAX);
if (len == 0) return false;
int ret;
if (path[len - 1] != '/')
{
char buf[PATH_MAX + 1];
memcpy(buf, path, len);
buf[len] = '/';
buf[len + 1] = 0;
ret = access(buf, F_OK);
}
else
ret = access(path, F_OK);
return pathType == FF_PATHTYPE_DIRECTORY ? ret == 0 : ret == -1 && errno == ENOTDIR;
#endif
}
#endif
@@ -211,3 +241,8 @@ static inline bool ffSearchUserConfigFile(const FFlist* configDirs, const char*
return false;
}
#ifdef _WIN32
// Only O_RDONLY is supported
HANDLE openat(HANDLE dfd, const char* fileName, bool directory);
#endif
+24 -5
View File
@@ -1,6 +1,7 @@
#include "io.h"
#include "fastfetch.h"
#include "util/stringUtils.h"
#include "common/time.h"
#include <fcntl.h>
#include <termios.h>
@@ -37,7 +38,7 @@ static void createSubfolders(const char* fileName)
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
{
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
int openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
mode_t openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
if(fd == -1)
@@ -108,6 +109,15 @@ ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
return ffReadFDData(fd, dataSize, data);
}
ssize_t ffReadFileDataRelative(int dfd, const char* fileName, size_t dataSize, void* data)
{
int FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC);
if(fd == -1)
return -1;
return ffReadFDData(fd, dataSize, data);
}
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
{
int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY | O_CLOEXEC);
@@ -117,6 +127,15 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
return ffAppendFDBuffer(fd, buffer);
}
bool ffAppendFileBufferRelative(int dfd, const char* fileName, FFstrbuf* buffer)
{
int FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC);
if(fd == -1)
return false;
return ffAppendFDBuffer(fd, buffer);
}
bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* out)
{
bool result = false;
@@ -127,10 +146,10 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
if (wordexp(in, &exp, 0) != 0)
return false;
if (exp.we_wordc == 1)
if (exp.we_wordc >= 1)
{
result = true;
ffStrbufSetS(out, exp.we_wordv[0]);
ffStrbufSetS(out, exp.we_wordv[exp.we_wordc > 1 ? ffTimeGetNow() % exp.we_wordc : 0]);
}
wordfree(&exp);
@@ -141,10 +160,10 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
if (glob(in, GLOB_NOSORT | GLOB_TILDE, NULL, &gb) != 0)
return false;
if (gb.gl_matchc == 1)
if (gb.gl_matchc >= 1)
{
result = true;
ffStrbufSetS(out, gb.gl_pathv[0]);
ffStrbufSetS(out, gb.gl_pathv[gb.gl_matchc > 1 ? ffTimeGetNow() % gb.gl_matchc : 0]);
}
globfree(&gb);
+46 -1
View File
@@ -3,6 +3,8 @@
#include "util/stringUtils.h"
#include <windows.h>
#include <ntstatus.h>
#include <winternl.h>
static void createSubfolders(const char* fileName)
{
@@ -38,7 +40,7 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
static inline void readWithLength(HANDLE handle, FFstrbuf* buffer, uint32_t length)
{
ffStrbufEnsureFixedLengthFree(buffer, length);
ffStrbufEnsureFree(buffer, length);
DWORD bytesRead = 0;
while(
length > 0 &&
@@ -100,6 +102,49 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
return ffAppendFDBuffer(handle, buffer);
}
HANDLE openat(HANDLE dfd, const char* fileName, bool directory)
{
NTSTATUS ret;
UNICODE_STRING fileNameW;
ret = RtlAnsiStringToUnicodeString(&fileNameW, &(ANSI_STRING) {
.Length = (USHORT) strlen(fileName),
.Buffer = (PCHAR) fileName
}, TRUE);
if (!NT_SUCCESS(ret)) return INVALID_HANDLE_VALUE;
FF_AUTO_CLOSE_FD HANDLE hFile;
IO_STATUS_BLOCK iosb = {};
ret = NtOpenFile(&hFile, FILE_READ_DATA | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) {
.Length = sizeof(OBJECT_ATTRIBUTES),
.RootDirectory = dfd,
.ObjectName = &fileNameW,
}, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE));
RtlFreeUnicodeString(&fileNameW);
if(!NT_SUCCESS(ret) || iosb.Information != FILE_OPENED)
return INVALID_HANDLE_VALUE;
return hFile;
}
bool ffAppendFileBufferRelative(HANDLE dfd, const char* fileName, FFstrbuf* buffer)
{
HANDLE FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, false);
if(fd == INVALID_HANDLE_VALUE)
return false;
return ffAppendFDBuffer(fd, buffer);
}
ssize_t ffReadFileDataRelative(HANDLE dfd, const char* fileName, size_t dataSize, void* data)
{
HANDLE FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, false);
if(fd == INVALID_HANDLE_VALUE)
return -1;
return ffReadFDData(fd, dataSize, data);
}
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
{
DWORD length = ExpandEnvironmentStringsA(in, NULL, 0);
+11
View File
@@ -29,6 +29,17 @@ static void* libraryLoad(const char* path, int maxVersion)
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
FF_UNUSED(maxVersion)
if(result != NULL)
return result;
uint32_t pathLen = ffStrbufLastIndexC(&instance.state.platform.exePath, '/');
if (pathLen == instance.state.platform.exePath.length)
return result;
char absPath[MAX_PATH + 1];
strcpy(mempcpy(absPath, instance.state.platform.exePath.chars, pathLen + 1), path);
return dlopen(absPath, FF_DLOPEN_FLAGS);
#else
if(result != NULL || maxVersion < 0)
-20
View File
@@ -43,11 +43,6 @@ static inline void ffLibraryUnload(void** handle)
if(symbolMapping == NULL) \
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, symbolMapping, symbolName, alternateName, returnValue) \
symbolMapping = dlsym(library, #symbolName); \
if(symbolMapping == NULL && !(symbolMapping = (__typeof__(&symbolName)) dlsym(library, #alternateName))) \
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
@@ -57,18 +52,12 @@ static inline void ffLibraryUnload(void** handle)
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE2(library, symbolName, alternateName) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue);
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
@@ -87,9 +76,6 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...);
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
symbolMapping = (__typeof__(&symbolName)) &symbolName
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, symbolMapping, symbolName, alternateName, returnValue) \
symbolMapping = (__typeof__(&symbolName)) &symbolName
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
@@ -99,18 +85,12 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...);
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE2(library, symbolName, alternateName) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue);
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
+73 -71
View File
@@ -5,65 +5,65 @@ static FFModuleBaseInfo* A[] = {
};
static FFModuleBaseInfo* B[] = {
(void*) &instance.config.modules.battery,
(void*) &instance.config.modules.bios,
(void*) &instance.config.modules.bluetooth,
(void*) &instance.config.modules.bluetoothRadio,
(void*) &instance.config.modules.board,
(void*) &instance.config.modules.bootmgr,
(void*) &instance.config.modules.break_,
(void*) &instance.config.modules.brightness,
(void*) &instance.config.modules.btrfs,
(FFModuleBaseInfo*) &instance.config.modules.battery,
(FFModuleBaseInfo*) &instance.config.modules.bios,
(FFModuleBaseInfo*) &instance.config.modules.bluetooth,
(FFModuleBaseInfo*) &instance.config.modules.bluetoothRadio,
(FFModuleBaseInfo*) &instance.config.modules.board,
(FFModuleBaseInfo*) &instance.config.modules.bootmgr,
(FFModuleBaseInfo*) &instance.config.modules.break_,
(FFModuleBaseInfo*) &instance.config.modules.brightness,
(FFModuleBaseInfo*) &instance.config.modules.btrfs,
NULL,
};
static FFModuleBaseInfo* C[] = {
(void*) &instance.config.modules.camera,
(void*) &instance.config.modules.chassis,
(void*) &instance.config.modules.command,
(void*) &instance.config.modules.colors,
(void*) &instance.config.modules.cpu,
(void*) &instance.config.modules.cpuCache,
(void*) &instance.config.modules.cpuUsage,
(void*) &instance.config.modules.cursor,
(void*) &instance.config.modules.custom,
(FFModuleBaseInfo*) &instance.config.modules.camera,
(FFModuleBaseInfo*) &instance.config.modules.chassis,
(FFModuleBaseInfo*) &instance.config.modules.command,
(FFModuleBaseInfo*) &instance.config.modules.colors,
(FFModuleBaseInfo*) &instance.config.modules.cpu,
(FFModuleBaseInfo*) &instance.config.modules.cpuCache,
(FFModuleBaseInfo*) &instance.config.modules.cpuUsage,
(FFModuleBaseInfo*) &instance.config.modules.cursor,
(FFModuleBaseInfo*) &instance.config.modules.custom,
NULL,
};
static FFModuleBaseInfo* D[] = {
(void*) &instance.config.modules.dateTime,
(void*) &instance.config.modules.de,
(void*) &instance.config.modules.display,
(void*) &instance.config.modules.disk,
(void*) &instance.config.modules.diskIo,
(void*) &instance.config.modules.dns,
(FFModuleBaseInfo*) &instance.config.modules.dateTime,
(FFModuleBaseInfo*) &instance.config.modules.de,
(FFModuleBaseInfo*) &instance.config.modules.display,
(FFModuleBaseInfo*) &instance.config.modules.disk,
(FFModuleBaseInfo*) &instance.config.modules.diskIo,
(FFModuleBaseInfo*) &instance.config.modules.dns,
NULL,
};
static FFModuleBaseInfo* E[] = {
(void*) &instance.config.modules.editor,
(FFModuleBaseInfo*) &instance.config.modules.editor,
NULL,
};
static FFModuleBaseInfo* F[] = {
(void*) &instance.config.modules.font,
(FFModuleBaseInfo*) &instance.config.modules.font,
NULL,
};
static FFModuleBaseInfo* G[] = {
(void*) &instance.config.modules.gamepad,
(void*) &instance.config.modules.gpu,
(FFModuleBaseInfo*) &instance.config.modules.gamepad,
(FFModuleBaseInfo*) &instance.config.modules.gpu,
NULL,
};
static FFModuleBaseInfo* H[] = {
(void*) &instance.config.modules.host,
(FFModuleBaseInfo*) &instance.config.modules.host,
NULL,
};
static FFModuleBaseInfo* I[] = {
(void*) &instance.config.modules.icons,
(void*) &instance.config.modules.initSystem,
(FFModuleBaseInfo*) &instance.config.modules.icons,
(FFModuleBaseInfo*) &instance.config.modules.initSystem,
NULL,
};
@@ -72,45 +72,47 @@ static FFModuleBaseInfo* J[] = {
};
static FFModuleBaseInfo* K[] = {
(void*) &instance.config.modules.kernel,
(FFModuleBaseInfo*) &instance.config.modules.kernel,
(FFModuleBaseInfo*) &instance.config.modules.keyboard,
NULL,
};
static FFModuleBaseInfo* L[] = {
(void*) &instance.config.modules.lm,
(void*) &instance.config.modules.loadavg,
(void*) &instance.config.modules.locale,
(void*) &instance.config.modules.localIP,
(FFModuleBaseInfo*) &instance.config.modules.lm,
(FFModuleBaseInfo*) &instance.config.modules.loadavg,
(FFModuleBaseInfo*) &instance.config.modules.locale,
(FFModuleBaseInfo*) &instance.config.modules.localIP,
NULL,
};
static FFModuleBaseInfo* M[] = {
(void*) &instance.config.modules.media,
(void*) &instance.config.modules.memory,
(void*) &instance.config.modules.monitor,
(FFModuleBaseInfo*) &instance.config.modules.media,
(FFModuleBaseInfo*) &instance.config.modules.memory,
(FFModuleBaseInfo*) &instance.config.modules.monitor,
(FFModuleBaseInfo*) &instance.config.modules.mouse,
NULL,
};
static FFModuleBaseInfo* N[] = {
(void*) &instance.config.modules.netIo,
(FFModuleBaseInfo*) &instance.config.modules.netIo,
NULL,
};
static FFModuleBaseInfo* O[] = {
(void*) &instance.config.modules.openCL,
(void*) &instance.config.modules.openGL,
(void*) &instance.config.modules.os,
(FFModuleBaseInfo*) &instance.config.modules.openCL,
(FFModuleBaseInfo*) &instance.config.modules.openGL,
(FFModuleBaseInfo*) &instance.config.modules.os,
NULL,
};
static FFModuleBaseInfo* P[] = {
(void*) &instance.config.modules.packages,
(void*) &instance.config.modules.physicalDisk,
(void*) &instance.config.modules.physicalMemory,
(void*) &instance.config.modules.player,
(void*) &instance.config.modules.powerAdapter,
(void*) &instance.config.modules.processes,
(void*) &instance.config.modules.publicIP,
(FFModuleBaseInfo*) &instance.config.modules.packages,
(FFModuleBaseInfo*) &instance.config.modules.physicalDisk,
(FFModuleBaseInfo*) &instance.config.modules.physicalMemory,
(FFModuleBaseInfo*) &instance.config.modules.player,
(FFModuleBaseInfo*) &instance.config.modules.powerAdapter,
(FFModuleBaseInfo*) &instance.config.modules.processes,
(FFModuleBaseInfo*) &instance.config.modules.publicIP,
NULL,
};
@@ -123,42 +125,42 @@ static FFModuleBaseInfo* R[] = {
};
static FFModuleBaseInfo* S[] = {
(void*) &instance.config.modules.separator,
(void*) &instance.config.modules.shell,
(void*) &instance.config.modules.sound,
(void*) &instance.config.modules.swap,
(FFModuleBaseInfo*) &instance.config.modules.separator,
(FFModuleBaseInfo*) &instance.config.modules.shell,
(FFModuleBaseInfo*) &instance.config.modules.sound,
(FFModuleBaseInfo*) &instance.config.modules.swap,
NULL,
};
static FFModuleBaseInfo* T[] = {
(void*) &instance.config.modules.terminal,
(void*) &instance.config.modules.terminalFont,
(void*) &instance.config.modules.terminalSize,
(void*) &instance.config.modules.terminalTheme,
(void*) &instance.config.modules.title,
(void*) &instance.config.modules.theme,
(void*) &instance.config.modules.tpm,
(FFModuleBaseInfo*) &instance.config.modules.terminal,
(FFModuleBaseInfo*) &instance.config.modules.terminalFont,
(FFModuleBaseInfo*) &instance.config.modules.terminalSize,
(FFModuleBaseInfo*) &instance.config.modules.terminalTheme,
(FFModuleBaseInfo*) &instance.config.modules.title,
(FFModuleBaseInfo*) &instance.config.modules.theme,
(FFModuleBaseInfo*) &instance.config.modules.tpm,
NULL,
};
static FFModuleBaseInfo* U[] = {
(void*) &instance.config.modules.uptime,
(void*) &instance.config.modules.users,
(FFModuleBaseInfo*) &instance.config.modules.uptime,
(FFModuleBaseInfo*) &instance.config.modules.users,
NULL,
};
static FFModuleBaseInfo* V[] = {
(void*) &instance.config.modules.version,
(void*) &instance.config.modules.vulkan,
(FFModuleBaseInfo*) &instance.config.modules.version,
(FFModuleBaseInfo*) &instance.config.modules.vulkan,
NULL,
};
static FFModuleBaseInfo* W[] = {
(void*) &instance.config.modules.wallpaper,
(void*) &instance.config.modules.weather,
(void*) &instance.config.modules.wm,
(void*) &instance.config.modules.wifi,
(void*) &instance.config.modules.wmTheme,
(FFModuleBaseInfo*) &instance.config.modules.wallpaper,
(FFModuleBaseInfo*) &instance.config.modules.weather,
(FFModuleBaseInfo*) &instance.config.modules.wm,
(FFModuleBaseInfo*) &instance.config.modules.wifi,
(FFModuleBaseInfo*) &instance.config.modules.wmTheme,
NULL,
};
@@ -171,7 +173,7 @@ static FFModuleBaseInfo* Y[] = {
};
static FFModuleBaseInfo* Z[] = {
(void*) &instance.config.modules.zpool,
(FFModuleBaseInfo*) &instance.config.modules.zpool,
NULL,
};
+5 -1
View File
@@ -91,7 +91,11 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
if (rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == pid)
{
struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP);
if (sdl)
if (sdl
#ifndef __sun
&& sdl->sdl_len
#endif
)
{
assert(sdl->sdl_nlen <= IF_NAMESIZE);
memcpy(iface, sdl->sdl_data, sdl->sdl_nlen);
+2 -4
View File
@@ -13,11 +13,9 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
if (!netRoute) return false;
// skip first line
flockfile(netRoute);
while (getc_unlocked(netRoute) != '\n');
funlockfile(netRoute);
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu,
FF_UNUSED(fscanf(netRoute, "%*[^\n]\n"));
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu,
while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", iface, &destination) == 2)
{
if (destination != 0) continue;
+17 -24
View File
@@ -6,6 +6,20 @@ struct yyjson_val;
struct yyjson_mut_doc;
struct yyjson_mut_val;
typedef struct FFModuleFormatArg
{
const char* desc;
const char* name;
} FFModuleFormatArg;
typedef struct FFModuleFormatArgList
{
FFModuleFormatArg* args;
uint32_t count;
} FFModuleFormatArgList;
#define FF_FORMAT_ARG_LIST(list) { .args = list, .count = sizeof(list) / sizeof(FFModuleFormatArg) }
// Must be the first field of FFModuleOptions
typedef struct FFModuleBaseInfo
{
@@ -19,38 +33,17 @@ typedef struct FFModuleBaseInfo
void (*parseJsonObject)(void* options, struct yyjson_val *module);
void (*printModule)(void* options);
void (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
void (*printHelpFormat)(void);
void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
FFModuleFormatArgList formatArgs;
} FFModuleBaseInfo;
static inline void ffOptionInitModuleBaseInfo(
FFModuleBaseInfo* baseInfo,
const char* name,
const char* description,
void* parseCommandOptions, // bool (*const parseCommandOptions)(void* options, const char* key, const char* value)
void* parseJsonObject, // void (*const parseJsonObject)(void* options, yyjson_val *module)
void* printModule, // void (*const printModule)(void* options)
void* generateJsonResult, // void (*const generateJsonResult)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
void (*printHelpFormat)(void),
void* generateJsonConfig // void (*const generateJsonConfig)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
)
{
baseInfo->name = name;
baseInfo->description = description;
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
baseInfo->generateJsonResult = (__typeof__(baseInfo->generateJsonResult)) generateJsonResult;
baseInfo->printHelpFormat = printHelpFormat;
baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig;
}
typedef enum FFModuleKeyType
typedef enum __attribute__((__packed__)) FFModuleKeyType
{
FF_MODULE_KEY_TYPE_NONE = 0,
FF_MODULE_KEY_TYPE_STRING = 1 << 0,
FF_MODULE_KEY_TYPE_ICON = 1 << 1,
FF_MODULE_KEY_TYPE_BOTH = FF_MODULE_KEY_TYPE_STRING | FF_MODULE_KEY_TYPE_ICON,
FF_MODULE_KEY_TYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFModuleKeyType;
typedef struct FFModuleArgs
+43 -1
View File
@@ -72,7 +72,7 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
}
if(counter == 0)
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
ffStrbufAppendF(result, "%" PRIu64 " %s", bytes, prefixes[0]);
else
ffStrbufAppendF(result, "%.*f %s", instance.config.display.sizeNdigits, size, prefixes[counter]);
}
@@ -190,6 +190,48 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co
}
}
void ffParseDuration(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t seconds, FFstrbuf* result)
{
if(days == 0 && hours == 0 && minutes == 0)
{
ffStrbufAppendF(result, "%u seconds", seconds);
return;
}
if(days > 0)
{
ffStrbufAppendF(result, "%u day", days);
if(days > 1)
ffStrbufAppendC(result, 's');
if(days >= 100)
ffStrbufAppendS(result, "(!)");
if(hours > 0 || minutes > 0)
ffStrbufAppendS(result, ", ");
}
if(hours > 0)
{
ffStrbufAppendF(result, "%u hour", hours);
if(hours > 1)
ffStrbufAppendC(result, 's');
if(minutes > 0)
ffStrbufAppendS(result, ", ");
}
if(minutes > 0)
{
ffStrbufAppendF(result, "%u min", minutes);
if(minutes > 1)
ffStrbufAppendC(result, 's');
}
}
#ifdef _WIN32
#pragma GCC diagnostic pop
#endif
+1
View File
@@ -27,3 +27,4 @@ int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2);
void ffParseSize(uint64_t bytes, FFstrbuf* result);
bool ffParseFrequency(uint32_t mhz, FFstrbuf* result);
void ffParseDuration(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t seconds, FFstrbuf* result);
+72 -10
View File
@@ -14,7 +14,46 @@ static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module)
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
}
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module)
const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFlags* result)
{
if (yyjson_is_uint(jsonVal))
{
*result = (FFPercentageTypeFlags) yyjson_get_uint(jsonVal);
return NULL;
}
if (yyjson_is_arr(jsonVal))
{
FFPercentageTypeFlags flags = 0;
yyjson_val* item;
size_t idx, max;
yyjson_arr_foreach(jsonVal, idx, max, item)
{
const char* flag = yyjson_get_str(item);
if (!flag)
return "Error: percent.type: invalid flag string";
if (ffStrEqualsIgnCase(flag, "num"))
flags |= FF_PERCENTAGE_TYPE_NUM_BIT;
else if (ffStrEqualsIgnCase(flag, "bar"))
flags |= FF_PERCENTAGE_TYPE_BAR_BIT;
else if (ffStrEqualsIgnCase(flag, "hide-others"))
flags |= FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT;
else if (ffStrEqualsIgnCase(flag, "num-color"))
flags |= FF_PERCENTAGE_TYPE_NUM_COLOR_BIT;
else if (ffStrEqualsIgnCase(flag, "bar-monochrome"))
flags |= FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT;
else
return "Error: percent.type: unknown flag string";
}
*result = flags;
return NULL;
}
return "Error: usage: percent.type must be a number or an array of strings";
}
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module)
{
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
@@ -41,15 +80,18 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con
}
else
{
const char* colorGreen = instance.config.display.percentColorGreen.chars;
const char* colorYellow = instance.config.display.percentColorYellow.chars;
const char* colorRed = instance.config.display.percentColorRed.chars;
const char* colorGreen = options->percentColorGreen.chars;
const char* colorYellow = options->percentColorYellow.chars;
const char* colorRed = options->percentColorRed.chars;
FFPercentageTypeFlags percentType = config.type == 0 ? options->percentType : config.type;
bool monochrome = !!(percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT);
for (uint32_t i = 0; i < blocksPercent; ++i)
{
if(!options->pipe)
{
if (options->percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT)
if (monochrome)
{
const char* color = NULL;
if (green <= yellow)
@@ -104,14 +146,15 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con
}
}
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module)
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, bool parentheses, const FFModuleArgs* module)
{
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
const FFOptionsDisplay* options = &instance.config.display;
FFPercentageTypeFlags percentType = config.type == 0 ? options->percentType : config.type;
bool colored = !!(options->percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
bool colored = !!(percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
if (parentheses)
ffStrbufAppendC(buffer, '(');
@@ -156,7 +199,7 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig con
ffStrbufAppendC(buffer, ')');
}
bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFColorRangeConfig* config)
bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config)
{
if (!ffStrStartsWithIgnCase(subkey, "percent-"))
return false;
@@ -187,10 +230,16 @@ bool ffPercentParseCommandOptions(const char* key, const char* subkey, const cha
return true;
}
if (ffStrEqualsIgnCase(subkey, "type"))
{
config->type = (FFPercentageTypeFlags) ffOptionParseUInt32(key, value);
return true;
}
return false;
}
bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeConfig* config)
bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageModuleConfig* config)
{
if (!ffStrEqualsIgnCase(key, "percent"))
return false;
@@ -225,10 +274,21 @@ bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeCo
config->yellow = (uint8_t) num;
}
yyjson_val* typeVal = yyjson_obj_get(value, "type");
if (typeVal)
{
const char* error = ffPercentParseTypeJsonConfig(typeVal, &config->type);
if (error)
{
fputs(error, stderr);
exit(480);
}
}
return true;
}
void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFColorRangeConfig defaultConfig, FFColorRangeConfig config)
void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig defaultConfig, FFPercentageModuleConfig config)
{
if (config.green == defaultConfig.green && config.yellow == defaultConfig.yellow)
return;
@@ -238,4 +298,6 @@ void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FF
yyjson_mut_obj_add_uint(doc, percent, "green", config.green);
if (config.yellow != defaultConfig.yellow)
yyjson_mut_obj_add_uint(doc, percent, "yellow", config.yellow);
if (config.type != defaultConfig.type)
yyjson_mut_obj_add_uint(doc, percent, "type", config.type);
}
+18 -7
View File
@@ -4,14 +4,24 @@
#include "common/parsing.h"
#include "common/option.h"
enum FFPercentageTypeFlags
typedef enum __attribute__((__packed__)) FFPercentageTypeFlags
{
FF_PERCENTAGE_TYPE_NONE = 0,
FF_PERCENTAGE_TYPE_NUM_BIT = 1 << 0,
FF_PERCENTAGE_TYPE_BAR_BIT = 1 << 1,
FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT = 1 << 2,
FF_PERCENTAGE_TYPE_NUM_COLOR_BIT = 1 << 3,
FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT = FF_PERCENTAGE_TYPE_NUM_COLOR_BIT,
};
FF_PERCENTAGE_TYPE_FORCE_UNSIGNED_ = UINT8_MAX,
} FFPercentageTypeFlags;
static_assert(sizeof(FFPercentageTypeFlags) == 1, "");
typedef struct FFPercentageModuleConfig
{
uint8_t green;
uint8_t yellow;
FFPercentageTypeFlags type;
} FFPercentageModuleConfig;
// if (green <= yellow)
// [0, green]: print green
@@ -23,12 +33,13 @@ enum FFPercentageTypeFlags
// [yellow, green): print yellow
// [0, yellow): print red
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module);
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module);
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module);
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, bool parentheses, const FFModuleArgs* module);
typedef struct yyjson_val yyjson_val;
typedef struct yyjson_mut_doc yyjson_mut_doc;
typedef struct yyjson_mut_val yyjson_mut_val;
bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFColorRangeConfig* config);
bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeConfig* config);
void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFColorRangeConfig defaultConfig, FFColorRangeConfig config);
bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config);
bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageModuleConfig* config);
void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig defaultConfig, FFPercentageModuleConfig config);
const char* ffPercentParseTypeJsonConfig(yyjson_val* value, FFPercentageTypeFlags* result);
+1 -16
View File
@@ -50,7 +50,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
else
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 2, ((FFformatarg[]){
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, ((FFformatarg[]) {
FF_FORMAT_ARG(moduleIndex, "index"),
FF_FORMAT_ARG(moduleArgs->keyIcon, "icon"),
}));
@@ -148,18 +148,3 @@ void ffPrintCharTimes(char c, uint32_t times)
if(remaining > 0)
fwrite(str, 1, remaining, stdout);
}
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[])
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(name);
ffStrbufLowerCase(&buffer);
printf("--%s-format:\n", buffer.chars);
printf("Sets the format string for %s output.\n", name);
puts("To see how a format string is constructed, take a look at \"fastfetch --help format\".");
puts("The following values are passed:");
for(unsigned i = 0; i < numArgs; i++)
printf(" {%u}: %s\n", i + 1, args[i]);
printf("The default is something similar to \"%s\".\n", def);
}
+4 -11
View File
@@ -3,26 +3,19 @@
#include "fastfetch.h"
#include "common/format.h"
typedef enum FFPrintType {
typedef enum __attribute__((__packed__)) FFPrintType {
FF_PRINT_TYPE_DEFAULT = 0,
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0, // key has been formatted outside
FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR = 1 << 1,
FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH = 1 << 2,
FF_PRINT_TYPE_NO_CUSTOM_OUTPUT_FORMAT = 1 << 3, // reserved
FF_PRINT_TYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFPrintType;
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType);
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, numArgs, arguments) do {\
static_assert(sizeof(arguments) / sizeof(*(arguments)) == (numArgs), "Invalid number of format arguments");\
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (numArgs), (arguments));\
} while (0)
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, arguments) \
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (sizeof(arguments) / sizeof(*arguments)), (arguments));
FF_C_PRINTF(5, 6) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
void ffPrintColor(const FFstrbuf* colorValue);
void ffPrintCharTimes(char c, uint32_t times);
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[]);
#define FF_PRINT_MODULE_FORMAT_HELP_CHECKED(moduleName, def, numArgs, args) do {\
static_assert(sizeof(args) / sizeof(*(args)) == (numArgs), "Invalid number of format arguments");\
ffPrintModuleFormatHelp((moduleName), (def), (numArgs), (args));\
} while (0)
+91 -26
View File
@@ -1,7 +1,6 @@
#include "fastfetch.h"
#include "common/processing.h"
#include "common/io/io.h"
#include "common/time.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
@@ -23,9 +22,12 @@
#elif defined(__sun)
#include <procfs.h>
#elif defined(__OpenBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <kvm.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <kvm.h>
#elif defined(__NetBSD__)
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
enum { FF_PIPE_BUFSIZ = 8192 };
@@ -87,6 +89,16 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
waitpid(childPid, NULL, 0);
return "poll(&pollfd, 1, timeout) timeout (try increasing --processing-timeout)";
}
else if (errno == EINTR)
{
// The child process has been terminated. See `chldSignalHandler` in `common/init.c`
if (waitpid(childPid, NULL, WNOHANG) == childPid)
{
// Read remaining data from the pipe
fcntl(childPipeFd, F_SETFL, O_CLOEXEC | O_NONBLOCK);
childPid = -1;
}
}
else if (pollfd.revents & POLLERR)
{
kill(childPid, SIGTERM);
@@ -101,7 +113,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
else if (nRead == 0)
{
int stat_loc = 0;
if (waitpid(childPid, &stat_loc, 0) == childPid)
if (childPid > 0 && waitpid(childPid, &stat_loc, 0) == childPid)
{
if (!WIFEXITED(stat_loc))
return "child process exited abnormally";
@@ -110,10 +122,15 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
// We only handle 127 as an error. See `getTerminalVersionUrxvt` in `terminalshell.c`
return NULL;
}
return "waitpid() failed";
return NULL;
}
else if (nRead < 0)
break;
{
if (errno == EAGAIN)
return NULL;
else
break;
}
};
return "read(childPipeFd, str, FF_PIPE_BUFSIZ) failed";
@@ -139,12 +156,13 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
if (exePath)
{
snprintf(filePath, sizeof(filePath), "/proc/%d/exe", (int)pid);
ffStrbufEnsureFixedLengthFree(exePath, PATH_MAX);
ssize_t length = readlink(filePath, exePath->chars, exePath->allocated - 1);
char buf[PATH_MAX];
ssize_t length = readlink(filePath, buf, PATH_MAX - 1);
if (length > 0) // doesn't contain trailing NUL
{
exePath->chars[length] = '\0';
exePath->length = (uint32_t) length;
buf[length] = '\0';
ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length);
ffStrbufAppendNS(exePath, (uint32_t)length, buf);
}
}
@@ -152,14 +170,12 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
size_t len = 0;
int mibs[] = { CTL_KERN, KERN_PROCARGS2, pid };
if (sysctl(mibs, sizeof(mibs) / sizeof(*mibs), NULL, &len, NULL, 0) == 0)
if (sysctl(mibs, ARRAY_SIZE(mibs), NULL, &len, NULL, 0) == 0)
{// try get arg0
#ifndef MAC_OS_X_VERSION_10_15
//don't know why if don't let len longer, proArgs2 and len will change during the following sysctl() in old MacOS version.
len++;
#endif
FF_AUTO_FREE char* const procArgs2 = malloc(len);
if (sysctl(mibs, sizeof(mibs) / sizeof(*mibs), procArgs2, &len, NULL, 0) == 0)
if (sysctl(mibs, ARRAY_SIZE(mibs), procArgs2, &len, NULL, 0) == 0)
{
// https://gist.github.com/nonowarn/770696#file-getargv-c-L46
uint32_t argc = *(uint32_t*) procArgs2;
@@ -191,17 +207,18 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
}
else
{
ffStrbufEnsureFixedLengthFree(exe, PATH_MAX);
int length = proc_pidpath(pid, exe->chars, exe->allocated);
char buf[PROC_PIDPATHINFO_MAXSIZE];
int length = proc_pidpath(pid, buf, ARRAY_SIZE(buf));
if (length > 0)
{
exe->length = (uint32_t) length;
ffStrbufEnsureFixedLengthFree(exe, (uint32_t) length);
ffStrbufAppendNS(exe, (uint32_t) length, buf);
if (exePath)
ffStrbufSet(exePath, exe);
}
}
#elif defined(__FreeBSD__)
#elif defined(__FreeBSD__) || defined(__NetBSD__)
size_t size = ARG_MAX;
FF_AUTO_FREE char* args = malloc(size);
@@ -209,7 +226,13 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
static_assert(ARG_MAX > PATH_MAX, "");
if(exePath && sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid}, 4,
(int[]){CTL_KERN,
#if __FreeBSD__
KERN_PROC, KERN_PROC_PATHNAME, pid
#else
KERN_PROC_ARGS, pid, KERN_PROC_PATHNAME
#endif
}, 4,
args, &size,
NULL, 0
) == 0)
@@ -217,7 +240,13 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
size = ARG_MAX;
if(sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_ARGS, pid}, 4,
(int[]){CTL_KERN,
#if __FreeBSD__
KERN_PROC, KERN_PROC_ARGS, pid
#else
KERN_PROC_ARGS, pid, KERN_PROC_ARGV,
#endif
}, 4,
args, &size,
NULL, 0
) == 0)
@@ -242,7 +271,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
#elif defined(__sun)
char filePath[PATH_MAX];
char filePath[128];
snprintf(filePath, sizeof(filePath), "/proc/%d/psinfo", (int) pid);
psinfo_t proc;
if (ffReadFileData(filePath, sizeof(proc), &proc) == sizeof(proc))
@@ -254,12 +283,13 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
if (exePath)
{
snprintf(filePath, sizeof(filePath), "/proc/%d/path/a.out", (int) pid);
ffStrbufEnsureFixedLengthFree(exePath, PATH_MAX);
ssize_t length = readlink(filePath, exePath->chars, exePath->allocated - 1);
char buf[PATH_MAX];
ssize_t length = readlink(filePath, buf, PATH_MAX - 1);
if (length > 0) // doesn't contain trailing NUL
{
exePath->chars[length] = '\0';
exePath->length = (uint32_t) length;
buf[length] = '\0';
ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length);
ffStrbufAppendNS(exePath, (uint32_t)length, buf);
}
}
@@ -350,6 +380,13 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
#elif defined(__FreeBSD__)
#ifdef __DragonFly__
#define ki_comm kp_comm
#define ki_ppid kp_ppid
#define ki_tdev kp_tdev
#define ki_flag kp_flags
#endif
struct kinfo_proc proc;
size_t size = sizeof(proc);
if(sysctl(
@@ -376,6 +413,34 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
*tty = -1;
}
#elif defined(__NetBSD__)
struct kinfo_proc2 proc;
size_t size = sizeof(proc);
if(sysctl(
(int[]){CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid, sizeof(proc), 1}, 6,
&proc, &size,
NULL, 0
) != 0)
return "sysctl(KERN_PROC_PID) failed";
ffStrbufSetS(name, proc.p_comm);
if (ppid)
*ppid = (pid_t)proc.p_ppid;
if (tty)
{
if (proc.p_flag & P_CONTROLT)
{
const char* ttyName = devname(proc.p_tdev, S_IFCHR);
if (ffStrStartsWith(ttyName, "pts/"))
*tty = (int32_t) strtol(ttyName + strlen("pts/"), NULL, 10);
else
*tty = -1;
}
else
*tty = -1;
}
#elif defined(__sun)
char path[128];
snprintf(path, sizeof(path), "/proc/%d/psinfo", (int) pid);
+10 -4
View File
@@ -49,8 +49,11 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
{
int timeout = instance.config.general.processingTimeout;
wchar_t pipeName[32];
swprintf(pipeName, ARRAY_SIZE(pipeName), L"\\\\.\\pipe\\FASTFETCH-%u", GetCurrentProcessId());
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = CreateNamedPipeW(
L"\\\\.\\pipe\\LOCAL\\",
pipeName,
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | (timeout < 0 ? 0 : FILE_FLAG_OVERLAPPED),
0,
1,
@@ -60,10 +63,10 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
NULL
);
if (hChildPipeRead == INVALID_HANDLE_VALUE)
return "CreateNamedPipeW(L\"\\\\.\\pipe\\LOCAL\\\") failed";
return "CreateNamedPipeW(L\"\\\\.\\pipe\\FASTFETCH-$(PID)\") failed";
HANDLE hChildPipeWrite = CreateFileW(
L"\\\\.\\pipe\\LOCAL\\",
pipeName,
GENERIC_WRITE,
0,
&(SECURITY_ATTRIBUTES){
@@ -76,7 +79,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
NULL
);
if (hChildPipeWrite == INVALID_HANDLE_VALUE)
return "CreateFileW(L\"\\\\.\\pipe\\LOCAL\\\") failed";
return "CreateFileW(L\"\\\\.\\pipe\\FASTFETCH-$(PID)\") failed";
PROCESS_INFORMATION piProcInfo = {0};
@@ -166,6 +169,9 @@ bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFst
? GetCurrentProcess()
: OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (hProcess == NULL)
return false;
if (gui)
*gui = GetGuiResources(hProcess, GR_GDIOBJECTS) > 0;
+1 -1
View File
@@ -100,7 +100,7 @@ bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquer
bool valueStorage[32];
bool* unsetValues = valueStorage;
if (numQueries > sizeof(valueStorage) / sizeof(valueStorage[0]))
if (numQueries > ARRAY_SIZE(valueStorage))
unsetValues = malloc(sizeof(bool) * numQueries);
bool allSet = true;
+1 -1
View File
@@ -2,7 +2,7 @@
#include "fastfetch.h"
typedef enum FFvarianttype
typedef enum __attribute__((__packed__)) FFvarianttype
{
FF_VARIANT_TYPE_STRING,
FF_VARIANT_TYPE_BOOL,
+52 -1
View File
@@ -186,7 +186,8 @@
"data-raw": "Text data, printed as is",
"sixel": "Image file, printed as sixel codes",
"kitty": "Image file, printed as kitty graphics protocol",
"kitty_direct": "Image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)",
"kitty-direct": "Image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)",
"kitty-icat": "Image file, use `kitten icat` to display the image. Requires binary `kitten` to be installed",
"iterm": "Image file, printed as iterm graphics protocol",
"chafa": "Image file, printed as ascii art using libchafa",
"raw": "Image file, printed as raw binary string",
@@ -351,6 +352,14 @@
"type": "path"
}
},
{
"long": "kitty-icat",
"desc": "Short for --logo-type kitty-icat --logo <path>",
"remark": "See \"--help logo-type\" for more info",
"arg": {
"type": "path"
}
},
{
"long": "iterm",
"desc": "Short for --logo-type iterm --logo <path>",
@@ -916,6 +925,14 @@
"type": "str"
}
},
{
"long": "diskio-wait-time",
"desc": "Set the wait time (in ms) when detecting disk usage",
"arg": {
"type": "num",
"default": 1000
}
},
{
"long": "physicaldisk-name-prefix",
"desc": "Show disks with given name prefix only",
@@ -1070,6 +1087,14 @@
"default": false
}
},
{
"long": "cpuusage-wait-time",
"desc": "Set the wait time (in ms) when detecting CPU usage",
"arg": {
"type": "num",
"default": 200
}
},
{
"long": "de-slow-version-detection",
"desc": "Set if DE version should be detected with slow operations",
@@ -1305,6 +1330,14 @@
"default": false
}
},
{
"long": "netio-wait-time",
"desc": "Set the wait time (in ms) when detecting network usage",
"arg": {
"type": "num",
"default": 1000
}
},
{
"long": "publicip-timeout",
"desc": "Time in milliseconds to wait for the public ip server to respond",
@@ -1578,6 +1611,24 @@
},
"pseudo": true
},
{
"long": "<module>-percent-type",
"desc": "Set the percentage output type",
"remark": [
"0 for use global `--percent-type` value",
"1 for percentage number",
"2 for multi-color bar",
"3 for both",
"6 for bar only",
"9 for colored number",
"10 for monochrome bar"
],
"arg": {
"type": "num",
"default": 0
},
"pseudo": true
},
{
"long": "<module>-temp-green",
"desc": [
+1
View File
@@ -15,6 +15,7 @@ typedef struct FFBatteryResult
double capacity;
double temperature;
uint32_t cycleCount;
int32_t timeRemaining;
} FFBatteryResult;
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results);
+24 -2
View File
@@ -1,6 +1,6 @@
#include "fastfetch.h"
#include "battery.h"
#include "util/stringUtils.h"
#include "common/processing.h"
#include "common/properties.h"
@@ -36,6 +36,7 @@ static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results)
FFBatteryResult* battery = ffListAdd(results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = -1;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->status);
@@ -44,7 +45,27 @@ static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results)
ffStrbufInit(&battery->manufactureDate);
battery->capacity = yyjson_get_num(yyjson_obj_get(root, "percentage"));
ffStrbufAppendS(&battery->status, yyjson_get_str(yyjson_obj_get(root, "status")));
const char* acStatus = yyjson_get_str(yyjson_obj_get(root, "plugged"));
if (acStatus)
{
if (ffStrEquals(acStatus, "PLUGGED_AC"))
ffStrbufAppendS(&battery->status, "AC Connected, ");
else if (ffStrEquals(acStatus, "PLUGGED_USB"))
ffStrbufAppendS(&battery->status, "USB Connected, ");
else if (ffStrEquals(acStatus, "PLUGGED_WIRELESS"))
ffStrbufAppendS(&battery->status, "Wireless Connected, ");
}
const char* status = yyjson_get_str(yyjson_obj_get(root, "status"));
if (status)
{
if (ffStrEquals(status, "CHARGING"))
ffStrbufAppendS(&battery->status, "Charging");
else if (ffStrEquals(status, "DISCHARGING"))
ffStrbufAppendS(&battery->status, "Discharging");
}
ffStrbufTrimRight(&battery->status, ' ');
ffStrbufTrimRight(&battery->status, ',');
if(options->temp)
battery->temperature = yyjson_get_num(yyjson_obj_get(root, "temperature"));
@@ -74,6 +95,7 @@ static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results)
FFBatteryResult* battery = ffListAdd(results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = -1;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->status);
+17 -6
View File
@@ -57,13 +57,24 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
ffCfDictGetInt(properties, CFSTR(kIOPMPSCycleCountKey), &cycleCount);
battery->cycleCount = cycleCount < 0 ? 0 : (uint32_t) cycleCount;
if (!ffCfDictGetBool(properties, CFSTR(kIOPMPSExternalConnectedKey), &boolValue) && boolValue)
ffStrbufAppendS(&battery->status, "AC connected, ");
else
ffStrbufAppendS(&battery->status, "Discharging, ");
if (!ffCfDictGetBool(properties, CFSTR(kIOPMPSIsChargingKey), &boolValue) && boolValue)
battery->timeRemaining = -1;
if (ffCfDictGetBool(properties, CFSTR(kIOPMPSExternalConnectedKey), &boolValue) == NULL)
{
if (boolValue)
ffStrbufAppendS(&battery->status, "AC connected, ");
else
{
ffStrbufAppendS(&battery->status, "Discharging, ");
ffCfDictGetInt(properties, CFSTR("AvgTimeToEmpty"), &battery->timeRemaining); // in minutes
if (battery->timeRemaining < 0 || battery->timeRemaining >= 0xFFFF)
battery->timeRemaining = -1;
else
battery->timeRemaining *= 60;
}
}
if (ffCfDictGetBool(properties, CFSTR(kIOPMPSIsChargingKey), &boolValue) == NULL && boolValue)
ffStrbufAppendS(&battery->status, "Charging, ");
if (!ffCfDictGetBool(properties, CFSTR(kIOPMPSAtCriticalLevelKey), &boolValue) && boolValue)
if (ffCfDictGetBool(properties, CFSTR(kIOPMPSAtCriticalLevelKey), &boolValue) == NULL && boolValue)
ffStrbufAppendS(&battery->status, "Critical, ");
ffStrbufTrimRight(&battery->status, ' ');
ffStrbufTrimRight(&battery->status, ',');
+16 -1
View File
@@ -41,7 +41,9 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
battery->timeRemaining = -1;
if (battio.battinfo.min > 0)
battery->timeRemaining = battio.battinfo.min * 60;
battery->capacity = battio.battinfo.cap;
if(battio.battinfo.state == ACPI_BATT_STAT_INVALID)
{
@@ -68,13 +70,26 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
ffStrbufTrimRight(&battery->status, ',');
}
#ifdef ACPIIO_BATT_GET_BIX
battio.unit = i;
if (ioctl(acpifd, ACPIIO_BATT_GET_BIX, &battio) >= 0)
{
ffStrbufAppendS(&battery->manufacturer, battio.bix.oeminfo);
ffStrbufAppendS(&battery->modelName, battio.bix.model);
ffStrbufAppendS(&battery->technology, battio.bix.type);
ffStrbufAppendS(&battery->serial, battio.bix.serial);
battery->cycleCount = battio.bix.cycles;
}
#elif defined(ACPIIO_BATT_GET_BIF)
battio.unit = i;
if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) >= 0)
{
ffStrbufAppendS(&battery->manufacturer, battio.bif.oeminfo);
ffStrbufAppendS(&battery->modelName, battio.bif.model);
ffStrbufAppendS(&battery->technology, battio.bif.type);
ffStrbufAppendS(&battery->serial, battio.bif.serial);
}
#endif
}
return NULL;
}
+76 -71
View File
@@ -3,39 +3,45 @@
#include "util/stringUtils.h"
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power
static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* options, FFlist* results)
static bool checkAc(const char* id, FFstrbuf* tmpBuffer)
{
uint32_t dirLength = dir->length;
if (ffStrStartsWith(id, "BAT"))
ffStrbufSetS(tmpBuffer, "/sys/class/power_supply/ADP1/online");
else if (ffStrStartsWith(id, "macsmc-battery"))
ffStrbufSetS(tmpBuffer, "/sys/class/power_supply/macsmc-ac/online");
else
ffStrbufClear(tmpBuffer);
char online = '\0';
return ffReadFileData(tmpBuffer->chars, 1, &online) == 1 && online == '1';
}
static void parseBattery(int dfd, const char* id, FFBatteryOptions* options, FFlist* results)
{
FF_STRBUF_AUTO_DESTROY tmpBuffer = ffStrbufCreate();
//type must exist and be "Battery"
ffStrbufAppendS(dir, "/type");
if (ffReadFileBuffer(dir->chars, &tmpBuffer))
ffStrbufTrimRightSpace(&tmpBuffer);
ffStrbufSubstrBefore(dir, dirLength);
// type must exist and be "Battery"
if (!ffReadFileBufferRelative(dfd, "type", &tmpBuffer))
return;
ffStrbufTrimRightSpace(&tmpBuffer);
if(!ffStrbufIgnCaseEqualS(&tmpBuffer, "Battery"))
return;
//scope may not exist or must not be "Device"
ffStrbufAppendS(dir, "/scope");
if (ffReadFileBuffer(dir->chars, &tmpBuffer))
// scope may not exist or must not be "Device"
if (ffReadFileBufferRelative(dfd, "scope", &tmpBuffer))
ffStrbufTrimRightSpace(&tmpBuffer);
ffStrbufSubstrBefore(dir, dirLength);
if(ffStrbufIgnCaseEqualS(&tmpBuffer, "Device"))
return;
//capacity must exist and be not empty
ffStrbufAppendS(dir, "/capacity");
bool available = ffReadFileBuffer(dir->chars, &tmpBuffer); // This is expensive in my laptop
ffStrbufSubstrBefore(dir, dirLength);
if (!available)
// capacity must exist and be not empty
// This is expensive in my laptop
if (!ffReadFileBufferRelative(dfd, "capacity", &tmpBuffer))
return;
FFBatteryResult* result = ffListAdd(results);
@@ -44,39 +50,63 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option
//At this point, we have a battery. Try to get as much values as possible.
ffStrbufInit(&result->manufacturer);
ffStrbufAppendS(dir, "/manufacturer");
if (ffReadFileBuffer(dir->chars, &result->manufacturer))
if (ffReadFileBufferRelative(dfd, "manufacturer", &result->manufacturer))
ffStrbufTrimRightSpace(&result->manufacturer);
else if (ffStrEquals(id, "macsmc-battery")) // asahi
ffStrbufSetStatic(&result->manufacturer, "Apple Inc.");
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufInit(&result->modelName);
ffStrbufAppendS(dir, "/model_name");
if (ffReadFileBuffer(dir->chars, &result->modelName))
if (ffReadFileBufferRelative(dfd, "model_name", &result->modelName))
ffStrbufTrimRightSpace(&result->modelName);
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufInit(&result->technology);
ffStrbufAppendS(dir, "/technology");
if (ffReadFileBuffer(dir->chars, &result->technology))
if (ffReadFileBufferRelative(dfd, "technology", &result->technology))
ffStrbufTrimRightSpace(&result->technology);
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufInit(&result->status);
ffStrbufAppendS(dir, "/status");
if (ffReadFileBuffer(dir->chars, &result->status))
if (ffReadFileBufferRelative(dfd, "status", &result->status))
ffStrbufTrimRightSpace(&result->status);
ffStrbufSubstrBefore(dir, dirLength);
// Unknown, Charging, Discharging, Not charging, Full
if (ffStrbufEqualS(&result->status, "Not charging") || ffStrbufEqualS(&result->status, "Full"))
ffStrbufSetStatic(&result->status, "AC Connected");
else if (ffStrbufEqualS(&result->status, "Unknown"))
ffStrbufClear(&result->status);
ffStrbufAppendS(dir, "/capacity_level");
if (ffReadFileBuffer(dir->chars, &tmpBuffer))
result->timeRemaining = -1;
if (ffStrbufEqualS(&result->status, "Discharging"))
{
if (ffReadFileBufferRelative(dfd, "time_to_empty_now", &tmpBuffer))
result->timeRemaining = (int32_t) ffStrbufToSInt(&tmpBuffer, 0);
else
{
if (ffReadFileBufferRelative(dfd, "charge_now", &tmpBuffer))
{
int64_t chargeNow = ffStrbufToSInt(&tmpBuffer, 0);
if (chargeNow > 0)
{
if (ffReadFileBufferRelative(dfd, "current_now", &tmpBuffer))
{
int64_t currentNow = ffStrbufToSInt(&tmpBuffer, INT64_MIN);
if (currentNow < 0) currentNow = -currentNow;
if (currentNow > 0)
result->timeRemaining = (int32_t) ((chargeNow * 3600) / currentNow);
}
}
}
}
if (checkAc(id, &tmpBuffer))
ffStrbufAppendS(&result->status, ", AC Connected");
}
else if (ffStrbufEqualS(&result->status, "Not charging") || ffStrbufEqualS(&result->status, "Full"))
ffStrbufSetStatic(&result->status, "AC Connected");
else if (ffStrbufEqualS(&result->status, "Charging"))
ffStrbufAppendS(&result->status, ", AC Connected");
else if (ffStrbufEqualS(&result->status, "Unknown"))
{
ffStrbufClear(&result->status);
if (checkAc(id, &tmpBuffer))
ffStrbufAppendS(&result->status, "AC Connected");
}
if (ffReadFileBufferRelative(dfd, "capacity_level", &tmpBuffer))
{
ffStrbufTrimRightSpace(&result->manufacturer);
if (ffStrbufEqualS(&tmpBuffer, "Critical"))
@@ -87,50 +117,33 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option
ffStrbufSetStatic(&result->status, "Critical");
}
}
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufInit(&result->serial);
ffStrbufAppendS(dir, "/serial_number");
if (ffReadFileBuffer(dir->chars, &result->serial))
if (ffReadFileBufferRelative(dfd, "serial_number", &result->serial))
ffStrbufTrimRightSpace(&result->serial);
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufAppendS(dir, "/cycle_count");
available = ffReadFileBuffer(dir->chars, &tmpBuffer);
ffStrbufSubstrBefore(dir, dirLength);
if (available)
if (ffReadFileBufferRelative(dfd, "cycle_count", &tmpBuffer))
{
int64_t cycleCount = ffStrbufToSInt(&tmpBuffer, 0);
result->cycleCount = cycleCount < 0 || cycleCount > UINT32_MAX ? 0 : (uint32_t) cycleCount;
}
ffStrbufInit(&result->manufactureDate);
ffStrbufAppendS(dir, "/manufacture_year");
available = ffReadFileBuffer(dir->chars, &tmpBuffer);
ffStrbufSubstrBefore(dir, dirLength);
if (available)
if (ffReadFileBufferRelative(dfd, "manufacture_year", &tmpBuffer))
{
int year = (int) ffStrbufToSInt(&tmpBuffer, 0);
if (year > 0)
{
ffStrbufAppendS(dir, "/manufacture_month");
available = ffReadFileBuffer(dir->chars, &tmpBuffer);
ffStrbufSubstrBefore(dir, dirLength);
if (available)
if (ffReadFileBufferRelative(dfd, "manufacture_month", &tmpBuffer))
{
int month = (int) ffStrbufToSInt(&tmpBuffer, 0);
if (month > 0)
{
ffStrbufAppendS(dir, "/manufacture_day");
available = ffReadFileBuffer(dir->chars, &tmpBuffer);
ffStrbufSubstrBefore(dir, dirLength);
if (available)
if (ffReadFileBufferRelative(dfd, "manufacture_day", &tmpBuffer))
{
int day = (int) ffStrbufToSInt(&tmpBuffer, 0);
if (day > 0)
{
ffStrbufSetF(&result->manufactureDate, "%.4d-%.2d-%.2d", year, month, day);
}
}
}
}
@@ -140,33 +153,25 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option
result->temperature = FF_BATTERY_TEMP_UNSET;
if (options->temp)
{
ffStrbufAppendS(dir, "/temp");
if (ffReadFileBuffer(dir->chars, &tmpBuffer))
if (ffReadFileBufferRelative(dfd, "temp", &tmpBuffer))
result->temperature = ffStrbufToDouble(&tmpBuffer) / 10;
ffStrbufSubstrBefore(dir, dirLength);
}
}
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
ffStrbufAppendS(&baseDir, "/sys/class/power_supply/");
uint32_t baseDirLength = baseDir.length;
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/power_supply/");
if(dirp == NULL)
return "opendir(\"/sys/class/power_supply/\") == NULL";
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
if(entry->d_name[0] == '.')
continue;
ffStrbufAppendS(&baseDir, entry->d_name);
parseBattery(&baseDir, entry->d_name, options, results);
ffStrbufSubstrBefore(&baseDir, baseDirLength);
FF_AUTO_CLOSE_FD int dfd = openat(dirfd(dirp), entry->d_name, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
if (dfd > 0) parseBattery(dfd, entry->d_name, options, results);
}
return NULL;
+107
View File
@@ -0,0 +1,107 @@
#include "battery.h"
#include "common/io/io.h"
#include "util/FFstrbuf.h"
#include "util/stringUtils.h"
#include <prop/prop_array.h>
#include <prop/prop_bool.h>
#include <prop/prop_dictionary.h>
#include <prop/prop_object.h>
#include <sys/envsys.h>
#include <prop/proplib.h>
#include <paths.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
{
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
prop_dictionary_t root = NULL;
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
bool acConnected = false;
{
prop_array_t acad = prop_dictionary_get(root, "acpiacad0");
if (acad)
{
prop_dictionary_t dict = prop_array_get(acad, 0);
prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &acConnected);
}
}
prop_object_iterator_t itKey = prop_dictionary_iterator(root);
for (prop_dictionary_keysym_t key; (key = prop_object_iterator_next(itKey)) != NULL; )
{
if (!ffStrStartsWith(prop_dictionary_keysym_value(key), "acpibat")) continue;
prop_array_t bat = prop_dictionary_get_keysym(root, key);
uint32_t max = 0, curr = 0, dischargeRate = 0;
bool charging = false, critical = false;
prop_object_iterator_t iter = prop_array_iterator(bat);
for (prop_dictionary_t dict; (dict = prop_object_iterator_next(iter)) != NULL;)
{
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY)
continue;
const char* desc = NULL;
if (!prop_dictionary_get_string(dict, "description", &desc))
continue;
if (ffStrEquals(desc, "present"))
{
int value = 0;
if (prop_dictionary_get_int(dict, "cur-value", &value) && value == 0)
continue;
}
else if (ffStrEquals(desc, "charging"))
{
prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &charging);
}
else if (ffStrEquals(desc, "charge"))
{
prop_dictionary_get_uint32(dict, "max-value", &max);
prop_dictionary_get_uint32(dict, "cur-value", &curr);
const char* state = NULL;
if (prop_dictionary_get_string(dict, "state", &state) && ffStrEquals(state, "critical"))
critical = true;
}
else if (ffStrEquals(desc, "discharge rate"))
{
prop_dictionary_get_uint(dict, "cur-value", &dischargeRate);
}
}
if (max > 0)
{
FFBatteryResult* battery = ffListAdd(results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
battery->timeRemaining = -1;
battery->capacity = (double) curr / (double) max * 100.;
if (charging)
ffStrbufAppendS(&battery->status, "Charging, ");
else if (dischargeRate)
ffStrbufAppendS(&battery->status, "Discharging, ");
if (critical)
ffStrbufAppendS(&battery->status, "Critical, ");
if (acConnected)
ffStrbufAppendS(&battery->status, "AC Connected");
ffStrbufTrimRight(&battery->status, ' ');
ffStrbufTrimRight(&battery->status, ',');
}
}
prop_object_iterator_release(itKey);
return NULL;
}
+52
View File
@@ -0,0 +1,52 @@
#include "battery.h"
#include "common/io/io.h"
#include <machine/apmvar.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* result)
{
FF_AUTO_CLOSE_FD int devfd = open("/dev/apm", O_RDONLY);
if (devfd < 0) return "open(dev/apm, O_RDONLY) failed";
struct apm_power_info info = {};
if (ioctl(devfd, APM_IOC_GETPOWER, &info) < 0)
return "ioctl(APM_IOC_GETPOWER) failed";
if (info.battery_state == APM_BATTERY_ABSENT)
return NULL;
FFBatteryResult* battery = (FFBatteryResult*) ffListAdd(result);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = -1;
battery->capacity = info.battery_life;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
if (info.ac_state == APM_AC_ON)
ffStrbufAppendS(&battery->status, "AC Connected");
else if (info.ac_state == APM_AC_BACKUP)
ffStrbufAppendS(&battery->status, "Backup In Use");
else if (info.ac_state == APM_AC_OFF)
{
battery->timeRemaining = (int) info.minutes_left * 60;
ffStrbufAppendS(&battery->status, "Discharging");
}
if (info.battery_state == APM_BATT_CRITICAL || info.battery_state == APM_BATT_CHARGING)
{
if (battery->status.length) ffStrbufAppendS(&battery->status, ", ");
ffStrbufAppendS(&battery->status, info.battery_state == APM_BATT_CRITICAL ? "Critical" : "Charging");
}
return NULL;
}
+9
View File
@@ -121,6 +121,13 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
battery->temperature = temp / 10.0 - 273.15;
}
{
bqi.InformationLevel = BatteryEstimatedTime;
ULONG time;
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &time, sizeof(time), &dwOut, NULL))
battery->timeRemaining = time == BATTERY_UNKNOWN_TIME ? -1 : (int32_t) time;
}
{
BATTERY_STATUS bs;
BATTERY_WAIT_STATUS bws = { .BatteryTag = bqi.BatteryTag };
@@ -241,6 +248,7 @@ static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FF
ffStrbufInit(&battery->serial);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = info.EstimatedTime == BATTERY_UNKNOWN_TIME ? -1 : (int32_t) info.EstimatedTime;
battery->capacity = info.RemainingCapacity * 100.0 / info.MaxCapacity;
if(info.AcOnLine)
@@ -252,6 +260,7 @@ static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FF
else if(info.Discharging)
ffStrbufAppendS(&battery->status, "Discharging");
detectBySmbios(battery);
return NULL;
+1 -1
View File
@@ -25,7 +25,7 @@ const char* ffDetectBios(FFBiosResult* result)
{
ffStrbufSetStatic(&result->type,
ffPathExists("/dev/efi" /*efidev*/, FF_PATHTYPE_FILE) ||
ffPathExists("/boot/efi/efi" /*efi partition*/, FF_PATHTYPE_DIRECTORY)
ffPathExists("/boot/efi/efi/" /*efi partition*/, FF_PATHTYPE_DIRECTORY)
? "UEFI" : "BIOS");
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ const char *ffDetectBios(FFBiosResult *bios)
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->vendor);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->version);
if (ffPathExists("/sys/firmware/efi", FF_PATHTYPE_DIRECTORY) || ffPathExists("/sys/firmware/acpi/tables/UEFI", FF_PATHTYPE_FILE))
if (ffPathExists("/sys/firmware/efi/", FF_PATHTYPE_DIRECTORY) || ffPathExists("/sys/firmware/acpi/tables/UEFI", FF_PATHTYPE_FILE))
ffStrbufSetStatic(&bios->type, "UEFI");
else
ffStrbufSetStatic(&bios->type, "BIOS");
+15
View File
@@ -0,0 +1,15 @@
#include "bios.h"
#include "common/sysctl.h"
#include "util/smbiosHelper.h"
const char* ffDetectBios(FFBiosResult* bios)
{
if (ffSysctlGetString("machdep.dmi.bios-date", &bios->date) == NULL)
ffCleanUpSmbiosValue(&bios->date);
if (ffSysctlGetString("machdep.dmi.bios-version", &bios->version) == NULL)
ffCleanUpSmbiosValue(&bios->version);
if (ffSysctlGetString("machdep.dmi.bios-vendor", &bios->vendor) == NULL)
ffCleanUpSmbiosValue(&bios->vendor);
ffSysctlGetString("machdep.bootmethod", &bios->type);
return NULL;
}
+1 -1
View File
@@ -1,6 +1,6 @@
#include "bios.h"
const char* ffDetectBios(FFBiosResult* bios)
const char* ffDetectBios(FF_MAYBE_UNUSED FFBiosResult* bios)
{
return "Not supported on this platform";
}
+1 -1
View File
@@ -11,4 +11,4 @@ typedef struct FFBluetoothResult
bool connected;
} FFBluetoothResult;
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */);
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */);
+22 -2
View File
@@ -2,7 +2,15 @@
#import <IOBluetooth/IOBluetooth.h>
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
@interface IOBluetoothDevice()
@property (nonatomic) uint8_t batteryPercentCase;
@property (nonatomic) uint8_t batteryPercentCombined;
@property (nonatomic) uint8_t batteryPercentLeft;
@property (nonatomic) uint8_t batteryPercentRight;
@property (nonatomic) uint8_t batteryPercentSingle;
@end
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */)
{
NSArray<IOBluetoothDevice*>* ioDevices = IOBluetoothDevice.pairedDevices;
if(!ioDevices)
@@ -10,11 +18,23 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
for(IOBluetoothDevice* ioDevice in ioDevices)
{
if (!options->showDisconnected && !ioDevice.isConnected)
continue;
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitS(&device->name, ioDevice.name.UTF8String);
ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String);
ffStrbufReplaceAllC(&device->address, '-', ':');
ffStrbufUpperCase(&device->address);
ffStrbufInit(&device->type);
device->battery = 0;
if (ioDevice.batteryPercentSingle)
device->battery = ioDevice.batteryPercentSingle;
else if (ioDevice.batteryPercentCombined)
device->battery = ioDevice.batteryPercentCombined;
else if (ioDevice.batteryPercentCase)
device->battery = ioDevice.batteryPercentCase;
device->connected = !!ioDevice.isConnected;
if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorLimitedDiscoverableMode)
ffStrbufAppendS(&device->type, "Limited Discoverable Mode, ");
+25
View File
@@ -0,0 +1,25 @@
#include "bluetooth.h"
#define L2CAP_SOCKET_CHECKED
#include <bluetooth.h>
static int enumDev(FF_MAYBE_UNUSED int sockfd, struct bt_devinfo const* dev, FFlist* devices)
{
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitS(&device->name, bt_devremote_name_gen(dev->devname, &dev->bdaddr));
ffStrbufInitS(&device->address, bt_ntoa(&dev->bdaddr, NULL));
ffStrbufUpperCase(&device->address);
ffStrbufInit(&device->type);
device->battery = 0;
device->connected = true;
return 0;
}
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
{
// struct hostent* ent = bt_gethostent();
if (bt_devenum((void*) enumDev, devices) < 0)
return "bt_devenum() failed";
return 0;
}
+68 -22
View File
@@ -3,6 +3,7 @@
#ifdef FF_HAVE_DBUS
#include "common/dbus.h"
#include "common/io/io.h"
/* Example dbus reply, striped to only the relevant parts:
array [ //root
@@ -44,16 +45,16 @@ array [ //root
]
*/
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
static bool detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
return true;
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
return;
return true;
const char* deviceProperty;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty);
@@ -74,6 +75,13 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue
}
else if(ffStrEquals(deviceProperty, "Connected"))
ffDBusGetBool(dbus, &dictIter, &device->connected);
else if(ffStrEquals(deviceProperty, "Paired"))
{
bool paired = true;
ffDBusGetBool(dbus, &dictIter, &paired);
if (!paired) return false;
}
return true;
}
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
@@ -103,32 +111,37 @@ static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFB
do
{
detectBluetoothValue(dbus, &arrayIter, device);
bool shouldContinue = detectBluetoothValue(dbus, &arrayIter, device);
if (!shouldContinue)
{
ffStrbufClear(&device->name);
break;
}
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
}
static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
static FFBluetoothResult* detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
return NULL;
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_OBJECT_PATH)
return;
return NULL;
const char* objectPath;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &objectPath);
// We don't want adapter objects
if(!ffStrContains(objectPath, "/dev_"))
return;
return NULL;
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
return;
return NULL;
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
@@ -145,16 +158,10 @@ static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessage
detectBluetoothProperty(dbus, &arrayIter, device);
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
if(device->name.length == 0)
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->address);
ffStrbufDestroy(&device->type);
--devices->length;
}
return device;
}
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter, int32_t connectedCount)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
return;
@@ -164,11 +171,25 @@ static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIt
do
{
detectBluetoothObject(devices, dbus, &arrayIter);
FFBluetoothResult* device = detectBluetoothObject(devices, dbus, &arrayIter);
if (device)
{
if(device->name.length == 0 || (connectedCount > 0 && !device->connected))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->address);
ffStrbufDestroy(&device->type);
--devices->length;
}
if (device->connected && --connectedCount == 0)
break;
}
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
}
static const char* detectBluetooth(FFlist* devices)
static const char* detectBluetooth(FFlist* devices, int32_t connectedCount)
{
FFDBusData dbus;
const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus);
@@ -186,18 +207,43 @@ static const char* detectBluetooth(FFlist* devices)
return "Failed to get root iterator of GetManagedObjects";
}
detectBluetoothRoot(devices, &dbus, &rootIter);
detectBluetoothRoot(devices, &dbus, &rootIter, connectedCount);
dbus.lib->ffdbus_message_unref(managedObjects);
return NULL;
}
static uint32_t connectedDevices(void)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/bluetooth");
if(dirp == NULL)
return 0;
uint32_t result = 0;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (strchr(entry->d_name, ':') != NULL)
++result;
}
return result;
}
#endif
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
const char* ffDetectBluetooth(FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
{
#ifdef FF_HAVE_DBUS
return detectBluetooth(devices);
int32_t connectedCount = -1;
if (!options->showDisconnected)
{
connectedCount = (int32_t) connectedDevices();
if (connectedCount == 0)
return NULL;
}
return detectBluetooth(devices, connectedCount);
#else
return "Fastfetch was compiled without DBus support";
#endif
@@ -1,6 +1,6 @@
#include "bluetooth.h"
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
{
return "Not supported on this platform";
}
+14 -10
View File
@@ -7,7 +7,7 @@
#pragma GCC diagnostic ignored "-Wpointer-sign"
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */)
{
// Actually bluetoothapis.dll, but it's missing on Windows 7
FF_LIBRARY_LOAD(bluetoothapis, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
@@ -20,26 +20,27 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
};
HBLUETOOTH_DEVICE_FIND hFind = ffBluetoothFindFirstDevice(&(BLUETOOTH_DEVICE_SEARCH_PARAMS) {
.fReturnConnected = TRUE,
.fReturnRemembered = TRUE,
.fReturnAuthenticated = TRUE,
.fReturnUnknown = TRUE,
.fReturnRemembered = options->showDisconnected,
.fReturnAuthenticated = options->showDisconnected,
.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS)
}, &btdi);
if(!hFind)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
return NULL;
return "BluetoothFindFirstDevice() failed";
}
do {
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitWS(&device->name, btdi.szName);
ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x",
btdi.Address.rgBytes[0],
btdi.Address.rgBytes[1],
btdi.Address.rgBytes[2],
btdi.Address.rgBytes[3],
ffStrbufInitF(&device->address, "%02X:%02X:%02X:%02X:%02X:%02X",
btdi.Address.rgBytes[5],
btdi.Address.rgBytes[4],
btdi.Address.rgBytes[5]);
btdi.Address.rgBytes[3],
btdi.Address.rgBytes[2],
btdi.Address.rgBytes[1],
btdi.Address.rgBytes[0]);
ffStrbufInit(&device->type);
device->battery = 0;
device->connected = !!btdi.fConnected;
@@ -121,5 +122,8 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
ffBluetoothFindDeviceClose(hFind);
const char* ffBluetoothDetectBattery(FFlist* result);
ffBluetoothDetectBattery(devices);
return NULL;
}
@@ -0,0 +1,122 @@
extern "C"
{
#include "bluetooth.h"
}
#include "util/windows/wmi.hpp"
#include "util/windows/unicode.hpp"
STDAPI InitVariantFromStringArray(_In_reads_(cElems) PCWSTR *prgsz, _In_ ULONG cElems, _Out_ VARIANT *pvar);
template <typename Fn>
struct on_scope_exit {
on_scope_exit(Fn &&fn): _fn(std::move(fn)) {}
~on_scope_exit() { this->_fn(); }
private:
Fn _fn;
};
extern "C"
const char* ffBluetoothDetectBattery(FFlist* devices)
{
FFWmiQuery query(L"SELECT __PATH FROM Win32_PnPEntity WHERE Service = 'BthHFEnum'", nullptr, FFWmiNamespace::CIMV2);
if(!query)
return "Query WMI service failed";
IWbemClassObject* pInParams = nullptr;
on_scope_exit releaseInParams([&] { pInParams && pInParams->Release(); });
{
IWbemClassObject* pnpEntityClass = nullptr;
if (FAILED(query.pService->GetObjectW(bstr_t(L"Win32_PnPEntity"), 0, nullptr, &pnpEntityClass, nullptr)))
return "Failed to get PnP entity class";
on_scope_exit releasePnpEntityClass([&] { pnpEntityClass && pnpEntityClass->Release(); });
if (FAILED(pnpEntityClass->GetMethod(bstr_t(L"GetDeviceProperties"), 0, &pInParams, NULL)))
return "Failed to get GetDeviceProperties method";
VARIANT devicePropertyKeys;
PCWSTR props[] = { L"{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2", L"DEVPKEY_Bluetooth_DeviceAddress" };
if (FAILED(InitVariantFromStringArray(props, ARRAY_SIZE(props), &devicePropertyKeys)))
return "Failed to init variant from string array";
on_scope_exit releaseDevicePropertyKeys([&] { VariantClear(&devicePropertyKeys); });
if (FAILED(pInParams->Put(L"devicePropertyKeys", 0, &devicePropertyKeys, CIM_FLAG_ARRAY | CIM_STRING)))
return "Failed to put devicePropertyKeys";
}
while (FFWmiRecord record = query.next())
{
IWbemCallResult* pCallResult = nullptr;
if (FAILED(query.pService->ExecMethod(record.get(L"__PATH").bstrVal, bstr_t(L"GetDeviceProperties"), 0, nullptr, pInParams, nullptr, &pCallResult)))
continue;
on_scope_exit releaseCallResult([&] { pCallResult && pCallResult->Release(); });
IWbemClassObject* pResultObject = nullptr;
if (FAILED(pCallResult->GetResultObject((LONG) WBEM_INFINITE, &pResultObject)))
continue;
on_scope_exit releaseResultObject([&] { pResultObject && pResultObject->Release(); });
VARIANT propArray;
if (FAILED(pResultObject->Get(L"deviceProperties", 0, &propArray, nullptr, nullptr)))
continue;
on_scope_exit releasePropArray([&] { VariantClear(&propArray); });
if (propArray.vt != (VT_ARRAY | VT_UNKNOWN) ||
(propArray.parray->fFeatures & FADF_UNKNOWN) == 0 ||
propArray.parray->cDims != 1 ||
propArray.parray->rgsabound[0].cElements != 2
)
continue;
uint8_t batt = 0;
for (LONG i = 0; i < 2; i++)
{
IWbemClassObject* object = nullptr;
if (FAILED(SafeArrayGetElement(propArray.parray, &i, &object)))
continue;
FFWmiRecord rec(object);
auto data = rec.get(L"Data");
if (data.vt == VT_EMPTY)
break;
if (i == 0)
batt = data.get<uint8_t>();
else
{
FF_STRBUF_AUTO_DESTROY addr; // MAC address without colon
ffStrbufInitWSV(&addr, data.get<std::wstring_view>());
if (__builtin_expect(addr.length != 12, 0))
continue;
FF_LIST_FOR_EACH(FFBluetoothResult, bt, *devices)
{
if (bt->address.length != 12 + 5)
continue;
if (addr.chars[0] == bt->address.chars[0] &&
addr.chars[1] == bt->address.chars[1] &&
addr.chars[2] == bt->address.chars[3] &&
addr.chars[3] == bt->address.chars[4] &&
addr.chars[4] == bt->address.chars[6] &&
addr.chars[5] == bt->address.chars[7] &&
addr.chars[6] == bt->address.chars[9] &&
addr.chars[7] == bt->address.chars[10] &&
addr.chars[8] == bt->address.chars[12] &&
addr.chars[9] == bt->address.chars[13] &&
addr.chars[10] == bt->address.chars[15] &&
addr.chars[11] == bt->address.chars[16])
{
bt->battery = batt;
break;
}
}
}
}
}
return NULL;
}
@@ -3,56 +3,47 @@
#ifdef FF_HAVE_DBUS
#include "common/dbus.h"
#include "common/io/io.h"
/* Example dbus reply, striped to only the relevant parts:
array [ //root
/* Example dbus reply:
array [
dict entry(
object path "/org/bluez/hci0"
array [
dict entry(
string "org.bluez.Adapter1"
array [
dict entry(
string "Address"
variant string "XX:XX:XX:XX:XX:XX"
)
dict entry(
string "Name"
variant string "xxxxxxxx"
)
dict entry(
string "Powered"
variant boolean true
)
dict entry(
string "PowerState"
variant string "on"
)
dict entry(
string "Manufacturer"
variant uint16 2
)
dict entry(
string "Version"
variant byte 12
)
]
)
]
string "Address"
variant string "XX:XX:XX:XX:XX:XX"
)
dict entry(
string "Name"
variant string "xxxxxxxx"
)
dict entry(
string "Powered"
variant boolean true
)
dict entry(
string "PowerState"
variant string "on"
)
dict entry(
string "Manufacturer"
variant uint16 2
)
dict entry(
string "Version"
variant byte 12
)
]
*/
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothRadioResult* device)
static const char* detectBluetoothProperty(FFBluetoothRadioResult* device, FFDBusData* dbus, DBusMessageIter* iter)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
return "Expected dict entry";
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
return;
return "Expected dict entry key to be a string";
const char* deviceProperty;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty);
@@ -77,121 +68,73 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue
ffDBusGetBool(dbus, &dictIter, &device->discoverable);
else if(ffStrEquals(deviceProperty, "Pairable"))
ffDBusGetBool(dbus, &dictIter, &device->connectable);
return NULL;
}
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothRadioResult* device)
static const char* detectBluetoothRoot(FFBluetoothRadioResult* device, const char* hciName, FFDBusData* dbus)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
char objPath[300];
snprintf(objPath, sizeof(objPath), "/org/bluez/%s", hciName);
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
DBusMessage* properties = ffDBusGetMethodReply(dbus, "org.bluez", objPath, "org.freedesktop.DBus.Properties", "GetAll", "org.bluez.Adapter1");
if(!properties)
return "Failed to call org.freedesktop.DBus.Properties.GetAll";
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
return;
const char* propertyType;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &propertyType);
if(!ffStrContains(propertyType, ".Adapter"))
return; //We don't care about other properties
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
return;
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
do
DBusMessageIter rootIter;
if(!dbus->lib->ffdbus_message_iter_init(properties, &rootIter))
{
detectBluetoothValue(dbus, &arrayIter, device);
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
}
static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_OBJECT_PATH)
return;
const char* objectPath;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &objectPath);
//We want adapter objects
if(!ffStrStartsWith(objectPath, "/org/bluez/hci") || ffStrContains(objectPath, "/dev_"))
return;
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
return;
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
FFBluetoothRadioResult* device = ffListAdd(devices);
ffStrbufInit(&device->name);
ffStrbufInit(&device->address);
ffStrbufInitStatic(&device->vendor, "Unknown");
device->lmpVersion = INT_MIN;
device->lmpSubversion = INT_MIN;
device->enabled = false;
do
{
detectBluetoothProperty(dbus, &arrayIter, device);
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
if(device->name.length == 0)
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->address);
--devices->length;
dbus->lib->ffdbus_message_unref(properties);
return "Failed to get root iterator of org.freedesktop.DBus.Properties.GetAll";
}
}
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
return;
if(dbus->lib->ffdbus_message_iter_get_arg_type(&rootIter) != DBUS_TYPE_ARRAY)
{
dbus->lib->ffdbus_message_unref(properties);
return "Expected array";
}
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &arrayIter);
dbus->lib->ffdbus_message_iter_recurse(&rootIter, &arrayIter);
do
{
detectBluetoothObject(devices, dbus, &arrayIter);
detectBluetoothProperty(device, dbus, &arrayIter);
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
dbus->lib->ffdbus_message_unref(properties);
return NULL;
}
static const char* detectBluetooth(FFlist* devices)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/bluetooth");
if(dirp == NULL)
return "Failed to open /sys/class/bluetooth";
FFDBusData dbus;
const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus);
if(error)
return error;
DBusMessage* managedObjects = ffDBusGetMethodReply(&dbus, "org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", NULL);
if(!managedObjects)
return "Failed to call GetManagedObjects";
DBusMessageIter rootIter;
if(!dbus.lib->ffdbus_message_iter_init(managedObjects, &rootIter))
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
dbus.lib->ffdbus_message_unref(managedObjects);
return "Failed to get root iterator of GetManagedObjects";
if (entry->d_name[0] == '.')
continue;
if (strchr(entry->d_name, ':') != NULL) // ignore connected devices
continue;
FFBluetoothRadioResult* device = ffListAdd(devices);
ffStrbufInit(&device->name);
ffStrbufInit(&device->address);
ffStrbufInitStatic(&device->vendor, "Unknown");
device->lmpVersion = INT_MIN;
device->lmpSubversion = INT_MIN;
device->enabled = false;
detectBluetoothRoot(device, entry->d_name, &dbus);
}
detectBluetoothRoot(devices, &dbus, &rootIter);
dbus.lib->ffdbus_message_unref(managedObjects);
return NULL;
}
@@ -202,6 +145,7 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
#ifdef FF_HAVE_DBUS
return detectBluetooth(devices);
#else
FF_UNUSED(devices)
return "Fastfetch was compiled without DBus support";
#endif
}
@@ -84,12 +84,12 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
BLUETOOTH_ADDRESS_STRUCT addr = { .ullLong = blri.localInfo.address };
ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x",
addr.rgBytes[0],
addr.rgBytes[1],
addr.rgBytes[2],
addr.rgBytes[3],
addr.rgBytes[5],
addr.rgBytes[4],
addr.rgBytes[5]);
addr.rgBytes[3],
addr.rgBytes[2],
addr.rgBytes[1],
addr.rgBytes[0]);
device->lmpVersion = blri.radioInfo.lmpVersion;
device->lmpSubversion = blri.radioInfo.lmpSubversion;
+17
View File
@@ -0,0 +1,17 @@
#include "board.h"
#include "common/sysctl.h"
#include "util/smbiosHelper.h"
const char* ffDetectBoard(FFBoardResult* board)
{
if (ffSysctlGetString("machdep.dmi.board-product", &board->name) == NULL)
ffCleanUpSmbiosValue(&board->name);
if (ffSysctlGetString("machdep.dmi.board-version", &board->version) == NULL)
ffCleanUpSmbiosValue(&board->version);
if (ffSysctlGetString("machdep.dmi.board-vendor", &board->vendor) == NULL)
ffCleanUpSmbiosValue(&board->vendor);
if (ffSysctlGetString("machdep.dmi.board-serial", &board->serial) == NULL)
ffCleanUpSmbiosValue(&board->serial);
return NULL;
}
+2 -2
View File
@@ -34,9 +34,9 @@ bool ffEfiFillLoadOption(const FFEfiLoadOption* efiOption, FFBootmgrResult* resu
ffEfiUcs2ToUtf8(efiOption->Description, &result->name);
for (
ffEfiDevicePathProtocol* filePathList = (void*) &efiOption->Description[descLen + 1];
ffEfiDevicePathProtocol* filePathList = (ffEfiDevicePathProtocol*) &efiOption->Description[descLen + 1];
filePathList->Type != 0x7F; // End of Hardware Device Path
filePathList = (void*) ((uint8_t*) filePathList + filePathList->Length))
filePathList = (ffEfiDevicePathProtocol*) ((uint8_t*) filePathList + filePathList->Length))
{
if (filePathList->Type == 4 && filePathList->SubType == 4)
{
+2 -2
View File
@@ -38,9 +38,9 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
uint8_t buffer[2048];
wchar_t key[16];
swprintf(key, sizeof(key) / sizeof(*key), L"Boot%04X", value);
swprintf(key, ARRAY_SIZE(key), L"Boot%04X", value);
uint32_t size = GetFirmwareEnvironmentVariableW(key, L"{" FF_EFI_GLOBAL_GUID L"}", buffer, sizeof(buffer));
if (size < sizeof(FFEfiLoadOption) || size == sizeof(buffer))
if (size < sizeof(FFEfiLoadOption) || size == ARRAY_SIZE(buffer))
return "GetFirmwareEnvironmentVariableW(Boot####) failed";
ffEfiFillLoadOption((FFEfiLoadOption *)buffer, result);
+5 -5
View File
@@ -92,13 +92,13 @@ static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult*
for (uint32_t i = 0; i < 2; ++i)
{
IOAVServiceWriteI2C(service, 0x37, 0x51, i2cIn, sizeof(i2cIn));
IOAVServiceWriteI2C(service, 0x37, 0x51, i2cIn, ARRAY_SIZE(i2cIn));
usleep(options->ddcciSleep * 1000);
}
}
uint8_t i2cOut[12] = {};
if (IOAVServiceReadI2C(service, 0x37, 0x51, i2cOut, sizeof(i2cOut)) == KERN_SUCCESS)
if (IOAVServiceReadI2C(service, 0x37, 0x51, i2cOut, ARRAY_SIZE(i2cOut)) == KERN_SUCCESS)
{
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00)
continue;
@@ -113,7 +113,7 @@ static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult*
ffStrbufInit(&brightness->name);
uint8_t edid[128] = {};
if (IOAVServiceReadI2C(service, 0x50, 0x00, edid, sizeof(edid)) == KERN_SUCCESS)
if (IOAVServiceReadI2C(service, 0x50, 0x00, edid, ARRAY_SIZE(edid)) == KERN_SUCCESS)
ffEdidGetName(edid, &brightness->name);
}
}
@@ -155,12 +155,12 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
.sendAddress = 0x6e,
.sendTransactionType = kIOI2CSimpleTransactionType,
.sendBuffer = (vm_address_t) i2cIn,
.sendBytes = sizeof(i2cIn) / sizeof(i2cIn[0]),
.sendBytes = ARRAY_SIZE(i2cIn),
.minReplyDelay = options->ddcciSleep,
.replyAddress = 0x6F,
.replySubAddress = 0x51,
.replyTransactionType = kIOI2CDDCciReplyTransactionType,
.replyBytes = sizeof(i2cOut) / sizeof(i2cOut[0]),
.replyBytes = ARRAY_SIZE(i2cOut),
.replyBuffer = (vm_address_t) i2cOut,
};
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
+2 -2
View File
@@ -16,7 +16,7 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFl
for (char i = '0'; i <= '9'; ++i)
{
path[sizeof(path) - 2] = i;
path[ARRAY_SIZE(path) - 2] = i;
FF_AUTO_CLOSE_FD int blfd = open(path, O_RDONLY | O_CLOEXEC);
if (blfd < 0)
@@ -34,7 +34,7 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFl
brightness->current = status.brightness;
struct backlight_info info;
if(ioctl(blfd, BACKLIGHTGETINFO, &info) < 0)
if(ioctl(blfd, BACKLIGHTGETINFO, &info) == 0)
ffStrbufAppendS(&brightness->name, info.name);
else
ffStrbufAppendS(&brightness->name, path + strlen("/dev/backlight/"));
+3 -3
View File
@@ -25,7 +25,7 @@ static const char* detectWithBacklight(FFlist* result)
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
if(entry->d_name[0] == '.')
continue;
ffStrbufAppendS(&backlightDir, entry->d_name);
@@ -48,7 +48,7 @@ static const char* detectWithBacklight(FFlist* result)
// if we managed to get edid, use it
ffStrbufAppendS(&brightness->name, "/edid");
uint8_t edidData[128];
if(ffReadFileData(brightness->name.chars, sizeof(edidData), edidData) == sizeof(edidData))
if(ffReadFileData(brightness->name.chars, ARRAY_SIZE(edidData), edidData) == ARRAY_SIZE(edidData))
{
ffStrbufClear(&brightness->name);
ffEdidGetName(edidData, &brightness->name);
@@ -99,7 +99,7 @@ double ddca_set_default_sleep_multiplier(double multiplier); // ddcutil 1.4
DDCA_Status ddca_init(const char *libopts, int syslog_level, int opts);
#endif
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
static const char* detectWithDdcci(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
FF_LIBRARY_LOAD(libddcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
@@ -0,0 +1,25 @@
#include "brightness.h"
#include "common/sysctl.h"
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
// https://man.netbsd.org/NetBSD-10.1/acpiout.4#DESCRIPTION
char key[] = "hw.acpi.acpiout0.brightness";
char* pn = key + strlen("hw.acpi.acpiout");
for (uint32_t i = 0; i <= 9; ++i)
{
*pn = (char) ('0' + i);
int value = ffSysctlGetInt(key, -1);
if (value == -1) continue;
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
ffStrbufInitF(&brightness->name, "acpiout%d", i);
brightness->max = 100;
brightness->min = 0;
brightness->current = value;
}
return NULL;
}
@@ -0,0 +1,30 @@
#include "brightness.h"
#include "common/io/io.h"
#include <dev/wscons/wsconsio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
FF_AUTO_CLOSE_FD int devfd = open("/dev/ttyC0", O_RDONLY);
if (devfd < 0) return "open(dev/ttyC0, O_RDONLY) failed";
struct wsdisplay_param param = {
.param = WSDISPLAYIO_PARAM_BRIGHTNESS,
};
if (ioctl(devfd, WSDISPLAYIO_GETPARAM, &param) < 0)
return "ioctl(WSDISPLAYIO_GETPARAM) failed";
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
ffStrbufInitStatic(&brightness->name, "wsdisplay");
brightness->max = param.max;
brightness->min = param.min;
brightness->current = param.curval;
return NULL;
}
+41 -67
View File
@@ -1,16 +1,18 @@
#include "btrfs.h"
#include "common/io/io.h"
#include <fcntl.h>
enum { uuidLen = (uint32_t) __builtin_strlen("00000000-0000-0000-0000-000000000000") };
static const char* enumerateDevices(FFBtrfsResult* item, FFstrbuf* path, FFstrbuf* buffer)
static const char* enumerateDevices(FFBtrfsResult* item, int dfd, FFstrbuf* buffer)
{
ffStrbufAppendS(path, "devices/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path->chars);
int subfd = openat(dfd, "devices", O_RDONLY | O_CLOEXEC | O_DIRECTORY);
if (subfd < 0) return "openat(\"/sys/fs/btrfs/UUID/devices\") == -1";
FF_AUTO_CLOSE_DIR DIR* dirp = fdopendir(subfd);
if(dirp == NULL)
return "opendir(\"/sys/fs/btrfs/UUID/devices\") == NULL";
const uint32_t devicesPathLen = path->length;
return "fdopendir(\"/sys/fs/btrfs/UUID/devices\") == NULL";
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
@@ -21,25 +23,25 @@ static const char* enumerateDevices(FFBtrfsResult* item, FFstrbuf* path, FFstrbu
if (item->devices.length)
ffStrbufAppendC(&item->devices, ',');
ffStrbufAppendS(&item->devices, entry->d_name);
ffStrbufAppendS(path, entry->d_name);
ffStrbufAppendS(path, "/size");
if (ffReadFileBuffer(path->chars, buffer))
char path[ARRAY_SIZE(entry->d_name) + ARRAY_SIZE("/size") + 1];
snprintf(path, ARRAY_SIZE(path), "%s/size", entry->d_name);
if (ffReadFileBufferRelative(subfd, path, buffer))
item->totalSize += ffStrbufToUInt(buffer, 0) * 512;
ffStrbufSubstrBefore(path, devicesPathLen);
}
return NULL;
}
static const char* enumerateFeatures(FFBtrfsResult* item, FFstrbuf* path)
static const char* enumerateFeatures(FFBtrfsResult* item, int dfd)
{
ffStrbufAppendS(path, "features/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path->chars);
int subfd = openat(dfd, "features", O_RDONLY | O_CLOEXEC | O_DIRECTORY);
if (subfd < 0) return "openat(\"/sys/fs/btrfs/UUID/features\") == -1";
FF_AUTO_CLOSE_DIR DIR* dirp = fdopendir(subfd);
if(dirp == NULL)
return "opendir(\"/sys/fs/btrfs/UUID/features\") == NULL";
const uint32_t featuresPathLen = path->length;
return "fdopendir(\"/sys/fs/btrfs/UUID/features\") == NULL";
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
@@ -49,45 +51,33 @@ static const char* enumerateFeatures(FFBtrfsResult* item, FFstrbuf* path)
if (item->features.length)
ffStrbufAppendC(&item->features, ',');
ffStrbufAppendS(&item->features, entry->d_name);
ffStrbufSubstrBefore(path, featuresPathLen);
}
return NULL;
}
static const char* detectAllocation(FFBtrfsResult* item, FFstrbuf* path, FFstrbuf* buffer)
static const char* detectAllocation(FFBtrfsResult* item, int dfd, FFstrbuf* buffer)
{
ffStrbufAppendS(path, "allocation/");
const uint32_t AllocationPathLen = path->length;
FF_AUTO_CLOSE_FD int subfd = openat(dfd, "allocation", O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
if (subfd < 0) return "openat(\"/sys/fs/btrfs/UUID/allocation\") == -1";
ffStrbufAppendS(path, "global_rsv_size");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(subfd, "global_rsv_size", buffer))
item->globalReservationTotal = ffStrbufToUInt(buffer, 0);
else
return "ffReadFileBuffer(\"/sys/fs/btrfs/UUID/allocation/global_rsv_size\") == NULL";
ffStrbufSubstrBefore(path, AllocationPathLen);
ffStrbufAppendS(path, "global_rsv_reserved");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(subfd, "global_rsv_reserved", buffer))
item->globalReservationUsed = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, AllocationPathLen);
item->globalReservationUsed = item->globalReservationTotal - item->globalReservationUsed;
#define FF_BTRFS_DETECT_TYPE(index, _type) \
ffStrbufAppendS(path, #_type "/total_bytes"); \
if (ffReadFileBuffer(path->chars, buffer)) \
if (ffReadFileBufferRelative(subfd, #_type "/total_bytes", buffer)) \
item->allocation[index].total = ffStrbufToUInt(buffer, 0); \
ffStrbufSubstrBefore(path, AllocationPathLen); \
\
ffStrbufAppendS(path, #_type "/bytes_used"); \
if (ffReadFileBuffer(path->chars, buffer)) \
if (ffReadFileBufferRelative(subfd, #_type "/bytes_used", buffer)) \
item->allocation[index].used = ffStrbufToUInt(buffer, 0); \
ffStrbufSubstrBefore(path, AllocationPathLen); \
\
ffStrbufAppendS(path, #_type "/dup"); \
item->allocation[index].dup = ffPathExists(path->chars, FF_PATHTYPE_DIRECTORY); \
ffStrbufSubstrBefore(path, AllocationPathLen); \
item->allocation[index].dup = faccessat(subfd, #_type "/dup/", F_OK, 0) == 0; \
\
item->allocation[index].type = #_type;
@@ -102,10 +92,7 @@ static const char* detectAllocation(FFBtrfsResult* item, FFstrbuf* path, FFstrbu
const char* ffDetectBtrfs(FFlist* result)
{
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/fs/btrfs/");
const uint32_t basePathLen = path.length;
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path.chars);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/fs/btrfs/");
if(dirp == NULL)
return "opendir(\"/sys/fs/btrfs\") == NULL";
@@ -120,46 +107,33 @@ const char* ffDetectBtrfs(FFlist* result)
continue;
FFBtrfsResult* item = ffListAdd(result);
(*item) = (FFBtrfsResult){};
ffStrbufInitNS(&item->uuid, uuidLen, entry->d_name);
ffStrbufInit(&item->name);
ffStrbufInit(&item->devices);
ffStrbufInit(&item->features);
(*item) = (FFBtrfsResult){
.uuid = ffStrbufCreateNS(uuidLen, entry->d_name),
.name = ffStrbufCreate(),
.devices = ffStrbufCreate(),
.features = ffStrbufCreate(),
};
ffStrbufAppendNS(&path, uuidLen, entry->d_name);
ffStrbufAppendC(&path, '/');
const uint32_t itemPathLen = path.length;
FF_AUTO_CLOSE_FD int dfd = openat(dirfd(dirp), entry->d_name, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
if (dfd < 0) continue;
ffStrbufAppendS(&path, "label");
if (ffAppendFileBuffer(path.chars, &item->name))
if (ffAppendFileBufferRelative(dfd, "label", &item->name))
ffStrbufTrimRightSpace(&item->name);
ffStrbufSubstrBefore(&path, itemPathLen);
enumerateDevices(item, &path, &buffer);
ffStrbufSubstrBefore(&path, itemPathLen);
enumerateDevices(item, dfd, &buffer);
enumerateFeatures(item, &path);
ffStrbufSubstrBefore(&path, itemPathLen);
enumerateFeatures(item, dfd);
ffStrbufAppendS(&path, "generation");
if (ffReadFileBuffer(path.chars, &buffer))
if (ffReadFileBufferRelative(dfd, "generation", &buffer))
item->generation = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, itemPathLen);
ffStrbufAppendS(&path, "nodesize");
if (ffReadFileBuffer(path.chars, &buffer))
if (ffReadFileBufferRelative(dfd, "nodesize", &buffer))
item->nodeSize = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, itemPathLen);
ffStrbufAppendS(&path, "sectorsize");
if (ffReadFileBuffer(path.chars, &buffer))
if (ffReadFileBufferRelative(dfd, "sectorsize", &buffer))
item->sectorSize = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrBefore(&path, itemPathLen);
detectAllocation(item, &path, &buffer);
// finally
ffStrbufSubstrBefore(&path, basePathLen);
detectAllocation(item, dfd, &buffer);
}
return NULL;
+1 -1
View File
@@ -16,7 +16,7 @@ const char* ffDetectCamera(FFlist* result)
for (uint32_t i = 0; i <= 9; ++i)
{
path[sizeof(path) - 2] = (char) (i + '0');
path[ARRAY_SIZE(path) - 2] = (char) (i + '0');
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY);
if (fd < 0)
break;
+2 -2
View File
@@ -52,7 +52,7 @@ const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
wchar_t buffer[256];
uint32_t length = 0;
if (FAILED(device->GetString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, buffer, sizeof(buffer), &length)) || length == 0)
if (FAILED(device->GetString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, buffer, ARRAY_SIZE(buffer), &length)) || length == 0)
continue;
FFCameraResult* camera = (FFCameraResult*) ffListAdd(result);
@@ -63,7 +63,7 @@ const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
camera->width = 0;
camera->height = 0;
if (SUCCEEDED(device->GetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, buffer, sizeof(buffer), &length)) && length > 0)
if (SUCCEEDED(device->GetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, buffer, ARRAY_SIZE(buffer), &length)) && length > 0)
ffStrbufSetNWS(&camera->id, length, buffer);
IMFMediaSource* FF_AUTO_RELEASE_COM_OBJECT source = nullptr;
+17
View File
@@ -0,0 +1,17 @@
#include "chassis.h"
#include "common/sysctl.h"
#include "util/smbiosHelper.h"
const char* ffDetectChassis(FFChassisResult* chassis)
{
if (ffSysctlGetString("machdep.dmi.chassis-type", &chassis->type) == NULL)
ffCleanUpSmbiosValue(&chassis->type);
if (ffSysctlGetString("machdep.dmi.chassis-version", &chassis->version) == NULL)
ffCleanUpSmbiosValue(&chassis->version);
if (ffSysctlGetString("machdep.dmi.chassis-vendor", &chassis->vendor) == NULL)
ffCleanUpSmbiosValue(&chassis->vendor);
if (ffSysctlGetString("machdep.dmi.chassis-serial", &chassis->serial) == NULL)
ffCleanUpSmbiosValue(&chassis->serial);
return NULL;
}
+4 -1
View File
@@ -13,9 +13,10 @@ const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu)
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
" with Radeon Graphics"
};
ffStrbufRemoveStrings(&cpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
ffStrbufRemoveStrings(&cpu->name, ARRAY_SIZE(removeStrings), removeStrings);
ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own
ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it
ffStrbufRemoveDupWhitespaces(&cpu->name);
return NULL;
}
@@ -37,6 +38,8 @@ const char* ffCPUAppleCodeToName(uint32_t code)
case 6031:
case 6034: return "Apple M3 Max";
case 8132: return "Apple M4";
case 6040: return "Apple M4 Pro";
case 6041: return "Apple M4 Max";
default: return NULL;
}
}
+1
View File
@@ -15,6 +15,7 @@ typedef struct FFCPUResult
FFstrbuf name;
FFstrbuf vendor;
uint16_t packages;
uint16_t coresPhysical;
uint16_t coresLogical;
uint16_t coresOnline;
+9 -3
View File
@@ -59,7 +59,12 @@ static const char* detectFrequency(FFCPUResult* cpu)
pMax = pMax > pStart[i] ? pMax : pStart[i];
if (pMax > 0)
cpu->frequencyMax = pMax / 1000 / 1000;
{
if (pMax > 100000000) // Assume that pMax is in Hz, M1~M3
cpu->frequencyMax = pMax / 1000 / 1000;
else // Assume that pMax is in kHz, M4 and later (#1394)
cpu->frequencyMax = pMax / 1000;
}
return NULL;
}
@@ -85,8 +90,8 @@ static const char* detectCoreCount(FFCPUResult* cpu)
if (nPerfLevels <= 0) return "sysctl(hw.nperflevels) failed";
char sysctlKey[] = "hw.perflevelN.logicalcpu";
if (nPerfLevels > sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]))
nPerfLevels = sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]);
if (nPerfLevels > ARRAY_SIZE(cpu->coreTypes))
nPerfLevels = ARRAY_SIZE(cpu->coreTypes);
for (uint32_t i = 0; i < nPerfLevels; ++i)
{
sysctlKey[strlen("hw.perflevel")] = (char) ('0' + i);
@@ -104,6 +109,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
return "sysctlbyname(machdep.cpu.brand_string) failed";
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
cpu->packages = (uint16_t) ffSysctlGetInt("hw.packages", 1);
if (cpu->vendor.length == 0 && ffStrbufStartsWithS(&cpu->name, "Apple "))
ffStrbufAppendS(&cpu->vendor, "Apple");
+5 -1
View File
@@ -168,7 +168,8 @@ static const char* qcomPartId2name(uint32_t partId)
{
switch (partId)
{
case 0x001: return "Oryon";
case 0x001: return "Oryon 1";
case 0x002: return "Oryon 2";
case 0x00f: return "Scorpion";
case 0x02d: return "Scorpion";
case 0x04d: return "Krait";
@@ -262,6 +263,9 @@ static const char* applePartId2name(uint32_t partId)
case 0x037: return "Everest-A16";
case 0x038: return "Blizzard-M2-Max";
case 0x039: return "Avalanche-M2-Max";
case 0x046: return "Sawtooth-M11";
case 0x048: return "Sawtooth-M3-Max";
case 0x049: return "Everest-M3-Max";
default: return NULL;
}
}
+18 -2
View File
@@ -1,6 +1,12 @@
#include "cpu.h"
#include "common/sysctl.h"
#include <sys/param.h>
#if __has_include(<sys/cpuset.h>)
#include <sys/cpuset.h>
#define FF_HAVE_CPUSET 1
#endif
static const char* detectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
@@ -25,7 +31,7 @@ static const char* detectThermalTemp(double* current)
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString("hw.model", &cpu->name))
if (ffSysctlGetString("hw.model", &cpu->name) != NULL)
return "sysctlbyname(hw.model) failed";
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
@@ -60,9 +66,19 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
}
}
#if FF_HAVE_CPUSET && (__x86_64__ || __i386__)
// Bind current process to the first two cores, which is *usually* a performance core
cpuset_t currentCPU;
CPU_ZERO(&currentCPU);
CPU_SET(1, &currentCPU);
CPU_SET(2, &currentCPU);
cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), &currentCPU);
#endif
ffCPUDetectSpeedByCpuid(cpu);
cpu->frequencyBase = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
uint32_t clockrate = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
if (clockrate > cpu->frequencyBase) cpu->frequencyBase = clockrate;
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
+113 -37
View File
@@ -44,12 +44,20 @@ static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
if(
ffStrbufContainS(buffer, "cpu") ||
ffStrbufEqualS(buffer, "k10temp") || // AMD
ffStrbufEqualS(buffer, "fam15h_power") || // AMD
ffStrbufEqualS(buffer, "coretemp") // Intel
) return value / 1000.;
return 0.0/0.0;
}
static double detectTZTemp(FFstrbuf* buffer)
{
if (ffReadFileBuffer("/sys/class/thermal/thermal_zone0/temp", buffer))
return ffStrbufToDouble(buffer) / 1000.;
return 0.0/0.0;
}
static double detectCPUTemp(void)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
@@ -79,7 +87,7 @@ static double detectCPUTemp(void)
ffStrbufSubstrBefore(&baseDir, baseDirLength);
}
return 0.0/0.0;
return detectTZTemp(&buffer);
}
#ifdef __ANDROID__
@@ -89,7 +97,9 @@ static void detectQualcomm(FFCPUResult* cpu)
{
// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips
if (ffStrbufEqualS(&cpu->name, "SM8635"))
if (ffStrbufEqualS(&cpu->name, "SM8750"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Elite [SM8750]");
else if (ffStrbufEqualS(&cpu->name, "SM8635"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8s Gen 3 [SM8635]");
else if (ffStrbufEqualS(&cpu->name, "SM8650-AC"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Gen 3 for Galaxy [SM8650-AC]");
@@ -134,6 +144,36 @@ static void detectQualcomm(FFCPUResult* cpu)
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 4 Gen 1 [SM4375]");
}
static void detectMediaTek(FFCPUResult* cpu)
{
// https://en.wikipedia.org/wiki/List_of_MediaTek_systems_on_chips
if (ffStrbufEqualS(&cpu->name, "MT6991"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9400 [MT6991]");
else if (ffStrbufEqualS(&cpu->name, "MT6991Z"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9400 [MT6991Z]");
else if (ffStrbufEqualS(&cpu->name, "MT6989Z"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300+ [MT6989Z]");
else if (ffStrbufEqualS(&cpu->name, "MT8796Z"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300+ [MT8796Z]");
else if (ffStrbufEqualS(&cpu->name, "MT6989"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300 [MT6989]");
else if (ffStrbufEqualS(&cpu->name, "MT8796"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300 [MT8796]");
else if (ffStrbufEqualS(&cpu->name, "MT6985W"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9200+ [MT6985W]");
else if (ffStrbufEqualS(&cpu->name, "MT6985"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9200 [MT6985]");
else if (ffStrbufEqualS(&cpu->name, "MT6983W"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000+ [MT6983W]");
else if (ffStrbufEqualS(&cpu->name, "MT8798Z/T"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000+ [MT8798Z/T]");
else if (ffStrbufEqualS(&cpu->name, "MT6983Z"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000 [MT6983Z]");
else if (ffStrbufEqualS(&cpu->name, "MT8798Z/C"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000 [MT8798Z/C]");
}
static void detectAndroid(FFCPUResult* cpu)
{
if (cpu->name.length == 0)
@@ -151,46 +191,53 @@ static void detectAndroid(FFCPUResult* cpu)
if (ffStrbufEqualS(&cpu->vendor, "QTI") && ffStrbufStartsWithS(&cpu->name, "SM"))
detectQualcomm(cpu);
else if (ffStrbufEqualS(&cpu->vendor, "MTK") && ffStrbufStartsWithS(&cpu->name, "MT"))
detectMediaTek(cpu);
}
#endif
#if __arm__ || __aarch64__
#include "cpu_arm.h"
static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId)
static void detectArmName(FFstrbuf* cpuinfo, FFCPUResult* cpu, uint32_t implId)
{
FF_AUTO_FREE char* line = NULL;
rewind(cpuinfo);
char* line = NULL;
size_t len = 0;
uint32_t lastPartId = UINT32_MAX;
uint32_t num = 0;
while(getline(&line, &len, cpuinfo) != -1)
while(ffStrbufGetline(&line, &len, cpuinfo))
{
if (!ffStrStartsWith(line, "CPU part\t: ")) continue;
uint32_t partId = (uint32_t) strtoul(line + strlen("CPU part\t: "), NULL, 16);
const char* name = NULL;
if (partId > 0) // Linux reports 0 for unknown CPUs
switch (implId)
{
switch (implId)
{
case 0x41: name = armPartId2name(partId); break;
case 0x42: name = brcmPartId2name(partId); break;
case 0x43: name = caviumPartId2name(partId); break;
case 0x44: name = decPartId2name(partId); break;
case 0x46: name = fujitsuPartId2name(partId); break;
case 0x48: name = hisiPartId2name(partId); break;
case 0x4e: name = nvidiaPartId2name(partId); break;
case 0x50: name = apmPartId2name(partId); break;
case 0x51: name = qcomPartId2name(partId); break;
case 0x53: name = samsungPartId2name(partId); break;
case 0x56: name = marvellPartId2name(partId); break;
case 0x61: name = applePartId2name(partId); break;
case 0x66: name = faradayPartId2name(partId); break;
case 0x69: name = intelPartId2name(partId); break;
case 0x6d: name = msPartId2name(partId); break;
case 0x70: name = ftPartId2name(partId); break;
case 0xc0: name = amperePartId2name(partId); break;
}
case 0x41: name = armPartId2name(partId); break;
case 0x42: name = brcmPartId2name(partId); break;
case 0x43: name = caviumPartId2name(partId); break;
case 0x44: name = decPartId2name(partId); break;
case 0x46: name = fujitsuPartId2name(partId); break;
case 0x48: name = hisiPartId2name(partId); break;
case 0x4e: name = nvidiaPartId2name(partId); break;
case 0x50: name = apmPartId2name(partId); break;
case 0x51: name = qcomPartId2name(partId); break;
case 0x53: name = samsungPartId2name(partId); break;
case 0x56: name = marvellPartId2name(partId); break;
case 0x61:
if (partId == 0)
{
// https://github.com/Dr-Noob/cpufetch/issues/213#issuecomment-1927782105
ffStrbufSetStatic(&cpu->name, "Virtualized Apple Silicon");
ffStrbufGetlineRestore(&line, &len, cpuinfo);
return;
}
name = applePartId2name(partId);
break;
case 0x66: name = faradayPartId2name(partId); break;
case 0x69: name = intelPartId2name(partId); break;
case 0x6d: name = msPartId2name(partId); break;
case 0x70: name = ftPartId2name(partId); break;
case 0xc0: name = amperePartId2name(partId); break;
}
if (lastPartId != partId)
{
@@ -218,18 +265,18 @@ static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId)
#endif
static const char* parseCpuInfo(
FF_MAYBE_UNUSED FILE* cpuinfo,
FF_MAYBE_UNUSED FFCPUResult* cpu,
FFstrbuf* cpuinfo,
FFCPUResult* cpu,
FF_MAYBE_UNUSED FFstrbuf* physicalCoresBuffer,
FF_MAYBE_UNUSED FFstrbuf* cpuMHz,
FF_MAYBE_UNUSED FFstrbuf* cpuIsa,
FF_MAYBE_UNUSED FFstrbuf* cpuUarch,
FF_MAYBE_UNUSED FFstrbuf* cpuImplementer)
{
FF_AUTO_FREE char* line = NULL;
char* line = NULL;
size_t len = 0;
while(getline(&line, &len, cpuinfo) != -1)
while(ffStrbufGetline(&line, &len, cpuinfo))
{
//Stop after reasonable information is acquired
if((*line == '\0' || *line == '\n')
@@ -237,7 +284,10 @@ static const char* parseCpuInfo(
&& cpu->name.length > 0 // #1202 #1204
#endif
)
{
ffStrbufGetlineRestore(&line, &len, cpuinfo);
break;
}
(void)(
// arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful.
@@ -389,7 +439,7 @@ FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
// device-vendor,device-model\0soc-vendor,soc-model\0
char content[256];
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
ssize_t length = ffReadFileData("/proc/device-tree/compatible", ARRAY_SIZE(content), content);
if (length <= 2) return;
// get the second NUL terminated string if it exists
@@ -463,11 +513,32 @@ FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
}
}
FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
{
const char* p = cpuinfo->chars;
uint64_t low = 0, high = 0;
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
{
if (!p) break;
p += strlen("\nphysical id\t:");
char* pend;
unsigned long id = strtoul(p, &pend, 10);
if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist?
high |= 1 << (id - 64);
else
low |= 1 << id;
p = pend;
}
return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high));
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
FF_AUTO_CLOSE_FILE FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
if(cpuinfo == NULL)
return "fopen(\"/proc/cpuinfo\", \"r\") failed";
FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ);
if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0)
return "ffReadFileBuffer(\"/proc/cpuinfo\") failed";
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
@@ -477,12 +548,17 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate();
const char* error = parseCpuInfo(cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
const char* error = parseCpuInfo(&cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
if (error) return error;
cpu->coresLogical = (uint16_t) get_nprocs_conf();
cpu->coresOnline = (uint16_t) get_nprocs();
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
#if __x86_64__ || __i386__
cpu->packages = getPackageCount(&cpuinfo);
if (cpu->packages > 1)
cpu->coresPhysical *= cpu->packages;
#endif
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
ffCPUDetectSpeedByCpuid(cpu);
@@ -517,7 +593,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
#endif
if (cpu->name.length == 0)
detectArmName(cpuinfo, cpu, cpuImplementer);
detectArmName(&cpuinfo, cpu, cpuImplementer);
#endif
return NULL;
+68
View File
@@ -0,0 +1,68 @@
#include "cpu.h"
#include "common/sysctl.h"
#include "common/io/io.h"
#include <sys/envsys.h>
#include <prop/proplib.h>
#include <paths.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
static const char* detectCpuTemp(double* current)
{
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
prop_dictionary_t root = NULL;
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
prop_array_t array = prop_dictionary_get(root, "coretemp0");
if (!array) array = prop_dictionary_get(root, "amdzentemp0");
if (!array) array = prop_dictionary_get(root, "viac7temp0");
if (!array) array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones
if (!array) return "No temp data found in root dictionary";
if (prop_array_count(array) != 2)
return "Unexpected `xtemp0` data";
prop_dictionary_t dict = prop_array_get(array, 0);
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY)
return "Unexpected `xtemp0[0]`";
int temp = 0; // in µK
if (!prop_dictionary_get_int(dict, "cur-value", &temp))
return "Failed to get temperature";
*current = temp / 1e6 - 273.15;
return NULL;
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString("machdep.cpu_brand", &cpu->name) != NULL)
{
if (ffSysctlGetString("machdep.dmi.processor-version", &cpu->name) != NULL)
return "sysctlbyname(machdep.cpu_brand) failed";
}
if (ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor) == NULL)
ffStrbufTrimRightSpace(&cpu->vendor);
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
cpu->coresLogical = cpu->coresPhysical;
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.ncpuonline", cpu->coresLogical);
ffCPUDetectSpeedByCpuid(cpu);
uint32_t freq = (uint32_t) ffSysctlGetInt("machdep.cpu.frequency.target", 0);
if (freq > cpu->frequencyBase) cpu->frequencyBase = freq;
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp) detectCpuTemp(&cpu->temperature);
return NULL;
}
+1 -1
View File
@@ -1,6 +1,6 @@
#include "cpu.h"
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FF_MAYBE_UNUSED FFCPUResult* cpu)
{
return "Not supported on this platform";
}
+14 -2
View File
@@ -1,6 +1,9 @@
#include "cpu.h"
#include "common/sysctl.h"
#include <sys/time.h>
#include <sys/sensors.h>
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString(CTL_HW, HW_MODEL, &cpu->name))
@@ -12,8 +15,17 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
ffCPUDetectSpeedByCpuid(cpu);
cpu->frequencyBase = (uint32_t) ffSysctlGetInt(CTL_HW, HW_CPUSPEED, 0);
cpu->temperature = FF_CPU_TEMP_UNSET; // HW_SENSORS?
uint32_t cpuspeed = (uint32_t) ffSysctlGetInt(CTL_HW, HW_CPUSPEED, 0);
if (cpuspeed > cpu->frequencyBase) cpu->frequencyBase = cpuspeed;
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
{
struct sensor sensors;
size_t size = sizeof(sensors);
if (sysctl((int[]) {CTL_HW, HW_SENSORS, 0, SENSOR_TEMP, 0}, 5, &sensors, &size, NULL, 0) == 0)
cpu->temperature = (double) (sensors.value - 273150000) / 1E6;
}
return NULL;
}
+5 -3
View File
@@ -100,9 +100,7 @@ static const char* detectNCores(FFCPUResult* cpu)
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size)
)
{
if (ptr->Relationship == RelationProcessorCore)
++cpu->coresPhysical;
else if (ptr->Relationship == RelationGroup)
if (ptr->Relationship == RelationGroup)
{
for (uint32_t index = 0; index < ptr->Group.ActiveGroupCount; ++index)
{
@@ -110,6 +108,10 @@ static const char* detectNCores(FFCPUResult* cpu)
cpu->coresLogical += ptr->Group.GroupInfo[index].MaximumProcessorCount;
}
}
else if (ptr->Relationship == RelationProcessorCore)
++cpu->coresPhysical;
else if (ptr->Relationship == RelationProcessorPackage)
cpu->packages++;
}
return NULL;
+1 -1
View File
@@ -2,7 +2,7 @@
#include "fastfetch.h"
typedef enum FFCPUCacheType
typedef enum __attribute__((__packed__)) FFCPUCacheType
{
FF_CPU_CACHE_TYPE_UNIFIED = 0,
FF_CPU_CACHE_TYPE_INSTRUCTION = 1,
+10 -9
View File
@@ -1,5 +1,6 @@
#include "cpucache.h"
#include "common/sysctl.h"
#include "util/stringUtils.h"
const char* ffDetectCPUCache(FFCPUCacheResult* result)
{
@@ -10,44 +11,44 @@ const char* ffDetectCPUCache(FFCPUCacheResult* result)
// macOS provides the global system cache line size
uint32_t lineSize = (uint32_t) ffSysctlGetInt("hw.cachelinesize", 0);
char sysctlKey[256] = "hw.perflevelN.";
char sysctlKey[128] = "hw.perflevelN.";
char* pNum = sysctlKey + strlen("hw.perflevel");
char* pSubkey = sysctlKey + strlen("hw.perflevelN.");
const size_t lenLeft = sizeof(sysctlKey) - strlen("hw.perflevelN.");
const size_t lenLeft = ARRAY_SIZE(sysctlKey) - strlen("hw.perflevelN.");
for (uint32_t i = 0; i < nPerfLevels; ++i)
{
*pNum = (char) ('0' + i);
strncpy(pSubkey, "physicalcpu", lenLeft);
ffStrCopy(pSubkey, "physicalcpu", lenLeft);
uint32_t ncpu = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (ncpu <= 0) continue;
strncpy(pSubkey, "l1icachesize", lenLeft);
ffStrCopy(pSubkey, "l1icachesize", lenLeft);
uint32_t size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (size)
ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_INSTRUCTION)->num = ncpu;
strncpy(pSubkey, "l1dcachesize", lenLeft);
ffStrCopy(pSubkey, "l1dcachesize", lenLeft);
size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (size)
ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_DATA)->num = ncpu;
strncpy(pSubkey, "l2cachesize", lenLeft);
ffStrCopy(pSubkey, "l2cachesize", lenLeft);
size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (size)
{
strncpy(pSubkey, "cpusperl2", lenLeft);
ffStrCopy(pSubkey, "cpusperl2", lenLeft);
uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (cpuSper)
ffCPUCacheAddItem(result, 2, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper;
}
strncpy(pSubkey, "l3cachesize", lenLeft);
ffStrCopy(pSubkey, "l3cachesize", lenLeft);
size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (size)
{
strncpy(pSubkey, "cpusperl3", lenLeft);
ffStrCopy(pSubkey, "cpusperl3", lenLeft);
uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (cpuSper)
ffCPUCacheAddItem(result, 3, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper;
+7 -7
View File
@@ -13,7 +13,7 @@ void ffPrepareCPUUsage(void)
ffGetCpuUsageInfo(&cpuTimes1);
}
const char* ffGetCpuUsageResult(FFlist* result)
const char* ffGetCpuUsageResult(FFCPUUsageOptions* options, FFlist* result)
{
const char* error = NULL;
if(cpuTimes1.elementSize == 0)
@@ -21,7 +21,7 @@ const char* ffGetCpuUsageResult(FFlist* result)
ffListInit(&cpuTimes1, sizeof(FFCpuUsageInfo));
error = ffGetCpuUsageInfo(&cpuTimes1);
if(error) return error;
ffTimeSleep(200);
ffTimeSleep(options->waitTime);
}
if(cpuTimes1.length == 0) return "No CPU cores found";
@@ -36,14 +36,14 @@ retry:
for (uint32_t i = 0; i < cpuTimes1.length; ++i)
{
FFCpuUsageInfo* cpuTime1 = ffListGet(&cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
FFCpuUsageInfo* cpuTime1 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes2, i);
if (cpuTime2->totalAll <= cpuTime1->totalAll)
{
if (++retryCount <= 3)
{
ffListClear(&cpuTimes2);
ffTimeSleep(200);
ffTimeSleep(options->waitTime);
goto retry;
}
}
@@ -51,8 +51,8 @@ retry:
for (uint32_t i = 0; i < cpuTimes1.length; ++i)
{
FFCpuUsageInfo* cpuTime1 = ffListGet(&cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
FFCpuUsageInfo* cpuTime1 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes2, i);
*(double*) ffListAdd(result) = (double)(cpuTime2->inUseAll - cpuTime1->inUseAll) / (double)(cpuTime2->totalAll - cpuTime1->totalAll) * 100;
cpuTime1->inUseAll = cpuTime2->inUseAll;
cpuTime1->totalAll = cpuTime2->totalAll;
+1 -1
View File
@@ -8,4 +8,4 @@ typedef struct FFCpuUsageInfo {
} FFCpuUsageInfo;
const char* ffGetCpuUsageInfo(FFlist* cpuTimes);
const char* ffGetCpuUsageResult(FFlist* result); // list of double
const char* ffGetCpuUsageResult(FFCPUUsageOptions* options, FFlist* result); // list of double
+8 -4
View File
@@ -6,15 +6,19 @@
#include <sys/resource.h>
#include <stdlib.h>
#ifdef __OpenBSD__
#if __OpenBSD__ || __NetBSD__
#include <sys/sched.h>
#endif
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
size_t neededLength = 0;
#ifdef __OpenBSD__
int ctls[] = {CTL_KERN, KERN_CPTIME};
#if __OpenBSD__|| __NetBSD__
#ifdef KERN_CPTIME
int ctls[] = {CTL_KERN, KERN_CPTIME};
#else
int ctls[] = {CTL_KERN, KERN_CP_TIME};
#endif
if (sysctl(ctls, 2, NULL, &neededLength, NULL, 0) != 0)
return "sysctl({CTL_KERN, KERN_CPTIME}, 2, NULL) failed";
#else
@@ -27,7 +31,7 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
FF_AUTO_FREE uint64_t (*cpTimes)[CPUSTATES] = malloc(neededLength);
#ifdef __OpenBSD__
#if __OpenBSD__ || __NetBSD__
if (sysctl(ctls, 2, cpTimes, &neededLength, NULL, 0) != 0)
return "sysctl({CTL_KERN, KERN_CPTIME}, 2, NULL) failed";
#else
+2 -2
View File
@@ -8,13 +8,13 @@
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
char buf[PROC_FILE_BUFFSIZ];
ssize_t nRead = ffReadFileData("/proc/stat", sizeof(buf) - 1, buf);
ssize_t nRead = ffReadFileData("/proc/stat", ARRAY_SIZE(buf) - 1, buf);
if(nRead < 0)
{
#ifdef __ANDROID__
return "Accessing \"/proc/stat\" is restricted on Android O+";
#else
return "ffReadFileData(\"/proc/stat\", sizeof(buf) - 1, buf) failed";
return "ffReadFileData(\"/proc/stat\", ARRAY_SIZE(buf) - 1, buf) failed";
#endif
}
buf[nRead] = '\0';
+1 -1
View File
@@ -1,7 +1,7 @@
#include "fastfetch.h"
#include "detection/cpuusage/cpuusage.h"
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
const char* ffGetCpuUsageInfo(FF_MAYBE_UNUSED FFlist* cpuTimes)
{
return "Not support on this platform";
}
+29 -4
View File
@@ -5,7 +5,17 @@
#include <sys/mount.h>
#include <sys/stat.h>
#ifdef __NetBSD__
#include <sys/types.h>
#include <sys/statvfs.h>
#define getfsstat(...) getvfsstat(__VA_ARGS__)
#define statfs statvfs
#define f_flags f_flag
#define f_bsize f_frsize
#endif
#ifdef __FreeBSD__
#if __has_include(<libgeom.h>)
#include <libgeom.h>
static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
@@ -42,6 +52,12 @@ static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
return NULL;
}
#else
static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
{
return "Fastfetch was compiled without libgeom support";
}
#endif
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
@@ -51,7 +67,7 @@ static void detectFsInfo(struct statfs* fs, FFDisk* disk)
? FF_DISK_VOLUME_TYPE_REGULAR_BIT
: FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
}
else if(ffStrbufStartsWithS(&disk->mountpoint, "/boot") || ffStrbufStartsWithS(&disk->mountpoint, "/efi"))
else if(fs->f_flags & MNT_IGNORE)
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else if(!(fs->f_flags & MNT_LOCAL))
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
@@ -95,7 +111,15 @@ void detectFsInfo(struct statfs* fs, FFDisk* disk)
#else
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
FF_UNUSED(fs, disk);
#ifdef MNT_IGNORE
if(fs->f_flags & MNT_IGNORE)
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else
#endif
if(!(fs->f_flags & MNT_LOCAL))
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
}
#endif
@@ -117,7 +141,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
if(!ffDiskMatchMountpoint(options, fs->f_mntonname))
continue;
}
else if(!ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs"))
else if(!ffStrEquals(fs->f_mntonname, "/") && !ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs"))
continue;
#ifdef __FreeBSD__
@@ -151,10 +175,11 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
#ifdef __OpenBSD__
#define st_birthtimespec __st_birthtim
#endif
#ifndef __DragonFly__
struct stat st;
if(stat(fs->f_mntonname, &st) == 0 && st.st_birthtimespec.tv_sec > 0)
disk->createTime = (uint64_t)((st.st_birthtimespec.tv_sec * 1000) + (st.st_birthtimespec.tv_nsec / 1000000));
#endif
}
return NULL;
+14 -10
View File
@@ -149,7 +149,7 @@ static void detectName(FFDisk* disk)
#ifdef __ANDROID__
static void detectType(FF_MAYBE_UNUSED const FFlist* disks, FFDisk* currentDisk)
static void detectType(FF_MAYBE_UNUSED const FFlist* disks, FFDisk* currentDisk, FF_MAYBE_UNUSED struct mntent* device)
{
if(ffStrbufEqualS(&currentDisk->mountpoint, "/") || ffStrbufEqualS(&currentDisk->mountpoint, "/storage/emulated"))
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
@@ -176,7 +176,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
FF_STRBUF_AUTO_DESTROY zpoolName = ffStrbufCreateNS(index, currentDisk->mountFrom.chars);
for(uint32_t i = 0; i < disks->length - 1; i++)
{
const FFDisk* otherDevice = ffListGet(disks, i);
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
if(ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName))
return true;
}
@@ -188,7 +188,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
//Filter all disks which device was already found. This catches BTRFS subvolumes.
for(uint32_t i = 0; i < disks->length - 1; i++)
{
const FFDisk* otherDevice = ffListGet(disks, i);
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
if(ffStrbufEqual(&currentDisk->mountFrom, &otherDevice->mountFrom))
return true;
@@ -204,7 +204,7 @@ static bool isRemovable(FFDisk* currentDisk)
return false;
char sysBlockPartition[64];
snprintf(sysBlockPartition, sizeof(sysBlockPartition), "/sys/class/block/%s", currentDisk->mountFrom.chars + strlen("/dev/"));
snprintf(sysBlockPartition, ARRAY_SIZE(sysBlockPartition), "/sys/class/block/%s", currentDisk->mountFrom.chars + strlen("/dev/"));
char sysBlockVolume[PATH_MAX]; // /sys/devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
if (realpath(sysBlockPartition, sysBlockVolume) == NULL)
@@ -215,7 +215,7 @@ static bool isRemovable(FFDisk* currentDisk)
return ffReadFileData(sysBlockVolume, 1, &removableChar) > 0 && removableChar == '1';
}
static void detectType(const FFlist* disks, FFDisk* currentDisk)
static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mntent* device)
{
if(ffStrbufStartsWithS(&currentDisk->mountpoint, "/boot") || ffStrbufStartsWithS(&currentDisk->mountpoint, "/efi"))
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
@@ -225,6 +225,8 @@ static void detectType(const FFlist* disks, FFDisk* currentDisk)
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
if (hasmntopt(device, MNTOPT_RO))
currentDisk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
}
#endif
@@ -233,7 +235,7 @@ static void detectStats(FFDisk* disk)
{
struct statvfs fs;
if(statvfs(disk->mountpoint.chars, &fs) != 0)
memset(&fs, 0, sizeof(struct statvfs)); //Set all values to 0, so our values get initialized to 0 too
memset(&fs, 0, sizeof(fs)); //Set all values to 0, so our values get initialized to 0 too
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
disk->bytesFree = fs.f_bfree * fs.f_frsize;
@@ -251,15 +253,17 @@ static void detectStats(FFDisk* disk)
disk->filesTotal = disk->filesUsed = 0;
}
if(fs.f_flag & ST_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
disk->createTime = 0;
#ifdef FF_HAVE_STATX
struct statx stx;
if (statx(0, disk->mountpoint.chars, 0, STATX_BTIME, &stx) == 0 && (stx.stx_mask & STATX_BTIME))
disk->createTime = (uint64_t)((stx.stx_btime.tv_sec * 1000) + (stx.stx_btime.tv_nsec / 1000000));
#endif
#ifdef __ANDROID__ // hasmntopt requires a higher Android API level
if(fs.f_flag & ST_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
#endif
}
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
@@ -298,7 +302,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
detectName(disk); // Also detects external devices
//detect type
detectType(disks, disk);
detectType(disks, disk, device);
//Detects stats
detectStats(disk);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "disk.h"
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
const char* ffDetectDisksImpl(FF_MAYBE_UNUSED FFDiskOptions* options, FF_MAYBE_UNUSED FFlist* disks)
{
return "Not supported on this platform";
}
+6 -7
View File
@@ -48,7 +48,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
FF_STRBUF_AUTO_DESTROY zpoolName = ffStrbufCreateNS(index, currentDisk->mountFrom.chars);
for(uint32_t i = 0; i < disks->length - 1; i++)
{
const FFDisk* otherDevice = ffListGet(disks, i);
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
if(ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName))
return true;
}
@@ -60,7 +60,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
//Filter all disks which device was already found. This catches BTRFS subvolumes.
for(uint32_t i = 0; i < disks->length - 1; i++)
{
const FFDisk* otherDevice = ffListGet(disks, i);
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
if(ffStrbufEqual(&currentDisk->mountFrom, &otherDevice->mountFrom))
return true;
@@ -72,19 +72,21 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mnttab* device)
{
if(ffStrContains(device->mnt_mntopts, MNTOPT_NOBROWSE))
if(hasmntopt(device, MNTOPT_NOBROWSE))
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else if(isSubvolume(disks, currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
else
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
if (hasmntopt(device, MNTOPT_RO))
currentDisk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
}
static void detectStats(FFDisk* disk)
{
struct statvfs fs;
if(statvfs(disk->mountpoint.chars, &fs) != 0)
memset(&fs, 0, sizeof(struct statvfs));
memset(&fs, 0, sizeof(fs));
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
disk->bytesFree = fs.f_bfree * fs.f_frsize;
@@ -94,9 +96,6 @@ static void detectStats(FFDisk* disk)
disk->filesTotal = (uint32_t) fs.f_files;
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
if(fs.f_flag & ST_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
ffStrbufSetS(&disk->name, fs.f_fstr);
disk->createTime = 0;
+7 -7
View File
@@ -22,9 +22,9 @@ static unsigned __stdcall testRemoteVolumeAccessible(void* mountpoint)
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
{
wchar_t buf[MAX_PATH + 1];
uint32_t length = GetLogicalDriveStringsW(sizeof(buf) / sizeof(*buf), buf);
if (length == 0 || length >= sizeof(buf) / sizeof(*buf))
return "GetLogicalDriveStringsW(sizeof(buf) / sizeof(*buf), buf) failed";
uint32_t length = GetLogicalDriveStringsW(ARRAY_SIZE(buf), buf);
if (length == 0 || length >= ARRAY_SIZE(buf))
return "GetLogicalDriveStringsW(ARRAY_SIZE(buf), buf) failed";
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
@@ -32,7 +32,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
if (__builtin_expect(options->folders.length == 1 && options->folders.chars[0] == '/', 0))
{
wchar_t path[MAX_PATH + 1];
GetSystemWindowsDirectoryW(path, sizeof(path) / sizeof(*path));
GetSystemWindowsDirectoryW(path, ARRAY_SIZE(path));
ffStrbufSetF(&options->folders, "%c:\\", (char) path[0]);
}
@@ -76,7 +76,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
{
wchar_t volumeName[MAX_PATH + 1];
mountpoint[2] = L'\0';
if(QueryDosDeviceW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
if(QueryDosDeviceW(mountpoint, volumeName, ARRAY_SIZE(volumeName)))
ffStrbufSetWS(&disk->mountFrom, volumeName);
mountpoint[2] = L'\\';
}
@@ -104,11 +104,11 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
DWORD diskFlags;
BOOL result = GetVolumeInformationW(mountpoint,
diskName, sizeof(diskName) / sizeof(*diskName), //Volume name
diskName, ARRAY_SIZE(diskName), //Volume name
NULL, //Serial number
NULL, //Max component length
&diskFlags, //File system flags
diskFileSystem, sizeof(diskFileSystem) / sizeof(*diskFileSystem)
diskFileSystem, ARRAY_SIZE(diskFileSystem)
);
SetErrorMode(errorMode);
+4 -4
View File
@@ -41,9 +41,9 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
return "No physical disk found";
uint64_t time2 = ffTimeGetNow();
while (time2 - time1 < 1000)
while (time2 - time1 < options->waitTime)
{
ffTimeSleep((uint32_t) (1000 - (time2 - time1)));
ffTimeSleep((uint32_t) (options->waitTime - (time2 - time1)));
time2 = ffTimeGetNow();
}
@@ -56,8 +56,8 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
for (uint32_t i = 0; i < result->length; ++i)
{
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
FFDiskIOResult* icPrev = FF_LIST_GET(FFDiskIOResult, ioCounters1, i);
FFDiskIOResult* icCurr = FF_LIST_GET(FFDiskIOResult, *result, i);
if (!ffStrbufEqual(&icPrev->devPath, &icCurr->devPath))
return "Physical disk device path changed";
+48
View File
@@ -1,4 +1,7 @@
#include "diskio.h"
#if __has_include(<libgeom.h>)
#include "util/stringUtils.h"
#include <devstat.h>
@@ -58,3 +61,48 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
return NULL;
}
#else
#include <devstat.h>
#include <memory.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
if (checkversion() < 0)
return "checkversion() failed";
struct statinfo stats = {
.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)),
};
if (getdevs(&stats) < 0)
return "getdevs() failed";
for (int i = 0; i < stats.dinfo->numdevs; i++)
{
struct devstat* current = &stats.dinfo->devices[i];
if (current->device_type & DEVSTAT_TYPE_PASS)
continue;
char deviceName[128];
snprintf(deviceName, sizeof(deviceName), "%s%d", current->device_name, current->unit_number);
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInitF(&device->devPath, "/dev/%s", deviceName);
device->bytesRead = current->bytes_read;
device->readCount = current->num_reads;
device->bytesWritten = current->bytes_written;
device->writeCount = current->num_writes;
}
free(stats.dinfo->mem_ptr);
free(stats.dinfo);
return NULL;
}
#endif
+68 -77
View File
@@ -6,6 +6,71 @@
#include <ctype.h>
#include <limits.h>
#include <inttypes.h>
#include <fcntl.h>
static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FFDiskIOOptions* options)
{
FF_AUTO_CLOSE_FD int devfd = openat(dfd, "device", O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
if (devfd < 0) return; // virtual device
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
{
if (ffAppendFileBufferRelative(devfd, "vendor", &name))
{
ffStrbufTrimRightSpace(&name);
if (name.length > 0)
ffStrbufAppendC(&name, ' ');
}
if (ffAppendFileBufferRelative(devfd, "model", &name))
ffStrbufTrimRightSpace(&name);
if (name.length == 0)
ffStrbufSetS(&name, devName);
else if (ffStrStartsWith(devName, "nvme"))
{
int devid, nsid;
if (sscanf(devName, "nvme%dn%d", &devid, &nsid) == 2)
{
bool multiNs = nsid > 1;
if (!multiNs)
{
char pathSysBlock[16];
snprintf(pathSysBlock, ARRAY_SIZE(pathSysBlock), "nvme%dn2", devid);
multiNs = faccessat(devfd, pathSysBlock, F_OK, 0) == 0;
}
if (multiNs)
{
// In Asahi Linux, there are multiple namespaces for the same NVMe drive.
ffStrbufAppendF(&name, " - %d", nsid);
}
}
}
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
return;
}
// I/Os merges sectors ticks ...
uint64_t nRead, sectorRead, nWritten, sectorWritten;
{
char sysBlockStat[PROC_FILE_BUFFSIZ];
ssize_t fileSize = ffReadFileDataRelative(dfd, "stat", ARRAY_SIZE(sysBlockStat) - 1, sysBlockStat);
if (fileSize <= 0) return;
sysBlockStat[fileSize] = '\0';
if (sscanf(sysBlockStat, "%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u", &nRead, &sectorRead, &nWritten, &sectorWritten) <= 0)
return;
}
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitMove(&device->name, &name);
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
device->bytesRead = sectorRead * 512;
device->bytesWritten = sectorWritten * 512;
device->readCount = nRead;
device->writeCount = nWritten;
}
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
@@ -18,84 +83,10 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
const char* const devName = sysBlockEntry->d_name;
if (devName[0] == '.')
continue;
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;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
if (ffAppendFileBuffer(pathSysBlock, &name))
{
ffStrbufTrimRightSpace(&name);
if (name.length > 0)
ffStrbufAppendC(&name, ' ');
}
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
ffAppendFileBuffer(pathSysBlock, &name);
ffStrbufTrimRightSpace(&name);
if (name.length == 0)
ffStrbufSetS(&name, devName);
else if (ffStrStartsWith(devName, "nvme"))
{
int devid, nsid;
if (sscanf(devName, "nvme%dn%d", &devid, &nsid) == 2)
{
bool multiNs = nsid > 1;
if (!multiNs)
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/nvme%dn2", devName, devid);
multiNs = ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY);
}
if (multiNs)
{
// In Asahi Linux, there are multiple namespaces for the same NVMe drive.
ffStrbufAppendF(&name, " - %d", nsid);
}
}
}
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
continue;
}
// 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, "%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u", &nRead, &sectorRead, &nWritten, &sectorWritten) <= 0)
continue;
}
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitMove(&device->name, &name);
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
device->bytesRead = sectorRead * 512;
device->bytesWritten = sectorWritten * 512;
device->readCount = nRead;
device->writeCount = nWritten;
FF_AUTO_CLOSE_FD int dfd = openat(dirfd(sysBlockDirp), devName, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
if (dfd > 0) parseDiskIOCounters(dfd, devName, result, options);
}
return NULL;
+38
View File
@@ -0,0 +1,38 @@
#include "diskio.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <sys/iostat.h>
#include <sys/sysctl.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
int mib[] = {CTL_HW, HW_IOSTATS, sizeof(struct io_sysctl)};
size_t len;
if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0)
return "sysctl({HW_IOSTATS}, NULL) failed";
uint32_t nDrive = (uint32_t) (len / sizeof(struct io_sysctl));
struct io_sysctl* stats = malloc(len);
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
return "sysctl({HW_IOSTATS}, stats) failed";
for (uint32_t i = 0; i < nDrive; ++i)
{
struct io_sysctl* st = &stats[i];
if (options->namePrefix.length && strncmp(st->name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitF(&device->devPath, "/dev/%s", st->name);
ffStrbufInitS(&device->name, st->name);
device->bytesRead = st->rbytes;
device->readCount = st->rxfer;
device->bytesWritten = st->wbytes;
device->writeCount = st->wxfer;
}
return NULL;
}

Some files were not shown because too many files have changed in this diff Show More