Changeset 667501a in rtems


Ignore:
Timestamp:
Oct 2, 2019, 9:49:00 PM (3 weeks ago)
Author:
Joel Sherrill <joel@…>
Branches:
master
Children:
43a6991
Parents:
ff4a4a8
git-author:
Joel Sherrill <joel@…> (10/02/19 21:49:00)
git-committer:
Joel Sherrill <joel@…> (10/08/19 19:25:41)
Message:

termios: Add Capability to Generate SIGINTR and SIGQUIT

This patch adds the ability for termios to send SIGINTR on receipt
of VINTR and SIGQUIT for VKILL and return -1/EINTR from read() on
a termios channel. Importantly, this patch does not alter the default
behavior or force POSIX signal code in just because termios is used.
The application must explicitly enable the POSIX behavior of generating
a signal upon receipt of these characters. This is discussed in the
POSIX standard:

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap11.html

Closes #3800.

Files:
6 added
8 edited

Legend:

Unmodified
Added
Removed
  • cpukit/Makefile.am

    rff4a4a8 r667501a  
    251251librtemscpu_a_SOURCES += libcsupport/src/termiosinitialize.c
    252252librtemscpu_a_SOURCES += libcsupport/src/termios_num2baud.c
     253librtemscpu_a_SOURCES += libcsupport/src/termios_posix_isig_handler.c
    253254librtemscpu_a_SOURCES += libcsupport/src/termios_setbestbaud.c
    254255librtemscpu_a_SOURCES += libcsupport/src/termios_setinitialbaud.c
  • cpukit/include/rtems/libio.h

    rff4a4a8 r667501a  
    18811881/**@{**/
    18821882
     1883struct rtems_termios_tty;
     1884
    18831885typedef struct rtems_termios_callbacks {
    18841886  int    (*firstOpen)(int major, int minor, void *arg);
     
    19081910);
    19091911
     1912/**
     1913 * @brief Type returned by all input processing (isig) methods
     1914 */
     1915typedef enum {
     1916  /**
     1917   * This indicates that the input character was processed
     1918   * and possibly placed into the buffer.
     1919   */
     1920  RTEMS_TERMIOS_ISIG_WAS_PROCESSED,
     1921  /**
     1922   * This indicates that the input character was not processed and
     1923   * subsequent processing is required.
     1924   */
     1925  RTEMS_TERMIOS_ISIG_WAS_NOT_PROCESSED,
     1926  /**
     1927   * This indicates that the character was processed and determined
     1928   * to be one that requires a signal to be raised (e.g. VINTR or
     1929   * VKILL). The tty must be in the right termios mode for this to
     1930   * occur. There is no further processing of this character required and
     1931   * the pending read() operation should be interrupted.
     1932   */
     1933  RTEMS_TERMIOS_ISIG_INTERRUPT_READ
     1934} rtems_termios_isig_status_code;
     1935
     1936/**
     1937 * @brief Type for ISIG (VINTR/VKILL) handler
     1938 *
     1939 * This type defines the interface to a method which will process
     1940 * VKILL and VINTR characters. The user can register a handler to
     1941 * override the default behavior which is to take no special action
     1942 * on these characters. The POSIX required behavior is to
     1943 * generate a SIGINTR or SIGQUIT signal. This behavior is implemented if
     1944 * the user registers the @ref rtems_termios_posix_isig_handler().
     1945 *
     1946 * @param c     character that was input
     1947 * @param tty   termios structure pointer for this input tty
     1948 *
     1949 * @return The value returned is according to that documented
     1950 *         for @ref rtems_termios_isig_status_code.
     1951 */
     1952typedef rtems_termios_isig_status_code (*rtems_termios_isig_handler)(
     1953  unsigned char             c,
     1954  struct rtems_termios_tty *tty
     1955);
     1956
     1957/**
     1958 * @brief Default handler for ISIG (VINTR/VKILL)
     1959 *
     1960 * This handler is installed by default by termios. It performs
     1961 * no actions on receiving the VINTR and VKILL characters. This is
     1962 * not POSIX conformant behavior but is the historical RTEMS behavior
     1963 * and avoid any default dependency on signal processing code.
     1964 *
     1965 * @param c     character that was input
     1966 * @param tty   termios structure pointer for this input tty
     1967 *
     1968 * The installed ISIG handler is only invoked if the character is
     1969 * (VKILL or VINTR) and ISIG is enabled. Thus the handler need only
     1970 * check the character and perform the appropriate action.
     1971 *
     1972 * @return The value returned is according to that documented
     1973 *         for all methods adhering to @ref rtems_termios_isig_handler.
     1974 */
     1975rtems_termios_isig_status_code rtems_termios_default_isig_handler(
     1976  unsigned char             c,
     1977  struct rtems_termios_tty *tty
     1978);
     1979
     1980/**
     1981 * @brief POSIX handler for ISIG (VINTR/VKILL)
     1982 *
     1983 * This handler is installed by the used to obtain POSIX behavior
     1984 * upon receiving the VINTR and VKILL characters.  The POSIX required
     1985 * behavior is to generate a SIGINTR or SIGQUIT signal if ISIG is enabled.
     1986 *
     1987 * @param c     character that was input
     1988 * @param tty   termios structure pointer for this input tty
     1989 *
     1990 * @return The value returned is according to that documented
     1991 *         for all methods adhering to @ref rtems_termios_isig_handler.
     1992 */
     1993rtems_termios_isig_status_code rtems_termios_posix_isig_handler(
     1994  unsigned char             c,
     1995  struct rtems_termios_tty *tty
     1996);
     1997
     1998/**
     1999 * @brief Register handler for ISIG (VINTR/VKILL)
     2000 *
     2001 * This method is invoked to install an ISIG handler. This may be used
     2002 * to install @ref rtems_termios_posix_isig_handler() to obtain POSIX
     2003 * behavior or a custom handler. The handler
     2004 * @ref rtems_termios_default_isig_handler() is installed by default.
     2005 *
     2006 * @param handler entry point of the new ISIG handler
     2007 *
     2008 * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful.
     2009 */
     2010rtems_status_code rtems_termios_register_isig_handler(
     2011  rtems_termios_isig_handler handler
     2012);
     2013
     2014int rtems_termios_enqueue_raw_characters(
     2015  void *ttyp,
     2016  const char *buf,
     2017  int   len
     2018);
     2019
    19102020rtems_status_code rtems_termios_open (
    19112021  rtems_device_major_number      major,
     
    19312041);
    19322042
    1933 int rtems_termios_enqueue_raw_characters(
    1934   void *ttyp,
    1935   const char *buf,
    1936   int   len
    1937 );
    1938 
    19392043int rtems_termios_dequeue_characters(
    19402044  void *ttyp,
  • cpukit/include/rtems/rtems/status.h

    rff4a4a8 r667501a  
    167167   */
    168168  RTEMS_IO_ERROR                 = 27,
     169  /**
     170   *  This is the status used internally to indicate a blocking device
     171   *  driver call has been interrupted and should be reflected to the
     172   *  called as an INTERRUPTED.
     173   */
     174  RTEMS_INTERRUPTED              = 28,
    169175  /**
    170176   *  This is the status is used internally to RTEMS when performing
     
    175181   *  @note This status will @b NOT be returned to the user.
    176182   */
    177   RTEMS_PROXY_BLOCKING           = 28
     183  RTEMS_PROXY_BLOCKING           = 29
    178184} rtems_status_code;
    179185
     
    236242 *  @retval ENOSYS RTEMS_NOT_IMPLEMENTED, RTEMS_NOT_CONFIGURED
    237243 *  @retval ENOMEM RTEMS_NO_MEMORY
     244 *  @retval EINTR RTEMS_INTERRUPTED
    238245 */
    239246int rtems_status_code_to_errno(rtems_status_code sc);
  • cpukit/libcsupport/src/termios.c

    rff4a4a8 r667501a  
    13021302
    13031303/*
     1304 * This points to the currently registered method to perform
     1305 * ISIG processing of VKILL and VQUIT characters.
     1306 */
     1307static rtems_termios_isig_handler termios_isig_handler =
     1308   rtems_termios_default_isig_handler;
     1309
     1310/*
     1311 * This is the default method to process VKILL or VQUIT characters if
     1312 * ISIG processing is enabled. Note that it does nothing.
     1313 */
     1314rtems_termios_isig_status_code rtems_termios_default_isig_handler(
     1315  unsigned char c,
     1316  struct rtems_termios_tty *tty
     1317)
     1318{
     1319  return RTEMS_TERMIOS_ISIG_WAS_NOT_PROCESSED;
     1320}
     1321
     1322/*
     1323 * Register a method to process VKILL or VQUIT characters if
     1324 * ISIG processing is enabled.
     1325 */
     1326rtems_status_code rtems_termios_register_isig_handler(
     1327  rtems_termios_isig_handler handler
     1328)
     1329{
     1330  if (handler == NULL) {
     1331    return RTEMS_INVALID_ADDRESS;
     1332  }
     1333
     1334  termios_isig_handler = handler;
     1335  return RTEMS_SUCCESSFUL;
     1336}
     1337
     1338/**
     1339 * @brief Type returned by all input processing (iproc) methods
     1340 */
     1341typedef enum {
     1342  /**
     1343   * This indicates that the input character was processed
     1344   * and the results were placed into the buffer.
     1345   */
     1346  RTEMS_TERMIOS_IPROC_IN_BUFFER,
     1347  /**
     1348   * This indicates that the input character was processed
     1349   * and the result did not go into the buffer.
     1350   */
     1351  RTEMS_TERMIOS_IPROC_WAS_PROCESSED,
     1352  /**
     1353   * This indicates that the input character was not processed and
     1354   * subsequent processing is required.
     1355   */
     1356  RTEMS_TERMIOS_IPROC_WAS_NOT_PROCESSED,
     1357  /**
     1358   * This indicates that the character was processed and determined
     1359   * to be one that requires a signal to be raised (e.g. VINTR or
     1360   * VKILL). The tty must be in the right termios mode for this to
     1361   * occur. There is no further processing of this character required and
     1362   * the pending read() operation should be interrupted.
     1363   */
     1364  RTEMS_TERMIOS_IPROC_INTERRUPT_READ
     1365} rtems_termios_iproc_status_code;
     1366
     1367/*
    13041368 * Process a single input character
    13051369 */
    1306 static int
     1370static rtems_termios_iproc_status_code
    13071371iproc (unsigned char c, struct rtems_termios_tty *tty)
    13081372{
     1373  /*
     1374   * If signals are enabled, then allow possibility of VINTR causing
     1375   * SIGINTR and VQUIT causing SIGQUIT. Invoke user provided isig handler.
     1376   */
     1377  if ((tty->termios.c_lflag & ISIG)) {
     1378    if ((c == tty->termios.c_cc[VINTR]) || (c == tty->termios.c_cc[VQUIT])) {
     1379      rtems_termios_isig_status_code rc;
     1380      rc = (*termios_isig_handler)(c, tty);
     1381      if (rc == RTEMS_TERMIOS_ISIG_INTERRUPT_READ) {
     1382         return RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
     1383      }
     1384      if (rc == RTEMS_TERMIOS_ISIG_WAS_PROCESSED) {
     1385         return RTEMS_TERMIOS_IPROC_IN_BUFFER;
     1386      }
     1387      _Assert(rc == RTEMS_TERMIOS_ISIG_WAS_NOT_PROCESSED);
     1388    }
     1389  }
     1390
     1391  /*
     1392   * Perform canonical character processing.
     1393   */
    13091394  if ((c != '\0') && (tty->termios.c_lflag & ICANON)) {
    13101395    if (c == tty->termios.c_cc[VERASE]) {
    13111396      erase (tty, 0);
    1312       return 0;
     1397      return RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
    13131398    }
    13141399    else if (c == tty->termios.c_cc[VKILL]) {
    13151400      erase (tty, 1);
    1316       return 0;
     1401      return RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
    13171402    }
    13181403    else if (c == tty->termios.c_cc[VEOF]) {
    1319       return 1;
     1404      return RTEMS_TERMIOS_IPROC_IN_BUFFER;
    13201405    } else if (c == '\n') {
    13211406      if (tty->termios.c_lflag & (ECHO | ECHONL))
    13221407        echo (c, tty);
    13231408      tty->cbuf[tty->ccount++] = c;
    1324       return 1;
     1409      return RTEMS_TERMIOS_IPROC_IN_BUFFER;
    13251410    } else if ((c == tty->termios.c_cc[VEOL]) ||
    13261411               (c == tty->termios.c_cc[VEOL2])) {
     
    13281413        echo (c, tty);
    13291414      tty->cbuf[tty->ccount++] = c;
    1330       return 1;
     1415      return RTEMS_TERMIOS_IPROC_IN_BUFFER;
    13311416    }
    13321417  }
    13331418
    13341419  /*
     1420   * Perform non-canonical character processing.
     1421   *
    13351422   * FIXME: Should do IMAXBEL handling somehow
    13361423   */
     
    13391426      echo (c, tty);
    13401427    tty->cbuf[tty->ccount++] = c;
    1341   }
    1342   return 0;
     1428    return RTEMS_TERMIOS_IPROC_IN_BUFFER;
     1429  }
     1430  return RTEMS_TERMIOS_IPROC_WAS_NOT_PROCESSED;
    13431431}
    13441432
     
    13461434 * Process input character, with semaphore.
    13471435 */
    1348 static int
     1436static rtems_termios_iproc_status_code
    13491437siproc (unsigned char c, struct rtems_termios_tty *tty)
    13501438{
    1351   int i;
     1439  rtems_termios_iproc_status_code rc;
    13521440
    13531441  /*
     
    13561444  if (tty->termios.c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ECHOPRT|ECHOCTL|ECHOKE)) {
    13571445    rtems_mutex_lock (&tty->osem);
    1358     i = iproc (c, tty);
     1446    rc = iproc (c, tty);
    13591447    rtems_mutex_unlock (&tty->osem);
    13601448  }
    13611449  else {
    1362     i = iproc (c, tty);
    1363   }
    1364   return i;
    1365 }
    1366 
    1367 static int
     1450    rc = iproc (c, tty);
     1451  }
     1452  return rc;
     1453}
     1454
     1455static rtems_termios_iproc_status_code
    13681456siprocPoll (unsigned char c, rtems_termios_tty *tty)
    13691457{
    13701458  if (c == '\r' && (tty->termios.c_iflag & IGNCR) != 0) {
    1371     return 0;
    1372   }
    1373 
     1459    return RTEMS_TERMIOS_IPROC_WAS_NOT_PROCESSED;
     1460  }
     1461
     1462  /*
     1463   * iprocEarly is done at the interrupt level for interrupt driven
     1464   * devices so we need to perform those actions before processing
     1465   * the character.
     1466   */
    13741467  c = iprocEarly (c, tty);
    13751468  return siproc (c, tty);
     
    13791472 * Fill the input buffer by polling the device
    13801473 */
    1381 static void
     1474static rtems_termios_iproc_status_code
    13821475fillBufferPoll (struct rtems_termios_tty *tty)
    13831476{
    1384   int n;
     1477  int                             n;
     1478  rtems_termios_iproc_status_code rc;
     1479  rtems_termios_iproc_status_code retval = RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
    13851480
    13861481  if (tty->termios.c_lflag & ICANON) {
     
    13901485        rtems_task_wake_after (1);
    13911486      } else {
    1392         if  (siprocPoll (n, tty))
     1487        rc = siprocPoll (n, tty);
     1488        if (rc == RTEMS_TERMIOS_IPROC_IN_BUFFER) {
    13931489          break;
     1490        }
     1491        if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
     1492          retval = RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
     1493          break;
     1494        }
    13941495      }
    13951496    }
     
    14181519        rtems_task_wake_after (1);
    14191520      } else {
    1420         siprocPoll (n, tty);
     1521        rc = siprocPoll (n, tty);
     1522        if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
     1523          retval = RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
     1524          break;
     1525        }
    14211526        if (tty->ccount >= tty->termios.c_cc[VMIN])
    14221527          break;
     
    14261531    }
    14271532  }
     1533  return retval;
    14281534}
    14291535
     
    14311537 * Fill the input buffer from the raw input queue
    14321538 */
    1433 static void
     1539static rtems_termios_iproc_status_code
    14341540fillBufferQueue (struct rtems_termios_tty *tty)
    14351541{
     
    14491555    while ((tty->rawInBuf.Head != tty->rawInBuf.Tail) &&
    14501556                       (tty->ccount < (CBUFSIZE-1))) {
    1451       unsigned char c;
    1452       unsigned int newHead;
     1557      unsigned char                    c;
     1558      unsigned int                     newHead;
     1559      rtems_termios_iproc_status_code  rc;
    14531560
    14541561      newHead = (tty->rawInBuf.Head + 1) % tty->rawInBuf.Size;
     
    14801587      /* continue processing new character */
    14811588      if (tty->termios.c_lflag & ICANON) {
    1482         if (siproc (c, tty)) {
    1483           /* In canonical mode, input is made available line by line */
    1484           return;
     1589        rc = siproc (c, tty);
     1590        /* If the read() should be interrupted, return */
     1591        if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
     1592          return RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
     1593        }
     1594        /* In canonical mode, input is made available line by line */
     1595        if (rc == RTEMS_TERMIOS_IPROC_IN_BUFFER) {
     1596          return RTEMS_TERMIOS_IPROC_IN_BUFFER;
    14851597        }
    14861598      } else {
    1487         siproc (c, tty);
     1599        rc = siproc (c, tty);
     1600        /* If the read() should be interrupted, return */
     1601        if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
     1602          return RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
     1603        }
    14881604        if (tty->ccount >= tty->termios.c_cc[VMIN])
    14891605          wait = false;
     
    15201636    }
    15211637  }
    1522 }
    1523 
    1524 static uint32_t
    1525 rtems_termios_read_tty (struct rtems_termios_tty *tty, char *buffer,
    1526   uint32_t initial_count)
    1527 {
    1528   uint32_t count;
     1638  return RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
     1639}
     1640
     1641static rtems_status_code
     1642rtems_termios_read_tty (
     1643  struct rtems_termios_tty *tty,
     1644  char                     *buffer,
     1645  uint32_t                  initial_count,
     1646  uint32_t                 *count_read
     1647)
     1648{
     1649  uint32_t                         count;
     1650  rtems_termios_iproc_status_code  rc = RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
    15291651
    15301652  count = initial_count;
     
    15341656    tty->read_start_column = tty->column;
    15351657    if (tty->handler.poll_read != NULL && tty->handler.mode == TERMIOS_POLLED)
    1536       fillBufferPoll (tty);
     1658      rc = fillBufferPoll (tty);
    15371659    else
    1538       fillBufferQueue (tty);
    1539   }
     1660      rc = fillBufferQueue (tty);
     1661  }
     1662
     1663  /*
     1664   * If there are characters in the buffer, then copy them to the caller.
     1665   */
    15401666  while (count && (tty->cindex < tty->ccount)) {
    15411667    *buffer++ = tty->cbuf[tty->cindex++];
    15421668    count--;
    1543   }
     1669   }
    15441670  tty->tty_rcvwakeup = false;
    1545   return initial_count - count;
     1671  *count_read = initial_count - count;
     1672
     1673  /*
     1674   * fillBufferPoll and fillBufferQueue can indicate that the operation
     1675   * was interrupted. The isig handler can do nothing, have POSIX behavior
     1676   * and cause a signal, or a user defined action.
     1677   */
     1678  if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
     1679    return RTEMS_INTERRUPTED;
     1680  }
     1681
     1682  return RTEMS_SUCCESSFUL;
    15461683}
    15471684
     
    15491686rtems_termios_read (void *arg)
    15501687{
    1551   rtems_libio_rw_args_t *args = arg;
     1688  rtems_libio_rw_args_t    *args = arg;
    15521689  struct rtems_termios_tty *tty = args->iop->data1;
     1690  rtems_status_code         sc;
    15531691
    15541692  rtems_mutex_lock (&tty->isem);
    15551693
    15561694  if (rtems_termios_linesw[tty->t_line].l_read != NULL) {
    1557     rtems_status_code sc;
    15581695
    15591696    sc = rtems_termios_linesw[tty->t_line].l_read(tty,args);
     
    15631700  }
    15641701
    1565   args->bytes_moved = rtems_termios_read_tty (tty, args->buffer, args->count);
     1702  sc = rtems_termios_read_tty(
     1703    tty,
     1704    args->buffer,
     1705    args->count,
     1706    &args->bytes_moved
     1707  );
    15661708  rtems_mutex_unlock (&tty->isem);
    1567   return RTEMS_SUCCESSFUL;
     1709  return sc;
    15681710}
    15691711
     
    20232165{
    20242166  struct rtems_termios_tty *tty;
    2025   uint32_t bytes_moved;
     2167  uint32_t                  bytes_moved;
     2168  rtems_status_code         sc;
    20262169
    20272170  tty = iop->data1;
     
    20502193  }
    20512194
    2052   bytes_moved = rtems_termios_read_tty (tty, buffer, count);
     2195  sc = rtems_termios_read_tty(tty, buffer, count, &bytes_moved);
    20532196  rtems_mutex_unlock (&tty->isem);
     2197  if (sc != RTEMS_SUCCESSFUL) {
     2198     return rtems_status_code_to_errno (sc);
     2199  }
    20542200  return (ssize_t) bytes_moved;
     2201 
    20552202}
    20562203
  • cpukit/rtems/src/statustext.c

    rff4a4a8 r667501a  
    5454  "RTEMS_NO_MEMORY",
    5555  "RTEMS_IO_ERROR",
     56  "RTEMS_INTERRUPTED",
    5657  "RTEMS_PROXY_BLOCKING"
    5758};
  • cpukit/rtems/src/statustoerrno.c

    rff4a4a8 r667501a  
    4646  [RTEMS_NO_MEMORY]                = ENOMEM,
    4747  [RTEMS_IO_ERROR]                 = EIO,
     48  [RTEMS_INTERRUPTED]              = EINTR,
    4849  [RTEMS_PROXY_BLOCKING]           = EIO
    4950};
  • testsuites/libtests/Makefile.am

    rff4a4a8 r667501a  
    14901490termios09_SOURCES = termios09/init.c
    14911491termios09_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_termios09) \
    1492         $(support_includes)
     1492        $(support_includes)
     1493endif
     1494
     1495if TEST_termios10
     1496lib_tests += termios10
     1497lib_screens += termios10/termios10.scn
     1498lib_docs += termios10/termios10.doc
     1499termios10_SOURCES  = termios10/init.c
     1500termios10_SOURCES += termios03/termios_testdriver_polled.c
     1501termios10_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_termios10) \
     1502        $(support_includes) -I$(top_srcdir)/termios03
     1503endif
     1504
     1505if TEST_termios11
     1506lib_tests += termios11
     1507lib_screens += termios11/termios11.scn
     1508lib_docs += termios11/termios11.doc
     1509termios11_SOURCES  = termios10/init.c
     1510termios11_SOURCES += termios04/termios_testdriver_intr.c
     1511termios11_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_termios11) \
     1512        $(support_includes) -I$(top_srcdir)/termios04 -DINTERRUPT_DRIVEN
    14931513endif
    14941514
  • testsuites/libtests/configure.ac

    rff4a4a8 r667501a  
    226226RTEMS_TEST_CHECK([termios08])
    227227RTEMS_TEST_CHECK([termios09])
     228RTEMS_TEST_CHECK([termios10])
     229RTEMS_TEST_CHECK([termios11])
    228230RTEMS_TEST_CHECK([top])
    229231RTEMS_TEST_CHECK([ttest01])
Note: See TracChangeset for help on using the changeset viewer.