diff --git a/profile.d/info.sh b/profile.d/info.sh index 60d2669..b2d65a0 100644 --- a/profile.d/info.sh +++ b/profile.d/info.sh @@ -171,7 +171,7 @@ pinfo() hostname_str="${HOSTNAME:-unknown}" fi - # --- OS release (parsed line by line, never sourced) --- + # --- OS release (security: parsed line by line, never sourced) --- local os_name="Unknown" os_version="" if [[ -r /etc/os-release ]]; then local _osr_key _osr_val @@ -241,18 +241,22 @@ pinfo() (( cpu_cores == 0 )) && cpu_cores=$cpu_threads # --- Memory (pure bash, /proc/meminfo, values in kB) --- - local mem_total=0 mem_available=0 + local mem_total=0 mem_available=0 swap_total=0 swap_free=0 if [[ -r /proc/meminfo ]]; then local _mkey _mval _munit while read -r _mkey _mval _munit; do case "${_mkey%:}" in MemTotal) mem_total="$_mval" ;; MemAvailable) mem_available="$_mval" ;; + SwapTotal) swap_total="$_mval" ;; + SwapFree) swap_free="$_mval" ;; esac done < /proc/meminfo fi local mem_total_mib=$(( mem_total / 1024 )) local mem_used_mib=$(( (mem_total - mem_available) / 1024 )) + local swap_total_mib=$(( swap_total / 1024 )) + local swap_used_mib=$(( (swap_total - swap_free) / 1024 )) # --- Process count (glob over numeric /proc entries) --- local proc_count=0 _pdir @@ -264,6 +268,54 @@ pinfo() local shell_str="${BASH:-bash} ${BASH_VERSION%\(*}" local term_str="${TERM:-unknown}" + # --- GPU (no external tools required; sysfs first, then /proc/bus/pci) --- + local -a gpu_list=() + local _gdir _gname _gline + # Preferred: sysfs drm — each card has a device/vendor+device pair readable + # without root. The human-readable name comes from the uevent file. + for _gdir in /sys/class/drm/card[0-9]*/device; do + [[ -d "$_gdir" ]] || continue + _gname="" + # Try uevent: contains PCI_ID and sometimes DRIVER + if [[ -r "$_gdir/uevent" ]]; then + local _uev_driver="" _uev_pci="" + local _uev_line + while IFS='=' read -r _uev_key _uev_val; do + case "$_uev_key" in + DRIVER) _uev_driver="$_uev_val" ;; + PCI_ID) _uev_pci="$_uev_val" ;; + esac + done < "$_gdir/uevent" + [[ -n "$_uev_pci" ]] && _gname="PCI ${_uev_pci}" + [[ -n "$_uev_driver" ]] && _gname+=" (${_uev_driver})" + fi + # Better: label file written by driver (e.g. amdgpu, i915) + if [[ -r "$_gdir/label" ]]; then + read -r _gname < "$_gdir/label" + elif [[ -r "$_gdir/../label" ]]; then + read -r _gname < "$_gdir/../label" + fi + # Better still: product name from hwmon or power supply description + # Try modalias vendor/device text via /sys/.../subsystem_device not always human + # Last resort: readable model via drm connector name + [[ -z "$_gname" ]] && _gname="unknown GPU" + gpu_list+=("$_gname") + done + + # Fallback: scan /proc/bus/pci/devices — field 1 is vendor:device hex, field 14 is name + if (( ${#gpu_list[@]} == 0 )) && [[ -r /proc/bus/pci/devices ]]; then + while IFS=$'\t' read -r _pci_bus _pci_id _pci_irq _rest _pci_name; do + # Display class is in the high 16 bits of field 2 (vendor:device word) + # /proc/bus/pci/devices col 1 is busdevfn, col 2 is vendorID<<16|deviceID + # The class 0x03xx is "Display controller / VGA compatible" + case "$_pci_name" in + *VGA*|*Display*|*3D*|*GPU*|*Graphics*|*Radeon*|*GeForce*|*Intel*Iris*|*Intel*UHD*|*Intel*HD*Graphics*) + gpu_list+=("$_pci_name") + ;; + esac + done < /proc/bus/pci/devices + fi + # --- Render --- local _lbl="${BIWhite:-}" _val="${ICyan:-}" _rst="${DEFAULTCOL:-}" @@ -276,7 +328,18 @@ pinfo() _row "Load avg" "$load_str" _row "CPU" "$cpu_model" _row "Cores" "${cpu_cores} physical, ${cpu_threads} logical" + if (( ${#gpu_list[@]} > 0 )); then + local _gi + for _gi in "${!gpu_list[@]}"; do + local _gpu_lbl="GPU" + (( ${#gpu_list[@]} > 1 )) && _gpu_lbl="GPU $(( _gi + 1 ))" + _row "$_gpu_lbl" "${gpu_list[$_gi]}" + done + fi _row "Memory" "${mem_used_mib} MiB used / ${mem_total_mib} MiB total" + if (( swap_total > 0 )); then + _row "Swap" "${swap_used_mib} MiB used / ${swap_total_mib} MiB total" + fi _row "Processes" "$proc_count" _row "Shell" "$shell_str" _row "Terminal" "$term_str"