Changeset bb4d0b5 in mainline
- Timestamp:
- 2025-10-18T19:29:40Z (7 weeks ago)
- Branches:
- master
- Children:
- 3e41cc4
- Parents:
- 856a7b49
- Location:
- uspace
- Files:
-
- 3 added
- 9 edited
-
app/nav/dlg/ioerrdlg.c (added)
-
app/nav/dlg/ioerrdlg.h (added)
-
app/nav/dlg/newfiledlg.c (modified) (6 diffs)
-
app/nav/meson.build (modified) (2 diffs)
-
app/nav/nav.c (modified) (5 diffs)
-
app/nav/nav.h (modified) (2 diffs)
-
app/nav/newfile.c (modified) (1 diff)
-
app/nav/types/dlg/ioerrdlg.h (added)
-
app/nav/types/nav.h (modified) (2 diffs)
-
app/newfile/newfile.c (modified) (5 diffs)
-
lib/fmgt/include/types/fmgt.h (modified) (2 diffs)
-
lib/fmgt/src/fmgt.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/nav/dlg/newfiledlg.c
r856a7b49 rbb4d0b5 352 352 } 353 353 354 /** Destroy promptdialog.355 * 356 * @param dialog Promptdialog or @c NULL354 /** Destroy new file dialog. 355 * 356 * @param dialog New file dialog or @c NULL 357 357 */ 358 358 void new_file_dlg_destroy(new_file_dlg_t *dialog) … … 365 365 } 366 366 367 /** Set mesage dialog callback.368 * 369 * @param dialog Promptdialog370 * @param cb Promptdialog callbacks367 /** Set new file dialog callback. 368 * 369 * @param dialog new file dialog 370 * @param cb New file dialog callbacks 371 371 * @param arg Callback argument 372 372 */ … … 378 378 } 379 379 380 /** Promptdialog window close handler.380 /** New file dialog window close handler. 381 381 * 382 382 * @param window Window … … 393 393 } 394 394 395 /** Promptdialog window keyboard event handler.395 /** New file dialog window keyboard event handler. 396 396 * 397 397 * @param window Window … … 432 432 } 433 433 434 /** Promptdialog OK button click handler.434 /** New file dialog OK button click handler. 435 435 * 436 436 * @param pbutton Push button … … 452 452 } 453 453 454 /** Promptdialog cancel button click handler.454 /** New file dialog cancel button click handler. 455 455 * 456 456 * @param pbutton Push button -
uspace/app/nav/meson.build
r856a7b49 rbb4d0b5 29 29 deps = [ 'fmgt', 'ui' ] 30 30 src = files( 31 'dlg/ioerrdlg.c', 31 32 'dlg/newfiledlg.c', 32 33 'dlg/progress.c', … … 39 40 40 41 test_src = files( 42 'dlg/ioerrdlg.c', 41 43 'dlg/newfiledlg.c', 42 44 'dlg/progress.c', -
uspace/app/nav/nav.c
r856a7b49 rbb4d0b5 36 36 37 37 #include <fibril.h> 38 #include <fmgt.h> 38 39 #include <gfx/coord.h> 39 40 #include <stdio.h> 40 41 #include <stdlib.h> 41 42 #include <str.h> 43 #include <str_error.h> 42 44 #include <task.h> 43 45 #include <ui/fixed.h> … … 46 48 #include <ui/ui.h> 47 49 #include <ui/window.h> 50 #include "dlg/ioerrdlg.h" 48 51 #include "menu.h" 49 52 #include "newfile.h" … … 87 90 .babort = navigator_progress_babort, 88 91 .close = navigator_progress_close 92 }; 93 94 static void navigator_io_err_abort(io_err_dlg_t *, void *); 95 static void navigator_io_err_retry(io_err_dlg_t *, void *); 96 static void navigator_io_err_close(io_err_dlg_t *, void *); 97 98 static 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 89 102 }; 90 103 … … 244 257 } 245 258 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 246 263 *rnavigator = navigator; 247 264 return EOK; … … 630 647 } 631 648 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 */ 655 fmgt_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(¶ms); 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, ¶ms, &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 */ 707 static 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 */ 725 static 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 */ 743 static 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 632 756 /** @} 633 757 */ -
uspace/app/nav/nav.h
r856a7b49 rbb4d0b5 38 38 39 39 #include <errno.h> 40 #include <fmgt.h> 40 41 #include "types/dlg/progress.h" 41 42 #include "types/nav.h" … … 52 53 extern errno_t navigator_worker_start(navigator_t *, void (*)(void *), 53 54 void *); 55 extern fmgt_error_action_t navigator_io_error_query(void *, fmgt_io_error_t *); 54 56 55 57 #endif -
uspace/app/nav/newfile.c
r856a7b49 rbb4d0b5 69 69 static fmgt_cb_t new_file_fmgt_cb = { 70 70 .abort_query = new_file_abort_query, 71 .io_error_query = navigator_io_error_query, 71 72 .progress = new_file_progress, 72 73 }; -
uspace/app/nav/types/nav.h
r856a7b49 rbb4d0b5 38 38 39 39 #include <fibril.h> 40 #include <fmgt.h> 40 41 #include <stdbool.h> 41 42 #include <ui/fixed.h> … … 65 66 /** Abort current file management operation */ 66 67 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; 67 77 } navigator_t; 68 78 -
uspace/app/newfile/newfile.c
r856a7b49 rbb4d0b5 49 49 static bool newfile_abort_query(void *); 50 50 static void newfile_progress(void *, fmgt_progress_t *); 51 static fmgt_error_action_t newfile_io_error_query(void *, fmgt_io_error_t *); 51 52 52 53 static bool prog_upd = false; 54 static bool nonint = false; 53 55 static bool quiet = false; 54 56 … … 57 59 static fmgt_cb_t newfile_fmgt_cb = { 58 60 .abort_query = newfile_abort_query, 59 .progress = newfile_progress 61 .io_error_query = newfile_io_error_query, 62 .progress = newfile_progress, 60 63 }; 61 64 … … 121 124 } 122 125 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 */ 132 static 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 123 183 int main(int argc, char *argv[]) 124 184 { … … 126 186 errno_t rc; 127 187 int i; 128 bool nonint = false;129 188 bool sparse = false; 130 189 char *fsize = NULL; … … 210 269 rc = fmgt_new_file(fmgt, fname, nbytes, sparse ? nf_sparse : nf_none); 211 270 if (prog_upd) 212 p rintf("\n");271 putchar('\n'); 213 272 if (rc != EOK) { 214 273 printf("Error creating file: %s.\n", str_error(rc)); -
uspace/lib/fmgt/include/types/fmgt.h
r856a7b49 rbb4d0b5 39 39 40 40 #include <capa.h> 41 #include <errno.h> 41 42 #include <fibril_synch.h> 42 43 #include <stdbool.h> … … 52 53 } fmgt_progress_t; 53 54 55 /** File management I/O operation type */ 56 typedef enum { 57 /** Read */ 58 fmgt_io_read, 59 /** Write */ 60 fmgt_io_write 61 } fmgt_io_op_type_t; 62 63 /** File management I/O error report */ 64 typedef struct { 65 /** File name */ 66 const char *fname; 67 /** Operation type */ 68 fmgt_io_op_type_t optype; 69 /** Error code */ 70 errno_t rc; 71 } fmgt_io_error_t; 72 73 /** File management I/O error recovery action */ 74 typedef enum { 75 /** Retry */ 76 fmgt_er_retry, 77 /** Abort */ 78 fmgt_er_abort 79 } fmgt_error_action_t; 80 54 81 /** File management callbacks */ 55 82 typedef struct { 56 83 bool (*abort_query)(void *); 84 fmgt_error_action_t (*io_error_query)(void *, fmgt_io_error_t *); 57 85 void (*progress)(void *, fmgt_progress_t *); 58 86 } fmgt_cb_t; -
uspace/lib/fmgt/src/fmgt.c
r856a7b49 rbb4d0b5 221 221 } 222 222 223 /** Stop progress update timer. 224 * 225 * @param fmgt File management object 226 */ 227 static void fmgt_timer_stop(fmgt_t *fmgt) 228 { 229 (void)fibril_timer_clear(fmgt->timer); 230 } 231 223 232 /** Query caller whether operation should be aborted. 224 233 * … … 232 241 else 233 242 return false; 243 } 244 245 /** Query caller how to recover from I/O error. 246 * 247 * @param fmgt File management object 248 * @param err I/O error report 249 * @return What error recovery action should be taken. 250 */ 251 static fmgt_error_action_t fmgt_io_error_query(fmgt_t *fmgt, 252 fmgt_io_error_t *err) 253 { 254 if (fmgt->cb != NULL && fmgt->cb->io_error_query != NULL) 255 return fmgt->cb->io_error_query(fmgt->cb_arg, err); 256 else 257 return fmgt_er_abort; 234 258 } 235 259 … … 250 274 uint64_t now; 251 275 char *buffer; 276 fmgt_io_error_t err; 277 fmgt_error_action_t action; 252 278 errno_t rc; 253 279 … … 270 296 fmgt_initial_progress_update(fmgt); 271 297 298 /* Create sparse file? */ 272 299 if ((flags & nf_sparse) != 0) { 273 300 fmgt->curf_procb = fsize - 1; … … 280 307 now = BUFFER_SIZE; 281 308 282 rc = vfs_write(fd, &pos, buffer, now, &nw); 309 do { 310 rc = vfs_write(fd, &pos, buffer, now, &nw); 311 if (rc == EOK) 312 break; 313 314 /* I/O error */ 315 err.fname = fname; 316 err.optype = fmgt_io_write; 317 err.rc = rc; 318 fmgt_timer_stop(fmgt); 319 action = fmgt_io_error_query(fmgt, &err); 320 fmgt_timer_start(fmgt); 321 } while (action == fmgt_er_retry); 322 323 /* Not recovered? */ 283 324 if (rc != EOK) { 284 325 free(buffer);
Note:
See TracChangeset
for help on using the changeset viewer.
