Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 87822ce in mainline


Ignore:
Timestamp:
2021-03-04T19:14:30Z (7 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
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
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/cmds/modules/cat/cat.c

    r760a392 r87822ce  
    122122        cons_event_t ev;
    123123        kbd_event_t *kev;
     124        errno_t rc;
    124125
    125126        while (true) {
    126                 if (!console_get_event(console, &ev)) {
     127                rc = console_get_event(console, &ev);
     128                if (rc != EOK)
    127129                        return;
    128                 }
    129130                if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS) {
    130131                        kev = &ev.ev.key;
  • uspace/app/bdsh/cmds/modules/cp/cp.c

    r760a392 r87822ce  
    146146{
    147147        va_list args;
     148        errno_t rc;
    148149
    149150        va_start(args, message);
     
    154155                cons_event_t ev;
    155156                console_flush(con);
    156                 console_get_event(con, &ev);
     157                rc = console_get_event(con, &ev);
     158                if (rc != EOK)
     159                        exit(1);
    157160                if (ev.type != CEV_KEY || ev.ev.key.type != KEY_PRESS ||
    158161                    (ev.ev.key.mods & (KM_CTRL | KM_ALT)) != 0) {
  • uspace/app/edit/edit.c

    r760a392 r87822ce  
    251251
    252252        while (!done) {
    253                 console_get_event(con, &ev);
     253                rc = console_get_event(con, &ev);
     254                if (rc != EOK)
     255                        break;
     256
    254257                pane.rflags = 0;
    255258
     
    634637        int nc;
    635638        bool done;
     639        errno_t rc;
    636640
    637641        asprintf(&str, "%s: %s", prompt, init_value);
     
    648652
    649653        while (!done) {
    650                 console_get_event(con, &ev);
     654                rc = console_get_event(con, &ev);
     655                if (rc != EOK)
     656                        return NULL;
    651657
    652658                if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS) {
  • uspace/app/mkbd/main.c

    r760a392 r87822ce  
    174174        while (true) {
    175175                cons_event_t ev;
    176                 bool ok = console_get_event(con, &ev);
    177                 if (!ok) {
     176                errno_t rc = console_get_event(con, &ev);
     177                if (rc != EOK) {
    178178                        printf("Connection with console broken: %s.\n",
    179179                            str_error(errno));
  • uspace/app/modplay/modplay.c

    r760a392 r87822ce  
    174174        while (true) {
    175175                timeout = 0;
    176                 if (console_get_event_timeout(con, &event, &timeout))
     176                rc = console_get_event_timeout(con, &event, &timeout);
     177                if (rc == EOK)
    177178                        modplay_event(&event);
     179                else if (rc != ETIMEOUT)
     180                        break;
     181
    178182                if (quit)
    179183                        break;
  • uspace/app/netecho/netecho.c

    r760a392 r87822ce  
    121121{
    122122        cons_event_t ev;
     123        errno_t rc;
    123124
    124125        printf("Communication started. Press Ctrl-Q to quit.\n");
     
    128129        done = false;
    129130        while (!done) {
    130                 console_get_event(con, &ev);
     131                rc = console_get_event(con, &ev);
     132                if (rc != EOK)
     133                        break;
     134
    131135                if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS)
    132136                        key_handle(&ev.ev.key);
  • uspace/app/nterm/nterm.c

    r760a392 r87822ce  
    130130        done = false;
    131131        while (!done) {
    132                 console_get_event(con, &ev);
     132                rc = console_get_event(con, &ev);
     133                if (rc != EOK)
     134                        break;
     135
    133136                if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS)
    134137                        key_handle(&ev.ev.key);
  • uspace/app/ping/ping.c

    r760a392 r87822ce  
    196196        while (true) {
    197197                cons_event_t ev;
    198                 if (!console_get_event(con, &ev))
    199                         break;
     198                errno_t rc;
     199                rc = console_get_event(con, &ev);
     200                if (rc != EOK) {
     201                        ping_signal_received(RECEIVED_INTERRUPT);
     202                        break;
     203                }
    200204
    201205                if ((ev.type == CEV_KEY) && (ev.ev.key.type == KEY_PRESS) &&
  • uspace/app/tester/ipc/starve.c

    r760a392 r87822ce  
    5757                cons_event_t ev;
    5858                usec_t timeout = 0;
    59                 bool has_event = console_get_event_timeout(console, &ev, &timeout);
    60                 if (has_event && ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS) {
    61                         TPRINTF("Key %d pressed, terminating.\n", ev.ev.key.key);
     59                errno_t rc = console_get_event_timeout(console, &ev, &timeout);
     60                if (rc == EOK) {
     61                        if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS) {
     62                                TPRINTF("Key %d pressed, terminating.\n", ev.ev.key.key);
     63                                break;
     64                        }
     65                } else if (rc != ETIMEOUT) {
     66                        TPRINTF("Got rc=%d, terminating.\n", rc);
    6267                        break;
    6368                }
  • uspace/app/tetris/scores.c

    r760a392 r87822ce  
    126126        cons_event_t ev;
    127127        kbd_event_t *kev;
     128        errno_t rc;
    128129
    129130        clear_screen();
     
    141142        while (true) {
    142143                console_flush(console);
    143                 if (!console_get_event(console, &ev))
     144                rc = console_get_event(console, &ev);
     145                if (rc != EOK)
    144146                        exit(1);
    145147
  • uspace/app/tetris/screen.c

    r760a392 r87822ce  
    5454 */
    5555
     56#include <errno.h>
    5657#include <stdio.h>
    5758#include <stdlib.h>
     
    340341{
    341342        usec_t timeout = fallrate;
     343        errno_t rc;
    342344
    343345        while (timeout > 0) {
    344346                cons_event_t event;
    345347
    346                 if (!console_get_event_timeout(console, &event, &timeout))
     348                rc = console_get_event_timeout(console, &event, &timeout);
     349                if (rc == ETIMEOUT)
    347350                        break;
     351                if (rc != EOK)
     352                        exit(1);
    348353        }
    349354}
     
    354359int tgetchar(void)
    355360{
     361        errno_t rc;
     362
    356363        /*
    357364         * Reset timeleft to fallrate whenever it is not positive
     
    376383                cons_event_t event;
    377384
    378                 if (!console_get_event_timeout(console, &event, &timeleft)) {
     385                rc = console_get_event_timeout(console, &event, &timeleft);
     386                if (rc == ETIMEOUT) {
    379387                        timeleft = 0;
    380388                        return -1;
    381389                }
     390                if (rc != EOK)
     391                        exit(1);
    382392
    383393                if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS)
     
    394404{
    395405        char32_t c = 0;
     406        errno_t rc;
    396407
    397408        while (c == 0) {
    398409                cons_event_t event;
    399410
    400                 if (!console_get_event(console, &event))
     411                rc = console_get_event(console, &event);
     412                if (rc == ETIMEOUT)
    401413                        return -1;
     414                if (rc != EOK)
     415                        exit(1);
    402416
    403417                if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS)
  • uspace/app/tetris/tetris.c

    r760a392 r87822ce  
    202202        while (true) {
    203203                int i = getchar();
     204                if (i < 0)
     205                        return 0;
    204206
    205207                switch (i) {
  • uspace/app/top/screen.c

    r760a392 r87822ce  
    534534/** Get char with timeout
    535535 *
     536 * @param sec Timeout in seconds
     537 * @param rch Place to store character on success
     538 * @return EOK on success, ETIMEOUT on time out, EIO on other error
    536539 */
    537 int tgetchar(sec_t sec)
    538 {
     540errno_t tgetchar(sec_t sec, int *rch)
     541{
     542        errno_t rc;
     543
    539544        /*
    540545         * Reset timeleft whenever it is not positive.
     
    548553         * update timeleft so that the next call to tgetchar()
    549554         * will not wait as long. If there is no input,
    550          * make timeleft zero and return -1.
     555         * make timeleft zero and return ETIMEOUT.
    551556         */
    552557
     
    557562
    558563                warning_timeleft -= timeleft;
    559                 if (!console_get_event_timeout(console, &event, &timeleft)) {
     564                rc = console_get_event_timeout(console, &event, &timeleft);
     565                if (rc == ETIMEOUT) {
    560566                        timeleft = 0;
    561                         return -1;
    562                 }
     567                        return ETIMEOUT;
     568                }
     569
     570                if (rc != EOK)
     571                        return EIO;
     572
    563573                warning_timeleft += timeleft;
    564574
     
    567577        }
    568578
    569         return (int) c;
     579        *rch = (int) c;
     580        return EOK;
    570581}
    571582
  • uspace/app/top/screen.h

    r760a392 r87822ce  
    3535#define TOP_SCREEN_H_
    3636
     37#include <errno.h>
    3738#include <io/console.h>
    3839#include <io/verify.h>
     
    4748    _HELENOS_PRINTF_ATTRIBUTE(1, 2);
    4849
    49 extern int tgetchar(sec_t);
     50extern errno_t tgetchar(sec_t, int *);
    5051
    5152#endif
  • uspace/app/top/top.c

    r760a392 r87822ce  
    583583        data_t data_prev;
    584584        const char *ret = NULL;
     585        errno_t rc;
     586        int c;
    585587
    586588        screen_init();
     
    595597        /* And paint screen until death */
    596598        while (true) {
    597                 int c = tgetchar(UPDATE_INTERVAL);
    598 
    599                 if (c < 0) { /* timeout */
     599                rc = tgetchar(UPDATE_INTERVAL, &c);
     600
     601                if (rc == ETIMEOUT) { /* timeout */
    600602                        data_prev = data;
    601603                        if ((ret = read_data(&data)) != NULL) {
     
    608610
    609611                        c = -1;
     612                } else if (rc != EOK) {
     613                        /* Error (e.g. communication with console lost) */
     614                        goto out;
    610615                }
    611616
  • uspace/app/trace/trace.c

    r760a392 r87822ce  
    511511{
    512512        cons_event_t event;
     513        errno_t rc;
    513514
    514515        (void) arg;
     
    522523                fibril_mutex_unlock(&state_lock);
    523524
    524                 if (!console_get_event(console, &event))
     525                rc = console_get_event(console, &event);
     526                if (rc != EOK)
    525527                        return EINVAL;
    526528
  • 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.