Compare commits

...

45 Commits

Author SHA1 Message Date
a1943c32cc Update config 2023-08-04 16:46:53 +01:00
549b774e34 Merge remote-tracking branch 'suckless/master' 2023-08-04 15:57:45 +01:00
drkhsh
f68f49273e Release stable 1.0 version 2023-07-04 20:47:18 +02:00
drkhsh
86c7a84c23 Add back version flag to prepare for release 2023-05-15 19:16:12 +02:00
drkhsh
483169021b Fix release tarball to prepare for release
Correctly copies components to sub-directory, adds all required files
2023-05-15 19:11:39 +02:00
drkhsh
e0c155e9ab README: Sync description from manpage 2023-04-23 23:48:47 +02:00
drkhsh
ee586cfea9 manpage: Quality improvements
Adds signals section to the manpage and generally improves contents and
wording
2023-04-23 23:43:14 +02:00
drkhsh
c919def84f More LICENSE updates
Regarding 305aa5138a
2022-12-19 22:04:07 +01:00
drkhsh
034c591a95 Revert "config.mk: Fix PREFIX assignment"
"?=" is not POSIX, packagers should use "make PREFIX=".
This reverts commit c225c43151.
2022-12-19 19:26:57 +01:00
drkhsh
305aa5138a Update LICENSE
Real names should be used if possible, as the license is legally binding
2022-12-19 19:26:18 +01:00
drkhsh
1ae616190c Update LICENSE 2022-12-19 02:44:21 +01:00
planet36
581d937e51 entropy: Use Unicode escape sequence in string
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
c225c43151 config.mk: Fix PREFIX assignment
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
984f45719e num_files: opendir() returns a directory stream
opendir() returns a directory stream, not a file descriptor

Co-authored-by: drkhsh <me@drkhsh.at>
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
c432c981df Make LEN macro consistent with other suckless repos
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
87c3dd2c36 battery: Consistent naming for capacity percentage
https://www.kernel.org/doc/html/latest/power/power_supply_class.html

Co-authored-by: drkhsh <me@drkhsh.at>
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
d77f216fae Sort functions by name
Co-authored-by: drkhsh <me@drkhsh.at>
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
40f13be551 uptime: Use sizeof instead of repeating the size
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
c75cb9ad7a keymap: Variable "layout" should be const
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
89f8476110 disk: Cast fsblkcnt_t to double instead of float
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
0e2ff8dc10 verr: Remove special "usage" case
In function verr, remove special case for "usage"
string

Co-authored-by: drkhsh <me@drkhsh.at>
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
planet36
e22d447684 config.def.h: Remove stray double quote in comment
Signed-off-by: drkhsh <me@drkhsh.at>
2022-12-19 02:44:21 +01:00
drkhsh
173b03417d Update README 2022-12-19 02:44:21 +01:00
Patrick Iacob
982eb223a0 battery: Fix remaining on Linux
The current version displays the remaining time as 'n/a'.

Fixes this regression introduced in 69b2487650
where current_now and power_now were incorrectly replaced with current and
power when they were moved to a macro.
2022-12-01 09:04:32 +01:00
drkhsh
57c6e7340d New component: cat
Generically reads an arbitrary file natively.

Saves a few layers of execution in comparison to using `run_command`
with an argument like `cat ./file`.
2022-11-24 00:01:52 +01:00
drkhsh
4bd78c94ba README: Add note about FreeBSD sndio dep 2022-10-28 01:03:56 +02:00
drkhsh
cce2e5ecb0 radical re-formatting 3/3: Error checks
Check for `< 0` instead of `== -1`.

Fixes coding style. Formatting commits suck, incoherent coding style
sucks more.
https://suckless.org/coding_style/
2022-10-28 01:03:46 +02:00
drkhsh
3251e91187 radical re-formatting 2/3: Fix blocks
Fixes coding style. Formatting commits suck, incoherent coding style
sucks more.
https://suckless.org/coding_style/
2022-10-28 01:03:38 +02:00
drkhsh
2104dc362c radical re-formatting 1/3: Fix spacing
Fixes coding style. Formatting commits suck, incoherent coding style
sucks more.
https://suckless.org/coding_style/
2022-10-28 01:03:31 +02:00
drkhsh
0696635bcb radical re-formatting 0/3: Alphabetic headers
Except stated otherwise in comment.

Fixes coding style. Formatting commits suck, incoherent coding style
sucks more.
https://suckless.org/coding_style/
2022-10-28 01:03:20 +02:00
drkhsh
826a5dc862 ram: Refactor on OpenBSD
Fixes up overly complicated lines, by splitting up logic
2022-10-28 01:03:20 +02:00
drkhsh
d7ea986299 ram: Refactor Linux perc/used
Fixes up overly complicated line, by splitting up logic
2022-10-28 01:03:20 +02:00
drkhsh
3b86e4b5ef battery: Refactor remaining on OpenBSD
Fixes up overly complicated line, by splitting up logic
2022-10-28 01:03:20 +02:00
drkhsh
21327e0373 temp: Put sysctl into define to avoid line wraps
Long, wrapped, multi-line if statements suck to read.
This fixes readability.
2022-10-28 01:02:58 +02:00
drkhsh
69b2487650 various: Put paths into defines to avoid line wraps
Long, wrapped, multi-line if statements suck to read.
This fixes readability in the worst places by packing format strings for
paths into defines.
2022-10-28 01:01:10 +02:00
drkhsh
c46c1487a9 separator: kill that useless thing
Just use the format strings dude. :)
2022-10-28 01:00:40 +02:00
NRK
0c2b3e5b5c do not rely on obsolete feature
function prototype with unspecified argument is obsolete since c99.

additionally some of these function which don't take any argument were
being called with a `const char *` arg, which is UB.

