Changes in / [34832c3:b067800] in mainline


Ignore:
Files:
5 added
31 edited

Legend:

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

    r34832c3 rb067800  
    4545
    4646#define CP_VERSION "0.0.1"
    47 #define CP_DEFAULT_BUFLEN  1024
     47#define CP_DEFAULT_BUFLEN (1024 * 64)
    4848
    4949static const char *cmdname = "cp";
  • uspace/app/bdsh/cmds/modules/mkfile/mkfile.c

    r34832c3 rb067800  
    4848
    4949/** Number of bytes to write at a time */
    50 #define BUFFER_SIZE 16384
     50#define BUFFER_SIZE (1024 * 64)
    5151
    5252static const char *cmdname = "mkfile";
  • uspace/app/sysinst/meson.build

    r34832c3 rb067800  
    11#
    2 # Copyright (c) 2025 Jiri Svoboda
     2# Copyright (c) 2026 Jiri Svoboda
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 deps = [ 'block', 'fdisk', 'futil', 'sif', 'system', 'ui' ]
     29deps = [ 'block', 'fdisk', 'fmgt', 'sif', 'system', 'ui' ]
    3030src = files(
    3131        'rdimg.c',
  • uspace/app/sysinst/sysinst.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include <errno.h>
    4242#include <fdisk.h>
    43 #include <futil.h>
     43#include <fmgt.h>
    4444#include <gfx/render.h>
    4545#include <io/log.h>
     
    7575#define DEFAULT_DEV_2 "devices/\\hw\\sys\\00:01.0\\ide1\\c0d0"
    7676//#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.2\\uhci_rh\\usb01_a1\\mass-storage0\\l0"
     77/** Index of partition which we must install to (hardwired in load.cfg) */
     78#define INST_PART_IDX 1
     79/* File system type cannot be changed without modifying core.img */
     80#define INST_FSTYPE fs_ext4
    7781/** Volume label for the new file system */
    7882#define INST_VOL_LABEL "HelenOS"
     
    8791#define CD_MOUNT_POINT "/vol/" CD_VOL_LABEL
    8892
    89 #define BOOT_FILES_SRC CD_MOUNT_POINT
     93#define BOOT_FILES_SRC CD_MOUNT_POINT "/boot"
    9094#define BOOT_BLOCK_IDX 0 /* MBR */
    9195
    9296#define CFG_FILES_SRC "/cfg"
    93 #define CFG_FILES_DEST MOUNT_POINT "/cfg"
     97#define CFG_FILES_DEST MOUNT_POINT
    9498
    9599static const char *default_devs[] = {
     
    139143};
    140144
     145static void sysinst_upgrade_confirm_button(ui_msg_dialog_t *, void *, unsigned);
     146static void sysinst_upgrade_confirm_close(ui_msg_dialog_t *, void *);
     147
     148static ui_msg_dialog_cb_t sysinst_upgrade_confirm_cb = {
     149        .button = sysinst_upgrade_confirm_button,
     150        .close = sysinst_upgrade_confirm_close
     151};
     152
    141153static errno_t sysinst_restart_dlg_create(sysinst_t *);
    142154static void sysinst_restart_dlg_button(ui_msg_dialog_t *, void *, unsigned);
     
    151163static errno_t sysinst_restart(sysinst_t *);
    152164static void sysinst_progress_destroy(sysinst_progress_t *);
     165static void sysinst_progress(sysinst_t *, const char *);
    153166static void sysinst_action(sysinst_t *, const char *);
    154167static void sysinst_error(sysinst_t *, const char *);
    155168static void sysinst_debug(sysinst_t *, const char *);
    156169
    157 static void sysinst_futil_copy_file(void *, const char *, const char *);
    158 static void sysinst_futil_create_dir(void *, const char *);
     170static fmgt_exists_action_t sysinst_fmgt_exists_query(void *, fmgt_exists_t *);
     171static void sysinst_fmgt_action(void *, fmgt_action_t, const char *,
     172    const char *);
     173static void sysinst_fmgt_progress(void *, fmgt_progress_t *);
    159174static errno_t sysinst_eject_dev(sysinst_t *, service_id_t);
    160175static errno_t sysinst_eject_phys_by_mp(sysinst_t *, const char *);
    161 
    162 static futil_cb_t sysinst_futil_cb = {
    163         .copy_file = sysinst_futil_copy_file,
    164         .create_dir = sysinst_futil_create_dir
     176static errno_t sysinst_upgrade_confirm_create(sysinst_t *);
     177
     178static fmgt_cb_t sysinst_fmgt_cb = {
     179        .exists_query = sysinst_fmgt_exists_query,
     180        .action = sysinst_fmgt_action,
     181        .progress = sysinst_fmgt_progress
    165182};
    166183
     
    247264 */
    248265static void sysinst_confirm_close(ui_msg_dialog_t *dialog, void *arg)
     266{
     267        sysinst_t *sysinst = (sysinst_t *) arg;
     268
     269        ui_msg_dialog_destroy(dialog);
     270        ui_quit(sysinst->ui);
     271}
     272
     273/** Upgrade confirm dialog OK button press.
     274 *
     275 * @param dialog Message dialog
     276 * @param arg Argument (sysinst_t *)
     277 * @param btn Button number
     278 * @param earg Entry argument
     279 */
     280static void sysinst_upgrade_confirm_button(ui_msg_dialog_t *dialog, void *arg,
     281    unsigned btn)
     282{
     283        sysinst_t *sysinst = (sysinst_t *) arg;
     284
     285        ui_msg_dialog_destroy(dialog);
     286
     287        switch (btn) {
     288        case 0:
     289                /* OK */
     290                fibril_mutex_lock(&sysinst->responded_lock);
     291                sysinst->responded = true;
     292                sysinst->quit = false;
     293                fibril_mutex_unlock(&sysinst->responded_lock);
     294                fibril_condvar_signal(&sysinst->responded_cv);
     295                break;
     296        default:
     297                /* Cancel */
     298                fibril_mutex_lock(&sysinst->responded_lock);
     299                sysinst->responded = true;
     300                sysinst->quit = true;
     301                fibril_mutex_unlock(&sysinst->responded_lock);
     302                fibril_condvar_signal(&sysinst->responded_cv);
     303                break;
     304        }
     305}
     306
     307/** Upgrade confirm dialog close request.
     308 *
     309 * @param dialog Message dialog
     310 * @param arg Argument (sysinst_t *)
     311 */
     312static void sysinst_upgrade_confirm_close(ui_msg_dialog_t *dialog, void *arg)
    249313{
    250314        sysinst_t *sysinst = (sysinst_t *) arg;
     
    350414}
    351415
    352 /** Called when futil is starting to copy a file.
     416/** Called when fmgt hits an existing file while copying.
     417 *
     418 * @param arg Argument (sysinst_t *)
     419 * @param exists Information about existing file
     420 * @return Existing file recovery action
     421 */
     422fmgt_exists_action_t sysinst_fmgt_exists_query(void *arg, fmgt_exists_t *exists)
     423{
     424        sysinst_t *sysinst = (sysinst_t *)arg;
     425
     426        (void)sysinst;
     427        (void)exists->fname;
     428
     429        sysinst_action(sysinst, exists->fname);
     430
     431        /*
     432         * Before starting fmgt operation, the caller would specify
     433         * whether to overwrite existing files.
     434         */
     435        if (sysinst->overwrite)
     436                return fmgt_exr_overwrite;
     437        else
     438                return fmgt_exr_skip;
     439}
     440
     441/** Called when fmgt is starting to perform action on a file.
     442 *
     443 * @param arg Argument (sysinst_t *)
     444 * @param action Action being performed
     445 * @param src Source or only path
     446 * @param dest Destination path or @c NULL
     447 */
     448static void sysinst_fmgt_action(void *arg, fmgt_action_t action,
     449    const char *src, const char *dest)
     450{
     451        sysinst_t *sysinst = (sysinst_t *)arg;
     452        char buf[128];
     453
     454        (void)src;
     455
     456        switch (action) {
     457        case fmgt_ac_create:
     458                snprintf(buf, sizeof(buf), "Creating %s.", src);
     459                sysinst_action(sysinst, buf);
     460                break;
     461        case fmgt_ac_copy:
     462                snprintf(buf, sizeof(buf), "Copying %s.", dest);
     463                sysinst_action(sysinst, buf);
     464                break;
     465        default:
     466                break;
     467        }
     468}
     469
     470/** Called by fmgt to update on progress.
    353471 *
    354472 * @param arg Argument (sysinst_t *)
     
    356474 * @param dest Destination path
    357475 */
    358 static void sysinst_futil_copy_file(void *arg, const char *src,
    359     const char *dest)
     476static void sysinst_fmgt_progress(void *arg, fmgt_progress_t *progress)
    360477{
    361478        sysinst_t *sysinst = (sysinst_t *)arg;
    362479        char buf[128];
    363480
    364         (void)src;
    365         snprintf(buf, sizeof(buf), "Copying %s.", dest);
    366         sysinst_action(sysinst, buf);
    367 }
    368 
    369 /** Called when futil is about to create a directory.
    370  *
    371  * @param arg Argument (sysinst_t *)
    372  * @param dest Destination path
    373  */
    374 static void sysinst_futil_create_dir(void *arg, const char *dest)
    375 {
    376         sysinst_t *sysinst = (sysinst_t *)arg;
    377         char buf[128];
    378 
    379         snprintf(buf, sizeof(buf), "Creating %s.", dest);
    380         sysinst_action(sysinst, buf);
     481        snprintf(buf, sizeof(buf), "Copied %s files, %s; "
     482            "current file: %s done.", progress->total_procf,
     483            progress->total_procb, progress->curf_percent);
     484        sysinst_progress(sysinst, buf);
    381485}
    382486
     
    430534}
    431535
     536/** Find existing OS partition.
     537 *
     538 * @param sysinst System installer
     539 * @param fdev Destination device
     540 * @param rpart Place to store pointer to partition
     541 *
     542 * @return EOK on success or an error code
     543 */
     544static errno_t sysinst_existing_os_part_find(sysinst_t *sysinst,
     545    fdisk_dev_t *fdev, fdisk_part_t **rpart)
     546{
     547        fdisk_part_t *part;
     548        fdisk_part_info_t pinfo;
     549        errno_t rc;
     550
     551        sysinst_debug(sysinst, "sysinst_existing_os_part_find(): walk partitions");
     552
     553        part = fdisk_part_first(fdev);
     554        while (part != NULL) {
     555                rc = fdisk_part_get_info(part, &pinfo);
     556                if (rc != EOK) {
     557                        sysinst_error(sysinst,
     558                            "Error getting partition information.");
     559                        goto error;
     560                }
     561
     562                if (pinfo.index == INST_PART_IDX && pinfo.pkind == lpk_primary)
     563                        break;
     564
     565                part = fdisk_part_next(part);
     566        }
     567
     568        /* Partition with index INST_PART_IDX not found? */
     569        if (part == NULL)
     570                return ENOENT;
     571
     572        /* Correct file system type? */
     573        if (pinfo.fstype != INST_FSTYPE) {
     574                /* Not a usable existing partition. */
     575                return ENOENT;
     576        }
     577
     578        sysinst_debug(sysinst, "sysinst_existing_os_part_find(): OK");
     579        sysinst->psvc_id = pinfo.svc_id;
     580        *rpart = part;
     581        return EOK;
     582error:
     583        return rc;
     584}
     585
     586/** Create installation partition.
     587 *
     588 * @param sysinst System installer
     589 * @param fdev Destination device
     590 *
     591 * @return EOK on success or an error code
     592 */
     593static errno_t sysinst_inst_part_create(sysinst_t *sysinst, fdisk_dev_t *fdev)
     594{
     595        fdisk_part_t *part;
     596        fdisk_part_spec_t pspec;
     597        fdisk_part_info_t pinfo;
     598        capa_spec_t capa;
     599        errno_t rc;
     600
     601        sysinst_debug(sysinst, "sysinst_inst_part_create(): get maximum available block");
     602
     603        rc = fdisk_part_get_max_avail(fdev, spc_pri, &capa);
     604        if (rc != EOK) {
     605                sysinst_error(sysinst,
     606                    "Error getting available capacity.");
     607                goto error;
     608        }
     609
     610        fdisk_pspec_init(&pspec);
     611        pspec.capacity = capa;
     612        pspec.pkind = lpk_primary;
     613        pspec.fstype = INST_FSTYPE; /* Cannot be changed without modifying core.img */
     614        pspec.mountp = MOUNT_POINT;
     615        pspec.index = INST_PART_IDX; /* Cannot be changed without modifying core.img */
     616        pspec.label = INST_VOL_LABEL;
     617
     618        rc = fdisk_part_create(fdev, &pspec, &part);
     619        if (rc != EOK) {
     620                sysinst_error(sysinst, "Error creating partition.");
     621                goto error;
     622        }
     623
     624        rc = fdisk_part_get_info(part, &pinfo);
     625        if (rc != EOK) {
     626                sysinst_error(sysinst, "Error getting partition information.");
     627                goto error;
     628        }
     629
     630        sysinst_debug(sysinst, "sysinst_inst_part_create(): OK");
     631        sysinst->psvc_id = pinfo.svc_id;
     632        return EOK;
     633error:
     634        return rc;
     635}
     636
    432637/** Label and mount the destination device.
    433638 *
    434639 * @param sysinst System installer
    435640 * @param dev Disk device to label
    436  * @param psvc_id Place to store service ID of the created partition
    437641 *
    438642 * @return EOK on success or an error code
     
    443647        fdisk_dev_t *fdev = NULL;
    444648        fdisk_part_t *part;
    445         fdisk_part_spec_t pspec;
    446         fdisk_part_info_t pinfo;
     649        fdisk_label_info_t linfo;
     650        bool create_label = false;
    447651        bool dir_created = false;
    448652        bool label_created = false;
    449         capa_spec_t capa;
    450653        service_id_t sid;
    451654        errno_t rc;
     
    483686        sysinst_debug(sysinst, "sysinst_label_dev(): create label");
    484687
    485         rc = fdisk_label_create(fdev, lt_mbr);
    486         if (rc != EOK) {
    487                 sysinst_error(sysinst, "Error creating label.");
    488                 goto error;
     688        rc = fdisk_label_get_info(fdev, &linfo);
     689        if (rc != EOK) {
     690                sysinst_error(sysinst, "Error analyzing device.");
     691                goto error;
     692        }
     693
     694        switch (linfo.ltype) {
     695        case lt_none:
     696                /* need to create label */
     697                create_label = true;
     698                break;
     699        case lt_mbr:
     700                /* MBR label already present */
     701                break;
     702        default:
     703                /* a different type of label already present */
     704                sysinst_error(sysinst, "Disk contains unusable label.");
     705                goto error;
     706        }
     707
     708        /* Need to create label? */
     709        if (create_label) {
     710                rc = fdisk_label_create(fdev, lt_mbr);
     711                if (rc != EOK) {
     712                        sysinst_error(sysinst, "Error creating label.");
     713                        goto error;
     714                }
    489715        }
    490716
     
    493719        sysinst_debug(sysinst, "sysinst_label_dev(): create partition");
    494720
    495         rc = fdisk_part_get_max_avail(fdev, spc_pri, &capa);
    496         if (rc != EOK) {
    497                 sysinst_error(sysinst,
    498                     "Error getting available capacity.");
    499                 goto error;
    500         }
    501 
    502         fdisk_pspec_init(&pspec);
    503         pspec.capacity = capa;
    504         pspec.pkind = lpk_primary;
    505         pspec.fstype = fs_ext4; /* Cannot be changed without modifying core.img */
    506         pspec.mountp = MOUNT_POINT;
    507         pspec.label = INST_VOL_LABEL;
    508 
    509         rc = fdisk_part_create(fdev, &pspec, &part);
    510         if (rc != EOK) {
    511                 sysinst_error(sysinst, "Error creating partition.");
    512                 goto error;
    513         }
    514 
    515         rc = fdisk_part_get_info(part, &pinfo);
    516         if (rc != EOK) {
    517                 sysinst_error(sysinst, "Error getting partition information.");
    518                 goto error;
    519         }
    520 
    521         sysinst_debug(sysinst, "sysinst_label_dev(): OK");
    522         fdisk_dev_close(fdev);
    523         fdisk_destroy(fdisk);
    524         sysinst->psvc_id = pinfo.svc_id;
     721        /* Existing OS partition? */
     722        rc = sysinst_existing_os_part_find(sysinst, fdev, &part);
     723        if (rc == EOK) {
     724                /* Open dialog to confirm that user wants to upgrade. */
     725                rc = sysinst_upgrade_confirm_create(sysinst);
     726                if (rc != EOK) {
     727                        sysinst_error(sysinst, "Cannot create window.");
     728                        goto error;
     729                }
     730
     731                fibril_mutex_lock(&sysinst->responded_lock);
     732                while (!sysinst->responded)
     733                        fibril_condvar_wait(&sysinst->responded_cv,
     734                            &sysinst->responded_lock);
     735                fibril_mutex_unlock(&sysinst->responded_lock);
     736
     737                /* User decided not to upgrade existing installation? */
     738                if (sysinst->quit) {
     739                        (void)vfs_unlink_path(MOUNT_POINT);
     740                        return EOK;
     741                }
     742
     743                /* Set mount point for installation partition. */
     744                rc = fdisk_part_set_mountp(part, MOUNT_POINT);
     745                if (rc != EOK) {
     746                        sysinst_error(sysinst, "Cannot mount installation "
     747                            "partition.");
     748                        goto error;
     749                }
     750
     751                /* performing OS upgrade */
     752                sysinst->oper = sio_upgrade;
     753                if (sysinst->progress != NULL) {
     754                        (void)ui_label_set_text(sysinst->progress->label,
     755                            "Upgrading system. Please wait...");
     756                        (void)ui_label_paint(sysinst->progress->label);
     757                        (void)ui_window_set_caption(sysinst->bgwindow,
     758                            "System Upgrade");
     759                }
     760        } else {
     761                /* Create installation partition. */
     762                rc = sysinst_inst_part_create(sysinst, fdev);
     763                if (rc != EOK)
     764                        goto error;
     765
     766                /* performing initial OS installation */
     767                sysinst->oper = sio_install;
     768        }
     769
    525770        return EOK;
    526771error:
     
    568813        char *path = NULL;
    569814        const char **cp;
     815        fmgt_flist_t *flist = NULL;
    570816        int rv;
    571817
     
    579825
    580826                rc = vfs_link_path(path, KIND_DIRECTORY, NULL);
    581                 if (rc != EOK) {
     827                if (rc != EOK && rc != EEXIST) {
    582828                        sysinst_error(sysinst, "Error creating directory.");
    583829                        goto error;
     
    593839
    594840        /* Copy initial configuration files */
    595         rc = futil_rcopy_contents(sysinst->futil, CFG_FILES_SRC,
    596             CFG_FILES_DEST);
     841
     842        log_msg(LOG_DEFAULT, LVL_NOTE,
     843            "sysinst_copy_boot_files(): copy initial configuration files");
     844
     845        rc = fmgt_flist_create(&flist);
     846        if (rc != EOK)
     847                goto error;
     848
     849        rc = fmgt_flist_append(flist, CFG_FILES_SRC);
     850        if (rc != EOK)
     851                goto error;
     852
     853        /* Do not overwrite configuration files. */
     854        sysinst->overwrite = false;
     855        rc = fmgt_copy(sysinst->fmgt, flist, CFG_FILES_DEST);
    597856        if (rc != EOK) {
    598857                sysinst_error(sysinst, "Error copying initial configuration "
    599858                    "files.");
    600                 return rc;
    601         }
    602 
     859                goto error;
     860        }
     861
     862        fmgt_flist_destroy(flist);
     863        log_msg(LOG_DEFAULT, LVL_NOTE,
     864            "sysinst_copy_boot_files(): copy initial configuration files OK");
    603865        return EOK;
    604866error:
     867        if (flist != NULL)
     868                fmgt_flist_destroy(flist);
    605869        if (path != NULL)
    606870                free(path);
     
    614878static errno_t sysinst_copy_boot_files(sysinst_t *sysinst)
    615879{
     880        fmgt_flist_t *flist = NULL;
    616881        errno_t rc;
    617882
    618883        log_msg(LOG_DEFAULT, LVL_NOTE,
    619884            "sysinst_copy_boot_files(): copy bootloader files");
    620         rc = futil_rcopy_contents(sysinst->futil, BOOT_FILES_SRC, MOUNT_POINT);
     885        rc = fmgt_flist_create(&flist);
     886        if (rc != EOK)
     887                goto error;
     888
     889        rc = fmgt_flist_append(flist, BOOT_FILES_SRC);
     890        if (rc != EOK)
     891                goto error;
     892
     893        /* Overwrite boot files with new ones during upgrade. */
     894        sysinst->overwrite = true;
     895        rc = fmgt_copy(sysinst->fmgt, flist, MOUNT_POINT);
    621896        if (rc != EOK) {
    622897                sysinst_error(sysinst, "Error copying bootloader "
    623898                    "files.");
    624                 return rc;
    625         }
    626 
     899                goto error;
     900        }
     901
     902        fmgt_flist_destroy(flist);
    627903        sysinst_debug(sysinst, "sysinst_copy_boot_files(): OK");
    628904        return EOK;
     905error:
     906        if (flist != NULL)
     907                fmgt_flist_destroy(flist);
     908        return rc;
    629909}
    630910
     
    7401020}
    7411021
     1022/** Return file contents as a heap-allocated block of bytes.
     1023 *
     1024 * @param srcp File path
     1025 * @param rdata Place to store pointer to data
     1026 * @param rsize Place to store size of data
     1027 *
     1028 * @return EOK on success, ENOENT if failed to open file, EIO on other
     1029 *         I/O error, ENOMEM if out of memory
     1030 */
     1031static errno_t sysinst_get_file(const char *srcp, void **rdata, size_t *rsize)
     1032{
     1033        int sf;
     1034        size_t nr;
     1035        errno_t rc;
     1036        size_t fsize;
     1037        char *data;
     1038        vfs_stat_t st;
     1039
     1040        rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf);
     1041        if (rc != EOK)
     1042                return ENOENT;
     1043
     1044        if (vfs_stat(sf, &st) != EOK) {
     1045                vfs_put(sf);
     1046                return EIO;
     1047        }
     1048
     1049        fsize = st.size;
     1050
     1051        data = calloc(fsize, 1);
     1052        if (data == NULL) {
     1053                vfs_put(sf);
     1054                return ENOMEM;
     1055        }
     1056
     1057        rc = vfs_read(sf, (aoff64_t []) { 0 }, data, fsize, &nr);
     1058        if (rc != EOK || nr != fsize) {
     1059                vfs_put(sf);
     1060                free(data);
     1061                return EIO;
     1062        }
     1063
     1064        (void) vfs_put(sf);
     1065        *rdata = data;
     1066        *rsize = fsize;
     1067
     1068        return EOK;
     1069}
     1070
    7421071/** Copy boot blocks.
    7431072 *
     
    7651094            "sysinst_copy_boot_blocks: Read boot block image.");
    7661095
    767         rc = futil_get_file(sysinst->futil,
    768             BOOT_FILES_SRC "/boot/grub/i386-pc/boot.img",
     1096        rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/boot.img",
    7691097            &boot_img, &boot_img_size);
    770         if (rc != EOK || boot_img_size != 512)
     1098        if (rc != EOK || boot_img_size != 512) {
     1099                sysinst_error(sysinst, "Error reading boot block image.");
    7711100                return EIO;
     1101        }
    7721102
    7731103        log_msg(LOG_DEFAULT, LVL_NOTE,
    7741104            "sysinst_copy_boot_blocks: Read GRUB core image.");
    7751105
    776         rc = futil_get_file(sysinst->futil,
    777             BOOT_FILES_SRC "/boot/grub/i386-pc/core.img",
     1106        rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/core.img",
    7781107            &core_img, &core_img_size);
    779         if (rc != EOK)
     1108        if (rc != EOK) {
     1109                sysinst_error(sysinst, "Error reading GRUB core image.");
    7801110                return EIO;
     1111        }
    7811112
    7821113        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    7911122
    7921123        rc = block_init(sid);
    793         if (rc != EOK)
     1124        if (rc != EOK) {
     1125                sysinst_error(sysinst, "Error opening block device.");
    7941126                return rc;
     1127        }
    7951128
    7961129        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    7981131
    7991132        rc = block_get_bsize(sid, &bsize);
    800         if (rc != EOK)
     1133        if (rc != EOK) {
     1134                sysinst_error(sysinst, "Error getting block size.");
    8011135                return rc;
     1136        }
    8021137
    8031138        if (bsize != 512) {
     
    8101145
    8111146        rc = block_read_direct(sid, BOOT_BLOCK_IDX, 1, bbuf);
    812         if (rc != EOK)
     1147        if (rc != EOK) {
     1148                sysinst_error(sysinst, "Error reading boot block.");
    8131149                return EIO;
     1150        }
    8141151
    8151152        core_start = 16;
     
    8421179
    8431180        rc = block_write_direct(sid, BOOT_BLOCK_IDX, 1, bbuf);
    844         if (rc != EOK)
     1181        if (rc != EOK) {
     1182                sysinst_error(sysinst, "Error writing boot block.");
    8451183                return EIO;
     1184        }
    8461185
    8471186        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    8501189        /* XXX Must pad last block with zeros */
    8511190        rc = block_write_direct(sid, core_start, core_blocks, core_img);
    852         if (rc != EOK)
     1191        if (rc != EOK) {
     1192                sysinst_error(sysinst, "Error writing GRUB core blocks.");
    8531193                return EIO;
     1194        }
    8541195
    8551196        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    10041345        if (rc != EOK)
    10051346                goto error;
     1347        if (sysinst->quit)
     1348                return EOK;
    10061349
    10071350        clean_dev = true;
     
    10741417        sysinst_progress_destroy(sysinst->progress);
    10751418        sysinst->progress = NULL;
     1419
     1420        /* User decided not to upgrade system? */
     1421        if (sysinst->quit) {
     1422                ui_quit(sysinst->ui);
     1423                return EOK;
     1424        }
    10761425
    10771426        rc = sysinst_restart_dlg_create(sysinst);
     
    11151464                params.rect.p0.y = 0;
    11161465                params.rect.p1.x = 64;
    1117                 params.rect.p1.y = 5;
     1466                params.rect.p1.y = 7;
    11181467        } else {
    11191468                params.rect.p0.x = 0;
    11201469                params.rect.p0.y = 0;
    11211470                params.rect.p1.x = 500;
    1122                 params.rect.p1.y = 60;
     1471                params.rect.p1.y = 90;
    11231472        }
    11241473
     
    11461495        }
    11471496
     1497        /* Installing/upgrading system line */
    11481498        rc = ui_label_create(ui_res, "Installing system. Please wait...",
    11491499            &progress->label);
     
    11781528        }
    11791529
     1530        /* Action line */
    11801531        rc = ui_label_create(ui_res, "",
    11811532            &progress->action);
     
    11891540                rect.p0.y = 3;
    11901541                rect.p1.x = arect.p1.x;
     1542                rect.p1.y = 4;
     1543        } else {
     1544                rect.p0.x = arect.p0.x;
     1545                rect.p0.y = 40;
     1546                rect.p1.x = arect.p1.x;
     1547                rect.p1.y = 60;
     1548        }
     1549        ui_label_set_rect(progress->action, &rect);
     1550        ui_label_set_halign(progress->action, gfx_halign_center);
     1551        ui_label_set_valign(progress->action, gfx_valign_top);
     1552
     1553        rc = ui_fixed_add(fixed, ui_label_ctl(progress->action));
     1554        if (rc != EOK) {
     1555                sysinst_error(sysinst, "Error adding control to layout.");
     1556                ui_label_destroy(progress->label);
     1557                progress->label = NULL;
     1558                goto error;
     1559        }
     1560
     1561        /* Progress line */
     1562        rc = ui_label_create(ui_res, "",
     1563            &progress->progress);
     1564        if (rc != EOK) {
     1565                sysinst_error(sysinst, "Error creating label.");
     1566                goto error;
     1567        }
     1568
     1569        if (ui_is_textmode(sysinst->ui)) {
     1570                rect.p0.x = arect.p0.x;
     1571                rect.p0.y = 5;
     1572                rect.p1.x = arect.p1.x;
    11911573                rect.p1.y = arect.p1.y;
    11921574        } else {
    11931575                rect.p0.x = arect.p0.x;
    1194                 rect.p0.y = 30;
     1576                rect.p0.y = 70;
    11951577                rect.p1.x = arect.p1.x;
    11961578                rect.p1.y = arect.p1.y;
    11971579        }
    1198         ui_label_set_rect(progress->action, &rect);
    1199         ui_label_set_halign(progress->action, gfx_halign_center);
    1200         ui_label_set_valign(progress->action, gfx_valign_center);
    1201 
    1202         rc = ui_fixed_add(fixed, ui_label_ctl(progress->action));
     1580        ui_label_set_rect(progress->progress, &rect);
     1581        ui_label_set_halign(progress->progress, gfx_halign_center);
     1582        ui_label_set_valign(progress->progress, gfx_valign_top);
     1583
     1584        rc = ui_fixed_add(fixed, ui_label_ctl(progress->progress));
    12031585        if (rc != EOK) {
    12041586                sysinst_error(sysinst, "Error adding control to layout.");
     
    12461628}
    12471629
     1630/** Set current progress message.
     1631 *
     1632 * @param sysinst System installer
     1633 * @param progress Progress text
     1634 */
     1635static void sysinst_progress(sysinst_t *sysinst, const char *progress)
     1636{
     1637        log_msg(LOG_DEFAULT, LVL_NOTE, "%s", progress);
     1638
     1639        if (sysinst->progress == NULL)
     1640                return;
     1641
     1642        ui_label_set_text(sysinst->progress->progress, progress);
     1643        ui_label_paint(sysinst->progress->progress);
     1644}
     1645
    12481646/** Set current action message.
    12491647 *
     
    13321730}
    13331731
    1334 /** Create restart dialog.
    1335  *
    1336  * @param sysinst System installer
    1337  * @return EOK on success or an error code
    1338  */
    1339 static errno_t sysinst_restart_dlg_create(sysinst_t *sysinst)
     1732/** Create upgrade confirmation dialog.
     1733 *
     1734 * @param sysinst System installer
     1735 * @return EOK on success or an error code
     1736 */
     1737static errno_t sysinst_upgrade_confirm_create(sysinst_t *sysinst)
    13401738{
    13411739        ui_msg_dialog_params_t params;
     
    13441742
    13451743        ui_msg_dialog_params_init(&params);
     1744        params.caption = "System upgrade";
     1745        params.text = "Existing installation found. "
     1746            "Do you want to upgrade it?";
     1747        params.choice = umdc_ok_cancel;
     1748        params.flags |= umdf_topmost | umdf_center;
     1749
     1750        rc = ui_msg_dialog_create(sysinst->ui, &params, &dialog);
     1751        if (rc != EOK)
     1752                return rc;
     1753
     1754        ui_msg_dialog_set_cb(dialog, &sysinst_upgrade_confirm_cb, sysinst);
     1755        return EOK;
     1756}
     1757
     1758/** Create restart dialog.
     1759 *
     1760 * @param sysinst System installer
     1761 * @return EOK on success or an error code
     1762 */
     1763static errno_t sysinst_restart_dlg_create(sysinst_t *sysinst)
     1764{
     1765        ui_msg_dialog_params_t params;
     1766        ui_msg_dialog_t *dialog;
     1767        errno_t rc;
     1768
     1769        ui_msg_dialog_params_init(&params);
    13461770        params.caption = "Restart System";
    1347         params.text = "Installation complete. Restart the system?";
     1771
     1772        if (sysinst->oper == sio_install)
     1773                params.text = "Installation complete. Restart the system?";
     1774        else
     1775                params.text = "Upgrade complete. Restart the system?";
     1776
    13481777        params.choice = umdc_ok_cancel;
    13491778        params.flags |= umdf_topmost | umdf_center;
     
    13731802                return ENOMEM;
    13741803
    1375         rc = futil_create(&sysinst_futil_cb, (void *)sysinst, &sysinst->futil);
     1804        fibril_condvar_initialize(&sysinst->responded_cv);
     1805        fibril_mutex_initialize(&sysinst->responded_lock);
     1806
     1807        rc = fmgt_create(&sysinst->fmgt);
    13761808        if (rc != EOK) {
    13771809                printf("Out of memory.\n");
    13781810                goto error;
    13791811        }
     1812
     1813        fmgt_set_cb(sysinst->fmgt, &sysinst_fmgt_cb, (void *)sysinst);
     1814        fmgt_set_init_update(sysinst->fmgt, true);
    13801815
    13811816        rc = ui_create(display_spec, &ui);
     
    14211856        }
    14221857
    1423         (void)sysinst_confirm_create(sysinst);
     1858        rc = sysinst_confirm_create(sysinst);
     1859        if (rc != EOK) {
     1860                printf("Error creating window.\n");
     1861                goto error;
     1862        }
    14241863
    14251864        ui_run(ui);
     
    14341873        return EOK;
    14351874error:
    1436         if (sysinst->futil != NULL)
    1437                 futil_destroy(sysinst->futil);
     1875        if (sysinst->fmgt != NULL)
     1876                fmgt_destroy(sysinst->fmgt);
    14381877        if (sysinst->system != NULL)
    14391878                system_close(sysinst->system);
  • uspace/app/sysinst/sysinst.h

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3737#define SYSINST_H
    3838
    39 #include <futil.h>
     39#include <fibril_synch.h>
     40#include <fmgt.h>
    4041#include <gfx/color.h>
    4142#include <loc.h>
     43#include <stdbool.h>
    4244#include <system.h>
    4345#include <ui/fixed.h>
     
    5254        ui_label_t *label;
    5355        ui_label_t *action;
     56        ui_label_t *progress;
    5457} sysinst_progress_t;
     58
     59/** Installer operation */
     60typedef enum {
     61        /** initial OS installation */
     62        sio_install,
     63        /** OS upgrade */
     64        sio_upgrade
     65} sysinst_oper_t;
    5566
    5667/** System installer. */
     
    6374        /** Service ID of destination partition. */
    6475        sysarg_t psvc_id;
    65         futil_t *futil;
     76        /** operation being performed */
     77        sysinst_oper_t oper;
     78        fmgt_t *fmgt;
     79        /** @c true after user responds to interactive query. */
     80        bool responded;
     81        /** Signalled when @c responded changes */
     82        fibril_condvar_t responded_cv;
     83        /** Synchronize access to @c responded */
     84        fibril_mutex_t responded_lock;
     85        /** User decided to quit installation. */
     86        bool quit;
    6687        char errmsg[128];
     88        /** Allow overwriting files in current copy operation. */
     89        bool overwrite;
    6790} sysinst_t;
    6891
  • uspace/app/uidemo/uidemo.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3333 */
    3434
     35#include <fibril_synch.h>
    3536#include <gfx/bitmap.h>
    3637#include <gfx/coord.h>
     
    6061#include "uidemo.h"
    6162
     63enum {
     64        scrollbar_update_interval_ms = 1000,
     65        ui_demo_progress_step = 17
     66};
     67
    6268static errno_t bitmap_moire(gfx_bitmap_t *, gfx_coord_t, gfx_coord_t);
    6369
     
    714720        (void) demo;
    715721        ui_msg_dialog_destroy(dialog);
     722}
     723
     724static void ui_demo_timer_fun(void *arg)
     725{
     726        ui_demo_t *demo = (ui_demo_t *) arg;
     727
     728        if (demo->progress_value < 100) {
     729                demo->progress_value += ui_demo_progress_step;
     730                if (demo->progress_value > 100)
     731                        demo->progress_value = 100;
     732        } else {
     733                demo->progress_value = 0;
     734        }
     735
     736        ui_progress_set_value(demo->progress, demo->progress_value);
     737
     738        if (ui_tab_is_selected(demo->tbars)) {
     739                ui_lock(demo->ui);
     740                ui_progress_paint(demo->progress);
     741                ui_unlock(demo->ui);
     742        }
     743
     744        fibril_timer_set(demo->timer, 1000 * scrollbar_update_interval_ms,
     745            ui_demo_timer_fun, (void *)demo);
    716746}
    717747
     
    956986        }
    957987
     988        rc = ui_tab_create(demo.tabset, "Bars", &demo.tbars);
     989        if (rc != EOK) {
     990                printf("Error creating tab.\n");
     991                return rc;
     992        }
     993
    958994        rc = ui_fixed_add(demo.fixed, ui_tab_set_ctl(demo.tabset));
    959995        if (rc != EOK) {
     
    14291465        ui_tab_add(demo.tlists, ui_fixed_ctl(demo.lfixed));
    14301466
     1467        rc = ui_fixed_create(&demo.bars_fixed);
     1468        if (rc != EOK) {
     1469                printf("Error creating fixed layout.\n");
     1470                return rc;
     1471        }
     1472
     1473        rc = ui_progress_create(ui_res, 0, &demo.progress);
     1474        if (rc != EOK) {
     1475                printf("Error creating entry.\n");
     1476                return rc;
     1477        }
     1478
     1479        /* FIXME: Auto layout */
     1480        if (ui_is_textmode(ui)) {
     1481                rect.p0.x = 4;
     1482                rect.p0.y = 5;
     1483                rect.p1.x = 42;
     1484                rect.p1.y = 6;
     1485        } else {
     1486                rect.p0.x = 15;
     1487                rect.p0.y = 88;
     1488                rect.p1.x = 243;
     1489                rect.p1.y = 113;
     1490        }
     1491
     1492        ui_progress_set_rect(demo.progress, &rect);
     1493
     1494        rc = ui_fixed_add(demo.bars_fixed, ui_progress_ctl(demo.progress));
     1495        if (rc != EOK) {
     1496                printf("Error adding control to layout.\n");
     1497                return rc;
     1498        }
     1499
     1500        ui_tab_add(demo.tbars, ui_fixed_ctl(demo.bars_fixed));
     1501
    14311502        ui_window_add(window, ui_fixed_ctl(demo.fixed));
    14321503
     1504        demo.timer = fibril_timer_create(NULL);
     1505        if (demo.timer == NULL) {
     1506                printf("Error creating timer.\n");
     1507                return ENOMEM;
     1508        }
     1509
     1510        fibril_timer_set(demo.timer, 1000 * scrollbar_update_interval_ms,
     1511            ui_demo_timer_fun, (void *)&demo);
     1512
    14331513        rc = ui_window_paint(window);
    14341514        if (rc != EOK) {
     
    14381518
    14391519        ui_run(ui);
     1520
     1521        fibril_timer_clear(demo.timer);
     1522        fibril_timer_destroy(demo.timer);
    14401523
    14411524        ui_window_destroy(window);
  • uspace/app/uidemo/uidemo.h

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838
    3939#include <display.h>
     40#include <fibril_synch.h>
    4041#include <ui/checkbox.h>
    4142#include <ui/entry.h>
     
    4647#include <ui/menubar.h>
    4748#include <ui/pbutton.h>
     49#include <ui/progress.h>
    4850#include <ui/rbutton.h>
    4951#include <ui/scrollbar.h>
     
    6163        ui_fixed_t *bfixed;
    6264        ui_fixed_t *lfixed;
     65        ui_fixed_t *bars_fixed;
    6366        ui_menu_bar_t *mbar;
    6467        ui_menu_t *mfile;
     
    6972        ui_tab_t *tbasic;
    7073        ui_tab_t *tlists;
     74        ui_tab_t *tbars;
    7175        ui_entry_t *entry;
    7276        ui_image_t *image;
     
    8387        ui_scrollbar_t *vscrollbar;
    8488        ui_list_t *list;
     89        ui_progress_t *progress;
     90        unsigned progress_value;
     91        fibril_timer_t *timer;
    8592} ui_demo_t;
    8693
  • uspace/lib/cpp/src/__bits/runtime.cpp

    r34832c3 rb067800  
    11/*
     2 * Copyright (c) 2026 Jiri Svoboda
    23 * Copyright (c) 2018 Jaroslav Jindrak
    34 * All rights reserved.
     
    7172    }
    7273
     74    /**
     75     * Called when an object destructor exits due to an exception
     76     * during stack unwinding.
     77     */
     78    extern "C" void __cxa_call_terminate()
     79    {
     80        std::terminate();
     81    }
     82
    7383#ifdef __arm__
    7484    extern "C" int __aeabi_atexit(void* p, void (*f)(void*), void* d)
  • uspace/lib/ext4/src/ops.c

    r34832c3 rb067800  
    6464static bool ext4_is_dots(const uint8_t *, size_t);
    6565static errno_t ext4_instance_get(service_id_t, ext4_instance_t **);
     66static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *,
     67    ext4_inode_ref_t *, uint32_t, uint32_t, uint32_t *, int *, bool *);
    6668
    6769/* Forward declarations of ext4 libfs operations. */
     
    158160}
    159161
    160 /*
    161  * Ext4 libfs operations.
    162  */
    163 
    164162/** Get instance from internal table by service_id.
    165163 *
     
    170168 *
    171169 */
    172 errno_t ext4_instance_get(service_id_t service_id, ext4_instance_t **inst)
     170static errno_t ext4_instance_get(service_id_t service_id, ext4_instance_t **inst)
    173171{
    174172        fibril_mutex_lock(&instance_list_mutex);
     
    190188        return EINVAL;
    191189}
     190
     191/*
     192 * Ext4 libfs operations.
     193 */
    192194
    193195/** Get root node of filesystem specified by service_id.
     
    12841286    size_t *wbytes, aoff64_t *nsize)
    12851287{
    1286         fs_node_t *fn;
     1288        fs_node_t *fn = NULL;
    12871289        errno_t rc2;
     1290        bool fblock_allocated = false;
     1291        ext4_inode_ref_t *inode_ref = NULL;
     1292
    12881293        errno_t rc = ext4_node_get(&fn, service_id, index);
    12891294        if (rc != EOK)
     
    13141319
    13151320        /* Load inode */
    1316         ext4_inode_ref_t *inode_ref = enode->inode_ref;
     1321        inode_ref = enode->inode_ref;
    13171322        rc = ext4_filesystem_get_inode_data_block_index(inode_ref, iblock,
    13181323            &fblock);
     
    13221327        }
    13231328
    1324         /* Check for sparse file */
     1329        /* Handle sparse or unallocated block */
    13251330        if (fblock == 0) {
    1326                 if ((ext4_superblock_has_feature_incompatible(fs->superblock,
    1327                     EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
    1328                     (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
    1329                         uint32_t last_iblock =
    1330                             ext4_inode_get_size(fs->superblock, inode_ref->inode) /
    1331                             block_size;
    1332 
    1333                         while (last_iblock < iblock) {
    1334                                 rc = ext4_extent_append_block(inode_ref, &last_iblock,
    1335                                     &fblock, true);
    1336                                 if (rc != EOK) {
    1337                                         async_answer_0(&call, rc);
    1338                                         goto exit;
    1339                                 }
    1340                         }
    1341 
    1342                         rc = ext4_extent_append_block(inode_ref, &last_iblock,
    1343                             &fblock, false);
    1344                         if (rc != EOK) {
    1345                                 async_answer_0(&call, rc);
    1346                                 goto exit;
    1347                         }
    1348                 } else {
    1349                         rc = ext4_balloc_alloc_block(inode_ref, &fblock);
    1350                         if (rc != EOK) {
    1351                                 async_answer_0(&call, rc);
    1352                                 goto exit;
    1353                         }
    1354 
    1355                         rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
    1356                             iblock, fblock);
    1357                         if (rc != EOK) {
    1358                                 ext4_balloc_free_block(inode_ref, fblock);
    1359                                 async_answer_0(&call, rc);
    1360                                 goto exit;
    1361                         }
     1331                rc = handle_sparse_or_unallocated_fblock(fs, inode_ref,
     1332                    block_size, iblock, &fblock, &flags, &fblock_allocated);
     1333                if (rc != EOK) {
     1334                        async_answer_0(&call, rc);
     1335                        goto exit;
    13621336                }
    1363 
    1364                 flags = BLOCK_FLAGS_NOREAD;
    1365                 inode_ref->dirty = true;
    13661337        }
    13671338
     
    14021373
    14031374exit:
     1375        if (rc != EOK && fblock_allocated)
     1376                ext4_balloc_free_block(inode_ref, fblock);
     1377
    14041378        rc2 = ext4_node_put(fn);
    14051379        return rc == EOK ? rc2 : rc;
     1380}
     1381
     1382/** Handle sparse or unallocated block.
     1383 *
     1384 * @param fs            Filesystem handle
     1385 * @param inode_ref     I-node reference
     1386 * @param block_size    Filesystem block size
     1387 * @param iblock        Logical block
     1388 * @param fblock        Place to store allocated block address
     1389 * @param flags         BLOCK_FLAGS to update
     1390 * @param allocated     Place to store whether new block was allocated
     1391 *
     1392 * @return Error code
     1393 *
     1394 */
     1395static errno_t handle_sparse_or_unallocated_fblock(ext4_filesystem_t *fs,
     1396    ext4_inode_ref_t *inode_ref, uint32_t block_size, uint32_t iblock,
     1397    uint32_t *fblock, int *flags, bool *allocated)
     1398{
     1399        errno_t rc;
     1400
     1401        /* Check for sparse file */
     1402        if ((ext4_superblock_has_feature_incompatible(fs->superblock,
     1403            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
     1404            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
     1405                uint32_t last_iblock =
     1406                    ext4_inode_get_size(fs->superblock, inode_ref->inode) /
     1407                    block_size;
     1408
     1409                while (last_iblock < iblock) {
     1410                        rc = ext4_extent_append_block(inode_ref, &last_iblock,
     1411                            fblock, true);
     1412                        if (rc != EOK)
     1413                                return rc;
     1414                }
     1415
     1416                rc = ext4_extent_append_block(inode_ref, &last_iblock, fblock,
     1417                    false);
     1418                if (rc != EOK)
     1419                        return rc;
     1420
     1421                *allocated = false;
     1422        } else { /* Allocate new block */
     1423                rc = ext4_balloc_alloc_block(inode_ref, fblock);
     1424                if (rc != EOK)
     1425                        return rc;
     1426
     1427                rc = ext4_filesystem_set_inode_data_block_index(inode_ref,
     1428                    iblock, *fblock);
     1429                if (rc != EOK) {
     1430                        ext4_balloc_free_block(inode_ref, *fblock);
     1431                        return rc;
     1432                }
     1433
     1434                *allocated = true;
     1435        }
     1436
     1437        *flags = BLOCK_FLAGS_NOREAD;
     1438        inode_ref->dirty = true;
     1439
     1440        return EOK;
    14061441}
    14071442
  • uspace/lib/fdisk/include/types/fdisk.h

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    155155        /** File system type */
    156156        vol_fstype_t fstype;
     157        /** Partition index, default/0 = assign automatically */
     158        int index;
    157159        /** Volume label */
    158160        const char *label;
     
    171173        /** File system type */
    172174        vol_fstype_t fstype;
     175        /** Partition index */
     176        int index;
    173177        /** Volume label */
    174178        char *label;
  • uspace/lib/fdisk/src/fdisk.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    673673        info->fstype = part->fstype;
    674674        info->pkind = part->pkind;
     675        info->index = part->index;
    675676        info->label = part->label;
    676677        info->svc_id = part->svc_id;
     
    10311032
    10321033        if (pspec->pkind != lpk_logical) {
    1033                 rc = fdisk_part_get_free_idx(dev, &index);
    1034                 if (rc != EOK)
    1035                         return EIO;
     1034                if (pspec->index == 0) {
     1035                        /* allocate first free index */
     1036                        rc = fdisk_part_get_free_idx(dev, &index);
     1037                        if (rc != EOK)
     1038                                return EIO;
     1039                } else {
     1040                        /* user-specified index */
     1041                        index = pspec->index;
     1042                }
    10361043        } else {
    10371044                index = 0;
  • uspace/lib/fmgt/include/types/fmgt.h

    r34832c3 rb067800  
    114114} fmgt_exists_action_t;
    115115
     116/** Action being performed. */
     117typedef enum {
     118        /** copying file */
     119        fmgt_ac_copy,
     120        /** creating file or directory */
     121        fmgt_ac_create,
     122        /** deleting file or directory */
     123        fmgt_ac_delete,
     124        /** moving file */
     125        fmgt_ac_move,
     126        /** renaming file */
     127        fmgt_ac_rename,
     128        /** verifying file */
     129        fmgt_ac_verify,
     130} fmgt_action_t;
     131
    116132/** File management callbacks */
    117133typedef struct {
     
    119135        fmgt_error_action_t (*io_error_query)(void *, fmgt_io_error_t *);
    120136        fmgt_exists_action_t (*exists_query)(void *, fmgt_exists_t *);
     137        void (*action)(void *, fmgt_action_t, const char *, const char *);
    121138        void (*progress)(void *, fmgt_progress_t *);
    122139} fmgt_cb_t;
  • uspace/lib/fmgt/private/fmgt.h

    r34832c3 rb067800  
    5454extern void fmgt_initial_progress_update(fmgt_t *);
    5555extern void fmgt_final_progress_update(fmgt_t *);
     56extern void fmgt_report_action(fmgt_t *, fmgt_action_t, const char *,
     57    const char *);
    5658
    5759#endif
  • uspace/lib/fmgt/src/copy.c

    r34832c3 rb067800  
    6464
    6565        (void)dest;
     66        fmgt_report_action(fmgt, fmgt_ac_create, dest, NULL);
    6667        return fmgt_create_dir(fmgt, dest, false);
    6768}
     
    8687        char *buffer;
    8788        errno_t rc;
     89
     90        fmgt_report_action(fmgt, fmgt_ac_copy, src, dest);
    8891
    8992        buffer = calloc(BUFFER_SIZE, 1);
     
    171174        fmgt_initial_progress_update(fmgt);
    172175        rc = fmgt_walk(&params);
     176        fmgt_timer_stop(fmgt);
    173177        fmgt_final_progress_update(fmgt);
    174178        return rc;
  • uspace/lib/fmgt/src/delete.c

    r34832c3 rb067800  
    6464        errno_t rc;
    6565
     66        fmgt_report_action(fmgt, fmgt_ac_delete, src, NULL);
     67
    6668        /* Remove original file. */
    6769        rc = fmgt_remove(fmgt, src);
     
    8587        fmgt_t *fmgt = (fmgt_t *)walk->params->arg;
    8688        (void)dest;
     89        fmgt_report_action(fmgt, fmgt_ac_delete, src, NULL);
    8790        return fmgt_remove(fmgt, src);
    8891}
     
    110113        fmgt_initial_progress_update(fmgt);
    111114        rc = fmgt_walk(&params);
     115        fmgt_timer_stop(fmgt);
    112116        fmgt_final_progress_update(fmgt);
    113117        return rc;
  • uspace/lib/fmgt/src/fmgt.c

    r34832c3 rb067800  
    218218}
    219219
     220/** Report action being performed to the caller.
     221 *
     222 * @param fmgt File management object
     223 * @param action Action we started performing
     224 * @param src Source (or only) path
     225 * @param dest Destination path or @c NULL
     226 */
     227void fmgt_report_action(fmgt_t *fmgt, fmgt_action_t action, const char *src,
     228    const char *dest)
     229{
     230        if (fmgt->cb != NULL && fmgt->cb->action != NULL) {
     231                fmgt->cb->action(fmgt->cb_arg, action, src, dest);
     232        }
     233}
     234
    220235/** Provide initial progress update (if required).
    221236 *
  • uspace/lib/fmgt/src/move.c

    r34832c3 rb067800  
    8989        errno_t rc;
    9090
     91        fmgt_report_action(fmgt, fmgt_ac_move, src, dest);
     92
    9193        buffer = calloc(BUFFER_SIZE, 1);
    9294        if (buffer == NULL)
     
    166168
    167169        (void)dest;
     170        fmgt_report_action(fmgt, fmgt_ac_delete, src, NULL);
    168171        return fmgt_remove(fmgt, src);
    169172}
     
    195198        fmgt_initial_progress_update(fmgt);
    196199        rc = fmgt_walk(&params);
     200        fmgt_timer_stop(fmgt);
    197201        fmgt_final_progress_update(fmgt);
    198202        return rc;
  • uspace/lib/fmgt/src/newdir.c

    r34832c3 rb067800  
    8484        errno_t rc;
    8585
     86        fmgt_report_action(fmgt, fmgt_ac_create, dname, NULL);
     87
    8688        /* Clear statistics. */
    8789        fmgt_progress_init(fmgt);
  • uspace/lib/fmgt/src/newfile.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    9898        errno_t rc;
    9999
     100        fmgt_report_action(fmgt, fmgt_ac_create, fname, NULL);
     101
    100102        buffer = calloc(BUFFER_SIZE, 1);
    101103        if (buffer == NULL)
     
    112114        fmgt_progress_init(fmgt);
    113115        fmgt_initial_progress_update(fmgt);
     116        fmgt_timer_start(fmgt);
    114117
    115118        /* Create sparse file? */
     
    142145                        free(buffer);
    143146                        vfs_put(fd);
     147                        fmgt_timer_stop(fmgt);
    144148                        fmgt_final_progress_update(fmgt);
    145149                        return rc;
     
    152156                        free(buffer);
    153157                        vfs_put(fd);
     158                        fmgt_timer_stop(fmgt);
    154159                        fmgt_final_progress_update(fmgt);
    155160                        return EINTR;
     
    159164        free(buffer);
    160165        vfs_put(fd);
     166        fmgt_timer_stop(fmgt);
    161167        fmgt_final_progress_update(fmgt);
    162168        return EOK;
  • uspace/lib/fmgt/src/rename.c

    r34832c3 rb067800  
    5050        errno_t rc;
    5151
     52        fmgt_report_action(fmgt, fmgt_ac_rename, old_path, new_name);
     53
    5254        /* Clear statistics. */
    5355        fmgt_progress_init(fmgt);
  • uspace/lib/fmgt/src/verify.c

    r34832c3 rb067800  
    6868
    6969        (void)unused;
     70        fmgt_report_action(fmgt, fmgt_ac_verify, fname, NULL);
    7071
    7172        buffer = calloc(BUFFER_SIZE, 1);
     
    143144        fmgt_initial_progress_update(fmgt);
    144145        rc = fmgt_walk(&params);
     146        fmgt_timer_stop(fmgt);
    145147        fmgt_final_progress_update(fmgt);
    146148        return rc;
  • uspace/lib/futil/include/futil.h

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4646extern errno_t futil_copy_file(futil_t *, const char *, const char *);
    4747extern errno_t futil_rcopy_contents(futil_t *, const char *, const char *);
    48 extern errno_t futil_get_file(futil_t *, const char *, void **, size_t *);
    4948
    5049#endif
  • uspace/lib/futil/src/futil.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    179179                                futil->cb->create_dir(futil->cb_arg, destp);
    180180                        rc = vfs_link_path(destp, KIND_DIRECTORY, NULL);
    181                         if (rc != EOK)
     181                        if (rc != EOK && rc != EEXIST)
    182182                                goto error;
    183183                        rc = futil_rcopy_contents(futil, srcp, destp);
     
    199199}
    200200
    201 /** Return file contents as a heap-allocated block of bytes.
    202  *
    203  * @param futil File utility instance
    204  * @param srcp File path
    205  * @param rdata Place to store pointer to data
    206  * @param rsize Place to store size of data
    207  *
    208  * @return EOK on success, ENOENT if failed to open file, EIO on other
    209  *         I/O error, ENOMEM if out of memory
    210  */
    211 errno_t futil_get_file(futil_t *futil, const char *srcp, void **rdata,
    212     size_t *rsize)
    213 {
    214         int sf;
    215         size_t nr;
    216         errno_t rc;
    217         size_t fsize;
    218         char *data;
    219         vfs_stat_t st;
    220 
    221         rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf);
    222         if (rc != EOK)
    223                 return ENOENT;
    224 
    225         if (vfs_stat(sf, &st) != EOK) {
    226                 vfs_put(sf);
    227                 return EIO;
    228         }
    229 
    230         fsize = st.size;
    231 
    232         data = calloc(fsize, 1);
    233         if (data == NULL) {
    234                 vfs_put(sf);
    235                 return ENOMEM;
    236         }
    237 
    238         rc = vfs_read(sf, (aoff64_t []) { 0 }, data, fsize, &nr);
    239         if (rc != EOK || nr != fsize) {
    240                 vfs_put(sf);
    241                 free(data);
    242                 return EIO;
    243         }
    244 
    245         (void) vfs_put(sf);
    246         *rdata = data;
    247         *rsize = fsize;
    248 
    249         return EOK;
    250 }
    251 
    252201/** @}
    253202 */
  • uspace/lib/posix/src/unistd.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * Copyright (c) 2011 Jiri Zarevucky
    44 * Copyright (c) 2011 Petr Koupy
     
    6060
    6161/* Array of environment variable strings (NAME=VALUE). */
    62 char **environ = NULL;
     62static char *environ_initial[] = { NULL };
     63char **environ = environ_initial;
    6364
    6465/**
  • uspace/lib/ui/meson.build

    r34832c3 rb067800  
    11#
    2 # Copyright (c) 2023 Jiri Svoboda
     2# Copyright (c) 2026 Jiri Svoboda
    33# All rights reserved.
    44#
     
    4949        'src/pbutton.c',
    5050        'src/popup.c',
     51        'src/progress.c',
    5152        'src/promptdialog.c',
    5253        'src/rbutton.c',
     
    8586        'test/popup.c',
    8687        'test/promptdialog.c',
     88        'test/progress.c',
    8789        'test/rbutton.c',
    8890        'test/resource.c',
  • uspace/lib/ui/src/wdecor.c

    r34832c3 rb067800  
    13691369        fmt.valign = gfx_valign_top;
    13701370
    1371         rc = gfx_puttext(&pbutton->rect.p0, &fmt, "[\u25a0]");
     1371        rc = gfx_puttext(&pbutton->rect.p0, &fmt, "[X]");
    13721372        if (rc != EOK)
    13731373                return rc;
  • uspace/srv/fs/cdfs/cdfs_ops.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * Copyright (c) 2011 Martin Decky
    44 * All rights reserved.
     
    341341
    342342        ht_link_t *link = hash_table_find(&nodes, &key);
    343         if (link) {
    344                 cdfs_node_t *node =
    345                     hash_table_get_inst(link, cdfs_node_t, nh_link);
    346 
    347                 *rfn = FS_NODE(node);
    348         } else
     343        if (!link) {
    349344                *rfn = NULL;
    350 
     345                return EBADF;
     346        }
     347
     348        cdfs_node_t *node = hash_table_get_inst(link, cdfs_node_t, nh_link);
     349        *rfn = FS_NODE(node);
    351350        return EOK;
    352351}
     
    395394        errno_t rc = cdfs_root_get(&rootfn, fs->service_id);
    396395
    397         assert(rc == EOK);
     396        assert(rc == EOK || rc == EBADF);
    398397
    399398        if (!rootfn)
     
    13541353                cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    13551354
    1356                 if (!node->opened) {
     1355                /* Remove closed, but root node is always in memory. */
     1356                if (!node->opened && node->index != 0) {
    13571357                        hash_table_remove_item(&nodes, item);
    13581358
  • uspace/srv/fs/exfat/exfat_ops.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * Copyright (c) 2008 Jakub Jermar
    44 * Copyright (c) 2011 Oleg Romanenko
     
    573573        if (!idxp) {
    574574                *rfn = NULL;
    575                 return EOK;
     575                return EBADF;
    576576        }
    577577        /* idxp->lock held */
  • uspace/srv/fs/fat/fat_ops.c

    r34832c3 rb067800  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * Copyright (c) 2008 Jakub Jermar
    44 * Copyright (c) 2011 Oleg Romanenko
     
    436436        if (!idxp) {
    437437                *rfn = NULL;
    438                 return EOK;
     438                return EBADF;
    439439        }
    440440        /* idxp->lock held */
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r34832c3 rb067800  
    11/*
     2 * Copyright (c) 2026 Jiri Svoboda
    23 * Copyright (c) 2008 Jakub Jermar
    34 * All rights reserved.
     
    276277        ht_link_t *lnk = hash_table_find(&nodes, &key);
    277278
    278         if (lnk) {
    279                 tmpfs_node_t *nodep;
    280                 nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link);
    281                 *rfn = FS_NODE(nodep);
    282         } else {
     279        if (lnk == NULL) {
    283280                *rfn = NULL;
    284         }
     281                return EBADF;
     282        }
     283
     284        tmpfs_node_t *nodep;
     285        nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link);
     286        *rfn = FS_NODE(nodep);
    285287        return EOK;
    286288}
     
    320322
    321323        rc = tmpfs_root_get(&rootfn, service_id);
    322         assert(rc == EOK);
    323         if (!rootfn)
     324        assert(rc == EOK || rc == EBADF);
     325        if (rootfn == NULL)
    324326                nodep->index = TMPFS_SOME_ROOT;
    325327        else
  • version

    r34832c3 rb067800  
    3030HELENOS_RELEASE = 0.14.1
    3131HELENOS_CODENAME = Aladar
    32 HELENOS_COPYRIGHT = Copyright (c) 2001-2024 HelenOS project
     32HELENOS_COPYRIGHT = Copyright (c) 2001-2026 HelenOS project
Note: See TracChangeset for help on using the changeset viewer.