Changeset 791469bd in rtems


Ignore:
Timestamp:
Nov 6, 2017, 1:49:32 PM (18 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
336fe3b
Parents:
1055ff20
git-author:
Sebastian Huber <sebastian.huber@…> (11/06/17 13:49:32)
git-committer:
Sebastian Huber <sebastian.huber@…> (11/07/17 07:31:40)
Message:

termios: Fix canonical mode

In canonical mode, input is made available line by line. We must stop
the canonical buffer filling upon reception of an end-of-line character.

Close #3218.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libcsupport/src/termios.c

    r1055ff20 r791469bd  
    15711571      /* continue processing new character */
    15721572      if (tty->termios.c_lflag & ICANON) {
    1573         if (siproc (c, tty))
    1574           wait = false;
     1573        if (siproc (c, tty)) {
     1574          /* In canonical mode, input is made available line by line */
     1575          return;
     1576        }
    15751577      } else {
    15761578        siproc (c, tty);
  • testsuites/libtests/termios09/init.c

    r1055ff20 r791469bd  
    3737#define OUTPUT_BUFFER_SIZE 64
    3838
     39#define INPUT_BUFFER_SIZE 64
     40
    3941static const char * const paths[DEVICE_COUNT] = {
    4042  "/interrupt",
     
    4850  size_t output_count;
    4951  char output_buf[OUTPUT_BUFFER_SIZE];
    50   int input_char;
     52  size_t input_head;
     53  size_t input_tail;
     54  unsigned char input_buf[INPUT_BUFFER_SIZE];
    5155  int callback_counter;
    5256} device_context;
     
    6569      .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("Interrupt")
    6670    }, {
    67       .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("Polled"),
    68       .input_char = -1
     71      .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("Polled")
    6972    }
    7073  }
     
    113116{
    114117  device_context *dev = (device_context *) base;
    115   int c = dev->input_char;
    116 
    117   dev->input_char = -1;
     118  int c;
     119
     120  if (dev->input_head != dev->input_tail) {
     121    c = dev->input_buf[dev->input_head];
     122    dev->input_head = (dev->input_head + 1) % INPUT_BUFFER_SIZE;
     123  } else {
     124    c = -1;
     125  }
    118126
    119127  return c;
     
    188196static void input(test_context *ctx, size_t i, char c)
    189197{
     198  device_context *dev = &ctx->devices[i];
     199
    190200  switch (i) {
    191201    case INTERRUPT:
    192       rtems_termios_enqueue_raw_characters(ctx->devices[i].tty, &c, sizeof(c));
     202      rtems_termios_enqueue_raw_characters(dev->tty, &c, sizeof(c));
    193203      break;
    194204    case POLLED:
    195       ctx->devices[i].input_char = (unsigned char) c;
     205      dev->input_buf[dev->input_tail] = (unsigned char) c;
     206      dev->input_tail = (dev->input_tail + 1) % INPUT_BUFFER_SIZE;
     207      rtems_test_assert(dev->input_head != dev->input_tail);
    196208      break;
    197209    default:
     
    524536  rtems_test_assert(dev->callback_counter == 1);
    525537
     538  n = read(ctx->fds[i], buf, 2);
     539  rtems_test_assert(n == 1);
     540  rtems_test_assert(buf[0] == '\n');
    526541  n = read(ctx->fds[i], buf, 3);
    527   rtems_test_assert(n == 3);
    528   rtems_test_assert(buf[0] == '\n');
    529   rtems_test_assert(buf[1] == 'a');
    530   rtems_test_assert(buf[2] == '\n');
     542  rtems_test_assert(n == 2);
     543  rtems_test_assert(buf[0] == 'a');
     544  rtems_test_assert(buf[1] == '\n');
    531545
    532546  input(ctx, i, '\4');
     
    539553  rtems_test_assert(dev->callback_counter == 2);
    540554
    541   n = read(ctx->fds[i], buf, 2);
     555  n = read(ctx->fds[i], buf, 1);
     556  rtems_test_assert(n == 0);
     557
     558  n = read(ctx->fds[i], buf, 3);
    542559  rtems_test_assert(n == 2);
    543560  rtems_test_assert(buf[0] == 'b');
    544561  rtems_test_assert(buf[1] == '\n');
    545562
     563  /* EOL */
    546564  input(ctx, i, '1');
    547565  rtems_test_assert(dev->callback_counter == 3);
     
    553571  rtems_test_assert(dev->callback_counter == 3);
    554572
     573  n = read(ctx->fds[i], buf, 2);
     574  rtems_test_assert(n == 1);
     575  rtems_test_assert(buf[0] == '1');
    555576  n = read(ctx->fds[i], buf, 3);
    556   rtems_test_assert(n == 3);
    557   rtems_test_assert(buf[0] == '1');
    558   rtems_test_assert(buf[1] == 'c');
    559   rtems_test_assert(buf[2] == '\n');
    560 
     577  rtems_test_assert(n == 2);
     578  rtems_test_assert(buf[0] == 'c');
     579  rtems_test_assert(buf[1] == '\n');
     580
     581  /* EOL2 */
    561582  input(ctx, i, '2');
    562583  rtems_test_assert(dev->callback_counter == 4);
     
    568589  rtems_test_assert(dev->callback_counter == 4);
    569590
     591  n = read(ctx->fds[i], buf, 2);
     592  rtems_test_assert(n == 1);
     593  rtems_test_assert(buf[0] == '2');
    570594  n = read(ctx->fds[i], buf, 3);
    571   rtems_test_assert(n == 3);
    572   rtems_test_assert(buf[0] == '2');
    573   rtems_test_assert(buf[1] == 'd');
    574   rtems_test_assert(buf[2] == '\n');
     595  rtems_test_assert(n == 2);
     596  rtems_test_assert(buf[0] == 'd');
     597  rtems_test_assert(buf[1] == '\n');
    575598
    576599  for (j = 0; j < 255; ++j) {
     
    589612  dev->tty->tty_rcv.sw_arg = NULL;
    590613  set_veol_veol2(ctx, i, '\0', '\0');
     614  clear_set_lflag(ctx, i, ICANON, 0);
     615}
     616
     617static void test_read_icanon(test_context *ctx, size_t i)
     618{
     619  ssize_t n;
     620  char buf[3];
     621
     622  clear_set_lflag(ctx, i, 0, ICANON);
     623
     624  input(ctx, i, 'a');
     625  input(ctx, i, '\n');
     626  input(ctx, i, 'b');
     627  input(ctx, i, '\n');
     628  input(ctx, i, 'c');
     629  input(ctx, i, '\n');
     630
     631  n = read(ctx->fds[i], buf, 3);
     632  rtems_test_assert(n == 2);
     633  rtems_test_assert(buf[0] == 'a');
     634  rtems_test_assert(buf[1] == '\n');
     635
     636  n = read(ctx->fds[i], buf, 3);
     637  rtems_test_assert(n == 2);
     638  rtems_test_assert(buf[0] == 'b');
     639  rtems_test_assert(buf[1] == '\n');
     640
     641  n = read(ctx->fds[i], buf, 3);
     642  rtems_test_assert(n == 2);
     643  rtems_test_assert(buf[0] == 'c');
     644  rtems_test_assert(buf[1] == '\n');
     645
    591646  clear_set_lflag(ctx, i, ICANON, 0);
    592647}
     
    11071162  test_rx_callback(ctx);
    11081163  test_rx_callback_icanon(ctx);
     1164  test_read_icanon(ctx, INTERRUPT);
     1165  test_read_icanon(ctx, POLLED);
    11091166  test_onlret(ctx);
    11101167  test_onlcr(ctx);
Note: See TracChangeset for help on using the changeset viewer.