fix both these issues by declararing ALL the components to accept a
`const char *`, and name the arg "unused" if it's meant to be ignored.
2022-10-26 23:32:43 +02:00
NRK
28ef0b242c components/*.c: include slstatus.h
this gives the compiler a chance to check weather the prototype and
definiton matches or not, which would catch issues like 3c47701.
2022-10-26 23:32:07 +02:00
Spenser Truex
f29aa9ab06 Add 'Not charging' status support
Exists on various ThinkPads. Seems to be both a synonym for "full".

Tested on:
- ThinkPad T500 (Spenser Truex <truex@equwal.com)
- ThinkPad T420 (drkhsh <me@drkhsh.at)
2022-10-26 21:34:58 +02:00
drkhsh
0aacce1c52 Add comment about mixer oss module to README 2022-10-26 21:24:20 +02:00
drkhsh
1881569f6c Update LICENSE 2022-10-26 21:24:19 +02:00
Ingo Feinerer
3b699c127d Reset sndiod initialization flag on disconnects
If the connection is lost to the sndiod(8) daemon reset the
initialization to allow for a graceful restart.
2022-10-26 21:24:16 +02:00
michaelbuch12@gmail.com
798809ce02 Make volume component work on FreeBSD
- Edit compile instructions
- Reuse OpenBSD sndio implementation
2022-10-26 21:24:14 +02:00
michaelbuch12@gmail.com
77bfb76a97 Fix RAM component on FreeBSD
The current implementation uses the wrong type for
given sysctl calls leading to overflow and incorrectly
reported RAM usage. The fix is to use 'unsigned int'
which is what FreeBSD expects.
2022-10-26 21:24:11 +02:00
NRK
3c47701aea Fix keyboard_indicators() prototype
according to both the function definition and the comment in
config.def.h, keyboard_indicators() should take a format string.
2022-10-26 21:24:09 +02:00
35 changed files with 429 additions and 423 deletions

13
LICENSE
View File

@ -1,6 +1,6 @@
ISC License ISC License
Copyright 2016-2020 Aaron Marcher <me@drkhsh.at> Copyright 2016-2022 Aaron Marcher <me@drkhsh.at>
Copyright 2016 Roy Freytag <rfreytag@hs-mittweida.de> Copyright 2016 Roy Freytag <rfreytag@hs-mittweida.de>
Copyright 2016 Vincent Loupmon <vincentloupmon@gmail.com> Copyright 2016 Vincent Loupmon <vincentloupmon@gmail.com>
@ -9,23 +9,26 @@ Copyright 2016-2018 Ali H. Fardan <raiz@firemail.cc>
Copyright 2016 Jody Leonard <me@jodyleonard.com> Copyright 2016 Jody Leonard <me@jodyleonard.com>
Copyright 2016-2018 Quentin Rameau <quinq@fifth.space> Copyright 2016-2018 Quentin Rameau <quinq@fifth.space>
Copyright 2016 Mike Coddington <mike@coddington.us> Copyright 2016 Mike Coddington <mike@coddington.us>
Copyright 2016-2018 parazyd <parazyd@dyne.org> Copyright 2016-2018 Ivan J. <parazyd@dyne.org>
Copyright 2017 Tobias Stoeckmann <tobias@stoeckmann.org> Copyright 2017 Tobias Stoeckmann <tobias@stoeckmann.org>
Copyright 2017-2018 Laslo Hunhold <dev@frign.de> Copyright 2017-2018 Laslo Hunhold <dev@frign.de>
Copyright 2018 Darron Anderson <darronanderson@protonmail.com> Copyright 2018 Darron Anderson <darronanderson@protonmail.com>
Copyright 2018 Josuah Demangeon <mail@josuah.net> Copyright 2018 Josuah Demangeon <mail@josuah.net>
Copyright 2018 Tobias Tschinkowitz <tobias@he4d.net> Copyright 2018 Tobias Tschinkowitz <tobias@he4d.net>
Copyright 2018 David Demelier <markand@malikania.fr> Copyright 2018 David Demelier <markand@malikania.fr>
Copyright 2018-2019 Michael Buch <michaelbuch12@gmail.com> Copyright 2018-2012 Michael Buch <michaelbuch12@gmail.com>
Copyright 2018 Ian Remmler <ian@remmler.org> Copyright 2018 Ian Remmler <ian@remmler.org>
Copyright 2016-2019 Joerg Jung <jung@openbsd.org> Copyright 2016-2019 Joerg Jung <jung@openbsd.org>
Copyright 2019 Ryan Kes <alrayyes@gmail.com> Copyright 2019 Ryan Kes <alrayyes@gmail.com>
Copyright 2019 Cem Keylan <cem@ckyln.com> Copyright 2019 Cem Keylan <cem@ckyln.com>
Copyright 2019 dsp <dsp@2f30.org> Copyright 2019 Dimitris Papastamos <dsp@2f30.org>
Copyright 2019-2020 Ingo Feinerer <feinerer@logic.at> Copyright 2019-2022 Ingo Feinerer <feinerer@logic.at>
Copyright 2020 Alexandre Ratchov <alex@caoua.org> Copyright 2020 Alexandre Ratchov <alex@caoua.org>
Copyright 2020 Mart Lubbers <mart@martlubbers.net> Copyright 2020 Mart Lubbers <mart@martlubbers.net>
Copyright 2020 Daniel Moch <daniel@danielmoch.com> Copyright 2020 Daniel Moch <daniel@danielmoch.com>
Copyright 2022 Nickolas Raymond Kaczynski <nrk@disroot.org>
Copyright 2022 Patrick Iacob <iacobp@oregonstate.edu>
Copyright 2021-2022 Steven Ward <planet36@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above

View File

@ -7,6 +7,7 @@ include config.mk
REQ = util REQ = util
COM =\ COM =\
components/battery\ components/battery\
components/cat\
components/cpu\ components/cpu\
components/datetime\ components/datetime\
components/disk\ components/disk\
@ -21,7 +22,6 @@ COM =\
components/num_files\ components/num_files\
components/ram\ components/ram\
components/run_command\ components/run_command\
components/separator\
components/swap\ components/swap\
components/temperature\ components/temperature\
components/uptime\ components/uptime\
@ -31,7 +31,7 @@ COM =\
all: slstatus all: slstatus
$(COM:=.o): config.mk $(REQ:=.h) $(COM:=.o): config.mk $(REQ:=.h) slstatus.h
slstatus.o: slstatus.c slstatus.h arg.h config.h config.mk $(REQ:=.h) slstatus.o: slstatus.c slstatus.h arg.h config.h config.mk $(REQ:=.h)
.c.o: .c.o:
@ -44,14 +44,15 @@ slstatus: slstatus.o $(COM:=.o) $(REQ:=.o)
$(CC) -o $@ $(LDFLAGS) $(COM:=.o) $(REQ:=.o) slstatus.o $(LDLIBS) $(CC) -o $@ $(LDFLAGS) $(COM:=.o) $(REQ:=.o) slstatus.o $(LDLIBS)
clean: clean:
rm -f slstatus slstatus.o $(COM:=.o) $(REQ:=.o) rm -f slstatus slstatus.o $(COM:=.o) $(REQ:=.o) slstatus-${VERSION}.tar.gz
dist: dist:
rm -rf "slstatus-$(VERSION)" rm -rf "slstatus-$(VERSION)"
mkdir -p "slstatus-$(VERSION)/components" mkdir -p "slstatus-$(VERSION)/components"
cp -R LICENSE Makefile README config.mk config.def.h \ cp -R LICENSE Makefile README config.mk config.def.h \
arg.h slstatus.c $(COM:=.c) $(REQ:=.c) $(REQ:=.h) \ arg.h slstatus.h slstatus.c $(REQ:=.c) $(REQ:=.h) \
slstatus.1 "slstatus-$(VERSION)" slstatus.1 "slstatus-$(VERSION)"
cp -R $(COM:=.c) "slstatus-$(VERSION)/components"
tar -cf - "slstatus-$(VERSION)" | gzip -c > "slstatus-$(VERSION).tar.gz" tar -cf - "slstatus-$(VERSION)" | gzip -c > "slstatus-$(VERSION).tar.gz"
rm -rf "slstatus-$(VERSION)" rm -rf "slstatus-$(VERSION)"

18
README
View File

@ -1,12 +1,15 @@
slstatus - suckless status slstatus - suckless status
========================== ==========================
slstatus is a suckless status monitor for window managers that use WM_NAME slstatus is a small tool for providing system status information to other
(e.g. dwm) or stdin to fill the status bar. programs over the EWMH property of the root window (used by dwm(1)) or
standard input/output. It is designed to be as efficient as possible by
only issuing the minimum of system calls required.
Features Features
-------- --------
- Battery percentage/state/time left - Battery percentage/state/time left
- Cat (read file)
- CPU usage - CPU usage
- CPU frequency - CPU frequency
- Custom shell commands - Custom shell commands
@ -35,6 +38,10 @@ Requirements
Currently slstatus works on FreeBSD, Linux and OpenBSD. Currently slstatus works on FreeBSD, Linux and OpenBSD.
In order to build slstatus you need the Xlib header files. In order to build slstatus you need the Xlib header files.
- For volume percentage on Linux the kernel module `snd-mixer-oss` must be
loaded.
- For volume percentage on FreeBSD, `sndio` must be installed.
Installation Installation
------------ ------------
@ -56,10 +63,3 @@ Configuration
------------- -------------
slstatus can be customized by creating a custom config.h and (re)compiling the slstatus can be customized by creating a custom config.h and (re)compiling the
source code. This keeps it fast, secure and simple. source code. This keeps it fast, secure and simple.
Upcoming
--------
A release (v1.0) will come soon... ;)
After a long phase of inactivity, development has been continued!

2
arg.h
View File

@ -13,7 +13,7 @@ extern char *argv0;
break; \ break; \
} \ } \
for (i_ = 1, argused_ = 0; (*argv)[i_]; i_++) { \ for (i_ = 1, argused_ = 0; (*argv)[i_]; i_++) { \
switch((*argv)[i_]) switch ((*argv)[i_])
#define ARGEND if (argused_) { \ #define ARGEND if (argused_) { \
if ((*argv)[i_ + 1]) { \ if ((*argv)[i_ + 1]) { \
break; \ break; \

View File

@ -2,26 +2,35 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
#if defined(__linux__) #if defined(__linux__)
/*
* https://www.kernel.org/doc/html/latest/power/power_supply_class.html
*/
#include <limits.h> #include <limits.h>
#include <stdint.h> #include <stdint.h>
#include <unistd.h> #include <unistd.h>
#define POWER_SUPPLY_CAPACITY "/sys/class/power_supply/%s/capacity"
#define POWER_SUPPLY_STATUS "/sys/class/power_supply/%s/status"
#define POWER_SUPPLY_CHARGE "/sys/class/power_supply/%s/charge_now"
#define POWER_SUPPLY_ENERGY "/sys/class/power_supply/%s/energy_now"
#define POWER_SUPPLY_CURRENT "/sys/class/power_supply/%s/current_now"
#define POWER_SUPPLY_POWER "/sys/class/power_supply/%s/power_now"
static const char * static const char *
pick(const char *bat, const char *f1, const char *f2, char *path, pick(const char *bat, const char *f1, const char *f2, char *path,
size_t length) size_t length)
{ {
if (esnprintf(path, length, f1, bat) > 0 && if (esnprintf(path, length, f1, bat) > 0 &&
access(path, R_OK) == 0) { access(path, R_OK) == 0)
return f1; return f1;
}
if (esnprintf(path, length, f2, bat) > 0 && if (esnprintf(path, length, f2, bat) > 0 &&
access(path, R_OK) == 0) { access(path, R_OK) == 0)
return f2; return f2;
}
return NULL; return NULL;
} }
@ -29,18 +38,15 @@
const char * const char *
battery_perc(const char *bat) battery_perc(const char *bat)
{ {
int perc; int cap_perc;
char path[PATH_MAX]; char path[PATH_MAX];
if (esnprintf(path, sizeof(path), if (esnprintf(path, sizeof(path), POWER_SUPPLY_CAPACITY, bat) < 0)
"/sys/class/power_supply/%s/capacity", bat) < 0) {
return NULL; return NULL;
} if (pscanf(path, "%d", &cap_perc) != 1)
if (pscanf(path, "%d", &perc) != 1) {
return NULL; return NULL;
}
return bprintf("%d", perc); return bprintf("%d", cap_perc);
} }
const char * const char *
@ -53,23 +59,20 @@
{ "Charging", "+" }, { "Charging", "+" },
{ "Discharging", "-" }, { "Discharging", "-" },
{ "Full", "o" }, { "Full", "o" },
{ "Not charging", "o" },
}; };
size_t i; size_t i;
char path[PATH_MAX], state[12]; char path[PATH_MAX], state[12];
if (esnprintf(path, sizeof(path), if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, bat) < 0)
"/sys/class/power_supply/%s/status", bat) < 0) {
return NULL; return NULL;
} if (pscanf(path, "%12[a-zA-Z ]", state) != 1)
if (pscanf(path, "%12s", state) != 1) {
return NULL; return NULL;
}
for (i = 0; i < LEN(map); i++) { for (i = 0; i < LEN(map); i++)
if (!strcmp(map[i].state, state)) { if (!strcmp(map[i].state, state))
break; break;
}
}
return (i == LEN(map)) ? "?" : map[i].symbol; return (i == LEN(map)) ? "?" : map[i].symbol;
} }
@ -80,32 +83,24 @@
double timeleft; double timeleft;
char path[PATH_MAX], state[12]; char path[PATH_MAX], state[12];
if (esnprintf(path, sizeof(path), if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, bat) < 0)
"/sys/class/power_supply/%s/status", bat) < 0) {
return NULL; return NULL;
} if (pscanf(path, "%12[a-zA-Z ]", state) != 1)
if (pscanf(path, "%12s", state) != 1) {
return NULL; return NULL;
}
if (!pick(bat, "/sys/class/power_supply/%s/charge_now", if (!pick(bat, POWER_SUPPLY_CHARGE, POWER_SUPPLY_ENERGY, path,
"/sys/class/power_supply/%s/energy_now", path,
sizeof(path)) || sizeof(path)) ||
pscanf(path, "%ju", &charge_now) < 0) { pscanf(path, "%ju", &charge_now) < 0)
return NULL; return NULL;
}
if (!strcmp(state, "Discharging")) { if (!strcmp(state, "Discharging")) {
if (!pick(bat, "/sys/class/power_supply/%s/current_now", if (!pick(bat, POWER_SUPPLY_CURRENT, POWER_SUPPLY_POWER, path,
"/sys/class/power_supply/%s/power_now", path,
sizeof(path)) || sizeof(path)) ||
pscanf(path, "%ju", &current_now) < 0) { pscanf(path, "%ju", &current_now) < 0)
return NULL; return NULL;
}
if (current_now == 0) { if (current_now == 0)
return NULL; return NULL;
}
timeleft = (double)charge_now / (double)current_now; timeleft = (double)charge_now / (double)current_now;
h = timeleft; h = timeleft;
@ -147,9 +142,8 @@
{ {
struct apm_power_info apm_info; struct apm_power_info apm_info;
if (load_apm_power_info(&apm_info)) { if (load_apm_power_info(&apm_info))
return bprintf("%d", apm_info.battery_life); return bprintf("%d", apm_info.battery_life);
}
return NULL; return NULL;
} }
@ -168,11 +162,10 @@
size_t i; size_t i;
if (load_apm_power_info(&apm_info)) { if (load_apm_power_info(&apm_info)) {
for (i = 0; i < LEN(map); i++) { for (i = 0; i < LEN(map); i++)
if (map[i].state == apm_info.ac_state) { if (map[i].state == apm_info.ac_state)
break; break;
}
}
return (i == LEN(map)) ? "?" : map[i].symbol; return (i == LEN(map)) ? "?" : map[i].symbol;
} }
@ -183,12 +176,13 @@
battery_remaining(const char *unused) battery_remaining(const char *unused)
{ {
struct apm_power_info apm_info; struct apm_power_info apm_info;
unsigned int h, m;
if (load_apm_power_info(&apm_info)) { if (load_apm_power_info(&apm_info)) {
if (apm_info.ac_state != APM_AC_ON) { if (apm_info.ac_state != APM_AC_ON) {
return bprintf("%uh %02um", h = apm_info.minutes_left / 60;
apm_info.minutes_left / 60, m = apm_info.minutes_left % 60;
apm_info.minutes_left % 60); return bprintf("%uh %02um", h, m);
} else { } else {
return ""; return "";
} }
@ -199,18 +193,21 @@
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
#include <sys/sysctl.h> #include <sys/sysctl.h>
#define BATTERY_LIFE "hw.acpi.battery.life"
#define BATTERY_STATE "hw.acpi.battery.state"
#define BATTERY_TIME "hw.acpi.battery.time"
const char * const char *
battery_perc(const char *unused) battery_perc(const char *unused)
{ {
int cap; int cap_perc;
size_t len; size_t len;
len = sizeof(cap); len = sizeof(cap_perc);
if (sysctlbyname("hw.acpi.battery.life", &cap, &len, NULL, 0) == -1 if (sysctlbyname(BATTERY_LIFE, &cap_perc, &len, NULL, 0) < 0 || !len)
|| !len)
return NULL; return NULL;
return bprintf("%d", cap); return bprintf("%d", cap_perc);
} }
const char * const char *
@ -220,12 +217,11 @@
size_t len; size_t len;
len = sizeof(state); len = sizeof(state);
if (sysctlbyname("hw.acpi.battery.state", &state, &len, NULL, 0) == -1 if (sysctlbyname(BATTERY_STATE, &state, &len, NULL, 0) < 0 || !len)
|| !len)
return NULL; return NULL;
switch(state) { switch (state) {
case 0: case 0: /* FALLTHROUGH */
case 2: case 2:
return "+"; return "+";
case 1: case 1:
@ -242,9 +238,8 @@
size_t len; size_t len;
len = sizeof(rem); len = sizeof(rem);
if (sysctlbyname("hw.acpi.battery.time", &rem, &len, NULL, 0) == -1 if (sysctlbyname(BATTERY_TIME, &rem, &len, NULL, 0) < 0 || !len
|| !len || rem < 0)
|| rem == -1)
return NULL; return NULL;
return bprintf("%uh %02um", rem / 60, rem % 60); return bprintf("%uh %02um", rem / 60, rem % 60);

32
components/cat.c Normal file
View File

@ -0,0 +1,32 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <string.h>
#include "../slstatus.h"
#include "../util.h"
const char *
cat(const char *path)
{
char *f;
FILE *fp;
if (!(fp = fopen(path, "r"))) {
warn("fopen '%s':", path);
return NULL;
}
f = fgets(buf, sizeof(buf) - 1, fp);
if (fclose(fp) < 0) {
warn("fclose '%s':", path);
return NULL;
}
if (!f)
return NULL;
if ((f = strrchr(buf, '\n')))
f[0] = '\0';
return buf[0] ? buf : NULL;
}

View File

@ -3,25 +3,26 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
#if defined(__linux__) #if defined(__linux__)
#define CPU_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
const char * const char *
cpu_freq(void) cpu_freq(const char *unused)
{ {
uintmax_t freq; uintmax_t freq;
/* in kHz */ /* in kHz */
if (pscanf("/sys/devices/system/cpu/cpu0/cpufreq/" if (pscanf(CPU_FREQ, "%ju", &freq) != 1)
"scaling_cur_freq", "%ju", &freq) != 1) {
return NULL; return NULL;
}
return fmt_human(freq * 1000, 1000); return fmt_human(freq * 1000, 1000);
} }
const char * const char *
cpu_perc(void) cpu_perc(const char *unused)
{ {
static long double a[7]; static long double a[7];
long double b[7], sum; long double b[7], sum;
@ -30,19 +31,17 @@
/* cpu user nice system idle iowait irq softirq */ /* cpu user nice system idle iowait irq softirq */
if (pscanf("/proc/stat", "%*s %Lf %Lf %Lf %Lf %Lf %Lf %Lf", if (pscanf("/proc/stat", "%*s %Lf %Lf %Lf %Lf %Lf %Lf %Lf",
&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]) &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6])
!= 7) { != 7)
return NULL; return NULL;
}
if (b[0] == 0) { if (b[0] == 0)
return NULL; return NULL;
}
sum = (b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6]) - sum = (b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6]) -
(a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6]); (a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6]);
if (sum == 0) { if (sum == 0)
return NULL; return NULL;
}
return bprintf("%d", (int)(100 * return bprintf("%d", (int)(100 *
((b[0] + b[1] + b[2] + b[5] + b[6]) - ((b[0] + b[1] + b[2] + b[5] + b[6]) -
@ -54,7 +53,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
const char * const char *
cpu_freq(void) cpu_freq(const char *unused)
{ {
int freq, mib[2]; int freq, mib[2];
size_t size; size_t size;
@ -74,7 +73,7 @@
} }
const char * const char *
cpu_perc(void) cpu_perc(const char *unused)
{ {
int mib[2]; int mib[2];
static uintmax_t a[CPUSTATES]; static uintmax_t a[CPUSTATES];
@ -91,16 +90,14 @@
warn("sysctl 'KERN_CPTIME':"); warn("sysctl 'KERN_CPTIME':");
return NULL; return NULL;
} }
if (b[0] == 0) { if (b[0] == 0)
return NULL; return NULL;
}
sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) - sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) -
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]); (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]);
if (sum == 0) { if (sum == 0)
return NULL; return NULL;
}
return bprintf("%d", 100 * return bprintf("%d", 100 *
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] + ((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
@ -109,20 +106,19 @@
b[CP_INTR])) / sum); b[CP_INTR])) / sum);
} }
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
#include <devstat.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <devstat.h>
const char * const char *
cpu_freq(void) cpu_freq(const char *unused)
{ {
int freq; int freq;
size_t size; size_t size;
size = sizeof(freq); size = sizeof(freq);
/* in MHz */ /* in MHz */
if (sysctlbyname("hw.clockrate", &freq, &size, NULL, 0) == -1 if (sysctlbyname("hw.clockrate", &freq, &size, NULL, 0) < 0 || !size) {
|| !size) {
warn("sysctlbyname 'hw.clockrate':"); warn("sysctlbyname 'hw.clockrate':");
return NULL; return NULL;
} }
@ -131,7 +127,7 @@
} }
const char * const char *
cpu_perc(void) cpu_perc(const char *unused)
{ {
size_t size; size_t size;
static long a[CPUSTATES]; static long a[CPUSTATES];
@ -139,21 +135,18 @@
size = sizeof(a); size = sizeof(a);
memcpy(b, a, sizeof(b)); memcpy(b, a, sizeof(b));
if (sysctlbyname("kern.cp_time", &a, &size, NULL, 0) == -1 if (sysctlbyname("kern.cp_time", &a, &size, NULL, 0) < 0 || !size) {
|| !size) {
warn("sysctlbyname 'kern.cp_time':"); warn("sysctlbyname 'kern.cp_time':");
return NULL; return NULL;
} }
if (b[0] == 0) { if (b[0] == 0)
return NULL; return NULL;
}
sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) - sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) -
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]); (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]);
if (sum == 0) { if (sum == 0)
return NULL; return NULL;
}
return bprintf("%d", 100 * return bprintf("%d", 100 *
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] + ((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +

View File

@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
const char * const char *

View File

@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
const char * const char *
@ -28,7 +29,7 @@ disk_perc(const char *path)
} }
return bprintf("%d", (int)(100 * return bprintf("%d", (int)(100 *
(1.0f - ((float)fs.f_bavail / (float)fs.f_blocks)))); (1 - ((double)fs.f_bavail / (double)fs.f_blocks))));
} }
const char * const char *

