Changeset c111da2 in mainline for uspace/app


Ignore:
Timestamp:
2025-10-09T15:44:52Z (3 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
cfd04c4
Parents:
1a96db9
Message:

Create non-zero size file in Navigator, new newfile utility.

Location:
uspace/app
Files:
7 added
10 edited

Legend:

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

    r1a96db9 rc111da2  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2008 Tim Post
    34 * All rights reserved.
     
    106107                }
    107108
    108                 capa_spec_t capa;
    109                 capa_from_blocks(de->s.size, 1, &capa);
    110                 capa_simplify(&capa);
    111 
    112                 char *rptr;
    113                 errno_t rc = capa_format(&capa, &rptr);
    114                 if (rc != EOK) {
    115                         return rc;
    116                 }
    117 
    118                 char *sep = str_rchr(rptr, ' ');
     109                char fsize[CAPA_BLOCKS_BUFSIZE];
     110                capa_blocks_format_buf(de->s.size, 1, fsize, sizeof(fsize));
     111
     112                char *sep = str_rchr(fsize, ' ');
    119113                if (sep == NULL) {
    120                         free(rptr);
    121114                        return ENOENT;
    122115                }
     
    124117                *sep = '\0';
    125118
    126                 printf("%-40s\t%*s %2s\n", de->name, width - 3, rptr, sep + 1);
    127                 free(rptr);
     119                printf("%-40s\t%*s %2s\n", de->name, width - 3, fsize, sep + 1);
    128120        } else if (de->s.is_directory)
    129121                printf("%-40s\t%*s\n", de->name, width, "<dir>");
  • uspace/app/df/df.c

    r1a96db9 rc111da2  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2013 Manuele Conti
    34 * All rights reserved.
     
    5657static bool display_blocks;
    5758
    58 static errno_t size_to_human_readable(uint64_t, size_t, char **);
    5959static void print_header(void);
    60 static errno_t print_statfs(vfs_statfs_t *, char *, char *);
     60static void print_statfs(vfs_statfs_t *, char *, char *);
    6161static void print_usage(void);
    6262
     
    6565        int optres, errflg = 0;
    6666        vfs_statfs_t st;
    67         errno_t rc;
    6867
    6968        display_blocks = false;
     
    109108        list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
    110109                if (vfs_statfs_path(mtab_ent->mp, &st) == 0) {
    111                         rc = print_statfs(&st, mtab_ent->fs_name, mtab_ent->mp);
    112                         if (rc != EOK)
    113                                 return 1;
     110                        print_statfs(&st, mtab_ent->fs_name, mtab_ent->mp);
    114111                } else {
    115112                        fprintf(stderr, "Cannot get information for '%s' (%s).\n",
     
    120117        putchar('\n');
    121118        return 0;
    122 }
    123 
    124 static errno_t size_to_human_readable(uint64_t nblocks, size_t block_size, char **rptr)
    125 {
    126         capa_spec_t capa;
    127 
    128         capa_from_blocks(nblocks, block_size, &capa);
    129         capa_simplify(&capa);
    130         return capa_format(&capa, rptr);
    131119}
    132120
     
    141129}
    142130
    143 static errno_t print_statfs(vfs_statfs_t *st, char *name, char *mountpoint)
     131static void print_statfs(vfs_statfs_t *st, char *name, char *mountpoint)
    144132{
    145133        uint64_t const used_blocks = st->f_blocks - st->f_bfree;
    146134        unsigned const perc_used = PERCENTAGE(used_blocks, st->f_blocks);
    147         char *str;
    148         errno_t rc;
     135        char str[CAPA_BLOCKS_BUFSIZE];
    149136
    150137        printf("%10s", name);
     
    152139        if (!display_blocks) {
    153140                /* Print size */
    154                 rc = size_to_human_readable(st->f_blocks, st->f_bsize, &str);
    155                 if (rc != EOK)
    156                         goto error;
     141                capa_blocks_format_buf(st->f_blocks, st->f_bsize, str,
     142                    sizeof(str));
    157143                printf(" %14s", str);
    158                 free(str);
    159144
    160145                /* Number of used blocks */
    161                 rc = size_to_human_readable(used_blocks, st->f_bsize, &str);
    162                 if (rc != EOK)
    163                         goto error;
     146                capa_blocks_format_buf(used_blocks, st->f_bsize, str,
     147                    sizeof(str));
    164148                printf(" %14s", str);
    165                 free(str);
    166149
    167150                /* Number of available blocks */
    168                 rc = size_to_human_readable(st->f_bfree, st->f_bsize, &str);
    169                 if (rc != EOK)
    170                         goto error;
     151                capa_blocks_format_buf(st->f_bfree, st->f_bsize, str,
     152                    sizeof(str));
    171153                printf(" %14s", str);
    172                 free(str);
    173154
    174155                /* Percentage of used blocks */
     
    183164                    perc_used, mountpoint);
    184165        }
    185 
    186         return EOK;
    187 error:
    188         printf("\nError: Out of memory.\n");
    189         return ENOMEM;
    190166}
    191167
  • uspace/app/meson.build

    r1a96db9 rc111da2  
    11#
     2# Copyright (c) 2025 Jiri Svoboda
    23# Copyright (c) 2019 Jiří Zárevúcky
    34# All rights reserved.
     
    6970        'nav',
    7071        'netecho',
     72        'newfile',
    7173        'nic',
    7274        'nterm',
  • uspace/app/nav/dlg/newfiledlg.c

    r1a96db9 rc111da2  
    358358
    359359        (void)window;
    360         if (dialog->cb != NULL && dialog->cb->bcancel != NULL) {
     360        if (dialog->cb != NULL && dialog->cb->close != NULL) {
    361361                dialog->cb->close(dialog, dialog->arg);
    362362        }
     
    373373{
    374374        new_file_dlg_t *dialog = (new_file_dlg_t *) arg;
    375         const char *text;
     375        const char *fname;
     376        const char *fsize;
    376377
    377378        if (event->type == KEY_PRESS &&
     
    380381                        /* Confirm */
    381382                        if (dialog->cb != NULL && dialog->cb->bok != NULL) {
    382                                 text = ui_entry_get_text(dialog->ename);
    383                                 dialog->cb->bok(dialog, dialog->arg, text);
     383                                fname = ui_entry_get_text(dialog->ename);
     384                                fsize = ui_entry_get_text(dialog->esize);
     385                                dialog->cb->bok(dialog, dialog->arg, fname,
     386                                    fsize);
    384387                                return;
    385388                        }
     
    404407{
    405408        new_file_dlg_t *dialog = (new_file_dlg_t *) arg;
    406         const char *text;
     409        const char *fname;
     410        const char *fsize;
    407411
    408412        if (dialog->cb != NULL && dialog->cb->bok != NULL) {
    409                 text = ui_entry_get_text(dialog->ename);
    410                 dialog->cb->bok(dialog, dialog->arg, text);
     413                fname = ui_entry_get_text(dialog->ename);
     414                fsize = ui_entry_get_text(dialog->esize);
     415                dialog->cb->bok(dialog, dialog->arg, fname, fsize);
    411416        }
    412417}
  • uspace/app/nav/meson.build

    r1a96db9 rc111da2  
    3030src = files(
    3131        'dlg/newfiledlg.c',
     32        'dlg/progress.c',
    3233        'main.c',
    3334        'menu.c',
     
    3940test_src = files(
    4041        'dlg/newfiledlg.c',
     42        'dlg/progress.c',
    4143        'menu.c',
    4244        'nav.c',
  • uspace/app/nav/nav.c

    r1a96db9 rc111da2  
    3535 */
    3636
     37#include <fibril.h>
    3738#include <gfx/coord.h>
    3839#include <stdio.h>
     
    535536}
    536537
     538/** Wrapper fibril function for worker function.
     539 *
     540 * This is the main fibril function for the worker fibril. It executes
     541 * the worker function, then clears worker FID to indicate the worker
     542 * is finished.
     543 *
     544 * @param arg Argument (navigator_worker_job_t *)
     545 * @return EOK
     546 */
     547static errno_t navigator_worker_func(void *arg)
     548{
     549        navigator_worker_job_t *job = (navigator_worker_job_t *)arg;
     550
     551        job->wfunc(job->arg);
     552        job->navigator->worker_fid = 0;
     553        free(job);
     554        return EOK;
     555}
     556
     557/** Start long-time work in a worker fibril.
     558 *
     559 * Actions which can take time (file operations) cannot block the main UI
     560 * fibril. This function will start an action in the worker fibril, i.e.,
     561 * in the background. At the same time the caller should create a modal
     562 * progress dialog that will be shown until the work is completed.
     563 *
     564 * (Only a single worker can execute at any given time).
     565 *
     566 * @param nav Navigator
     567 * @param wfunc Worker main function
     568 * @param arg Argument to worker function
     569 *
     570 * @return EOK on success or an error code
     571 */
     572errno_t navigator_worker_start(navigator_t *nav, void (*wfunc)(void *),
     573    void *arg)
     574{
     575        navigator_worker_job_t *job;
     576
     577        if (nav->worker_fid != 0)
     578                return EBUSY;
     579
     580        job = calloc(1, sizeof(navigator_worker_job_t));
     581        if (job == NULL)
     582                return ENOMEM;
     583
     584        job->navigator = nav;
     585        job->wfunc = wfunc;
     586        job->arg = arg;
     587
     588        nav->worker_fid = fibril_create(navigator_worker_func, (void *)job);
     589        if (nav->worker_fid == 0) {
     590                free(job);
     591                return ENOMEM;
     592        }
     593
     594        fibril_add_ready(nav->worker_fid);
     595        return EOK;
     596}
     597
    537598/** @}
    538599 */
  • uspace/app/nav/nav.h

    r1a96db9 rc111da2  
    4747extern void navigator_switch_panel(navigator_t *);
    4848extern void navigator_refresh_panels(navigator_t *);
     49extern errno_t navigator_worker_start(navigator_t *, void (*)(void *),
     50    void *);
    4951
    5052#endif
  • uspace/app/nav/newfile.c

    r1a96db9 rc111da2  
    3434 */
    3535
     36#include <capa.h>
     37#include <fmgt.h>
    3638#include <stdlib.h>
    3739#include <str_error.h>
     
    4244#include <ui/ui.h>
    4345#include <ui/window.h>
     46#include <str.h>
    4447#include "dlg/newfiledlg.h"
     48#include "dlg/progress.h"
    4549#include "menu.h"
    4650#include "newfile.h"
    4751#include "nav.h"
    48 
    49 static void new_file_bok(new_file_dlg_t *, void *, const char *);
     52#include "types/newfile.h"
     53
     54static void new_file_bok(new_file_dlg_t *, void *, const char *, const char *);
    5055static void new_file_bcancel(new_file_dlg_t *, void *);
    5156static void new_file_close(new_file_dlg_t *, void *);
     
    5762};
    5863
     64static void new_file_progress(void *, fmgt_progress_t *);
     65
     66static fmgt_cb_t new_file_fmgt_cb = {
     67        .progress = new_file_progress
     68};
     69
    5970/** Open New File dialog.
    6071 *
     
    6980}
    7081
     82/** New file worker function.
     83 *
     84 * @param arg Argument (navigator_new_file_job_t)
     85 */
     86static void new_file_wfunc(void *arg)
     87{
     88        fmgt_t *fmgt = NULL;
     89        navigator_new_file_job_t *job = (navigator_new_file_job_t *)arg;
     90        char *msg = NULL;
     91        navigator_t *nav = job->navigator;
     92        ui_msg_dialog_t *dialog = NULL;
     93        ui_msg_dialog_params_t params;
     94        errno_t rc;
     95        int rv;
     96
     97        rc = fmgt_create(&fmgt);
     98        if (rc != EOK) {
     99                /* out of memory */
     100                return;
     101        }
     102
     103        fmgt_set_cb(fmgt, &new_file_fmgt_cb, (void *)nav);
     104        fmgt_set_init_update(fmgt, true);
     105
     106        rc = fmgt_new_file(fmgt, job->fname, job->nbytes);
     107        if (rc != EOK) {
     108                rv = asprintf(&msg, "Error creating file (%s).",
     109                    str_error(rc));
     110                if (rv < 0)
     111                        return;
     112                goto error;
     113        }
     114
     115        fmgt_destroy(fmgt);
     116        ui_lock(nav->ui);
     117        progress_dlg_destroy(nav->progress_dlg);
     118        navigator_refresh_panels(nav);
     119        ui_unlock(nav->ui);
     120        free(job);
     121        return;
     122error:
     123        ui_lock(nav->ui);
     124        progress_dlg_destroy(nav->progress_dlg);
     125        ui_msg_dialog_params_init(&params);
     126        params.caption = "Error";
     127        params.text = msg;
     128        (void) ui_msg_dialog_create(nav->ui, &params, &dialog);
     129        ui_unlock(nav->ui);
     130        free(msg);
     131}
     132
    71133/** New file dialog confirmed.
    72134 *
     
    74136 * @param arg Argument (navigator_t *)
    75137 * @param fname New file name
    76  */
    77 static void new_file_bok(new_file_dlg_t *dlg, void *arg, const char *fname)
     138 * @param fsize New file size
     139 */
     140static void new_file_bok(new_file_dlg_t *dlg, void *arg, const char *fname,
     141    const char *fsize)
    78142{
    79143        navigator_t *nav = (navigator_t *)arg;
    80144        ui_msg_dialog_t *dialog = NULL;
     145        navigator_new_file_job_t *job;
    81146        ui_msg_dialog_params_t params;
     147        progress_dlg_params_t pd_params;
     148        capa_spec_t fcap;
    82149        char *msg = NULL;
     150        errno_t rc;
     151        uint64_t nbytes;
    83152        int rv;
    84         FILE *f;
     153
     154        rc = capa_parse(fsize, &fcap);
     155        if (rc != EOK) {
     156                /* invalid file size */
     157                return;
     158        }
    85159
    86160        new_file_dlg_destroy(dlg);
    87         f = fopen(fname, "wx");
    88         if (f == NULL) {
    89                 rv = asprintf(&msg, "Error creating file (%s).",
    90                     str_error(errno));
     161
     162        rc = capa_to_blocks(&fcap, cv_nom, 1, &nbytes);
     163        if (rc != EOK) {
     164                rv = asprintf(&msg, "File size too large (%s).", fsize);
    91165                if (rv < 0)
    92166                        return;
    93 
    94                 ui_msg_dialog_params_init(&params);
    95                 params.caption = "Error";
    96                 params.text = msg;
    97                 (void) ui_msg_dialog_create(nav->ui, &params, &dialog);
    98                 free(msg);
     167                goto error;
     168        }
     169
     170        job = calloc(1, sizeof(navigator_new_file_job_t));
     171        if (job == NULL)
    99172                return;
    100         }
    101 
    102         fclose(f);
    103         navigator_refresh_panels(nav);
     173
     174        job->navigator = nav;
     175        job->fname = fname;
     176        job->nbytes = nbytes;
     177
     178        progress_dlg_params_init(&pd_params);
     179        pd_params.caption = "Creating new file";
     180
     181        rc = progress_dlg_create(nav->ui, &pd_params, &nav->progress_dlg);
     182        if (rc != EOK) {
     183                msg = str_dup("Out of memory.");
     184                if (msg == NULL)
     185                        return;
     186                goto error;
     187        }
     188
     189        rc = navigator_worker_start(nav, new_file_wfunc, (void *)job);
     190        if (rc != EOK) {
     191                msg = str_dup("Out of memory.");
     192                if (msg == NULL)
     193                        return;
     194                goto error;
     195        }
     196
     197        return;
     198error:
     199        ui_msg_dialog_params_init(&params);
     200        params.caption = "Error";
     201        params.text = msg;
     202        (void) ui_msg_dialog_create(nav->ui, &params, &dialog);
     203        free(msg);
    104204}
    105205
     
    126226}
    127227
     228/** New file progress update.
     229 *
     230 * @param arg Argument (navigator_t *)
     231 * @param progress Progress update
     232 */
     233static void new_file_progress(void *arg, fmgt_progress_t *progress)
     234{
     235        navigator_t *nav = (navigator_t *)arg;
     236        char buf[128];
     237
     238        snprintf(buf, sizeof(buf), "Written %s of %s (%s done).",
     239            progress->curf_procb, progress->curf_totalb,
     240            progress->curf_percent);
     241        progress_dlg_set_curf_prog(nav->progress_dlg, buf);
     242}
     243
    128244/** @}
    129245 */
  • uspace/app/nav/types/dlg/newfiledlg.h

    r1a96db9 rc111da2  
    6060} new_file_dlg_t;
    6161
    62 /** Prompt dialog callback */
     62/** New File dialog callbacks */
    6363typedef struct new_file_dlg_cb {
    6464        /** OK button was pressed */
    65         void (*bok)(new_file_dlg_t *, void *, const char *);
     65        void (*bok)(new_file_dlg_t *, void *, const char *, const char *);
    6666        /** Cancel button was pressed */
    6767        void (*bcancel)(new_file_dlg_t *, void *);
  • uspace/app/nav/types/nav.h

    r1a96db9 rc111da2  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3737#define TYPES_NAV_H
    3838
     39#include <fibril.h>
    3940#include <ui/fixed.h>
    4041#include <ui/ui.h>
     
    5758        /** Panels */
    5859        struct panel *panel[navigator_panels];
     60        /** Progress dialog */
     61        struct progress_dlg *progress_dlg;
     62        /** Worker fibril ID */
     63        fid_t worker_fid;
    5964} navigator_t;
     65
     66/** Navigator worker job */
     67typedef struct {
     68        /** Navigator */
     69        navigator_t *navigator;
     70        /** Worker function */
     71        void (*wfunc)(void *);
     72        /** Worker argument */
     73        void *arg;
     74} navigator_worker_job_t;
    6075
    6176#endif
Note: See TracChangeset for help on using the changeset viewer.