Re: svn commit: r311952 - head/sys/ddb

2017-01-17 Thread Bruce Evans

On Mon, 16 Jan 2017, Julian Elischer wrote:


On 16/01/2017 11:53 AM, Bruce Evans wrote:

On Sun, 15 Jan 2017, Adrian Chadd wrote:


hah, i took this, then life got in the way. :)

Bruce - what do you think of
https://bz-attachments.freebsd.org/attachment.cgi?id=138881 ?


Also https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=184987 .

I think it is hard to read and review since it is not in the mail.
After fetching it and quoting it:


review it in the review page and just send a link in the email.. that's what 
it's for.


That's what is hard to read and harder to review.

Bruce
___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r311952 - head/sys/ddb

2017-01-15 Thread Julian Elischer

On 16/01/2017 11:53 AM, Bruce Evans wrote:

On Sun, 15 Jan 2017, Adrian Chadd wrote:


hah, i took this, then life got in the way. :)

Bruce - what do you think of
https://bz-attachments.freebsd.org/attachment.cgi?id=138881 ?


Also https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=184987 .

I think it is hard to read and review since it is not in the mail.
After fetching it and quoting it:


review it in the review page and just send a link in the email.. 
that's what it's for.




X diff -r 91820d9948e0 -r 13f40d577646 sys/kern/tty_ttydisc.c
X --- a/sys/kern/tty_ttydisc.cFri Feb 22 09:45:32 2013 +0100
X +++ b/sys/kern/tty_ttydisc.cTue Dec 17 23:03:17 2013 +0100
X @@ -448,6 +448,9 @@
X  if (tp->t_flags & TF_ZOMBIE)
X  return (EIO);
X X +if (tp->t_termios.c_lflag & FLUSHO)
X +return (0);
X +

This seems to be far too simple.  As pointed out in the PR thread, it
is missing at least the clearing of uio_resid.

   (BTW, returns for TF_ZOMBIE and IO_NDELAY tend to have the opposite
   problem.  The tend to reduce uio_resid to count i/o that they have
   not done.  They should just return an error like the above return
   for TF_ZOMBIE does.  Upper layers are supposed to translate this
   error to success if any i/o has been done.  Upper layers often get
   this wrong, and my fixes currently do too much compensation in lower
   layers.)

The old tty driver has squillions of FLUSHO checks for output not 
involving
uio.  Mostly for echo of input.  However, any input (and other 
operations?)

normally turns of FLUSHO, so this is hard to see.

To see if this works compatibly now, try typing 111^O2.  ^O should be
echoed as ^O^R followed by reprinting the line according to the 
implicit

VREPRINT (^R).  This should cancel FLUSHO, so the 2 is just echoed on
the new line.  However ^O instead of 2 should just cancel FLUSHO. So
^O^O should be equivalent to ^R except it prints ^O before ^R.

It is wrong for FLUSHO to have any effect except in modes where 
VDISCARD

has an effect.  VDISCARD seems to be conditional on precisely
!EXTPROC && IEXTEN.  Its inactivity in other modes should be 
implemented
by forcing it off on certain mode changes.  The old tty driver 
forces it

off in squillions of places, perhaps including all mode changes for
simplicity.  There would be a problem if stty(1) could actually set it,
since then invalid settings like "raw flusho" would be allowed. 
Clearing

it after all mode changes would prevent stty actually setting it.


X  /*
X   * We don't need to check whether the process is the foreground
X   * process group or if we have a carrier. This is already done
X @@ -881,6 +884,14 @@
X X  /* Special control characters that are implementation 
dependent. */