View File

@ -1,27 +1,29 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#include "../slstatus.h"
#if defined(__linux__) #if defined(__linux__)
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "../util.h" #include "../util.h"
#define ENTROPY_AVAIL "/proc/sys/kernel/random/entropy_avail"
const char * const char *
entropy(void) entropy(const char *unused)
{ {
uintmax_t num; uintmax_t num;
if (pscanf("/proc/sys/kernel/random/entropy_avail", "%ju", &num) if (pscanf(ENTROPY_AVAIL, "%ju", &num) != 1)
!= 1) {
return NULL; return NULL;
}
return bprintf("%ju", num); return bprintf("%ju", num);
} }
#elif defined(__OpenBSD__) | defined(__FreeBSD__) #elif defined(__OpenBSD__) | defined(__FreeBSD__)
const char * const char *
entropy(void) entropy(const char *unused)
{ {
// https://www.unicode.org/charts/PDF/U2200.pdf
/* Unicode Character 'INFINITY' (U+221E) */ /* Unicode Character 'INFINITY' (U+221E) */
return "\xe2\x88\x9e"; return "\u221E";
} }
#endif #endif

View File

@ -2,10 +2,11 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
const char * const char *
hostname(void) hostname(const char *unused)
{ {
if (gethostname(buf, sizeof(buf)) < 0) { if (gethostname(buf, sizeof(buf)) < 0) {
warn("gethostbyname:"); warn("gethostbyname:");

View File

@ -4,13 +4,14 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if defined(__OpenBSD__) #if defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h>
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
static const char * static const char *
@ -26,9 +27,9 @@ ip(const char *interface, unsigned short sa_family)
} }
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (!ifa->ifa_addr) { if (!ifa->ifa_addr)
continue; continue;
}
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (!strcmp(ifa->ifa_name, interface) && if (!strcmp(ifa->ifa_name, interface) &&

View File

@ -1,11 +1,12 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#include <sys/utsname.h>
#include <stdio.h> #include <stdio.h>
#include <sys/utsname.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
const char * const char *
kernel_release(void) kernel_release(const char *unused)
{ {
struct utsname udata; struct utsname udata;

View File

@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
/* /*
@ -32,17 +33,18 @@ keyboard_indicators(const char *fmt)
fmtlen = strnlen(fmt, 4); fmtlen = strnlen(fmt, 4);
for (i = n = 0; i < fmtlen; i++) { for (i = n = 0; i < fmtlen; i++) {
key = tolower(fmt[i]); key = tolower(fmt[i]);
if (key != 'c' && key != 'n') { if (key != 'c' && key != 'n')
continue; continue;
}
togglecase = (i + 1 >= fmtlen || fmt[i + 1] != '?'); togglecase = (i + 1 >= fmtlen || fmt[i + 1] != '?');
isset = (state.led_mask & (1 << (key == 'n'))); isset = (state.led_mask & (1 << (key == 'n')));
if (togglecase) {
if (togglecase)
buf[n++] = isset ? toupper(key) : key; buf[n++] = isset ? toupper(key) : key;
} else if (isset) { else if (isset)
buf[n++] = fmt[i]; buf[n++] = fmt[i];
} }
}
buf[n] = 0; buf[n] = 0;
return buf; return buf;
} }

View File

@ -5,6 +5,7 @@
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
static int static int
@ -14,11 +15,9 @@ valid_layout_or_variant(char *sym)
/* invalid symbols from xkb rules config */ /* invalid symbols from xkb rules config */
static const char *invalid[] = { "evdev", "inet", "pc", "base" }; static const char *invalid[] = { "evdev", "inet", "pc", "base" };
for (i = 0; i < LEN(invalid); i++) { for (i = 0; i < LEN(invalid); i++)
if (!strncmp(sym, invalid[i], strlen(invalid[i]))) { if (!strncmp(sym, invalid[i], strlen(invalid[i])))
return 0; return 0;
}
}
return 1; return 1;
} }
@ -46,12 +45,13 @@ get_layout(char *syms, int grp_num)
} }
const char * const char *
keymap(void) keymap(const char *unused)
{ {
Display *dpy; Display *dpy;
XkbDescRec *desc; XkbDescRec *desc;
XkbStateRec state; XkbStateRec state;
char *symbols, *layout; char *symbols;
const char *layout;
layout = NULL; layout = NULL;
@ -75,13 +75,12 @@ keymap(void)
warn("XGetAtomName: Failed to get atom name"); warn("XGetAtomName: Failed to get atom name");
goto end; goto end;
} }
layout = (char *)bprintf("%s", get_layout(symbols, state.group)); layout = bprintf("%s", get_layout(symbols, state.group));
XFree(symbols); XFree(symbols);
end: end:
XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1); XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1);
if (XCloseDisplay(dpy)) { if (XCloseDisplay(dpy))
warn("XCloseDisplay: Failed to close display"); warn("XCloseDisplay: Failed to close display");
}
return layout; return layout;
} }

