Changeset bb4d0b5 in mainline for uspace/app


Ignore:
Timestamp:
2025-10-18T19:29:40Z (2 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
3e41cc4
Parents:
856a7b49
Message:

Allow user to decide whether to retry or abort when I/O error occurs.

Location:
uspace/app
Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/nav/dlg/newfiledlg.c

    r856a7b49 rbb4d0b5  
    352352}
    353353
    354 /** Destroy prompt dialog.
    355  *
    356  * @param dialog Prompt dialog or @c NULL
     354/** Destroy new file dialog.
     355 *
     356 * @param dialog New file dialog or @c NULL
    357357 */
    358358void new_file_dlg_destroy(new_file_dlg_t *dialog)
     
    365365}
    366366
    367 /** Set mesage dialog callback.
    368  *
    369  * @param dialog Prompt dialog
    370  * @param cb Prompt dialog callbacks
     367/** Set new file dialog callback.
     368 *
     369 * @param dialog new file dialog
     370 * @param cb New file dialog callbacks
    371371 * @param arg Callback argument
    372372 */
     
    378378}
    379379
    380 /** Prompt dialog window close handler.
     380/** New file dialog window close handler.
    381381 *
    382382 * @param window Window
     
    393393}
    394394
    395 /** Prompt dialog window keyboard event handler.
     395/** New file dialog window keyboard event handler.
    396396 *
    397397 * @param window Window
     
    432432}
    433433
    434 /** Prompt dialog OK button click handler.
     434/** New file dialog OK button click handler.
    435435 *
    436436 * @param pbutton Push button
     
    452452}
    453453
    454 /** Prompt dialog cancel button click handler.
     454/** New file dialog cancel button click handler.
    455455 *
    456456 * @param pbutton Push button
  • uspace/app/nav/meson.build

    r856a7b49 rbb4d0b5  
    2929deps = [ 'fmgt', 'ui' ]
    3030src = files(
     31        'dlg/ioerrdlg.c',
    3132        'dlg/newfiledlg.c',
    3233        'dlg/progress.c',
     
    3940
    4041test_src = files(
     42        'dlg/ioerrdlg.c',
    4143        'dlg/newfiledlg.c',
    4244        'dlg/progress.c',
  • uspace/app/nav/nav.c

    r856a7b49 rbb4d0b5  
    3636
    3737#include <fibril.h>
     38#include <fmgt.h>
    3839#include <gfx/coord.h>
    3940#include <stdio.h>
    4041#include <stdlib.h>
    4142#include <str.h>
     43#include <str_error.h>
    4244#include <task.h>
    4345#include <ui/fixed.h>
     
    4648#include <ui/ui.h>
    4749#include <ui/window.h>
     50#include "dlg/ioerrdlg.h"
    4851#include "menu.h"
    4952#include "newfile.h"
     
    8790        .babort = navigator_progress_babort,
    8891        .close = navigator_progress_close
     92};
     93
     94static void navigator_io_err_abort(io_err_dlg_t *, void *);
     95static void navigator_io_err_retry(io_err_dlg_t *, void *);
     96static void navigator_io_err_close(io_err_dlg_t *, void *);
     97
     98static io_err_dlg_cb_t navigator_io_err_dlg_cb = {
     99        .babort = navigator_io_err_abort,
     100        .bretry = navigator_io_err_retry,
     101        .close = navigator_io_err_close
    89102};
    90103
     
    244257        }
    245258
     259        fibril_mutex_initialize(&navigator->io_err_act_lock);
     260        fibril_condvar_initialize(&navigator->io_err_act_cv);
     261        navigator->io_err_act_sel = false;
     262
    246263        *rnavigator = navigator;
    247264        return EOK;
     
    630647}
    631648
     649/** Called by fmgt to query for I/O error recovery action.
     650 *
     651 * @param arg Argument (navigator_t *)
     652 * @param err I/O error report
     653 * @return Recovery action to take.
     654 */
     655fmgt_error_action_t navigator_io_error_query(void *arg, fmgt_io_error_t *err)
     656{
     657        navigator_t *nav = (navigator_t *)arg;
     658        io_err_dlg_t *dlg;
     659        io_err_dlg_params_t params;
     660        fmgt_error_action_t err_act;
     661        char *text1;
     662        errno_t rc;
     663        int rv;
     664
     665        io_err_dlg_params_init(&params);
     666        rv = asprintf(&text1, err->optype == fmgt_io_write ?
     667            "Error writing file %s." : "Error reading file %s.",
     668            err->fname);
     669        if (rv < 0)
     670                return fmgt_er_abort;
     671
     672        params.text1 = text1;
     673        params.text2 = str_error(err->rc);
     674
     675        ui_lock(nav->ui);
     676        rc = io_err_dlg_create(nav->ui, &params, &dlg);
     677        if (rc != EOK) {
     678                ui_unlock(nav->ui);
     679                free(text1);
     680                return fmgt_er_abort;
     681        }
     682
     683        io_err_dlg_set_cb(dlg, &navigator_io_err_dlg_cb, (void *)nav);
     684
     685        ui_unlock(nav->ui);
     686        free(text1);
     687
     688        fibril_mutex_lock(&nav->io_err_act_lock);
     689
     690        while (!nav->io_err_act_sel) {
     691                fibril_condvar_wait(&nav->io_err_act_cv,
     692                    &nav->io_err_act_lock);
     693        }
     694
     695        err_act = nav->io_err_act;
     696        nav->io_err_act_sel = false;
     697        fibril_mutex_unlock(&nav->io_err_act_lock);
     698
     699        return err_act;
     700}
     701
     702/** I/O error dialog abort button was pressed.
     703 *
     704 * @param dlg I/O error dialog
     705 * @param arg Argument (navigator_t *)
     706 */
     707static void navigator_io_err_abort(io_err_dlg_t *dlg, void *arg)
     708{
     709        navigator_t *nav = (navigator_t *)arg;
     710
     711        io_err_dlg_destroy(dlg);
     712
     713        fibril_mutex_lock(&nav->io_err_act_lock);
     714        nav->io_err_act = fmgt_er_abort;
     715        nav->io_err_act_sel = true;
     716        fibril_condvar_signal(&nav->io_err_act_cv);
     717        fibril_mutex_unlock(&nav->io_err_act_lock);
     718}
     719
     720/** I/O error dialog retry button was pressed.
     721 *
     722 * @param dlg I/O error dialog
     723 * @param arg Argument (navigator_t *)
     724 */
     725static void navigator_io_err_retry(io_err_dlg_t *dlg, void *arg)
     726{
     727        navigator_t *nav = (navigator_t *)arg;
     728
     729        io_err_dlg_destroy(dlg);
     730
     731        fibril_mutex_lock(&nav->io_err_act_lock);
     732        nav->io_err_act = fmgt_er_retry;
     733        nav->io_err_act_sel = true;
     734        fibril_condvar_signal(&nav->io_err_act_cv);
     735        fibril_mutex_unlock(&nav->io_err_act_lock);
     736}
     737
     738/** I/O error dialog closure requested.
     739 *
     740 * @param dlg I/O error dialog
     741 * @param arg Argument (navigator_t *)
     742 */
     743static void navigator_io_err_close(io_err_dlg_t *dlg, void *arg)
     744{
     745        navigator_t *nav = (navigator_t *)arg;
     746
     747        io_err_dlg_destroy(dlg);
     748
     749        fibril_mutex_lock(&nav->io_err_act_lock);
     750        nav->io_err_act = fmgt_er_abort;
     751        nav->io_err_act_sel = true;
     752        fibril_condvar_signal(&nav->io_err_act_cv);
     753        fibril_mutex_unlock(&nav->io_err_act_lock);
     754}
     755
    632756/** @}
    633757 */
  • uspace/app/nav/nav.h

    r856a7b49 rbb4d0b5  
    3838
    3939#include <errno.h>
     40#include <fmgt.h>
    4041#include "types/dlg/progress.h"
    4142#include "types/nav.h"
     
    5253extern errno_t navigator_worker_start(navigator_t *, void (*)(void *),
    5354    void *);
     55extern fmgt_error_action_t navigator_io_error_query(void *, fmgt_io_error_t *);
    5456
    5557#endif
  • uspace/app/nav/newfile.c

    r856a7b49 rbb4d0b5  
    6969static fmgt_cb_t new_file_fmgt_cb = {
    7070        .abort_query = new_file_abort_query,
     71        .io_error_query = navigator_io_error_query,
    7172        .progress = new_file_progress,
    7273};
  • uspace/app/nav/types/nav.h

    r856a7b49 rbb4d0b5  
    3838
    3939#include <fibril.h>
     40#include <fmgt.h>
    4041#include <stdbool.h>
    4142#include <ui/fixed.h>
     
    6566        /** Abort current file management operation */
    6667        bool abort_op;
     68
     69        /** @c true if user selected I/O error recovery action */
     70        bool io_err_act_sel;
     71        /** Selected I/O error recovery action */
     72        fmgt_error_action_t io_err_act;
     73        /** Signalled when user selects I/O error recovery action */
     74        fibril_condvar_t io_err_act_cv;
     75        /** Synchronizes access to I/O error recovery action */
     76        fibril_mutex_t io_err_act_lock;
    6777} navigator_t;
    6878
  • uspace/app/newfile/newfile.c

    r856a7b49 rbb4d0b5  
    4949static bool newfile_abort_query(void *);
    5050static void newfile_progress(void *, fmgt_progress_t *);
     51static fmgt_error_action_t newfile_io_error_query(void *, fmgt_io_error_t *);
    5152
    5253static bool prog_upd = false;
     54static bool nonint = false;
    5355static bool quiet = false;
    5456
     
    5759static fmgt_cb_t newfile_fmgt_cb = {
    5860        .abort_query = newfile_abort_query,
    59         .progress = newfile_progress
     61        .io_error_query = newfile_io_error_query,
     62        .progress = newfile_progress,
    6063};
    6164
     
    121124}
    122125
     126/** Called by fmgt to let user choose I/O error recovery action.
     127 *
     128 * @param arg Argument (not used)
     129 * @param err I/O error report
     130 * @return Error recovery action.
     131 */
     132static fmgt_error_action_t newfile_io_error_query(void *arg,
     133    fmgt_io_error_t *err)
     134{
     135        cons_event_t event;
     136        kbd_event_t *ev;
     137        errno_t rc;
     138
     139        (void)arg;
     140
     141        if (nonint)
     142                return fmgt_er_abort;
     143
     144        if (prog_upd)
     145                putchar('\n');
     146
     147        fprintf(stderr, "I/O error %s file '%s' (%s).\n",
     148            err->optype == fmgt_io_write ? "writing" : "reading",
     149            err->fname, str_error(err->rc));
     150        fprintf(stderr, "[A]bort or [R]etry?\n");
     151
     152        if (con == NULL)
     153                return fmgt_er_abort;
     154
     155        while (true) {
     156                rc = console_get_event(con, &event);
     157                if (rc != EOK)
     158                        return fmgt_er_abort;
     159
     160                if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS) {
     161                        ev = &event.ev.key;
     162                        if ((ev->mods & KM_ALT) == 0 &&
     163                            (ev->mods & KM_CTRL) == 0) {
     164                                if (ev->c == 'r' || ev->c == 'R')
     165                                        return fmgt_er_retry;
     166                                if (ev->c == 'a' || ev->c == 'A')
     167                                        return fmgt_er_abort;
     168                        }
     169                }
     170
     171                if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS) {
     172                        ev = &event.ev.key;
     173                        if ((ev->mods & KM_ALT) == 0 &&
     174                            (ev->mods & KM_SHIFT) == 0 &&
     175                            (ev->mods & KM_CTRL) != 0) {
     176                                if (ev->key == KC_C)
     177                                        return fmgt_er_abort;
     178                        }
     179                }
     180        }
     181}
     182
    123183int main(int argc, char *argv[])
    124184{
     
    126186        errno_t rc;
    127187        int i;
    128         bool nonint = false;
    129188        bool sparse = false;
    130189        char *fsize = NULL;
     
    210269        rc = fmgt_new_file(fmgt, fname, nbytes, sparse ? nf_sparse : nf_none);
    211270        if (prog_upd)
    212                 printf("\n");
     271                putchar('\n');
    213272        if (rc != EOK) {
    214273                printf("Error creating file: %s.\n", str_error(rc));
Note: See TracChangeset for help on using the changeset viewer.