Changeset 5df2570 in mainline


Ignore:
Timestamp:
2026-04-14T21:44:17Z (5 weeks ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, topic/fix-logger-deadlock
Children:
3272be1, e2b47b3c
Parents:
417cc85
Message:

Switch installer from futil to fmgt.

Location:
uspace
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sysinst/meson.build

    r417cc85 r5df2570  
    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

    r417cc85 r5df2570  
    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>
     
    9191#define CD_MOUNT_POINT "/vol/" CD_VOL_LABEL
    9292
    93 #define BOOT_FILES_SRC CD_MOUNT_POINT
     93#define BOOT_FILES_SRC CD_MOUNT_POINT "/boot"
    9494#define BOOT_BLOCK_IDX 0 /* MBR */
    9595
    9696#define CFG_FILES_SRC "/cfg"
    97 #define CFG_FILES_DEST MOUNT_POINT "/cfg"
     97#define CFG_FILES_DEST MOUNT_POINT
    9898
    9999static const char *default_devs[] = {
     
    163163static errno_t sysinst_restart(sysinst_t *);
    164164static void sysinst_progress_destroy(sysinst_progress_t *);
     165static void sysinst_progress(sysinst_t *, const char *);
    165166static void sysinst_action(sysinst_t *, const char *);
    166167static void sysinst_error(sysinst_t *, const char *);
    167168static void sysinst_debug(sysinst_t *, const char *);
    168169
    169 static void sysinst_futil_copy_file(void *, const char *, const char *);
    170 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 *);
    171174static errno_t sysinst_eject_dev(sysinst_t *, service_id_t);
    172175static errno_t sysinst_eject_phys_by_mp(sysinst_t *, const char *);
    173176static errno_t sysinst_upgrade_confirm_create(sysinst_t *);
    174177
    175 static futil_cb_t sysinst_futil_cb = {
    176         .copy_file = sysinst_futil_copy_file,
    177         .create_dir = sysinst_futil_create_dir
     178static fmgt_cb_t sysinst_fmgt_cb = {
     179        .exists_query = sysinst_fmgt_exists_query,
     180        .action = sysinst_fmgt_action,
     181        .progress = sysinst_fmgt_progress
    178182};
    179183
     
    410414}
    411415
    412 /** 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        (void)sysinst;
     426        (void)exists->fname;
     427        // XXX Do not overwrite configuration files.
     428        return fmgt_exr_overwrite;
     429}
     430
     431/** Called when fmgt is starting to perform action on a file.
     432 *
     433 * @param arg Argument (sysinst_t *)
     434 * @param action Action being performed
     435 * @param src Source or only path
     436 * @param dest Destination path or @c NULL
     437 */
     438static void sysinst_fmgt_action(void *arg, fmgt_action_t action,
     439    const char *src, const char *dest)
     440{
     441        sysinst_t *sysinst = (sysinst_t *)arg;
     442        char buf[128];
     443
     444        (void)src;
     445
     446        switch (action) {
     447        case fmgt_ac_create:
     448                snprintf(buf, sizeof(buf), "Creating %s.", src);
     449                sysinst_action(sysinst, buf);
     450                break;
     451        case fmgt_ac_copy:
     452                snprintf(buf, sizeof(buf), "Copying %s.", dest);
     453                sysinst_action(sysinst, buf);
     454                break;
     455        default:
     456                break;
     457        }
     458}
     459
     460/** Called by fmgt to update on progress.
    413461 *
    414462 * @param arg Argument (sysinst_t *)
     
    416464 * @param dest Destination path
    417465 */
    418 static void sysinst_futil_copy_file(void *arg, const char *src,
    419     const char *dest)
     466static void sysinst_fmgt_progress(void *arg, fmgt_progress_t *progress)
    420467{
    421468        sysinst_t *sysinst = (sysinst_t *)arg;
    422469        char buf[128];
    423470
    424         (void)src;
    425         snprintf(buf, sizeof(buf), "Copying %s.", dest);
    426         sysinst_action(sysinst, buf);
    427 }
    428 
    429 /** Called when futil is about to create a directory.
    430  *
    431  * @param arg Argument (sysinst_t *)
    432  * @param dest Destination path
    433  */
    434 static void sysinst_futil_create_dir(void *arg, const char *dest)
    435 {
    436         sysinst_t *sysinst = (sysinst_t *)arg;
    437         char buf[128];
    438 
    439         snprintf(buf, sizeof(buf), "Creating %s.", dest);
    440         sysinst_action(sysinst, buf);
     471        snprintf(buf, sizeof(buf), "Copied %s files, %s; "
     472            "current file: %s done.", progress->total_procf,
     473            progress->total_procb, progress->curf_percent);
     474        sysinst_progress(sysinst, buf);
    441475}
    442476
     
    769803        char *path = NULL;
    770804        const char **cp;
     805        fmgt_flist_t *flist = NULL;
    771806        int rv;
    772807
     
    794829
    795830        /* Copy initial configuration files */
    796         rc = futil_rcopy_contents(sysinst->futil, CFG_FILES_SRC,
    797             CFG_FILES_DEST);
     831
     832        log_msg(LOG_DEFAULT, LVL_NOTE,
     833            "sysinst_copy_boot_files(): copy initial configuration files");
     834
     835        rc = fmgt_flist_create(&flist);
     836        if (rc != EOK)
     837                goto error;
     838
     839        rc = fmgt_flist_append(flist, CFG_FILES_SRC);
     840        if (rc != EOK)
     841                goto error;
     842
     843        rc = fmgt_copy(sysinst->fmgt, flist, CFG_FILES_DEST);
    798844        if (rc != EOK) {
    799845                sysinst_error(sysinst, "Error copying initial configuration "
    800846                    "files.");
    801                 return rc;
    802         }
    803 
     847                goto error;
     848        }
     849
     850        fmgt_flist_destroy(flist);
     851        log_msg(LOG_DEFAULT, LVL_NOTE,
     852            "sysinst_copy_boot_files(): copy initial configuration files OK");
    804853        return EOK;
    805854error:
     855        if (flist != NULL)
     856                fmgt_flist_destroy(flist);
    806857        if (path != NULL)
    807858                free(path);
     
    815866static errno_t sysinst_copy_boot_files(sysinst_t *sysinst)
    816867{
     868        fmgt_flist_t *flist = NULL;
    817869        errno_t rc;
    818870
    819871        log_msg(LOG_DEFAULT, LVL_NOTE,
    820872            "sysinst_copy_boot_files(): copy bootloader files");
    821         rc = futil_rcopy_contents(sysinst->futil, BOOT_FILES_SRC, MOUNT_POINT);
     873        rc = fmgt_flist_create(&flist);
     874        if (rc != EOK)
     875                goto error;
     876
     877        rc = fmgt_flist_append(flist, BOOT_FILES_SRC);
     878        if (rc != EOK)
     879                goto error;
     880
     881        rc = fmgt_copy(sysinst->fmgt, flist, MOUNT_POINT);
    822882        if (rc != EOK) {
    823883                sysinst_error(sysinst, "Error copying bootloader "
    824884                    "files.");
    825                 return rc;
    826         }
    827 
     885                goto error;
     886        }
     887
     888        fmgt_flist_destroy(flist);
    828889        sysinst_debug(sysinst, "sysinst_copy_boot_files(): OK");
    829890        return EOK;
     891error:
     892        if (flist != NULL)
     893                fmgt_flist_destroy(flist);
     894        return rc;
    830895}
    831896
     
    9411006}
    9421007
     1008/** Return file contents as a heap-allocated block of bytes.
     1009 *
     1010 * @param srcp File path
     1011 * @param rdata Place to store pointer to data
     1012 * @param rsize Place to store size of data
     1013 *
     1014 * @return EOK on success, ENOENT if failed to open file, EIO on other
     1015 *         I/O error, ENOMEM if out of memory
     1016 */
     1017static errno_t sysinst_get_file(const char *srcp, void **rdata, size_t *rsize)
     1018{
     1019        int sf;
     1020        size_t nr;
     1021        errno_t rc;
     1022        size_t fsize;
     1023        char *data;
     1024        vfs_stat_t st;
     1025
     1026        rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf);
     1027        if (rc != EOK)
     1028                return ENOENT;
     1029
     1030        if (vfs_stat(sf, &st) != EOK) {
     1031                vfs_put(sf);
     1032                return EIO;
     1033        }
     1034
     1035        fsize = st.size;
     1036
     1037        data = calloc(fsize, 1);
     1038        if (data == NULL) {
     1039                vfs_put(sf);
     1040                return ENOMEM;
     1041        }
     1042
     1043        rc = vfs_read(sf, (aoff64_t []) { 0 }, data, fsize, &nr);
     1044        if (rc != EOK || nr != fsize) {
     1045                vfs_put(sf);
     1046                free(data);
     1047                return EIO;
     1048        }
     1049
     1050        (void) vfs_put(sf);
     1051        *rdata = data;
     1052        *rsize = fsize;
     1053
     1054        return EOK;
     1055}
     1056
    9431057/** Copy boot blocks.
    9441058 *
     
    9661080            "sysinst_copy_boot_blocks: Read boot block image.");
    9671081
    968         rc = futil_get_file(sysinst->futil,
    969             BOOT_FILES_SRC "/boot/grub/i386-pc/boot.img",
     1082        rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/boot.img",
    9701083            &boot_img, &boot_img_size);
    971         if (rc != EOK || boot_img_size != 512)
     1084        if (rc != EOK || boot_img_size != 512) {
     1085                sysinst_error(sysinst, "Error reading boot block image.");
    9721086                return EIO;
     1087        }
    9731088
    9741089        log_msg(LOG_DEFAULT, LVL_NOTE,
    9751090            "sysinst_copy_boot_blocks: Read GRUB core image.");
    9761091
    977         rc = futil_get_file(sysinst->futil,
    978             BOOT_FILES_SRC "/boot/grub/i386-pc/core.img",
     1092        rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/core.img",
    9791093            &core_img, &core_img_size);
    980         if (rc != EOK)
     1094        if (rc != EOK) {
     1095                sysinst_error(sysinst, "Error reading GRUB core image.");
    9811096                return EIO;
     1097        }
    9821098
    9831099        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    9921108
    9931109        rc = block_init(sid);
    994         if (rc != EOK)
     1110        if (rc != EOK) {
     1111                sysinst_error(sysinst, "Error opening block device.");
    9951112                return rc;
     1113        }
    9961114
    9971115        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    9991117
    10001118        rc = block_get_bsize(sid, &bsize);
    1001         if (rc != EOK)
     1119        if (rc != EOK) {
     1120                sysinst_error(sysinst, "Error getting block size.");
    10021121                return rc;
     1122        }
    10031123
    10041124        if (bsize != 512) {
     
    10111131
    10121132        rc = block_read_direct(sid, BOOT_BLOCK_IDX, 1, bbuf);
    1013         if (rc != EOK)
     1133        if (rc != EOK) {
     1134                sysinst_error(sysinst, "Error reading boot block.");
    10141135                return EIO;
     1136        }
    10151137
    10161138        core_start = 16;
     
    10431165
    10441166        rc = block_write_direct(sid, BOOT_BLOCK_IDX, 1, bbuf);
    1045         if (rc != EOK)
     1167        if (rc != EOK) {
     1168                sysinst_error(sysinst, "Error writing boot block.");
    10461169                return EIO;
     1170        }
    10471171
    10481172        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    10511175        /* XXX Must pad last block with zeros */
    10521176        rc = block_write_direct(sid, core_start, core_blocks, core_img);
    1053         if (rc != EOK)
     1177        if (rc != EOK) {
     1178                sysinst_error(sysinst, "Error writing GRUB core blocks.");
    10541179                return EIO;
     1180        }
    10551181
    10561182        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    13241450                params.rect.p0.y = 0;
    13251451                params.rect.p1.x = 64;
    1326                 params.rect.p1.y = 5;
     1452                params.rect.p1.y = 7;
    13271453        } else {
    13281454                params.rect.p0.x = 0;
    13291455                params.rect.p0.y = 0;
    13301456                params.rect.p1.x = 500;
    1331                 params.rect.p1.y = 60;
     1457                params.rect.p1.y = 90;
    13321458        }
    13331459
     
    13551481        }
    13561482
     1483        /* Installing/upgrading system line */
    13571484        rc = ui_label_create(ui_res, "Installing system. Please wait...",
    13581485            &progress->label);
     
    13871514        }
    13881515
     1516        /* Action line */
    13891517        rc = ui_label_create(ui_res, "",
    13901518            &progress->action);
     
    13981526                rect.p0.y = 3;
    13991527                rect.p1.x = arect.p1.x;
     1528                rect.p1.y = 4;
     1529        } else {
     1530                rect.p0.x = arect.p0.x;
     1531                rect.p0.y = 40;
     1532                rect.p1.x = arect.p1.x;
     1533                rect.p1.y = 60;
     1534        }
     1535        ui_label_set_rect(progress->action, &rect);
     1536        ui_label_set_halign(progress->action, gfx_halign_center);
     1537        ui_label_set_valign(progress->action, gfx_valign_top);
     1538
     1539        rc = ui_fixed_add(fixed, ui_label_ctl(progress->action));
     1540        if (rc != EOK) {
     1541                sysinst_error(sysinst, "Error adding control to layout.");
     1542                ui_label_destroy(progress->label);
     1543                progress->label = NULL;
     1544                goto error;
     1545        }
     1546
     1547        /* Progress line */
     1548        rc = ui_label_create(ui_res, "",
     1549            &progress->progress);
     1550        if (rc != EOK) {
     1551                sysinst_error(sysinst, "Error creating label.");
     1552                goto error;
     1553        }
     1554
     1555        if (ui_is_textmode(sysinst->ui)) {
     1556                rect.p0.x = arect.p0.x;
     1557                rect.p0.y = 5;
     1558                rect.p1.x = arect.p1.x;
    14001559                rect.p1.y = arect.p1.y;
    14011560        } else {
    14021561                rect.p0.x = arect.p0.x;
    1403                 rect.p0.y = 30;
     1562                rect.p0.y = 70;
    14041563                rect.p1.x = arect.p1.x;
    14051564                rect.p1.y = arect.p1.y;
    14061565        }
    1407         ui_label_set_rect(progress->action, &rect);
    1408         ui_label_set_halign(progress->action, gfx_halign_center);
    1409         ui_label_set_valign(progress->action, gfx_valign_center);
    1410 
    1411         rc = ui_fixed_add(fixed, ui_label_ctl(progress->action));
     1566        ui_label_set_rect(progress->progress, &rect);
     1567        ui_label_set_halign(progress->progress, gfx_halign_center);
     1568        ui_label_set_valign(progress->progress, gfx_valign_top);
     1569
     1570        rc = ui_fixed_add(fixed, ui_label_ctl(progress->progress));
    14121571        if (rc != EOK) {
    14131572                sysinst_error(sysinst, "Error adding control to layout.");
     
    14551614}
    14561615
     1616/** Set current progress message.
     1617 *
     1618 * @param sysinst System installer
     1619 * @param progress Progress text
     1620 */
     1621static void sysinst_progress(sysinst_t *sysinst, const char *progress)
     1622{
     1623        log_msg(LOG_DEFAULT, LVL_NOTE, "%s", progress);
     1624
     1625        if (sysinst->progress == NULL)
     1626                return;
     1627
     1628        ui_label_set_text(sysinst->progress->progress, progress);
     1629        ui_label_paint(sysinst->progress->progress);
     1630}
     1631
    14571632/** Set current action message.
    14581633 *
     
    16161791        fibril_mutex_initialize(&sysinst->responded_lock);
    16171792
    1618         rc = futil_create(&sysinst_futil_cb, (void *)sysinst, &sysinst->futil);
     1793        rc = fmgt_create(&sysinst->fmgt);
    16191794        if (rc != EOK) {
    16201795                printf("Out of memory.\n");
    16211796                goto error;
    16221797        }
     1798
     1799        fmgt_set_cb(sysinst->fmgt, &sysinst_fmgt_cb, (void *)sysinst);
     1800        fmgt_set_init_update(sysinst->fmgt, true);
    16231801
    16241802        rc = ui_create(display_spec, &ui);
     
    16811859        return EOK;
    16821860error:
    1683         if (sysinst->futil != NULL)
    1684                 futil_destroy(sysinst->futil);
     1861        if (sysinst->fmgt != NULL)
     1862                fmgt_destroy(sysinst->fmgt);
    16851863        if (sysinst->system != NULL)
    16861864                system_close(sysinst->system);
  • uspace/app/sysinst/sysinst.h

    r417cc85 r5df2570  
    3838
    3939#include <fibril_synch.h>
    40 #include <futil.h>
     40#include <fmgt.h>
    4141#include <gfx/color.h>
    4242#include <loc.h>
     
    5454        ui_label_t *label;
    5555        ui_label_t *action;
     56        ui_label_t *progress;
    5657} sysinst_progress_t;
    5758
     
    7576        /** operation being performed */
    7677        sysinst_oper_t oper;
    77         futil_t *futil;
     78        fmgt_t *fmgt;
    7879        /** @c true after user responds to interactive query. */
    7980        bool responded;
  • uspace/lib/fmgt/include/types/fmgt.h

    r417cc85 r5df2570  
    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

    r417cc85 r5df2570  
    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

    r417cc85 r5df2570  
    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);
  • uspace/lib/fmgt/src/delete.c

    r417cc85 r5df2570  
    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}
  • uspace/lib/fmgt/src/fmgt.c

    r417cc85 r5df2570  
    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

    r417cc85 r5df2570  
    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}
  • uspace/lib/fmgt/src/newdir.c

    r417cc85 r5df2570  
    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

    r417cc85 r5df2570  
    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)
  • uspace/lib/fmgt/src/rename.c

    r417cc85 r5df2570  
    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

    r417cc85 r5df2570  
    6868
    6969        (void)unused;
     70        fmgt_report_action(fmgt, fmgt_ac_verify, fname, NULL);
    7071
    7172        buffer = calloc(BUFFER_SIZE, 1);
  • uspace/lib/futil/include/futil.h

    r417cc85 r5df2570  
    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

    r417cc85 r5df2570  
    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 */
Note: See TracChangeset for help on using the changeset viewer.