X  if (CMP_FLAG(l, IEXTEN)) {
X +/* Discard (^O) */

Style bug.  This comment is missing a "." and does less than echo 
the code.
The code doesn't hard-code VDISCARD as ^O, and it is unclear whether 
the

comment applies to the previous or the next line (except it is further
from echoing the previous line).

X +if (CMP_CC(VDISCARD, c)) {
X +if (!(tp->t_termios.c_lflag & FLUSHO))

Style bug.  This file elsewhere always uses the funky style of explicit
comparison of (sets of ) flags with 0.

X +ttyoutq_write_nofrag(>t_outq, "^O", 2);

This also hard-codes ^O.  The old driver echos the actual discard 
character
using ttyecho(c, tp).  I don't know if the funky rules for quoting 
control
characters apply in this case, but ttyecho() has to be quite 
complicated to

handle general cases.

X +tp->t_termios.c_lflag ^= FLUSHO;

The old driver adds an implicit VREPRINT char here if the input 
queue is
nonempty.  This usually results in echoing ^O^R and reprinting the 
line.


X +return(0);
X +}
X +

Otherwise, the action here is identical with the old driver.

X  /* Accept the next character as literal. */
X  if (CMP_CC(VLNEXT, c)) {
X  if (CMP_FLAG(l, ECHO)) {

The old driver needs 23 lines mentioning FLUSHO to keep it mostly 
clear.

These are:
- 3 in compat code (still there)
- 3 here
- 1 clear whenever restarting output at the end of interrupt input 
(most

  cases interrupt input)
- 4 checks in ttyoutput() which is used manly for echoing.  1 at the
  beginning would be simpler, but the checks are more or less before
  each putc() and there are many inconsistences for counting characters
  and the column position from the complications
- 1 clear in ttioctl() in 1 case of turning 1 type of flow control 
back on.
  Buggy, since FLUSHO should not be affected by flow control except 
by the

  xon char being treated as an ordinary char for canceling VDISCARD.
- 1 clear in ttioctl() for the same flow control done by TIOCSTART
- 1 check for ordinary writes as in this patch
- 2 in comments
- 2 more checks in the loop for ordinary writes.  Some checks are 
necessary,
  but these are misplaced.  FLUSHO can 

Re: svn commit: r311952 - head/sys/ddb

2017-01-15 Thread Bruce Evans

On Sun, 15 Jan 2017, Adrian Chadd wrote:


hah, i took this, then life got in the way. :)

Bruce - what do you think of
https://bz-attachments.freebsd.org/attachment.cgi?id=138881 ?


Also https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=184987 .

I think it is hard to read and review since it is not in the mail.
After fetching it and quoting it:

X diff -r 91820d9948e0 -r 13f40d577646 sys/kern/tty_ttydisc.c
X --- a/sys/kern/tty_ttydisc.c  Fri Feb 22 09:45:32 2013 +0100
X +++ b/sys/kern/tty_ttydisc.c  Tue Dec 17 23:03:17 2013 +0100
X @@ -448,6 +448,9 @@
X   if (tp->t_flags & TF_ZOMBIE)
X   return (EIO);
X 
X +	if (tp->t_termios.c_lflag & FLUSHO)

X + return (0);
X +

This seems to be far too simple.  As pointed out in the PR thread, it
is missing at least the clearing of uio_resid.

   (BTW, returns for TF_ZOMBIE and IO_NDELAY tend to have the opposite
   problem.  The tend to reduce uio_resid to count i/o that they have
   not done.  They should just return an error like the above return
   for TF_ZOMBIE does.  Upper layers are supposed to translate this
   error to success if any i/o has been done.  Upper layers often get
   this wrong, and my fixes currently do too much compensation in lower
   layers.)

The old tty driver has squillions of FLUSHO checks for output not involving
uio.  Mostly for echo of input.  However, any input (and other operations?)
normally turns of FLUSHO, so this is hard to see.

To see if this works compatibly now, try typing 111^O2.  ^O should be
echoed as ^O^R followed by reprinting the line according to the implicit
VREPRINT (^R).  This should cancel FLUSHO, so the 2 is just echoed on
the new line.  However ^O instead of 2 should just cancel FLUSHO.  So
^O^O should be equivalent to ^R except it prints ^O before ^R.

It is wrong for FLUSHO to have any effect except in modes where VDISCARD
has an effect.  VDISCARD seems to be conditional on precisely
!EXTPROC && IEXTEN.  Its inactivity in other modes should be implemented
by forcing it off on certain mode changes.  The old tty driver forces it
off in squillions of places, perhaps including all mode changes for
simplicity.  There would be a problem if stty(1) could actually set it,
since then invalid settings like "raw flusho" would be allowed.  Clearing
it after all mode changes would prevent stty actually setting it.


X   /*
X* We don't need to check whether the process is the foreground
X* process group or if we have a carrier. This is already done
X @@ -881,6 +884,14 @@
X 
X  	/* Special control characters that are implementation dependent. */

X   if (CMP_FLAG(l, IEXTEN)) {
X + /* Discard (^O) */

Style bug.  This comment is missing a "." and does less than echo the code.
The code doesn't hard-code VDISCARD as ^O, and it is unclear whether the
comment applies to the previous or the next line (except it is further
from echoing the previous line).

X + if (CMP_CC(VDISCARD, c)) {
X + if (!(tp->t_termios.c_lflag & FLUSHO))

Style bug.  This file elsewhere always uses the funky style of explicit
comparison of (sets of ) flags with 0.

X + ttyoutq_write_nofrag(>t_outq, "^O", 2);

This also hard-codes ^O.  The old driver echos the actual discard character
using ttyecho(c, tp).  I don't know if the funky rules for quoting control
characters apply in this case, but ttyecho() has to be quite complicated to
handle general cases.

X + tp->t_termios.c_lflag ^= FLUSHO;

The old driver adds an implicit VREPRINT char here if the input queue is
nonempty.  This usually results in echoing ^O^R and reprinting the line.

X + return(0);
X + }
X +

Otherwise, the action here is identical with the old driver.

X   /* Accept the next character as literal. */
X   if (CMP_CC(VLNEXT, c)) {
X   if (CMP_FLAG(l, ECHO)) {

The old driver needs 23 lines mentioning FLUSHO to keep it mostly clear.
These are:
- 3 in compat code (still there)
- 3 here
- 1 clear whenever restarting output at the end of interrupt input (most
  cases interrupt input)
- 4 checks in ttyoutput() which is used manly for echoing.  1 at the
  beginning would be simpler, but the checks are more or less before
  each putc() and there are many inconsistences for counting characters
  and the column position from the complications
- 1 clear in ttioctl() in 1 case of turning 1 type of flow control back on.
  Buggy, since FLUSHO should not be affected by flow control except by the
  xon char being treated as an ordinary char for canceling VDISCARD.
- 1 clear in ttioctl() for the same flow control done by TIOCSTART
- 1 check for ordinary writes as in this patch
- 2 in comments
- 2 more checks in the loop for ordinary writes.  Some checks are necessary,
  but these are misplaced.  FLUSHO can change underneath when we unlock to
  do the i/o, so it must be re-checked when we 

Re: svn commit: r311952 - head/sys/ddb

2017-01-15 Thread Bruce Evans

On Sun, 15 Jan 2017, Slawa Olhovchenkov wrote:


On Sun, Jan 15, 2017 at 01:07:58PM +0800, Julian Elischer wrote:



the old DEC machines had (from memory) ^O  which dropped all pending
output.
Not so useful when there is 2MB of network buffers queued up to you,
but very useful on
and asr-33 teletype.


Now it useful too, on serial console.
^O processing be present years ago in FreeBSD, but removed at time of
tty code rewrite. As I know patch for restore exist, nobody
review/commit.


Urk.  I have fixes for hundreds of things broken in the rewrite, but didn't
notice this one.  The only fix I have near here is a partial one for funky
quoting of control characters according to ECHOK and ECHOKE.  ECHOK is a
POSIX feature and ECHOKE is a BSD feature.  The man page still docoments
the old behaviour.

Grepping for CCEQ (and its renaming to the worse name CMP_FLAG in the
rewrite) shows that the only other control character with lost support
is VDSUSP.

Zgrepping for VDISCARD and VDSUSP in /usr/share/man shows the following
bugs:
- VDISCARD and VDSUSP are listed but not described in any useful way in
  termios(4)
- VDSUSP (and dsusp) is listed but not described in any useful way in
  stty(1)
- VDISCARD (and discard) are not mentioned in stty(1).  However,
  'stty discard c' works, and stty's display of the discard character
  works.  stty's displays exactly the special characters that used to
  work.
- VDISCARD and VDSUSP are otherwise undocumented.
- FLUSHO in termios(4) and flusho in stty(1) are listed and described, but
  their close connection with VDISCARD is not mentioned (except stty says
  "being discarded").  FLUSHO is mostly an internal flag.  In the working
  version, It is normally toggled by VDISCARD but is cleared by other actions.
  It can also be controlled by an ioctl, and stty supports the ioctl.  But
  settings by stty are rarely useful since it is normally cleared by other
  The patch in the PR doesn't handle the other actions right.
  actions which stty can't control.

Partial fixes for ECHOKE and nearby things:

X Index: tty_ttydisc.c
X ===
X --- tty_ttydisc.c (revision 312117)
X +++ tty_ttydisc.c (working copy)
X @@ -798,6 +842,16 @@
X   }
X   } else {
X   /* Don't print spaces. */
X + /*
X +  * XXX broken if VERASE is disabled.  Can get here
X +  * then if ECHO is off and:
X +  * - for VERASE2 if that is not disabled
X +  * - for the buggy ECHOK/ECHOKE cases
X +  * - perhaps in other cases.
X +  * This routine is too generic.
X +  *
X +  * XXX the logic is not just non-printing of spaces.
X +  */
X   ttydisc_echo(tp, tp->t_termios.c_cc[VERASE], 0);
X   }
X   }
X @@ -993,7 +1049,30 @@
X   ttydisc_rubchar(tp);
X   return (0);
X   } else if (CMP_CC(VKILL, c)) {
X +#if 0
X + /*
X +  * XXX broken.  This doesn't even look at ECHOK or
X +  * ECHOKE (nothing does now), and it doesn't produce
X +  * the documented behaviour of ECHOK.  ECHOK exists
X +  * to be a non-erasing version of ECHOKE that uses
X +  * fewer terminal capabilities.  ECHOPRT is also
X +  * broken (never even looked at).
X +  */
X   while (ttydisc_rubchar(tp) == 0);
X +#else
X + if (CMP_FLAG(l, ECHOKE)) {
X + /* XXX too hard to fix. */
X + while (ttydisc_rubchar(tp) == 0)
X + ;
X + } else {
X + ttydisc_echo_force(tp, c, 0);
X + if (CMP_FLAG(l, ECHOK))
X + ttydisc_echo_force(tp, '\n', 0);
X + while (ttyinq_peekchar(>t_inq, ,
X + ) == 0)
X + ttyinq_unputchar(>t_inq);
X + }
X +#endif
X   return (0);
X   } else if (CMP_FLAG(l, IEXTEN)) {
X   if (CMP_CC(VWERASE, c)) {
X @@ -1021,12 +1100,13 @@
X 
X  parmrk:

X   if (CMP_FLAG(i, PARMRK)) {
X - /* Prepend 0xff 0x00 0x.. */
X + /* Prepend 0xff 0x00. */
X   ob[2] = c;
X   ol = 3;
X   quote = 1;
X   } else {
X - ob[0] = c;
X + /* Kill the character for read().  Keep it in c for echoing. */
X + ob[0] = '\0';
X   ol = 1;
X   }
X

Bruce
___
svn-src-head@freebsd.org 

Re: svn commit: r311952 - head/sys/ddb

2017-01-15 Thread Slawa Olhovchenkov
On Sun, Jan 15, 2017 at 10:46:35AM -0800, Adrian Chadd wrote:

> url? :)

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=184987
Assignee:   Adrian Chadd

> On 15 January 2017 at 06:45, Slawa Olhovchenkov  wrote:
> > On Sun, Jan 15, 2017 at 01:07:58PM +0800, Julian Elischer wrote:
> >
> >>
> >> the old DEC machines had (from memory) ^O  which dropped all pending
> >> output.
> >> Not so useful when there is 2MB of network buffers queued up to you,
> >> but very useful on
> >> and asr-33 teletype.
> >
> > Now it useful too, on serial console.
> > ^O processing be present years ago in FreeBSD, but removed at time of
> > tty code rewrite. As I know patch for restore exist, nobody
> > review/commit.
> >
> >
___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r311952 - head/sys/ddb

2017-01-15 Thread Adrian Chadd
url? :)

-a


On 15 January 2017 at 06:45, Slawa Olhovchenkov  wrote:
> On Sun, Jan 15, 2017 at 01:07:58PM +0800, Julian Elischer wrote:
>
>>
>> the old DEC machines had (from memory) ^O  which dropped all pending
>> output.
>> Not so useful when there is 2MB of network buffers queued up to you,
>> but very useful on
>> and asr-33 teletype.
>
> Now it useful too, on serial console.
> ^O processing be present years ago in FreeBSD, but removed at time of
> tty code rewrite. As I know patch for restore exist, nobody
> review/commit.
>
>
___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r311952 - head/sys/ddb

2017-01-15 Thread Slawa Olhovchenkov
On Sun, Jan 15, 2017 at 01:07:58PM +0800, Julian Elischer wrote:

> 
> the old DEC machines had (from memory) ^O  which dropped all pending 
> output.
> Not so useful when there is 2MB of network buffers queued up to you, 
> but very useful on
> and asr-33 teletype.

Now it useful too, on serial console.
^O processing be present years ago in FreeBSD, but removed at time of
tty code rewrite. As I know patch for restore exist, nobody
review/commit.

___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r311952 - head/sys/ddb

2017-01-14 Thread Julian Elischer

On 15/01/2017 6:06 AM, Mark Johnston wrote:

On Fri, Jan 13, 2017 at 02:51:04PM +1100, Bruce Evans wrote:

On Thu, 12 Jan 2017, Mark Johnston wrote:


Log:
  Enable the use of ^C and ^S/^Q in DDB.

  This lets one interrupt DDB's output, which is useful if paging is
  disabled and the output device is slow.

This is quite broken.  It removes the code that was necessary for avoiding
loss of input.

Hi Bruce,

I've reverted this for now. I haven't thought much about how
db_check_interrupt() might losslessly poll the console driver for
ctrl-C, but I do think it's a valuable feature to have - just this
morning I absent-mindedly dumped a 128K-entry KTR ring from a DDB prompt
after having set $lines = 0, and had to wait for quite a while to get
my prompt back.


Modified: head/sys/ddb/db_input.c
==
--- head/sys/ddb/db_input.c Thu Jan 12 00:09:31 2017(r311951)
+++ head/sys/ddb/db_input.c Thu Jan 12 00:22:36 2017(r311952)
@@ -63,7 +63,6 @@ static intdb_lhist_nlines;
#define BLANK   ' '
#define BACKUP  '\b'

-static int cnmaygetc(void);
static void db_delete(int n, int bwd);
static int  db_inputchar(int c);
static void db_putnchars(int c, int count);
@@ -291,12 +290,6 @@ db_inputchar(c)
return (0);
}

