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");