View File

@ -2,10 +2,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
const char * const char *
load_avg(void) load_avg(const char *unused)
{ {
double avgs[3]; double avgs[3];

View File

@ -1,12 +1,16 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <limits.h> #include <limits.h>
#include <stdio.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
#if defined(__linux__) #if defined(__linux__)
#include <stdint.h> #include <stdint.h>
#define NET_RX_BYTES "/sys/class/net/%s/statistics/rx_bytes"
#define NET_TX_BYTES "/sys/class/net/%s/statistics/tx_bytes"
const char * const char *
netspeed_rx(const char *interface) netspeed_rx(const char *interface)
{ {
@ -17,17 +21,12 @@
oldrxbytes = rxbytes; oldrxbytes = rxbytes;
if (esnprintf(path, sizeof(path), if (esnprintf(path, sizeof(path), NET_RX_BYTES, interface) < 0)
"/sys/class/net/%s/statistics/rx_bytes",
interface) < 0) {
return NULL; return NULL;
} if (pscanf(path, "%ju", &rxbytes) != 1)
if (pscanf(path, "%ju", &rxbytes) != 1) {
return NULL; return NULL;
} if (oldrxbytes == 0)
if (oldrxbytes == 0) {
return NULL; return NULL;
}
return fmt_human((rxbytes - oldrxbytes) * 1000 / interval, return fmt_human((rxbytes - oldrxbytes) * 1000 / interval,
1024); 1024);
@ -43,27 +42,22 @@
oldtxbytes = txbytes; oldtxbytes = txbytes;
if (esnprintf(path, sizeof(path), if (esnprintf(path, sizeof(path), NET_TX_BYTES, interface) < 0)
"/sys/class/net/%s/statistics/tx_bytes",
interface) < 0) {
return NULL; return NULL;
} if (pscanf(path, "%ju", &txbytes) != 1)
if (pscanf(path, "%ju", &txbytes) != 1) {
return NULL; return NULL;
} if (oldtxbytes == 0)
if (oldtxbytes == 0) {
return NULL; return NULL;
}
return fmt_human((txbytes - oldtxbytes) * 1000 / interval, return fmt_human((txbytes - oldtxbytes) * 1000 / interval,
1024); 1024);
} }
#elif defined(__OpenBSD__) | defined(__FreeBSD__) #elif defined(__OpenBSD__) | defined(__FreeBSD__)
#include <string.h>
#include <ifaddrs.h> #include <ifaddrs.h>
#include <net/if.h>
#include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <net/if.h>
const char * const char *
netspeed_rx(const char *interface) netspeed_rx(const char *interface)
@ -77,25 +71,23 @@
oldrxbytes = rxbytes; oldrxbytes = rxbytes;
if (getifaddrs(&ifal) == -1) { if (getifaddrs(&ifal) < 0) {
warn("getifaddrs failed"); warn("getifaddrs failed");
return NULL; return NULL;
} }
rxbytes = 0; rxbytes = 0;
for (ifa = ifal; ifa; ifa = ifa->ifa_next) { for (ifa = ifal; ifa; ifa = ifa->ifa_next)
if (!strcmp(ifa->ifa_name, interface) && if (!strcmp(ifa->ifa_name, interface) &&
(ifd = (struct if_data *)ifa->ifa_data)) { (ifd = (struct if_data *)ifa->ifa_data))
rxbytes += ifd->ifi_ibytes, if_ok = 1; rxbytes += ifd->ifi_ibytes, if_ok = 1;
}
}
freeifaddrs(ifal); freeifaddrs(ifal);
if (!if_ok) { if (!if_ok) {
warn("reading 'if_data' failed"); warn("reading 'if_data' failed");
return NULL; return NULL;
} }
if (oldrxbytes == 0) { if (oldrxbytes == 0)
return NULL; return NULL;
}
return fmt_human((rxbytes - oldrxbytes) * 1000 / interval, return fmt_human((rxbytes - oldrxbytes) * 1000 / interval,
1024); 1024);
@ -113,25 +105,23 @@
oldtxbytes = txbytes; oldtxbytes = txbytes;
if (getifaddrs(&ifal) == -1) { if (getifaddrs(&ifal) < 0) {
warn("getifaddrs failed"); warn("getifaddrs failed");
return NULL; return NULL;
} }
txbytes = 0; txbytes = 0;
for (ifa = ifal; ifa; ifa = ifa->ifa_next) { for (ifa = ifal; ifa; ifa = ifa->ifa_next)
if (!strcmp(ifa->ifa_name, interface) && if (!strcmp(ifa->ifa_name, interface) &&
(ifd = (struct if_data *)ifa->ifa_data)) { (ifd = (struct if_data *)ifa->ifa_data))
txbytes += ifd->ifi_obytes, if_ok = 1; txbytes += ifd->ifi_obytes, if_ok = 1;
}
}
freeifaddrs(ifal); freeifaddrs(ifal);
if (!if_ok) { if (!if_ok) {
warn("reading 'if_data' failed"); warn("reading 'if_data' failed");
return NULL; return NULL;
} }
if (oldtxbytes == 0) { if (oldtxbytes == 0)
return NULL; return NULL;
}
return fmt_human((txbytes - oldtxbytes) * 1000 / interval, return fmt_human((txbytes - oldtxbytes) * 1000 / interval,
1024); 1024);

View File

@ -3,29 +3,30 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
const char * const char *
num_files(const char *path) num_files(const char *path)
{ {
struct dirent *dp; struct dirent *dp;
DIR *fd; DIR *dir;
int num; int num;
if (!(fd = opendir(path))) { if (!(dir = opendir(path))) {
warn("opendir '%s':", path); warn("opendir '%s':", path);
return NULL; return NULL;
} }
num = 0; num = 0;
while ((dp = readdir(fd))) { while ((dp = readdir(dir))) {
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue; /* skip self and parent */ continue; /* skip self and parent */
}
num++; num++;
} }
closedir(fd); closedir(dir);
return bprintf("%d", num); return bprintf("%d", num);
} }

View File

@ -1,13 +1,14 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#include <stdio.h> #include <stdio.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
#if defined(__linux__) #if defined(__linux__)
#include <stdint.h> #include <stdint.h>
const char * const char *
ram_free(void) ram_free(const char *unused)
{ {
uintmax_t free; uintmax_t free;
@ -15,17 +16,17 @@
"MemTotal: %ju kB\n" "MemTotal: %ju kB\n"
"MemFree: %ju kB\n" "MemFree: %ju kB\n"
"MemAvailable: %ju kB\n", "MemAvailable: %ju kB\n",
&free, &free, &free) != 3) { &free, &free, &free) != 3)
return NULL; return NULL;
}
return fmt_human(free * 1024, 1024); return fmt_human(free * 1024, 1024);
} }
const char * const char *
ram_perc(void) ram_perc(const char *unused)
{ {
uintmax_t total, free, buffers, cached; uintmax_t total, free, buffers, cached;
int percent;
if (pscanf("/proc/meminfo", if (pscanf("/proc/meminfo",
"MemTotal: %ju kB\n" "MemTotal: %ju kB\n"
@ -33,35 +34,32 @@
"MemAvailable: %ju kB\n" "MemAvailable: %ju kB\n"
"Buffers: %ju kB\n" "Buffers: %ju kB\n"
"Cached: %ju kB\n", "Cached: %ju kB\n",
&total, &free, &buffers, &buffers, &cached) != 5) { &total, &free, &buffers, &buffers, &cached) != 5)
return NULL; return NULL;
}
if (total == 0) { if (total == 0)
return NULL; return NULL;
}
return bprintf("%d", 100 * ((total - free) - (buffers + cached)) percent = 100 * ((total - free) - (buffers + cached)) / total;
/ total); return bprintf("%d", percent);
} }
const char * const char *
ram_total(void) ram_total(const char *unused)
{ {
uintmax_t total; uintmax_t total;
if (pscanf("/proc/meminfo", "MemTotal: %ju kB\n", &total) if (pscanf("/proc/meminfo", "MemTotal: %ju kB\n", &total)
!= 1) { != 1)
return NULL; return NULL;
}
return fmt_human(total * 1024, 1024); return fmt_human(total * 1024, 1024);
} }
const char * const char *
ram_used(void) ram_used(const char *unused)
{ {
uintmax_t total, free, buffers, cached; uintmax_t total, free, buffers, cached, used;
if (pscanf("/proc/meminfo", if (pscanf("/proc/meminfo",
"MemTotal: %ju kB\n" "MemTotal: %ju kB\n"
@ -69,12 +67,11 @@
"MemAvailable: %ju kB\n" "MemAvailable: %ju kB\n"
"Buffers: %ju kB\n" "Buffers: %ju kB\n"
"Cached: %ju kB\n", "Cached: %ju kB\n",
&total, &free, &buffers, &buffers, &cached) != 5) { &total, &free, &buffers, &buffers, &cached) != 5)
return NULL; return NULL;
}
return fmt_human((total - free - buffers - cached) * 1024, used = (total - free - buffers - cached);
1024); return fmt_human(used * 1024, 1024);
} }
#elif defined(__OpenBSD__) #elif defined(__OpenBSD__)
#include <stdlib.h> #include <stdlib.h>
@ -93,68 +90,61 @@
size = sizeof(*uvmexp); size = sizeof(*uvmexp);
if (sysctl(uvmexp_mib, 2, uvmexp, &size, NULL, 0) >= 0) { if (sysctl(uvmexp_mib, 2, uvmexp, &size, NULL, 0) >= 0)
return 1; return 1;
}
return 0; return 0;
} }
const char * const char *
ram_free(void) ram_free(const char *unused)
{ {
struct uvmexp uvmexp; struct uvmexp uvmexp;
int free_pages; int free_pages;
if (load_uvmexp(&uvmexp)) { if (!load_uvmexp(&uvmexp))
return NULL;
free_pages = uvmexp.npages - uvmexp.active; free_pages = uvmexp.npages - uvmexp.active;
return fmt_human(pagetok(free_pages, uvmexp.pageshift) * return fmt_human(pagetok(free_pages, uvmexp.pageshift) *
1024, 1024); 1024, 1024);
} }
return NULL;
}
const char * const char *
ram_perc(void) ram_perc(const char *unused)
{ {
struct uvmexp uvmexp; struct uvmexp uvmexp;
int percent; int percent;
if (load_uvmexp(&uvmexp)) { if (!load_uvmexp(&uvmexp))
return NULL;
percent = uvmexp.active * 100 / uvmexp.npages; percent = uvmexp.active * 100 / uvmexp.npages;
return bprintf("%d", percent); return bprintf("%d", percent);
} }
return NULL;
}
const char * const char *
ram_total(void) ram_total(const char *unused)
{ {
struct uvmexp uvmexp; struct uvmexp uvmexp;
if (load_uvmexp(&uvmexp)) { if (!load_uvmexp(&uvmexp))
return NULL;
return fmt_human(pagetok(uvmexp.npages, return fmt_human(pagetok(uvmexp.npages,
uvmexp.pageshift) * 1024, uvmexp.pageshift) * 1024, 1024);
1024);
}
return NULL;
} }
const char * const char *
ram_used(void) ram_used(const char *unused)
{ {
struct uvmexp uvmexp; struct uvmexp uvmexp;
if (load_uvmexp(&uvmexp)) { if (!load_uvmexp(&uvmexp))
return fmt_human(pagetok(uvmexp.active,
uvmexp.pageshift) * 1024,
1024);
}
return NULL; return NULL;
return fmt_human(pagetok(uvmexp.active,
uvmexp.pageshift) * 1024, 1024);
} }
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
#include <sys/sysctl.h> #include <sys/sysctl.h>
@ -163,13 +153,13 @@
#include <vm/vm_param.h> #include <vm/vm_param.h>
const char * const char *
ram_free(void) { ram_free(const char *unused) {
struct vmtotal vm_stats; struct vmtotal vm_stats;
int mib[] = {CTL_VM, VM_TOTAL}; int mib[] = {CTL_VM, VM_TOTAL};
size_t len; size_t len;
len = sizeof(struct vmtotal); len = sizeof(struct vmtotal);
if (sysctl(mib, 2, &vm_stats, &len, NULL, 0) == -1 if (sysctl(mib, 2, &vm_stats, &len, NULL, 0) < 0
|| !len) || !len)
return NULL; return NULL;
@ -177,44 +167,44 @@
} }
const char * const char *
ram_total(void) { ram_total(const char *unused) {
long npages; unsigned int npages;
size_t len; size_t len;
len = sizeof(npages); len = sizeof(npages);
if (sysctlbyname("vm.stats.vm.v_page_count", &npages, &len, NULL, 0) == -1 if (sysctlbyname("vm.stats.vm.v_page_count",
|| !len) &npages, &len, NULL, 0) < 0 || !len)
return NULL; return NULL;
return fmt_human(npages * getpagesize(), 1024); return fmt_human(npages * getpagesize(), 1024);
} }
const char * const char *
ram_perc(void) { ram_perc(const char *unused) {
long npages; unsigned int npages;
long active; unsigned int active;
size_t len; size_t len;
len = sizeof(npages); len = sizeof(npages);
if (sysctlbyname("vm.stats.vm.v_page_count", &npages, &len, NULL, 0) == -1 if (sysctlbyname("vm.stats.vm.v_page_count",
|| !len) &npages, &len, NULL, 0) < 0 || !len)
return NULL; return NULL;
if (sysctlbyname("vm.stats.vm.v_active_count", &active, &len, NULL, 0) == -1 if (sysctlbyname("vm.stats.vm.v_active_count",
|| !len) &active, &len, NULL, 0) < 0 || !len)
return NULL; return NULL;
return bprintf("%d", active * 100 / npages); return bprintf("%d", active * 100 / npages);
} }
const char * const char *
ram_used(void) { ram_used(const char *unused) {
long active; unsigned int active;
size_t len; size_t len;
len = sizeof(active); len = sizeof(active);
if (sysctlbyname("vm.stats.vm.v_active_count", &active, &len, NULL, 0) == -1 if (sysctlbyname("vm.stats.vm.v_active_count",
|| !len) &active, &len, NULL, 0) < 0 || !len)
return NULL; return NULL;
return fmt_human(active * getpagesize(), 1024); return fmt_human(active * getpagesize(), 1024);

View File

@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
const char * const char *
@ -14,17 +15,17 @@ run_command(const char *cmd)
warn("popen '%s':", cmd); warn("popen '%s':", cmd);
return NULL; return NULL;
} }
p = fgets(buf, sizeof(buf) - 1, fp); p = fgets(buf, sizeof(buf) - 1, fp);
if (pclose(fp) < 0) { if (pclose(fp) < 0) {
warn("pclose '%s':", cmd); warn("pclose '%s':", cmd);
return NULL; return NULL;
} }
if (!p) { if (!p)
return NULL; return NULL;
}
if ((p = strrchr(buf, '\n'))) { if ((p = strrchr(buf, '\n')))
p[0] = '\0'; p[0] = '\0';
}
return buf[0] ? buf : NULL; return buf[0] ? buf : NULL;
} }

