Re: [dwm] input status text bug?

2007-11-03 Thread Anselm R. Garbe
On Fri, Nov 02, 2007 at 10:49:18PM +0100, Sander van Dijk wrote:
 On Nov 2, 2007 10:02 PM, Anselm R. Garbe [EMAIL PROTECTED] wrote:
  Hmm, if that's the reason I tend to write a read()-based getline
  function which does not block ;)
 
 Try doing this:
 
 for i in `seq 1 10`
 do
 echo -n bla
 if test $i = 5
 then
 echo
 fi
 sleep 3
 done | dwm
 
 Than dwm will be unresponsive for a while, after some time it'll
 update the statustext as blablablablabla and continue to be
 unresponsive.

Well I extended the old low-level approach with an offset
handling, and your example and all others work really quite well
now (recheck hg tip).

One thing which behaves differently now is, that dwm will drop
subsequent multiline data except the first line during a single
read(). This approach makes the algorithm more readable and
elegant, and usually nobody writes more than a single line to
dwm per status update.

Regards,
-- 
 Anselm R. Garbe  http://www.suckless.org/  GPG key: 0D73F361



Re: [dwm] input status text bug?

2007-11-02 Thread Enno Gottox Boland
It doesn't work at all...
2007/11/2, Anselm R. Garbe [EMAIL PROTECTED]:
 Ritesh,

 I pushed a simplified status text processing version which uses
 fgets again, for readability and simplicity reasons.

 Could you please recheck if hg tip fixes your issue?

 Regards,
 --
  Anselm R. Garbe  http://www.suckless.org/  GPG key: 0D73F361




-- 
http://www.gnuffy.org - Real Community Distro
http://www.gnuffy.org/index.php/GnuEm - Gnuffy on Ipaq (Codename Peggy)



Re: [dwm] input status text bug?

2007-11-02 Thread Enno Gottox Boland
The reason was something in my .xinitrc. I changed it and everything is fine.

2007/11/2, Anselm R. Garbe [EMAIL PROTECTED]:
 On Fri, Nov 02, 2007 at 05:21:36PM +0100, Enno Gottox Boland wrote:
  It doesn't work at all...

 Sorry, but I can't reproduce. It works correctly for me so far.

  2007/11/2, Anselm R. Garbe [EMAIL PROTECTED]:
   Ritesh,
  
   I pushed a simplified status text processing version which uses
   fgets again, for readability and simplicity reasons.
  
   Could you please recheck if hg tip fixes your issue?
 --
  Anselm R. Garbe  http://www.suckless.org/  GPG key: 0D73F361




-- 
http://www.gnuffy.org - Real Community Distro
http://www.gnuffy.org/index.php/GnuEm - Gnuffy on Ipaq (Codename Peggy)



Re: [dwm] input status text bug?

2007-11-02 Thread Sander van Dijk
On Nov 2, 2007 6:37 PM, Anselm R. Garbe [EMAIL PROTECTED] wrote:
 On Fri, Nov 02, 2007 at 05:21:36PM +0100, Enno Gottox Boland wrote:
  It doesn't work at all...

 Sorry, but I can't reproduce. It works correctly for me so far.

It seems to me that the call to fgets() blocks, that is, when it's
reading for example from a fifo, and data is coming in over that fifo,
it will ignore any events until it encounters a newline (the statusbar
isn't updated until it does, and it doesn't respond to keypresses and
such).
I'm not sure if that is what we want, but if it is, than I think it
should at least be explicitly documented somewhere (probably both in
the README and in the BUGS section of the manpage).

Greetings, Sander.



Re: [dwm] input status text bug?

2007-11-02 Thread Sander van Dijk
On Nov 2, 2007 10:02 PM, Anselm R. Garbe [EMAIL PROTECTED] wrote:
 Hmm, if that's the reason I tend to write a read()-based getline
 function which does not block ;)

Try doing this:

for i in `seq 1 10`
do
echo -n bla
if test $i = 5
then
echo
fi
sleep 3
done | dwm

