Changeset 87822ce in mainline for uspace/lib


Ignore:
Timestamp:
2021-03-04T19:14:30Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d6c4d40
Parents:
760a392
Message:

Avoid infinite loop when console communication is broken

Need to make sure callers of console_get_event_timeout() can distinguish
between timeout and I/O error. Fix all callers of console_get_event()
and console_get_event_timeout() not to enter infinite loop when console
connection is broken. Also avoid setting of errno variable.

Location:
uspace/lib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/io/console.c

    r760a392 r87822ce  
    180180}
    181181
    182 bool console_get_event(console_ctrl_t *ctrl, cons_event_t *event)
     182/** Get console event.
     183 *
     184 * @param ctrl Console
     185 * @param event Place to store event
     186 * @return EOK on success, EIO on failure
     187 */
     188errno_t console_get_event(console_ctrl_t *ctrl, cons_event_t *event)
    183189{
    184190        if (ctrl->input_aid == 0) {
     
    192198                async_wait_for(aid, &rc);
    193199
    194                 if (rc != EOK) {
    195                         errno = rc;
    196                         return false;
    197                 }
     200                if (rc != EOK)
     201                        return EIO;
    198202
    199203                rc = console_ev_decode(&result, event);
    200                 if (rc != EOK) {
    201                         errno = rc;
    202                         return false;
    203                 }
     204                if (rc != EOK)
     205                        return EIO;
    204206        } else {
    205207                errno_t retval;
     
    208210                ctrl->input_aid = 0;
    209211
    210                 if (retval != EOK) {
    211                         errno = retval;
    212                         return false;
    213                 }
     212                if (retval != EOK)
     213                        return EIO;
    214214
    215215                errno_t rc = console_ev_decode(&ctrl->input_call, event);
    216                 if (rc != EOK) {
    217                         errno = rc;
    218                         return false;
    219                 }
    220         }
    221 
    222         return true;
    223 }
    224 
    225 bool console_get_event_timeout(console_ctrl_t *ctrl, cons_event_t *event,
     216                if (rc != EOK)
     217                        return EIO;
     218        }
     219
     220        return EOK;
     221}
     222
     223/** Get console event with timeout.
     224 *
     225 * @param ctrl Console
     226 * @param event Place to store event
     227 * @param timeout Pointer to timeout. This will be updated to reflect
     228 *                the remaining time in case of timeout.
     229 * @return EOK on success (event received), ETIMEOUT on time out,
     230 *         EIO on I/O error (e.g. lost console connection), ENOMEM
     231 *         if out of memory
     232 */
     233errno_t console_get_event_timeout(console_ctrl_t *ctrl, cons_event_t *event,
    226234    usec_t *timeout)
    227235{
     
    239247        errno_t rc = async_wait_timeout(ctrl->input_aid, &retval, *timeout);
    240248        if (rc != EOK) {
     249                if (rc == ENOMEM)
     250                        return ENOMEM;
    241251                *timeout = 0;
    242                 errno = rc;
    243                 return false;
     252                return ETIMEOUT;
    244253        }
    245254
    246255        ctrl->input_aid = 0;
    247256
    248         if (retval != EOK) {
    249                 errno = retval;
    250                 return false;
    251         }
     257        if (retval != EOK)
     258                return EIO;
    252259
    253260        rc = console_ev_decode(&ctrl->input_call, event);
    254         if (rc != EOK) {
    255                 errno = rc;
    256                 return false;
    257         }
     261        if (rc != EOK)
     262                return EIO;
    258263
    259264        /* Update timeout */
     
    262267        *timeout -= NSEC2USEC(ts_sub_diff(&t1, &t0));
    263268
    264         return true;
     269        return EOK;
    265270}
    266271
  • uspace/lib/c/include/io/console.h

    r760a392 r87822ce  
    8484extern void console_cursor_visibility(console_ctrl_t *, bool);
    8585extern errno_t console_get_color_cap(console_ctrl_t *, sysarg_t *);
    86 extern bool console_get_event(console_ctrl_t *, cons_event_t *);
    87 extern bool console_get_event_timeout(console_ctrl_t *, cons_event_t *,
     86extern errno_t console_get_event(console_ctrl_t *, cons_event_t *);
     87extern errno_t console_get_event_timeout(console_ctrl_t *, cons_event_t *,
    8888    usec_t *);
    8989extern errno_t console_map(console_ctrl_t *, sysarg_t, sysarg_t,
  • uspace/lib/clui/tinput.c

    r760a392 r87822ce  
    874874errno_t tinput_read_i(tinput_t *ti, const char *istr, char **dstr)
    875875{
     876        errno_t rc;
     877
    876878        console_flush(ti->console);
    877879        if (console_get_size(ti->console, &ti->con_cols, &ti->con_rows) != EOK)
     
    891893
    892894                cons_event_t ev;
    893                 if (!console_get_event(ti->console, &ev))
     895                rc = console_get_event(ti->console, &ev);
     896                if (rc != EOK)
    894897                        return EIO;
    895898
  • uspace/lib/ui/src/ui.c

    r760a392 r87822ce  
    3939#include <fibril.h>
    4040#include <io/console.h>
     41#include <stdbool.h>
    4142#include <stdlib.h>
    4243#include <str.h>
     
    220221void ui_run(ui_t *ui)
    221222{
    222         bool have_event;
    223223        cons_event_t event;
    224224        usec_t timeout;
     225        errno_t rc;
    225226
    226227        /* Only return command prompt if we are running in a separate window */
     
    231232                if (ui->console != NULL) {
    232233                        timeout = 100000;
    233                         have_event = console_get_event_timeout(ui->console,
     234                        rc = console_get_event_timeout(ui->console,
    234235                            &event, &timeout);
    235                         if (have_event)
     236
     237                        /* Do we actually have an event? */
     238                        if (rc == EOK) {
    236239                                ui_cons_event_process(ui, &event);
     240                        } else if (rc != ETIMEOUT) {
     241                                /* Error, quit */
     242                                break;
     243                        }
    237244                } else {
    238245                        fibril_usleep(100000);
Note: See TracChangeset for help on using the changeset viewer.