View File

@ -1,10 +0,0 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include "../util.h"
const char *
separator(const char *separator)
{
return separator;
}

View File

@ -4,6 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
#if defined(__linux__) #if defined(__linux__)
@ -24,11 +25,9 @@
char *line = NULL; char *line = NULL;
/* get number of fields we want to extract */ /* get number of fields we want to extract */
for (i = 0, left = 0; i < LEN(ent); i++) { for (i = 0, left = 0; i < LEN(ent); i++)
if (ent[i].var) { if (ent[i].var)
left++; left++;
}
}
if (!(fp = fopen("/proc/meminfo", "r"))) { if (!(fp = fopen("/proc/meminfo", "r"))) {
warn("fopen '/proc/meminfo':"); warn("fopen '/proc/meminfo':");
@ -58,49 +57,45 @@
} }
const char * const char *
swap_free(void) swap_free(const char *unused)
{ {
long free; long free;
if (get_swap_info(NULL, &free, NULL)) { if (get_swap_info(NULL, &free, NULL))
return NULL; return NULL;
}
return fmt_human(free * 1024, 1024); return fmt_human(free * 1024, 1024);
} }
const char * const char *
swap_perc(void) swap_perc(const char *unused)
{ {
long total, free, cached; long total, free, cached;
if (get_swap_info(&total, &free, &cached) || total == 0) { if (get_swap_info(&total, &free, &cached) || total == 0)
return NULL; return NULL;
}
return bprintf("%d", 100 * (total - free - cached) / total); return bprintf("%d", 100 * (total - free - cached) / total);
} }
const char * const char *
swap_total(void) swap_total(const char *unused)
{ {
long total; long total;
if (get_swap_info(&total, NULL, NULL)) { if (get_swap_info(&total, NULL, NULL))
return NULL; return NULL;
}
return fmt_human(total * 1024, 1024); return fmt_human(total * 1024, 1024);
} }
const char * const char *
swap_used(void) swap_used(const char *unused)
{ {
long total, free, cached; long total, free, cached;
if (get_swap_info(&total, &free, &cached)) { if (get_swap_info(&total, &free, &cached))
return NULL; return NULL;
}
return fmt_human((total - free - cached) * 1024, 1024); return fmt_human((total - free - cached) * 1024, 1024);
} }
@ -147,74 +142,69 @@
} }
const char * const char *
swap_free(void) swap_free(const char *unused)
{ {
int total, used; int total, used;
if (getstats(&total, &used)) { if (getstats(&total, &used))
return NULL; return NULL;
}
return fmt_human((total - used) * 1024, 1024); return fmt_human((total - used) * 1024, 1024);
} }
const char * const char *
swap_perc(void) swap_perc(const char *unused)
{ {
int total, used; int total, used;
if (getstats(&total, &used)) { if (getstats(&total, &used))
return NULL; return NULL;
}
if (total == 0) { if (total == 0)
return NULL; return NULL;
}
return bprintf("%d", 100 * used / total); return bprintf("%d", 100 * used / total);
} }
const char * const char *
swap_total(void) swap_total(const char *unused)
{ {
int total, used; int total, used;
if (getstats(&total, &used)) { if (getstats(&total, &used))
return NULL; return NULL;
}
return fmt_human(total * 1024, 1024); return fmt_human(total * 1024, 1024);
} }
const char * const char *
swap_used(void) swap_used(const char *unused)
{ {
int total, used; int total, used;
if (getstats(&total, &used)) { if (getstats(&total, &used))
return NULL; return NULL;
}
return fmt_human(used * 1024, 1024); return fmt_human(used * 1024, 1024);
} }
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
#include <fcntl.h>
#include <kvm.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <kvm.h>
static int getswapinfo(struct kvm_swap *swap_info, size_t size) static int getswapinfo(struct kvm_swap *swap_info, size_t size)
{ {
kvm_t *kd; kvm_t *kd;
kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, NULL); kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, NULL);
if(kd == NULL) { if (kd == NULL) {
warn("kvm_openfiles '/dev/null':"); warn("kvm_openfiles '/dev/null':");
return 0; return 0;
} }
if(kvm_getswapinfo(kd, swap_info, size, 0 /* Unused flags */) == -1) { if (kvm_getswapinfo(kd, swap_info, size, 0 /* Unused flags */) < 0) {
warn("kvm_getswapinfo:"); warn("kvm_getswapinfo:");
kvm_close(kd); kvm_close(kd);
return 0; return 0;
@ -225,12 +215,12 @@
} }
const char * const char *
swap_free(void) swap_free(const char *unused)
{ {
struct kvm_swap swap_info[1]; struct kvm_swap swap_info[1];
long used, total; long used, total;
if(!getswapinfo(swap_info, 1)) if (!getswapinfo(swap_info, 1))
return NULL; return NULL;
total = swap_info[0].ksw_total; total = swap_info[0].ksw_total;
@ -240,12 +230,12 @@
} }
const char * const char *
swap_perc(void) swap_perc(const char *unused)
{ {
struct kvm_swap swap_info[1]; struct kvm_swap swap_info[1];
long used, total; long used, total;
if(!getswapinfo(swap_info, 1)) if (!getswapinfo(swap_info, 1))
return NULL; return NULL;
total = swap_info[0].ksw_total; total = swap_info[0].ksw_total;
@ -255,12 +245,12 @@
} }
const char * const char *
swap_total(void) swap_total(const char *unused)
{ {
struct kvm_swap swap_info[1]; struct kvm_swap swap_info[1];
long total; long total;
if(!getswapinfo(swap_info, 1)) if (!getswapinfo(swap_info, 1))
return NULL; return NULL;
total = swap_info[0].ksw_total; total = swap_info[0].ksw_total;
@ -269,12 +259,12 @@
} }
const char * const char *
swap_used(void) swap_used(const char *unused)
{ {
struct kvm_swap swap_info[1]; struct kvm_swap swap_info[1];
long used; long used;
if(!getswapinfo(swap_info, 1)) if (!getswapinfo(swap_info, 1))
return NULL; return NULL;
used = swap_info[0].ksw_used; used = swap_info[0].ksw_used;

View File

@ -1,6 +1,7 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#include <stddef.h> #include <stddef.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
@ -12,9 +13,8 @@
{ {
uintmax_t temp; uintmax_t temp;
if (pscanf(file, "%ju", &temp) != 1) { if (pscanf(file, "%ju", &temp) != 1)
return NULL; return NULL;
}
return bprintf("%ju", temp / 1000); return bprintf("%ju", temp / 1000);
} }
@ -52,6 +52,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#define ACPI_TEMP "hw.acpi.thermal.%s.temperature"
const char * const char *
temp(const char *zone) temp(const char *zone)
{ {
@ -60,8 +62,8 @@
size_t len; size_t len;
len = sizeof(temp); len = sizeof(temp);
snprintf(buf, sizeof(buf), "hw.acpi.thermal.%s.temperature", zone); snprintf(buf, sizeof(buf), ACPI_TEMP, zone);
if (sysctlbyname(buf, &temp, &len, NULL, 0) == -1 if (sysctlbyname(buf, &temp, &len, NULL, 0) < 0
|| !len) || !len)
return NULL; return NULL;

View File

@ -3,6 +3,7 @@
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
#if defined(CLOCK_BOOTTIME) #if defined(CLOCK_BOOTTIME)
@ -14,14 +15,14 @@
#endif #endif
const char * const char *
uptime(void) uptime(const char *unused)
{ {
char warn_buf[256]; char warn_buf[256];
uintmax_t h, m; uintmax_t h, m;
struct timespec uptime; struct timespec uptime;
if (clock_gettime(UPTIME_FLAG, &uptime) < 0) { if (clock_gettime(UPTIME_FLAG, &uptime) < 0) {
snprintf(warn_buf, 256, "clock_gettime %d", UPTIME_FLAG); snprintf(warn_buf, sizeof(warn_buf), "clock_gettime %d", UPTIME_FLAG);
warn(warn_buf); warn(warn_buf);
return NULL; return NULL;
} }

View File

@ -4,16 +4,17 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
const char * const char *
gid(void) gid(const char *unused)
{ {
return bprintf("%d", getgid()); return bprintf("%d", getgid());
} }
const char * const char *
username(void) username(const char *unused)
{ {
struct passwd *pw; struct passwd *pw;
@ -26,7 +27,7 @@ username(void)
} }
const char * const char *
uid(void) uid(const char *unused)
{ {
return bprintf("%d", geteuid()); return bprintf("%d", geteuid());
} }

View File

@ -5,13 +5,14 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
#if defined(__OpenBSD__) #if defined(__OpenBSD__) | defined(__FreeBSD__)
#include <sys/queue.h>
#include <poll.h> #include <poll.h>
#include <sndio.h> #include <sndio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/queue.h>
struct control { struct control {
LIST_ENTRY(control) next; LIST_ENTRY(control) next;
@ -161,6 +162,7 @@
if (sioctl_revents(hdl, pfds) & POLLHUP) { if (sioctl_revents(hdl, pfds) & POLLHUP) {
warn("sndio: disconnected"); warn("sndio: disconnected");
cleanup(); cleanup();
initialized = 0;
return NULL; return NULL;
} }
} }

View File

@ -6,6 +6,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include "../slstatus.h"
#include "../util.h" #include "../util.h"
#define RSSI_TO_PERC(rssi) \ #define RSSI_TO_PERC(rssi) \
@ -17,6 +18,8 @@
#include <limits.h> #include <limits.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#define NET_OPERSTATE "/sys/class/net/%s/operstate"
const char * const char *
wifi_perc(const char *interface) wifi_perc(const char *interface)
{ {
@ -27,37 +30,32 @@
char status[5]; char status[5];
FILE *fp; FILE *fp;
if (esnprintf(path, sizeof(path), "/sys/class/net/%s/operstate", if (esnprintf(path, sizeof(path), NET_OPERSTATE, interface) < 0)
interface) < 0) {
return NULL; return NULL;
}
if (!(fp = fopen(path, "r"))) { if (!(fp = fopen(path, "r"))) {
warn("fopen '%s':", path); warn("fopen '%s':", path);
return NULL; return NULL;
} }
p = fgets(status, 5, fp); p = fgets(status, 5, fp);
fclose(fp); fclose(fp);
if (!p || strcmp(status, "up\n") != 0) { if (!p || strcmp(status, "up\n") != 0)
return NULL; return NULL;
}
if (!(fp = fopen("/proc/net/wireless", "r"))) { if (!(fp = fopen("/proc/net/wireless", "r"))) {
warn("fopen '/proc/net/wireless':"); warn("fopen '/proc/net/wireless':");
return NULL; return NULL;
} }
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++)
if (!(p = fgets(buf, sizeof(buf) - 1, fp))) if (!(p = fgets(buf, sizeof(buf) - 1, fp)))
break; break;
}
fclose(fp);
if (i < 2 || !p) {
return NULL;
}
if (!(datastart = strstr(buf, interface))) { fclose(fp);
if (i < 2 || !p)
return NULL;
if (!(datastart = strstr(buf, interface)))
return NULL; return NULL;
}
datastart = (datastart+(strlen(interface)+1)); datastart = (datastart+(strlen(interface)+1));
sscanf(datastart + 1, " %*d %d %*d %*d\t\t %*d\t " sscanf(datastart + 1, " %*d %d %*d %*d\t\t %*d\t "
@ -77,9 +75,8 @@
memset(&wreq, 0, sizeof(struct iwreq)); memset(&wreq, 0, sizeof(struct iwreq));
wreq.u.essid.length = IW_ESSID_MAX_SIZE+1; wreq.u.essid.length = IW_ESSID_MAX_SIZE+1;
if (esnprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "%s", if (esnprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "%s",
interface) < 0) { interface) < 0)
return NULL; return NULL;
}
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
warn("socket 'AF_INET':"); warn("socket 'AF_INET':");
@ -94,9 +91,8 @@
close(sockfd); close(sockfd);
if (!strcmp(id, "")) { if (!strcmp(id, ""))
return NULL; return NULL;
}
return id; return id;
} }
@ -152,11 +148,11 @@
int q; int q;
if (load_ieee80211_nodereq(interface, &nr)) { if (load_ieee80211_nodereq(interface, &nr)) {
if (nr.nr_max_rssi) { if (nr.nr_max_rssi)
q = IEEE80211_NODEREQ_RSSI(&nr); q = IEEE80211_NODEREQ_RSSI(&nr);
} else { else
q = RSSI_TO_PERC(nr.nr_rssi); q = RSSI_TO_PERC(nr.nr_rssi);
}
return bprintf("%d", q); return bprintf("%d", q);
} }
@ -168,9 +164,8 @@
{ {
struct ieee80211_nodereq nr; struct ieee80211_nodereq nr;
if (load_ieee80211_nodereq(interface, &nr)) { if (load_ieee80211_nodereq(interface, &nr))
return bprintf("%s", nr.nr_nwid); return bprintf("%s", nr.nr_nwid);
}
return NULL; return NULL;
} }
@ -256,7 +251,7 @@
fmt = NULL; fmt = NULL;
len = sizeof(ssid); len = sizeof(ssid);
memset(&ssid, 0, len); memset(&ssid, 0, len);
if (load_ieee80211req(sockfd, interface, &ssid, IEEE80211_IOC_SSID, &len )) { if (load_ieee80211req(sockfd, interface, &ssid, IEEE80211_IOC_SSID, &len)) {
if (len < sizeof(ssid)) if (len < sizeof(ssid))
len += 1; len += 1;
else else

View File

@ -14,16 +14,17 @@ static const char unknown_str[] = "n/a";
* *
* battery_perc battery percentage battery name (BAT0) * battery_perc battery percentage battery name (BAT0)
* NULL on OpenBSD/FreeBSD * NULL on OpenBSD/FreeBSD
* battery_state battery charging state battery name (BAT0)
* NULL on OpenBSD/FreeBSD
* battery_remaining battery remaining HH:MM battery name (BAT0) * battery_remaining battery remaining HH:MM battery name (BAT0)
* NULL on OpenBSD/FreeBSD * NULL on OpenBSD/FreeBSD
* cpu_perc cpu usage in percent NULL * battery_state battery charging state battery name (BAT0)
* NULL on OpenBSD/FreeBSD
* cat read arbitrary file path
* cpu_freq cpu frequency in MHz NULL * cpu_freq cpu frequency in MHz NULL
* cpu_perc cpu usage in percent NULL
* datetime date and time format string (%F %T) * datetime date and time format string (%F %T)
* disk_free free disk space in GB mountpoint path (/) * disk_free free disk space in GB mountpoint path (/)
* disk_perc disk usage in percent mountpoint path (/) * disk_perc disk usage in percent mountpoint path (/)
* disk_total total disk space in GB mountpoint path (/") * disk_total total disk space in GB mountpoint path (/)
* disk_used used disk space in GB mountpoint path (/) * disk_used used disk space in GB mountpoint path (/)
* entropy available entropy NULL * entropy available entropy NULL
* gid GID of current user NULL * gid GID of current user NULL
@ -45,7 +46,6 @@ static const char unknown_str[] = "n/a";
* ram_total total memory size in GB NULL * ram_total total memory size in GB NULL
* ram_used used memory in GB NULL * ram_used used memory in GB NULL
* run_command custom shell command command (echo foo) * run_command custom shell command command (echo foo)
* separator string to echo NULL
* swap_free free swap in GB NULL * swap_free free swap in GB NULL
* swap_perc swap usage in percent NULL * swap_perc swap usage in percent NULL
* swap_total total swap size in GB NULL * swap_total total swap size in GB NULL
@ -59,9 +59,9 @@ static const char unknown_str[] = "n/a";
* uptime system uptime NULL * uptime system uptime NULL
* username username of current user NULL * username username of current user NULL
* vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer) * vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer)
* NULL on OpenBSD * NULL on OpenBSD/FreeBSD
* wifi_perc WiFi signal in percent interface name (wlan0)
* wifi_essid WiFi ESSID interface name (wlan0) * wifi_essid WiFi ESSID interface name (wlan0)
* wifi_perc WiFi signal in percent interface name (wlan0)
*/ */
static const struct arg args[] = { static const struct arg args[] = {
/* function format argument */ /* function format argument */

View File

@ -14,16 +14,17 @@ static const char unknown_str[] = "n/a";
* *
* battery_perc battery percentage battery name (BAT0) * battery_perc battery percentage battery name (BAT0)
* NULL on OpenBSD/FreeBSD * NULL on OpenBSD/FreeBSD
* battery_state battery charging state battery name (BAT0)
* NULL on OpenBSD/FreeBSD
* battery_remaining battery remaining HH:MM battery name (BAT0) * battery_remaining battery remaining HH:MM battery name (BAT0)
* NULL on OpenBSD/FreeBSD * NULL on OpenBSD/FreeBSD
* cpu_perc cpu usage in percent NULL * battery_state battery charging state battery name (BAT0)
* NULL on OpenBSD/FreeBSD
* cat read arbitrary file path
* cpu_freq cpu frequency in MHz NULL * cpu_freq cpu frequency in MHz NULL
* cpu_perc cpu usage in percent NULL
* datetime date and time format string (%F %T) * datetime date and time format string (%F %T)
* disk_free free disk space in GB mountpoint path (/) * disk_free free disk space in GB mountpoint path (/)
* disk_perc disk usage in percent mountpoint path (/) * disk_perc disk usage in percent mountpoint path (/)
* disk_total total disk space in GB mountpoint path (/") * disk_total total disk space in GB mountpoint path (/)
* disk_used used disk space in GB mountpoint path (/) * disk_used used disk space in GB mountpoint path (/)
* entropy available entropy NULL * entropy available entropy NULL
* gid GID of current user NULL * gid GID of current user NULL
@ -45,7 +46,6 @@ static const char unknown_str[] = "n/a";
* ram_total total memory size in GB NULL * ram_total total memory size in GB NULL
* ram_used used memory in GB NULL * ram_used used memory in GB NULL
* run_command custom shell command command (echo foo) * run_command custom shell command command (echo foo)
* separator string to echo NULL
* swap_free free swap in GB NULL * swap_free free swap in GB NULL
* swap_perc swap usage in percent NULL * swap_perc swap usage in percent NULL
* swap_total total swap size in GB NULL * swap_total total swap size in GB NULL
@ -59,13 +59,16 @@ static const char unknown_str[] = "n/a";
* uptime system uptime NULL * uptime system uptime NULL
* username username of current user NULL * username username of current user NULL
* vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer) * vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer)
* NULL on OpenBSD * NULL on OpenBSD/FreeBSD
* wifi_perc WiFi signal in percent interface name (wlan0)
* wifi_essid WiFi ESSID interface name (wlan0) * wifi_essid WiFi ESSID interface name (wlan0)
* wifi_perc WiFi signal in percent interface name (wlan0)
*/ */
static const struct arg args[] = { static const struct arg args[] = {
/* function format argument */ /* function format argument */
{ cpu_perc, " CPU: %s% | ", NULL }, { cpu_perc, " CPU: %s% | ", NULL },
{ ram_perc, "RAM: %s% | ", NULL }, { ram_perc, "RAM: %s%, ", NULL },
{ ram_used, "%s | ", NULL },
{ netspeed_rx, "NET r:%s, ", "eno2" },
{ netspeed_tx, "t:%s | ", "eno2" },
{ datetime, "%s ", "%F %T" }, { datetime, "%s ", "%F %T" },
}; };

View File

@ -1,5 +1,5 @@
# slstatus version # slstatus version
VERSION = 0 VERSION = 1.0
# customize below to fit your system # customize below to fit your system
@ -11,11 +11,11 @@ X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib X11LIB = /usr/X11R6/lib
# flags # flags
CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\"
CFLAGS = -std=c99 -pedantic -Wall -Wextra -Os CFLAGS = -std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter -Os
LDFLAGS = -L$(X11LIB) -s LDFLAGS = -L$(X11LIB) -s
# OpenBSD: add -lsndio # OpenBSD: add -lsndio
# FreeBSD: add -lkvm # FreeBSD: add -lkvm -lsndio
LDLIBS = -lX11 LDLIBS = -lX11
# compiler and linker # compiler and linker

View File

@ -1,22 +1,29 @@
.Dd 2020-06-23 .Dd 2023-04-23
.Dt SLSTATUS 1 .Dt SLSTATUS 1
.Os .Os
.Sh NAME .Sh NAME
.Nm slstatus .Nm slstatus
.Nd suckless status monitor .Nd suckless status
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl s .Op Fl s
.Op Fl 1 .Op Fl 1
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
is a suckless status monitor for window managers that use WM_NAME (e.g. dwm) or is a small tool for providing system status information to other programs
stdin to fill the status bar. over the EWMH
.Em WM_NAME
property of the root window (used by
.Xr dwm 1 ) or standard input/output. It is designed to be as efficient as possible by
only issuing the minimum of system calls required.
.P
By default, By default,
.Nm .Nm
outputs to WM_NAME. outputs to WM_NAME.
.Sh OPTIONS .Sh OPTIONS
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl v
Print version information to stderr, then exit.
.It Fl s .It Fl s
Write to stdout instead of WM_NAME. Write to stdout instead of WM_NAME.
.It Fl 1 .It Fl 1
@ -26,3 +33,15 @@ Write once to stdout and quit.
.Nm .Nm
can be customized by creating a custom config.h and (re)compiling the source can be customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple. code. This keeps it fast, secure and simple.
.Sh SIGNALS
.Nm
responds to the following signals:
.Pp
.Bl -tag -width TERM -compact
.It USR1
Triggers an instant redraw.
.El
.Sh AUTHORS
See the LICENSE file for the authors.
.Sh SEE ALSO
.Xr dwm 1

View File

@ -12,7 +12,7 @@
#include "util.h" #include "util.h"
struct arg { struct arg {
const char *(*func)(); const char *(*func)(const char *);
const char *fmt; const char *fmt;
const char *args; const char *args;
}; };
@ -41,7 +41,7 @@ difftimespec(struct timespec *res, struct timespec *a, struct timespec *b)
static void static void
usage(void) usage(void)
{ {
die("usage: %s [-s] [-1]", argv0); die("usage: %s [-v] [-s] [-1]", argv0);
} }
int int
@ -56,9 +56,11 @@ main(int argc, char *argv[])
sflag = 0; sflag = 0;
ARGBEGIN { ARGBEGIN {
case 'v':
die("slstatus-"VERSION);
case '1': case '1':
done = 1; done = 1;
/* fallthrough */ /* FALLTHROUGH */
case 's': case 's':
sflag = 1; sflag = 1;
break; break;
@ -66,9 +68,8 @@ main(int argc, char *argv[])
usage(); usage();
} ARGEND } ARGEND
if (argc) { if (argc)
usage(); usage();
}
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
act.sa_handler = terminate; act.sa_handler = terminate;
@ -77,24 +78,22 @@ main(int argc, char *argv[])
act.sa_flags |= SA_RESTART; act.sa_flags |= SA_RESTART;
sigaction(SIGUSR1, &act, NULL); sigaction(SIGUSR1, &act, NULL);
if (!sflag && !(dpy = XOpenDisplay(NULL))) { if (!sflag && !(dpy = XOpenDisplay(NULL)))
die("XOpenDisplay: Failed to open display"); die("XOpenDisplay: Failed to open display");
}
do { do {
if (clock_gettime(CLOCK_MONOTONIC, &start) < 0) { if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
die("clock_gettime:"); die("clock_gettime:");
}
status[0] = '\0'; status[0] = '\0';
for (i = len = 0; i < LEN(args); i++) { for (i = len = 0; i < LEN(args); i++) {
if (!(res = args[i].func(args[i].args))) { if (!(res = args[i].func(args[i].args)))
res = unknown_str; res = unknown_str;
}
if ((ret = esnprintf(status + len, sizeof(status) - len, if ((ret = esnprintf(status + len, sizeof(status) - len,
args[i].fmt, res)) < 0) { args[i].fmt, res)) < 0)
break; break;
}
len += ret; len += ret;
} }
@ -104,38 +103,32 @@ main(int argc, char *argv[])
if (ferror(stdout)) if (ferror(stdout))
die("puts:"); die("puts:");
} else { } else {
if (XStoreName(dpy, DefaultRootWindow(dpy), status) if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0)
< 0) {
die("XStoreName: Allocation failed"); die("XStoreName: Allocation failed");
}
XFlush(dpy); XFlush(dpy);
} }
if (!done) { if (!done) {
if (clock_gettime(CLOCK_MONOTONIC, &current) < 0) { if (clock_gettime(CLOCK_MONOTONIC, &current) < 0)
die("clock_gettime:"); die("clock_gettime:");
}
difftimespec(&diff, &current, &start); difftimespec(&diff, &current, &start);
intspec.tv_sec = interval / 1000; intspec.tv_sec = interval / 1000;
intspec.tv_nsec = (interval % 1000) * 1E6; intspec.tv_nsec = (interval % 1000) * 1E6;
difftimespec(&wait, &intspec, &diff); difftimespec(&wait, &intspec, &diff);
if (wait.tv_sec >= 0) { if (wait.tv_sec >= 0 &&
if (nanosleep(&wait, NULL) < 0 && nanosleep(&wait, NULL) < 0 &&
errno != EINTR) { errno != EINTR)
die("nanosleep:"); die("nanosleep:");
} }
}
}
} while (!done); } while (!done);
if (!sflag) { if (!sflag) {
XStoreName(dpy, DefaultRootWindow(dpy), NULL); XStoreName(dpy, DefaultRootWindow(dpy), NULL);
if (XCloseDisplay(dpy) < 0) { if (XCloseDisplay(dpy) < 0)
die("XCloseDisplay: Failed to close display"); die("XCloseDisplay: Failed to close display");
} }
}
return 0; return 0;
} }

View File

@ -2,12 +2,15 @@
/* battery */ /* battery */
const char *battery_perc(const char *); const char *battery_perc(const char *);
const char *battery_state(const char *);
const char *battery_remaining(const char *); const char *battery_remaining(const char *);
const char *battery_state(const char *);
/* cat */
const char *cat(const char *path);
/* cpu */ /* cpu */
const char *cpu_freq(void); const char *cpu_freq(const char *unused);
const char *cpu_perc(void); const char *cpu_perc(const char *unused);
/* datetime */ /* datetime */
const char *datetime(const char *fmt); const char *datetime(const char *fmt);
@ -19,26 +22,26 @@ const char *disk_total(const char *path);
const char *disk_used(const char *path); const char *disk_used(const char *path);
/* entropy */ /* entropy */
const char *entropy(void); const char *entropy(const char *unused);
/* hostname */ /* hostname */
const char *hostname(void); const char *hostname(const char *unused);
/* ip */ /* ip */
const char *ipv4(const char *interface); const char *ipv4(const char *interface);
const char *ipv6(const char *interface); const char *ipv6(const char *interface);
/* kernel_release */ /* kernel_release */
const char *kernel_release(void); const char *kernel_release(const char *unused);
/* keyboard_indicators */ /* keyboard_indicators */
const char *keyboard_indicators(void); const char *keyboard_indicators(const char *fmt);
/* keymap */ /* keymap */
const char *keymap(void); const char *keymap(const char *unused);
/* load_avg */ /* load_avg */
const char *load_avg(void); const char *load_avg(const char *unused);
/* netspeeds */ /* netspeeds */
const char *netspeed_rx(const char *interface); const char *netspeed_rx(const char *interface);
@ -48,37 +51,34 @@ const char *netspeed_tx(const char *interface);
const char *num_files(const char *path); const char *num_files(const char *path);
/* ram */ /* ram */
const char *ram_free(void); const char *ram_free(const char *unused);
const char *ram_perc(void); const char *ram_perc(const char *unused);
const char *ram_total(void); const char *ram_total(const char *unused);
const char *ram_used(void); const char *ram_used(const char *unused);
/* run_command */ /* run_command */
const char *run_command(const char *cmd); const char *run_command(const char *cmd);
/* separator */
const char *separator(const char *separator);
/* swap */ /* swap */
const char *swap_free(void); const char *swap_free(const char *unused);
const char *swap_perc(void); const char *swap_perc(const char *unused);
const char *swap_total(void); const char *swap_total(const char *unused);
const char *swap_used(void); const char *swap_used(const char *unused);
/* temperature */ /* temperature */
const char *temp(const char *); const char *temp(const char *);
/* uptime */ /* uptime */
const char *uptime(void); const char *uptime(const char *unused);
/* user */ /* user */
const char *gid(void); const char *gid(const char *unused);
const char *username(void); const char *uid(const char *unused);
const char *uid(void); const char *username(const char *unused);
/* volume */ /* volume */
const char *vol_perc(const char *card); const char *vol_perc(const char *card);
/* wifi */ /* wifi */
const char *wifi_perc(const char *interface);
const char *wifi_essid(const char *interface); const char *wifi_essid(const char *interface);
const char *wifi_perc(const char *interface);

7
util.c
View File

@ -13,10 +13,6 @@ char *argv0;
static void static void
verr(const char *fmt, va_list ap) verr(const char *fmt, va_list ap)
{ {
if (argv0 && strncmp(fmt, "usage", sizeof("usage") - 1)) {
fprintf(stderr, "%s: ", argv0);
}
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
if (fmt[0] && fmt[strlen(fmt) - 1] == ':') { if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
@ -119,9 +115,8 @@ fmt_human(uintmax_t num, int base)
} }
scaled = num; scaled = num;
for (i = 0; i < prefixlen && scaled >= base; i++) { for (i = 0; i < prefixlen && scaled >= base; i++)
scaled /= base; scaled /= base;
}
return bprintf("%.1f %s", scaled, prefix[i]); return bprintf("%.1f %s", scaled, prefix[i]);
} }

2
util.h
View File

@ -3,7 +3,7 @@
extern char buf[1024]; extern char buf[1024];
#define LEN(x) (sizeof (x) / sizeof *(x)) #define LEN(x) (sizeof(x) / sizeof((x)[0]))
extern char *argv0; extern char *argv0;