Than dwm will be unresponsive for a while, after some time it'll
update the statustext as blablablablabla and continue to be
unresponsive.

Greetings, Sander.



Re: [dwm] input status text bug?

2007-10-31 Thread Anselm R. Garbe
Hi Ritesh,

On Tue, Oct 30, 2007 at 11:04:33PM -0400, Ritesh Kumar wrote:
 I used to run dwm using the following bash script:
 
 while true; do
 date;
 sleep 1;
 done | dwm
 
 ... and things used to run fine :).
 
 I changed it to:
 
 while true; do
 cat $HOME/.dwm/status_* ;
 date;
 sleep 1;
 done | dwm
 
 The status_* files contain text without trailing \n's.
 Surprisingly , the contents of the statusbar didn't change (only date, no
 other status text) ... even though the while loop outputs something like
 some text Tue Oct 30 22:46:56 EDT 2007
 some text Tue Oct 30 22:46:57 EDT 2007
 some text Tue Oct 30 22:46:58 EDT 2007
 ...

 My guess is that read() reads the status_* text and date in two successive
 calls causing the date to prevail till sleep 1 is done.

Well let's have a look at the relevant bits in the code:

(a) switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
[...]
default:
(b) for(stext[r] = '\0', p = stext + strlen(stext) - 1; p = stext 
 *p == '\n'; *p-- = '\0');
(c) for(; p = stext  *p != '\n'; --p);
(d) if(p  stext)
(e) strncpy(stext, p + 1, sizeof stext);
[...]

(a) Reads the next bunch of stdin, beginning at stext[0] and
ending at stext[r].

(b) 0-terminates stext, and trims rightmost '\n' from right to left only.

(c) If p still does not point to stext, it now seeks for a '\n'
character leftwards.

(d) If during (c) such a '\n' character was found, it is the
begin of the last line which has been read.

(e) Hence, we copy the last line read only to stext, beginning
at the '\n' character + 1 to stext. It is 0-terminated already.

So in my eyes, assumed the complete output of the input script
is read, the code is correct and does what it is supposed
to do: it only displays the last line read from stdin (this might
be a bunch of data which is not '\n'-terminated yet during this read
round of course).

If you like to debug, you could add an

  fprintf(stderr, 'stext == %s'\n, stext);

in there between (c) and (d). Then we can make sure that your
guess is correct.

If the input is not read during one read call as you believe,
then at least there must be some flashing, because dwm will
actually render the some text at the status bar, but maybe
your system is really fast and you don't notice this.

 I went through the source code and fixed the status input handling code to
 make sure it flushes the input status text only if in encounters a '\n'. The
 patch is given... unfortunately it is over my (recently posted) status text
 patch. I moved the trimming of trailing \n's to another function  setstext()
 (introduced by my status text patch)... however, the relevant code can be
 moved to the function run().
 
 What do you guys think... did I accidentally break something?

I see the problem in the above code, and also believe that your
solution is more correct. What scares me is, that it might seen
as valid input if someone feeds dwm with for example:

echo -n foo

during while... but we can fix this. Please lemme know if your
guess is correct through using the above fprintf-debug trick.

Regards,
-- 
 Anselm R. Garbe  http://www.suckless.org/  GPG key: 0D73F361



Re: [dwm] input status text bug?

2007-10-31 Thread Anselm R. Garbe
On Wed, Oct 31, 2007 at 09:28:33AM +0100, Anselm R. Garbe wrote:
 I see the problem in the above code, and also believe that your
 solution is more correct. What scares me is, that it might seen
 as valid input if someone feeds dwm with for example:
 
 echo -n foo
 
 during while... but we can fix this. Please lemme know if your
 guess is correct through using the above fprintf-debug trick.

The question I see (apart from certain flaws in your patch)
after all is:

Do we really want that dwm's status text is displayed
line-based? Isn't it fine as is, that it even does not break if
input is feed without line-terminators?

If we decide for line-based input reading, one easily could
block dwm from further event processing through running

