On Sat, 6 Dec 2008 19:38:16 +0100
Guillaume Quintin <[EMAIL PROTECTED]> wrote:

> On Sat, 6 Dec 2008 19:20:58 +0100
> Guillaume Quintin <[EMAIL PROTECTED]> wrote:
> 
> > On Sat, 06 Dec 2008 09:26:25 -0700
> > Neale Pickett <[EMAIL PROTECTED]> wrote:
> > 
> > > Jeremy Jay <[EMAIL PROTECTED]> writes:
> > > 
> > > > This was my hunch too, glad someone got it before me though.
> > > > This patch fixes the problem with 5.3.  Probably the same with
> > > > the double- fork version too.
> > > 
> > > The open FD was my first guess too, but the double-fork version
> > > didn't close any fds either, so I assumed it must be something
> > > else.
> > > 
> > > Guillaume, if you apply the "close(0)" patch, does the problem go
> > > away?
> > > 
> > > I'm away from my dwm computer right now, or I'd try it myself.
> > > 
> > > Neale
> > > 
> > 
> > I just tried the close(0) patch but it does not change anything.
> > And I found something very weird. I told you that in the previous
> > version of dwm (5.2) with the .xinitrc containing the "while | dwm"
> > all worked fine and I am sure of that. I quitted dwm-5.2 many times
> > with a lot of openned windows and all worked fine. But now, when I
> > reinstall dwm-5.2 I get the same problem than in dwm-5.3 and
> > dwm-5.3.1, "double-fork", "simple-fork" and re-"double-fork". I
> > don't understand why.
> > 
> > Why don't we change the way dwm gets its status text ? For example
> > we could use the SIGALRM signal to call a "spawn2" :
> > 
> > spawn2()
> > {
> >     check for a certain shell script ".dwmstatus";
> >     if it is not present then return;
> >     create some pipe p[];
> >     (double or simple)-fork;
> >     in the child process
> >     {
> >             close(0);
> >             close(1);
> >             close(2);
> >             set stdout to p[1]; /* I don't know how exactly */
> >             execv(".dwmstatus");
> >     }
> >     /* Here is dwm */
> >     read status from p[0];
> >     display status;
> > }
> > 
> > This will take only a few LOC, because all the reading p[0] part
> > will be in fact the reading-stdin code from the run() function which
> > will not be needed anymore. This has the advantages that one can
> > change the status when dwm is running and there are no more
> > "quitting" problem. This is just an idea, forgive me not to propose
> > some real code. Well tell me what you think of this idea.
> > 
> 
> This is more simple with the popen() function. We could simply get the
> shell commands to execute from the arguments passed to dwm or read
> them from any file or from stdin only once.
> 

This is a little very basic patch that does what I asked above. I tried
this using the SIGALRM signal but I "randomly" got fatal errors about
memory (un)locks.

I have a dwmstatus script :

~/.dwmstatus
#!/bin/sh
date

and my .xinitrc is :

~/.xinitrc
exec dwm -s ./dwmstatus

And every second I get the status bar text updated. Tell me what you
think about it.

-- 
Kind regards,
Guillaume Quintin.

--- org/dwm.c	2008-12-06 19:53:57.000000000 +0100
+++ dwm-5.3/dwm.c	2008-12-06 21:50:55.000000000 +0100
@@ -23,6 +23,7 @@
  *
  * To understand everything else, start reading main().
  */
+#define _POSIX_C_SOURCE 2
 #include <errno.h>
 #include <locale.h>
 #include <stdarg.h>
@@ -30,6 +31,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <time.h>
 #include <sys/select.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -204,8 +206,10 @@
 static int xerrordummy(Display *dpy, XErrorEvent *ee);
 static int xerrorstart(Display *dpy, XErrorEvent *ee);
 static void zoom(const Arg *arg);
+static void getstatustext(void);
 
 /* variables */
+static char sscript[256];
 static char stext[256];
 static int screen;
 static int sx, sy, sw, sh; /* X display screen geometry x, y, width, height */ 
@@ -1184,55 +1188,16 @@
 
 void
 run(void) {
-	char *p;
-	char sbuf[sizeof stext];
-	fd_set rd;
-	int r, xfd;
-	unsigned int len, offset;
+	int t,xfd;
 	XEvent ev;
 
 	/* main event loop, also reads status text from stdin */
 	XSync(dpy, False);
 	xfd = ConnectionNumber(dpy);
-	offset = 0;
-	len = sizeof stext - 1;
-	sbuf[len] = stext[len] = '\0'; /* 0-terminator is never touched */
+	getstatustext();
+	t = time(0) + 1;
 	while(running) {
-		FD_ZERO(&rd);
-		if(readin)
-			FD_SET(STDIN_FILENO, &rd);
-		FD_SET(xfd, &rd);
-		if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) {
-			if(errno == EINTR)
-				continue;
-			die("select failed\n");
-		}
-		if(FD_ISSET(STDIN_FILENO, &rd)) {
-			switch((r = read(STDIN_FILENO, sbuf + offset, len - offset))) {
-			case -1:
-				strncpy(stext, strerror(errno), len);
-				readin = False;
-				break;
-			case 0:
-				strncpy(stext, "EOF", 4);
-				readin = False;
-				break;
-			default:
-				for(p = sbuf + offset; r > 0; p++, r--, offset++)
-					if(*p == '\n' || *p == '\0') {
-						*p = '\0';
-						strncpy(stext, sbuf, len);
-						p += r - 1; /* p is sbuf + offset + r - 1 */
-						for(r = 0; *(p - r) && *(p - r) != '\n'; r++);
-						offset = r;
-						if(r)
-							memmove(sbuf, p - r + 1, r);
-						break;
-					}
-				break;
-			}
-			drawbar();
-		}
+		if ( time(0) >= t ) { t = time(0) + 1; getstatustext(); }
 		while(XPending(dpy)) {
 			XNextEvent(dpy, &ev);
 			if(handler[ev.type])
@@ -1728,13 +1693,42 @@
 	arrange();
 }
 
+void getstatustext(void)
+{
+	if ( !sscript[0] ) { return; }
+	FILE *f = popen(sscript,"r");
+	if ( !f ) { return; }
+	fgets(stext,255,f);
+	stext[255] = 0;
+	char *i = strstr(stext,"\n");
+	if ( i ) { *i = 0; }
+	pclose(f);
+	drawbar();
+}
+
 int
 main(int argc, char *argv[]) {
-	if(argc == 2 && !strcmp("-v", argv[1]))
-		die("dwm-"VERSION", © 2006-2008 dwm engineers, see LICENSE for details\n");
-	else if(argc != 1)
-		die("usage: dwm [-v]\n");
-
+	sscript[0] = 0;
+	int i = 1;
+	for( ; i < argc ; i++ )
+	{
+		if ( !strcmp("-s",argv[i]) )
+		{
+			i++;
+			strncpy(sscript,argv[i],254);
+			sscript[255] = 0;
+			printf("sscript = %s\n",sscript);
+			continue;
+		}
+		else if ( !strcmp("-v",argv[i]) )
+		{
+			die("dwm-"VERSION", © 2006-2008 dwm engineers, see LICENSE for details\n");
+		}
+		else
+		{
+			die("usage: dwm [-v] [-s status_script]\n");
+		}
+	}
 	if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
 		fprintf(stderr, "warning: no locale support\n");
 

Reply via email to