bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

AW: Re: read command sometimes misses newline on timeout


From: Thomas Oettli
Subject: AW: Re: read command sometimes misses newline on timeout
Date: Tue, 8 Oct 2024 11:11:37 +0000

Well, that sounds like a challenge. Please let me know if I can help you in any 
way.
I am running many Gentoo systems that use binary packages built on my own 
buildhost,
therefor it is fairly easy for me to patch the current version of Bash and test 
it on some systems.
Thanks in advance for your help.

  *
Thomas

________________________________
Von: Martin D Kealey <martin@kurahaupo.gen.nz>
Gesendet: Dienstag, 8. Oktober 2024 06:23
An: Martin D Kealey <martin@kurahaupo.gen.nz>
Cc: Thomas Oettli <thomas.oettli@sfs.com>; bug-bash <bug-bash@gnu.org>
Betreff: [EXT] Re: read command sometimes misses newline on timeout

CAUTION: This email originated from outside the SFS organization. Do not follow 
guidance, click links or open attachments unless you recognize the sender and 
know the content is safe.
MAIL FROM:  <@martin@kurahaupo.gen.nz>  Report as Spam / Check 
Mail<https://mail1.sfs.biz/pyquarantine.php?quarantine=orig&action=report_or_check&mailfrom=martin%40kurahaupo.gen.nz&id=20241008062330_84DA229C4B473>

OK, running a similar test with instrumentation gets:

$ time (
  trap ' echo BANG ' SIGALRM ;
  while :; do printf TEST; sleep .00$((1+RANDOM%2)); echo; done |
  for ((r=100000 ;r>0; --r)) do line= ; read -t .002 line; rc=$?; [[ $line = 
TEST ]] ; echo "STATUS $rc $? $line" ; done
 ) |&
  sort | uniq -c

      1 +# Hit read timeout SIGALRM, run from line 699 in ./read.def #+ STATUS 
142 1 TES
      1 +# Hit read timeout SIGALRM, run from line 72 in zread.c #+     STATUS 
142 1
      2 +# Hit read timeout SIGALRM, run from line 865 in ./read.def #+ STATUS 
142 1 T
      1 +# Hit read timeout SIGALRM, run from line 865 in ./read.def #+ STATUS 
142 1 TES
     16 +# Hit read timeout SIGALRM, run from line 913 in ./read.def #+ STATUS 
142 0 TEST
   1721 +# Hit read timeout SIGALRM, run from line 913 in ./read.def #+ STATUS 
142 1
      3 STATUS 0 0 TEST
  32649 STATUS 0 1
  34367 STATUS 142 0 TEST
  31235 STATUS 142 1
      2 STATUS 142 1 EST
      2 STATUS 142 1 T

real    3m21.411s
user    1m14.054s
sys     1m46.493s

That's to say, that out of 100000 reads:

  *   0.003% had both `read` returning 0 and filling var with TEST.
  *   34.4% had `read returning non-zero but filling var with TEST.
  *   32.6% had `read` returning 0 but leaving var empty (which is presumably 
the delayed bare newline after previously filling the var with TEST but 
returning 142).
  *   1.7% were handled by `check_read_timeout()`, and all had read returning a 
status of 142 (and leaving var empty).

I note that 1721+32649-34367=3 so I infer that the last 3 cases are 
interconnected:

Of that 1.7% almost all were handled by this section of read.def:
  /* I don't think this clause ever tests true. */
  if (skip_ctlnul && saw_escape && i == 1 && input_string[0] == CTLNUL)
    saw_escape = 0;             /* Avoid dequoting bare CTLNUL */

  input_string[i] = '\0';
  check_read_timeout ();

#if defined (READLINE)
  if (edit)
    free (rlbuf);
#endif

-Martin
PS: I've since run other tests that confirm the association I noted above, but 
I didn't keep the output. I'll run them again if anyone wants to see a more 
precise demonstration.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]