echo -n foo | dwm

I think that'd be a big disadvantage.

Regards,
-- 
 Anselm R. Garbe  http://www.suckless.org/  GPG key: 0D73F361



Re: [dwm] input status text bug?

2007-10-31 Thread Chris Webb
Anselm R. Garbe [EMAIL PROTECTED] writes:

 If we decide for line-based input reading, one easily could
 block dwm from further event processing through running
 
 echo -n foo | dwm
 
 I think that'd be a big disadvantage.

It could append read text to the end of stext[] whenever it successfully
reads(), except that the first character after a '\n' clears stext[] and
starts a new status. It needn't block.

Best wishes,

Chris.



Re: [dwm] input status text bug?

2007-10-31 Thread Ritesh Kumar
On 10/31/07, Sander van Dijk [EMAIL PROTECTED] wrote:

 On Oct 31, 2007 7:01 AM, Vasil Dimov [EMAIL PROTECTED] wrote:
  On Tue, Oct 30, 2007 at 23:04:33 -0400, Ritesh Kumar wrote:
  [...]
   I went through the source code and fixed the status input handling
 code to
   make sure it flushes the input status text only if in encounters a
 '\n'.
  [...]
   if(FD_ISSET(STDIN_FILENO, rd)) {
   -   switch(r = read(STDIN_FILENO, inputtext,
 sizeof inputtext - 1)) {
   +   pos = inputtext[strlen(inputtext)-1] != '\n' ?
 strlen(inputtext) : 0;
   +   switch(r = read(STDIN_FILENO,
 (inputtext[pos]), sizeof inputtext - 1 - pos)) {
  [...]
 
  Hmmz, aren't you trying to calculate strlen() of something undefined
  here?

 And also, when inputtext[0] = '\0', where does
 inputtext[strlen(inputtext)-1] point to?


Nice catch! Actually, I didn't think of this when I first developed the
patch.
However, the read() call always returns atleast one char in inputtext for
the default switch case. So, we are always bound to have strlen(inputtext) 
1 for all cases.
But I guess its better to be safe and put a check in for strlen(inputtext)
while calculating pos.

_r


Re: [dwm] input status text bug?

2007-10-31 Thread Ritesh Kumar
On 10/31/07, Anselm R. Garbe [EMAIL PROTECTED] wrote:

 Hi Ritesh,


snip


 Well let's have a look at the relevant bits in the code:

 (a) switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
 [...]
 default:
 (b) for(stext[r] = '\0', p = stext + strlen(stext) - 1; p =
 stext  *p == '\n'; *p-- = '\0');
 (c) for(; p = stext  *p != '\n'; --p);
 (d) if(p  stext)
 (e) strncpy(stext, p + 1, sizeof stext);
 [...]

 (a) Reads the next bunch of stdin, beginning at stext[0] and
 ending at stext[r].

 (b) 0-terminates stext, and trims rightmost '\n' from right to left only.

 (c) If p still does not point to stext, it now seeks for a '\n'
 character leftwards.

 (d) If during (c) such a '\n' character was found, it is the
 begin of the last line which has been read.

 (e) Hence, we copy the last line read only to stext, beginning
 at the '\n' character + 1 to stext. It is 0-terminated already.

 So in my eyes, assumed the complete output of the input script
 is read, the code is correct and does what it is supposed
 to do: it only displays the last line read from stdin (this might
 be a bunch of data which is not '\n'-terminated yet during this read
 round of course).


The problem is that select will notify dwm the moment *anything* is
available on stdin... and that could be partial data.
There is one semantic difference between the code snippets. While the
original one retains the last line of given multiline input, the suggested
snippet shows the first line. However, its hard to think of a situation
where somebody would pour in multiline text (all in a small amount of time)
for the status as dwm would not be able to show all of it anyways regardless
of the semantics.

If you like to debug, you could add an

   fprintf(stderr, 'stext == %s'\n, stext);

 in there between (c) and (d). Then we can make sure that your
 guess is correct.

 If the input is not read during one read call as you believe,
 then at least there must be some flashing, because dwm will
 actually render the some text at the status bar, but maybe
 your system is really fast and you don't notice this.


I will do this and post the results.
You are right about my system... its really fast :). Actually, I did see a
flash but it was merely a flicker and happened only sometimes.

_r


Re: [dwm] input status text bug?

2007-10-31 Thread Ritesh Kumar
On 10/31/07, Ritesh Kumar [EMAIL PROTECTED] wrote:

 On 10/31/07, Anselm R. Garbe [EMAIL PROTECTED] wrote:
 
  Hi Ritesh,


 snip


  Well let's have a look at the relevant bits in the code:
 
  (a) switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
  [...]
  default:
  (b) for(stext[r] = '\0', p = stext + strlen(stext) - 1; p =
  stext  *p == '\n'; *p-- = '\0');
  (c) for(; p = stext  *p != '\n'; --p);
  (d) if(p  stext)
  (e) strncpy(stext, p + 1, sizeof stext);
  [...]
 
  (a) Reads the next bunch of stdin, beginning at stext[0] and
  ending at stext[r].
 
  (b) 0-terminates stext, and trims rightmost '\n' from right to left
  only.
 
  (c) If p still does not point to stext, it now seeks for a '\n'
  character leftwards.
 
  (d) If during (c) such a '\n' character was found, it is the
  begin of the last line which has been read.
 
  (e) Hence, we copy the last line read only to stext, beginning
  at the '\n' character + 1 to stext. It is 0-terminated already.
 
  So in my eyes, assumed the complete output of the input script
  is read, the code is correct and does what it is supposed
  to do: it only displays the last line read from stdin (this might
  be a bunch of data which is not '\n'-terminated yet during this read
  round of course).


 The problem is that select will notify dwm the moment *anything* is
 available on stdin... and that could be partial data.
 There is one semantic difference between the code snippets. While the
 original one retains the last line of given multiline input, the suggested
 snippet shows the first line. However, its hard to think of a situation
 where somebody would pour in multiline text (all in a small amount of time)
 for the status as dwm would not be able to show all of it anyways regardless
 of the semantics.

 If you like to debug, you could add an
 
fprintf(stderr, 'stext == %s'\n, stext);
 
  in there between (c) and (d). Then we can make sure that your
  guess is correct.
 
  If the input is not read during one read call as you believe,
  then at least there must be some flashing, because dwm will
  actually render the some text at the status bar, but maybe
  your system is really fast and you don't notice this.


 I will do this and post the results.
 You are right about my system... its really fast :). Actually, I did see a
 flash but it was merely a flicker and happened only sometimes.

 _r

 Okay, I tried the debug: the output with the previous code is
inputtext == sometext
inputtext == Wed Oct 31 14:46:32 EDT 2007
inputtext == sometext
inputtext == Wed Oct 31 14:46:33 EDT 2007
inputtext == sometext
inputtext == Wed Oct 31 14:46:34 EDT 2007
inputtext == sometext
inputtext == Wed Oct 31 14:46:35 EDT 2007
inputtext == sometext
inputtext == Wed Oct 31 14:46:36 EDT 2007

So, read() is really not reading all of the 'intended text to be read' in
one go.

_r


[dwm] input status text bug?

2007-10-30 Thread Ritesh Kumar
Hi folks,
I came across this curious behavior for the input status text...

I used to run dwm using the following bash script:

while true; do
date;
sleep 1;
done | dwm

... and things used to run fine :).