-static int
-cnmaygetc()
-{
-   return (-1);
-}
-

BSD never had a usable console API (function) for checking for input.
cncheckc() is the correct name for such a function.  The actual
cncheckc() returns any input that it finds.  This is not the main
problem here.  The input will have to be read here anyway to determine
what it is.  The problems are that there is no console API at all for
ungetting characters in the input stream, and this function doesn't
even use a stub cnungetc(), but drops the input on the floor.  It does
document this behaviour in a comment, but doesn't say that it is wrong.


int
db_readline(lstart, lsize)
char *  lstart;
@@ -350,7 +343,7 @@ db_check_interrupt(void)
{
int c;

-   c = cnmaygetc();
+   c = cncheckc();
switch (c) {
case -1:/* no character */
return;

The stub function always returns -1, so db_check_interrupt() is turned into
a no-op.

db_check_interrupt() now eats the first byte of any input on every call.


@@ -361,7 +354,7 @@ db_check_interrupt(void)

case CTRL('s'):
do {
-   c = cnmaygetc();
+   c = cncheckc();
if (c == CTRL('c'))
db_error((char *)0);
} while (c != CTRL('q'));

This is now a bad implementation of xon/xoff.  It doesn't support ixany,
but busy-waits for ^Q or ^C using cncheckc().  It should at least
busy-wait using cngetc(), since that might be do a smarter busy wait.
cngetc() is actually only slightly smarter -- it uses busy-waiting too,
but with cpu_spinwait() in the loop.  This cpu_spinwait() makes little
difference since cncheckc() tends to be a heavyweight function.  Only
cpu_spinwait()s in the innermost loops of cncheckc(), if any, are likely
to have much effect.

Multiple consoles complicate this a bit.

db_check_interrupt() is called after every db_putc() of a newline.  So
the breakage is mainly for type-ahead while writing many lines.

I'll note that type-ahead interacts rather poorly with DDB's behaviour
of repeating the previous command upon reading an empty input line:
entering a carriage return at any point while "show ktr" is working will
cause it to be started again once it's finished.


the old DEC machines had (from memory) ^O  which dropped all pending 
output.
Not so useful when there is 2MB of network buffers queued up to you, 
but very useful on

and asr-33 teletype.




Control processing belongs in the lowest level of console drivers, and
at least the xon/xoff part is very easy to do.  This makes it work for
contexts like boot messages -- this can only be controlled now by booting
with -p, which gives something like an automatic ^S after every line,
but the control characters for this mode are unusual and there is no
way to get back to -p mode after turning it off or not starting with it.

[...]



___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r311952 - head/sys/ddb

2017-01-14 Thread Mark Johnston
On Fri, Jan 13, 2017 at 02:51:04PM +1100, Bruce Evans wrote:
> On Thu, 12 Jan 2017, Mark Johnston wrote:
> 
> > Log:
> >  Enable the use of ^C and ^S/^Q in DDB.
> >
> >  This lets one interrupt DDB's output, which is useful if paging is
> >  disabled and the output device is slow.
> 
> This is quite broken.  It removes the code that was necessary for avoiding
> loss of input.

Hi Bruce,

I've reverted this for now. I haven't thought much about how
db_check_interrupt() might losslessly poll the console driver for
ctrl-C, but I do think it's a valuable feature to have - just this
morning I absent-mindedly dumped a 128K-entry KTR ring from a DDB prompt
after having set $lines = 0, and had to wait for quite a while to get
my prompt back.

> 
> > Modified: head/sys/ddb/db_input.c
> > ==
> > --- head/sys/ddb/db_input.c Thu Jan 12 00:09:31 2017(r311951)
> > +++ head/sys/ddb/db_input.c Thu Jan 12 00:22:36 2017(r311952)
> > @@ -63,7 +63,6 @@ static intdb_lhist_nlines;
> > #define BLANK   ' '
> > #define BACKUP  '\b'
> >
> > -static int cnmaygetc(void);
> > static void db_delete(int n, int bwd);
> > static int  db_inputchar(int c);
> > static void db_putnchars(int c, int count);
> > @@ -291,12 +290,6 @@ db_inputchar(c)
> > return (0);
> > }
> >
> > -static int
> > -cnmaygetc()
> > -{
> > -   return (-1);
> > -}
> > -
> 
> BSD never had a usable console API (function) for checking for input.
> cncheckc() is the correct name for such a function.  The actual
> cncheckc() returns any input that it finds.  This is not the main
> problem here.  The input will have to be read here anyway to determine
> what it is.  The problems are that there is no console API at all for
> ungetting characters in the input stream, and this function doesn't
> even use a stub cnungetc(), but drops the input on the floor.  It does
> document this behaviour in a comment, but doesn't say that it is wrong.
> 
> > int
> > db_readline(lstart, lsize)
> > char *  lstart;
> > @@ -350,7 +343,7 @@ db_check_interrupt(void)
> > {
> > int c;
> >
> > -   c = cnmaygetc();
> > +   c = cncheckc();
> > switch (c) {
> > case -1:/* no character */
> > return;
> 
> The stub function always returns -1, so db_check_interrupt() is turned into
> a no-op.
> 
> db_check_interrupt() now eats the first byte of any input on every call.
> 
> > @@ -361,7 +354,7 @@ db_check_interrupt(void)
> >
> > case CTRL('s'):
> > do {
> > -   c = cnmaygetc();
> > +   c = cncheckc();
> > if (c == CTRL('c'))
> > db_error((char *)0);
> > } while (c != CTRL('q'));
> 
> This is now a bad implementation of xon/xoff.  It doesn't support ixany,
> but busy-waits for ^Q or ^C using cncheckc().  It should at least
> busy-wait using cngetc(), since that might be do a smarter busy wait.
> cngetc() is actually only slightly smarter -- it uses busy-waiting too,
> but with cpu_spinwait() in the loop.  This cpu_spinwait() makes little
> difference since cncheckc() tends to be a heavyweight function.  Only
> cpu_spinwait()s in the innermost loops of cncheckc(), if any, are likely
> to have much effect.
> 
> Multiple consoles complicate this a bit.
> 
> db_check_interrupt() is called after every db_putc() of a newline.  So
> the breakage is mainly for type-ahead while writing many lines.

I'll note that type-ahead interacts rather poorly with DDB's behaviour
of repeating the previous command upon reading an empty input line:
entering a carriage return at any point while "show ktr" is working will
cause it to be started again once it's finished.

> 
> Control processing belongs in the lowest level of console drivers, and
> at least the xon/xoff part is very easy to do.  This makes it work for
> contexts like boot messages -- this can only be controlled now by booting
> with -p, which gives something like an automatic ^S after every line,
> but the control characters for this mode are unusual and there is no
> way to get back to -p mode after turning it off or not starting with it.
> 
> [...]
___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r311952 - head/sys/ddb

2017-01-12 Thread Bruce Evans

On Thu, 12 Jan 2017, Mark Johnston wrote:


Log:
 Enable the use of ^C and ^S/^Q in DDB.

 This lets one interrupt DDB's output, which is useful if paging is
 disabled and the output device is slow.


This is quite broken.  It removes the code that was necessary for avoiding
loss of input.


Modified: head/sys/ddb/db_input.c
==
--- head/sys/ddb/db_input.c Thu Jan 12 00:09:31 2017(r311951)
+++ head/sys/ddb/db_input.c Thu Jan 12 00:22:36 2017(r311952)
@@ -63,7 +63,6 @@ static intdb_lhist_nlines;
#define BLANK   ' '
#define BACKUP  '\b'

-static int cnmaygetc(void);
static void db_delete(int n, int bwd);
static int  db_inputchar(int c);
static void db_putnchars(int c, int count);
@@ -291,12 +290,6 @@ db_inputchar(c)
return (0);
}

-static int
-cnmaygetc()
-{
-   return (-1);
-}
-


BSD never had a usable console API (function) for checking for input.
cncheckc() is the correct name for such a function.  The actual
cncheckc() returns any input that it finds.  This is not the main
problem here.  The input will have to be read here anyway to determine
what it is.  The problems are that there is no console API at all for
ungetting characters in the input stream, and this function doesn't
even use a stub cnungetc(), but drops the input on the floor.  It does
document this behaviour in a comment, but doesn't say that it is wrong.


int
db_readline(lstart, lsize)
char *  lstart;
@@ -350,7 +343,7 @@ db_check_interrupt(void)
{
int c;

-   c = cnmaygetc();
+   c = cncheckc();
switch (c) {
case -1:/* no character */
return;


The stub function always returns -1, so db_check_interrupt() is turned into
a no-op.

db_check_interrupt() now eats the first byte of any input on every call.


@@ -361,7 +354,7 @@ db_check_interrupt(void)

case CTRL('s'):
do {
-   c = cnmaygetc();
+   c = cncheckc();
if (c == CTRL('c'))
db_error((char *)0);
} while (c != CTRL('q'));


This is now a bad implementation of xon/xoff.  It doesn't support ixany,
but busy-waits for ^Q or ^C using cncheckc().  It should at least
busy-wait using cngetc(), since that might be do a smarter busy wait.
cngetc() is actually only slightly smarter -- it uses busy-waiting too,
but with cpu_spinwait() in the loop.  This cpu_spinwait() makes little
difference since cncheckc() tends to be a heavyweight function.  Only
cpu_spinwait()s in the innermost loops of cncheckc(), if any, are likely
to have much effect.

Multiple consoles complicate this a bit.

db_check_interrupt() is called after every db_putc() of a newline.  So
the breakage is mainly for type-ahead while writing many lines.

Control processing belongs in the lowest level of console drivers, and
at least the xon/xoff part is very easy to do.  This makes it work for
contexts like boot messages -- this can only be controlled now by booting
with -p, which gives something like an automatic ^S after every line,
but the control characters for this mode are unusual and there is no
way to get back to -p mode after turning it off or not starting with it.

-p mode also crashes if you don't turn it off before the (syscons)
keyboard is attached, since attachment temporarily breaks the input needed
to control the mode.  ddb control should worry about this even more.
Multiple consoles complicate this more than a bit.

For console driver development/debugging, I needed xon-xoff type control
and more (discard) at the driver level, especially when i/o to one of
the multiple consoles is unreachable to avoid deadlock, or too active.
It was easy to write primitive xon/xoff but not to avoid deadlocks in
this.  Hackish code looks like this:
diff -u2 syscons.c~ syscons.c

X --- syscons.c~2016-09-01 19:20:38.263745000 +
X +++ syscons.c 2016-10-14 07:12:18.947461000 +
X ...
X +static void
X +ec_wait(void)

ec_wait() is called to give time to read transient output about certain
errors (mainly in near-deadlock conditions).  The error message is written
directly to the frame buffer and will be overwritten if the deadlock
condition clears enough to allow normal output.

X +{
X + int c;
X + int timeout;
X +
X + if (ec_kill_ec_wait)
X + return;
X + c = inb(0xe060);

0xe060 is an otherwise-unused serial port which I can write control characters
too.

X + if (ec_wait_verbose)
X + ec_puts("\r\nec: hit any key to abort wait of 10 seconds...");
X + for (timeout = 0; timeout < ec_wait_delay; timeout++) {
X + // if (cncheckc() != -1)
X + // break;

Early versions used simply cncheckc().  This checks all consoles, so can
deadlock too easily, and it doesn't keep the input streams separate enough
for easy control