I noticed that barM.c obtained from here
dwm.suckless.org/dwmstatus/barM.c was using fixed buffers without
concern for the length of said buffer creating the possibility of a
buffer overflow.
I have also declared global variables and functions static because
there is only one file. This may lead to slightly better generated
code.
I have also made the program loop in order to eliminate the bash loop.
There is no advantage to looping in bash.
Finally I have made slight improvements to some of the comments.
--- barM.c
+++ barM.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014,2015 levi0x0
+ * Copyright (C) 2014,2015 levi0x0 with enhancements by ProgrammerNerd
*
* barM (bar_monitor or BarMonitor) is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -10,7 +10,7 @@
*
* Read main() to configure your new status Bar.
*
- * compile: gcc -o barM barM.c -lX11
+ * compile: gcc -o barM barM.c -O2 -s -lX11
*
* mv barM /usr/local/bin/
*/
@@ -25,36 +25,23 @@
/*
* Put this in your .xinitrc file:
*
- * while true;do
- * $(barM)
- * done &
+ * barM&
*
*/
-#define VERSION "0.11"
+#define VERSION "0.12"
#define TIME_FORMAT "(%H:%M) (%d-%m-%Y)"
#define MAXSTR 1024
-static char status[MAXSTR];
-/*append here your commands*/
-char *commands[] = {"uname",
+/*Append here your commands.*/
+static const char *const commands[] = {"uname",
"free -mh | awk 'NR==2{print $3\"/\"$2}'"
};
-/* will append the buffer to status*/
-void sprint(char *format, ...) {
- va_list li;
- static char s[MAXSTR];
- va_start(li, format);
- vsprintf(s, format, li);
- va_end(li);
- strcat(status, s);
-}
-
-/* returen the date*/
-char * date(void) {
+/* Returns the date*/
+static char * date(void) {
static char date[MAXSTR];
time_t now = time(0);
@@ -64,8 +51,10 @@
}
-/* open a pipe for a new coomand and return the output*/
-char * spawn(char *c) {
+/* Opens a pipe for a new command and return the output.*/
+#define xstr(s) str(s)
+#define str(s) #s
+static char * spawn(const char *c) {
FILE *proc;
static char buffer[MAXSTR];
@@ -74,14 +63,14 @@
exit(1);;
}
- fscanf(proc, "%[^\n]", buffer);
+ fscanf(proc, "%"xstr(MAXSTR)"[^\n]", buffer);
pclose(proc);
return buffer;
}
-void XSetRoot(char *name) {
+static void XSetRoot(const char *name) {
Display *display;
if (( display = XOpenDisplay(0x0)) == NULL ) {
@@ -95,17 +84,23 @@
XCloseDisplay(display);
}
-int main(int argc, char **argv) {
- int i = 0;
- for(i = 0; commands[i]; i++ ) {
- sprint("(%s) ", spawn(commands[i]));
+int main(int argc, char **argv) {
+ char status[MAXSTR];
+ for(;;){
+ int left=sizeof(status),i;
+ char*sta=status;
+ for(i = 0; i<sizeof(commands)/sizeof(commands[0]); ++i ) {
+ int ret=snprintf(sta,left,"(%s) ", spawn(commands[i]));
+ sta+=ret;
+ left-=ret;
+ if(sta>=(status+MAXSTR))/*When snprintf has to resort to truncating a string it will return the length as if it were not truncated.*/
+ goto skipDate;
+ }
+ strncpy(sta,date(),left);
+skipDate:
+ status[MAXSTR-1]=0;
+ XSetRoot(status);
+ sleep(1);
}
-
- sprint("%s", date());
- XSetRoot(status);
-
- /* sleep by default you dont need to add it to your bash*/
- sleep(1);
-
return 0;
}