X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/35295f190207d9001fdcf30fe76f11434691b259..832b21ca4b4ba866e010a6f52c0f84919c7123f2:/slstatus.c

diff --git a/slstatus.c b/slstatus.c
index ada6441..993eba4 100644
--- a/slstatus.c
+++ b/slstatus.c
@@ -35,7 +35,9 @@ struct arg {
 
 static char *smprintf(const char *fmt, ...);
 static char *battery_perc(const char *bat);
+static char *battery_power(const char *bat);
 static char *battery_state(const char *bat);
+static char *cpu_freq(void);
 static char *cpu_perc(void);
 static char *datetime(const char *fmt);
 static char *disk_free(const char *mnt);
@@ -71,7 +73,7 @@ static void usage(const int eval);
 char *argv0;
 static unsigned short int delay = 0;
 static unsigned short int done;
-static unsigned short int dflag, oflag;
+static unsigned short int dflag, oflag, nflag;
 static Display *dpy;
 
 #include "config.h"
@@ -118,6 +120,25 @@ battery_perc(const char *bat)
 	return smprintf("%d%%", perc);
 }
 
+static char *
+battery_power(const char *bat)
+{
+	char path[PATH_MAX];
+	FILE *fp;
+	int watts;
+
+	snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/", bat, "/power_now");
+	fp = fopen(path, "r");
+	if (fp == NULL) {
+		warn("Failed to open file %s", path);
+		return smprintf("%s", UNKNOWN_STR);
+	}
+	fscanf(fp, "%i", &watts);
+	fclose(fp);
+
+	return smprintf("%d", (watts + 500000) / 1000000);
+}
+
 static char *
 battery_state(const char *bat)
 {
@@ -147,6 +168,23 @@ battery_state(const char *bat)
 	}
 }
 
+static char *
+cpu_freq(void)
+{
+	int freq;
+	FILE *fp;
+
+	fp = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", "r");
+	if (fp == NULL) {
+		warn("Failed to open file /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq");
+		return smprintf("%s", UNKNOWN_STR);
+	}
+	fscanf(fp, "%i", &freq);
+	fclose(fp);
+
+	return smprintf("%d", (freq + 500) / 1000);
+}
+
 static char *
 cpu_perc(void)
 {
@@ -451,7 +489,7 @@ run_command(const char *cmd)
 	pclose(fp);
 	buf[sizeof(buf) - 1] = '\0';
 
-	if ((nlptr = strstr(buf, "\n")) != NULL) {
+	if ((nlptr = strrchr(buf, '\n')) != NULL) {
 		nlptr[0] = '\0';
 	}
 
@@ -643,8 +681,7 @@ uptime(void)
 static char *
 username(void)
 {
-	uid_t uid = geteuid();
-	struct passwd *pw = getpwuid(uid);
+	struct passwd *pw = getpwuid(geteuid());
 
 	if (pw == NULL) {
 		warn("Failed to get username");
@@ -668,17 +705,23 @@ vol_perc(const char *card)
 	int v, afd, devmask;
 	char *vnames[] = SOUND_DEVICE_NAMES;
 
-	afd = open(card, O_RDONLY);
-	if (afd < 0) {
+	afd = open(card, O_RDONLY | O_NONBLOCK);
+	if (afd == -1) {
 		warn("Cannot open %s", card);
 		return smprintf(UNKNOWN_STR);
 	}
 
-	ioctl(afd, MIXER_READ(SOUND_MIXER_DEVMASK), &devmask);
+	if (ioctl(afd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
+		warn("Cannot get volume for %s", card);
+		close(afd);
+		return smprintf("%s", UNKNOWN_STR);
+	}
 	for (i = 0; i < (sizeof(vnames) / sizeof((vnames[0]))); i++) {
-		if (devmask & (1 << i)) {
-			if (!strcmp("vol", vnames[i])) {
-				ioctl(afd, MIXER_READ(i), &v);
+		if (devmask & (1 << i) && !strcmp("vol", vnames[i])) {
+			if (ioctl(afd, MIXER_READ(i), &v) == -1) {
+				warn("vol_perc: ioctl");
+				close(afd);
+				return smprintf("%s", UNKNOWN_STR);
 			}
 		}
 	}
@@ -770,7 +813,7 @@ sighandler(const int signo)
 static void
 usage(const int eval)
 {
-	fprintf(stderr, "usage: %s [-d] [-o] [-v] [-h]\n", argv0);
+	fprintf(stderr, "usage: %s [-d] [-o] [-n] [-v] [-h]\n", argv0);
 	exit(eval);
 }
 
@@ -790,6 +833,9 @@ main(int argc, char *argv[])
 		case 'o':
 			oflag = 1;
 			break;
+		case 'n':
+			nflag = 1;
+			break;
 		case 'v':
 			printf("slstatus (C) 2016-2017 slstatus engineers\n");
 			return 0;
@@ -799,7 +845,7 @@ main(int argc, char *argv[])
 			usage(1);
 	} ARGEND
 
-	if (dflag && oflag) {
+	if ((dflag && oflag) || (dflag && nflag) || (oflag && nflag)) {
 		usage(1);
 	}
 	if (dflag && daemon(1, 1) < 0) {
@@ -837,11 +883,14 @@ main(int argc, char *argv[])
 			free(element);
 		}
 
-		if (!oflag) {
+		if (oflag) {
+			printf("%s\n", status_string);
+		} else if (nflag) {
+			printf("%s\n", status_string);
+			done = 1;
+		} else {
 			XStoreName(dpy, DefaultRootWindow(dpy), status_string);
 			XSync(dpy, False);
-		} else {
-			printf("%s\n", status_string);
 		}
 
 		if ((UPDATE_INTERVAL - delay) <= 0) {