I changed it to:

while true; do
cat $HOME/.dwm/status_* ;
date;
sleep 1;
done | dwm

The status_* files contain text without trailing \n's.
Surprisingly , the contents of the statusbar didn't change (only date, no
other status text) ... even though the while loop outputs something like
some text Tue Oct 30 22:46:56 EDT 2007
some text Tue Oct 30 22:46:57 EDT 2007
some text Tue Oct 30 22:46:58 EDT 2007
...

My guess is that read() reads the status_* text and date in two successive
calls causing the date to prevail till sleep 1 is done.

I went through the source code and fixed the status input handling code to
make sure it flushes the input status text only if in encounters a '\n'. The
patch is given... unfortunately it is over my (recently posted) status text
patch. I moved the trimming of trailing \n's to another function  setstext()
(introduced by my status text patch)... however, the relevant code can be
moved to the function run().

What do you guys think... did I accidentally break something?

_r

diff -r a5b57a189379 dwm.c
--- a/dwm.c Tue Oct 30 22:17:27 2007 -0400
+++ b/dwm.c Tue Oct 30 22:31:24 2007 -0400
@@ -1295,8 +1295,7 @@ restack(void) {

 void
 run(void) {
-   char *p;
-   int r, xfd;
+   int r, pos, xfd;
fd_set rd;
XEvent ev;

@@ -1315,7 +1314,8 @@ run(void) {
eprint(select failed\n);
}
if(FD_ISSET(STDIN_FILENO, rd)) {
-   switch(r = read(STDIN_FILENO, inputtext, sizeof
inputtext - 1)) {
+   pos = inputtext[strlen(inputtext)-1] != '\n' ?
strlen(inputtext) : 0;
+   switch(r = read(STDIN_FILENO, (inputtext[pos]),
sizeof inputtext - 1 - pos)) {
case -1:
strncpy(inputtext, strerror(errno), sizeof
inputtext - 1);
inputtext[sizeof inputtext - 1] = '\0';
@@ -1326,10 +1326,7 @@ run(void) {
readin = False;
break;
default:
-   for(inputtext[r] = '\0', p = inputtext +
strlen(inputtext) - 1; p = inputtext  *p == '\n'; *p-- = '\0');
-   for(; p = inputtext  *p != '\n'; --p);
-   if(p  inputtext)
-   strncpy(inputtext, p + 1, sizeof
inputtext);
+   inputtext[pos+r] = '\0' ;
}
drawbar();
}
@@ -1426,6 +1423,9 @@ setstext(void) {
stext[0] = '\0';
for(i=0; isizeof(statusbar)/sizeof(char*); i++)
strncat(stext, statusbar[i], sizeof(stext) - strlen(stext));
+   // Trim the trailing \n's
+   for(i=strlen(stext)-1; stext[i]=='\n'; i--)
+   stext[i] = '\0';
 }


Re: [dwm] input status text bug?

2007-10-30 Thread Ritesh Kumar
The full patch (against dwm 4.6 + clientspertag) is present at
http://www.cs.unc.edu/~ritesh/dwm/index.html
It should not be difficult to chop out unwanted bits from it :)

_r

On 10/30/07, Ritesh Kumar [EMAIL PROTECTED] wrote:

 Hi folks,
 I came across this curious behavior for the input status text...

 snip


Re: [dwm] input status text bug?

2007-10-30 Thread Vasil Dimov
On Tue, Oct 30, 2007 at 23:04:33 -0400, Ritesh Kumar wrote:
[...]
 I went through the source code and fixed the status input handling code to
 make sure it flushes the input status text only if in encounters a '\n'.
[...]
 if(FD_ISSET(STDIN_FILENO, rd)) {
 -   switch(r = read(STDIN_FILENO, inputtext, sizeof 
 inputtext - 1)) {
 +   pos = inputtext[strlen(inputtext)-1] != '\n' ? 
 strlen(inputtext) : 0;
 +   switch(r = read(STDIN_FILENO, (inputtext[pos]), 
 sizeof inputtext - 1 - pos)) {
[...]

Hmmz, aren't you trying to calculate strlen() of something undefined
here?

-- 
Vasil Dimov
[EMAIL PROTECTED]Software Developer @ Oracle/Innobase Oy
[EMAIL PROTECTED]Committer @ FreeBSD.org
[EMAIL PROTECTED]Home @ Sofia, Bulgaria


pgpr4itsL2xpO.pgp
Description: PGP signature