source: mainline/uspace/lib/fmgt/src/newfile.c@ 1ec732a

Last change on this file since 1ec732a was 1ec732a, checked in by Jiri Svoboda <jiri@…>, 3 weeks ago

Verify file - navigator operation and command-line utility.

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/*
2 * Copyright (c) 2025 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fmgt
30 * @{
31 */
32/** @file Create new files.
33 */
34
35#include <dirent.h>
36#include <errno.h>
37#include <stdbool.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <stddef.h>
41#include <str.h>
42#include <vfs/vfs.h>
43#include <dirent.h>
44
45#include "fmgt.h"
46#include "../private/fmgt.h"
47
48#define NEWNAME_LEN 64
49
50/** Suggest file name for new file.
51 *
52 * @param fmgt File management object
53 * @param rstr Place to store pointer to newly allocated string
54 * @return EOK on success or an error code
55 */
56errno_t fmgt_new_file_suggest(char **rstr)
57{
58 errno_t rc;
59 vfs_stat_t stat;
60 unsigned u;
61 char name[NEWNAME_LEN];
62
63 u = 0;
64 while (true) {
65 snprintf(name, sizeof(name), "noname%02u.txt", u);
66 rc = vfs_stat_path(name, &stat);
67 if (rc != EOK)
68 break;
69
70 ++u;
71 }
72
73 *rstr = str_dup(name);
74 if (*rstr == NULL)
75 return ENOMEM;
76
77 return EOK;
78}
79
80/** Create new file.
81 *
82 * @param fmgt File management object
83 * @param fname File name
84 * @param fsize Size of new file (number of zero bytes to fill in)
85 * @param flags New file flags
86 * @return EOK on success or an error code
87 */
88errno_t fmgt_new_file(fmgt_t *fmgt, const char *fname, uint64_t fsize,
89 fmgt_nf_flags_t flags)
90{
91 int fd;
92 size_t nw;
93 aoff64_t pos = 0;
94 uint64_t now;
95 char *buffer;
96 fmgt_io_error_t err;
97 fmgt_error_action_t action;
98 errno_t rc;
99
100 buffer = calloc(BUFFER_SIZE, 1);
101 if (buffer == NULL)
102 return ENOMEM;
103
104 rc = vfs_lookup_open(fname, WALK_REGULAR | WALK_MUST_CREATE,
105 MODE_WRITE, &fd);
106 if (rc != EOK) {
107 free(buffer);
108 return rc;
109 }
110
111 /* Clear statistics. */
112 fmgt_progress_init(fmgt);
113 fmgt_initial_progress_update(fmgt);
114
115 /* Create sparse file? */
116 if ((flags & nf_sparse) != 0) {
117 fmgt->curf_procb = fsize - 1;
118 pos = fsize - 1;
119 }
120
121 while (fmgt->curf_procb < fsize) {
122 now = fsize - fmgt->curf_procb;
123 if (now > BUFFER_SIZE)
124 now = BUFFER_SIZE;
125
126 do {
127 rc = vfs_write(fd, &pos, buffer, now, &nw);
128 if (rc == EOK)
129 break;
130
131 /* I/O error */
132 err.fname = fname;
133 err.optype = fmgt_io_write;
134 err.rc = rc;
135 fmgt_timer_stop(fmgt);
136 action = fmgt_io_error_query(fmgt, &err);
137 fmgt_timer_start(fmgt);
138 } while (action == fmgt_er_retry);
139
140 /* Not recovered? */
141 if (rc != EOK) {
142 free(buffer);
143 vfs_put(fd);
144 fmgt_final_progress_update(fmgt);
145 return rc;
146 }
147
148 fmgt_progress_incr_bytes(fmgt, nw);
149
150 /* User requested abort? */
151 if (fmgt_abort_query(fmgt)) {
152 free(buffer);
153 vfs_put(fd);
154 fmgt_final_progress_update(fmgt);
155 return EINTR;
156 }
157 }
158
159 free(buffer);
160 vfs_put(fd);
161 fmgt_final_progress_update(fmgt);
162 return EOK;
163}
164
165/** @}
166 */
Note: See TracBrowser for help on using the repository browser.