Changeset 857fba8 in mainline for uspace/lib/fmgt/src
- Timestamp:
- 2026-02-10T19:35:01Z (15 hours ago)
- Branches:
- master
- Parents:
- 0ce9eb8
- Location:
- uspace/lib/fmgt/src
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/fmgt/src/copy.c
r0ce9eb8 r857fba8 41 41 #include "fmgt/walk.h" 42 42 #include "../private/fmgt.h" 43 #include "../private/fsops.h" 43 44 44 45 static errno_t fmgt_copy_dir_enter(void *, const char *, const char *); … … 49 50 .file = fmgt_copy_file 50 51 }; 51 52 /** Open file.53 *54 * @param fmgt File management object55 * @param fname File name56 * @param rfd Place to store file descriptor57 * @return EOK on success or an error code58 */59 static errno_t fmgt_open(fmgt_t *fmgt, const char *fname, int *rfd)60 {61 fmgt_io_error_t err;62 fmgt_error_action_t action;63 errno_t rc;64 65 do {66 rc = vfs_lookup_open(fname, WALK_REGULAR, MODE_READ, rfd);67 if (rc == EOK)68 break;69 70 /* I/O error */71 err.fname = fname;72 err.optype = fmgt_io_open;73 err.rc = rc;74 fmgt_timer_stop(fmgt);75 action = fmgt_io_error_query(fmgt, &err);76 fmgt_timer_start(fmgt);77 } while (action == fmgt_er_retry);78 79 return rc;80 }81 82 /** Create file.83 *84 * @param fmgt File management object85 * @param fname Destination file name86 * @param rfd Place to store file descriptor87 * @param rskip If @c true, skip existing file and continue88 * @return EOK on success or an error code89 */90 static errno_t fmgt_create_file(fmgt_t *fmgt, const char *fname, int *rfd,91 bool *rskip)92 {93 fmgt_io_error_t err;94 fmgt_error_action_t action;95 fmgt_exists_t exists;96 fmgt_exists_action_t exaction;97 bool may_overwrite = false;98 unsigned flags;99 errno_t rc;100 101 *rskip = false;102 103 do {104 flags = WALK_REGULAR | (may_overwrite ? WALK_MAY_CREATE :105 WALK_MUST_CREATE);106 rc = vfs_lookup_open(fname, flags, MODE_WRITE, rfd);107 if (rc == EOK)108 break;109 110 if (rc == EEXIST) {111 /* File exists */112 exists.fname = fname;113 fmgt_timer_stop(fmgt);114 exaction = fmgt_exists_query(fmgt, &exists);115 fmgt_timer_start(fmgt);116 117 if (exaction == fmgt_exr_skip)118 *rskip = true;119 if (exaction != fmgt_exr_overwrite)120 break;121 122 may_overwrite = true;123 } else {124 /* I/O error */125 err.fname = fname;126 err.optype = fmgt_io_create;127 err.rc = rc;128 fmgt_timer_stop(fmgt);129 action = fmgt_io_error_query(fmgt, &err);130 fmgt_timer_start(fmgt);131 132 if (action != fmgt_er_retry)133 break;134 }135 } while (true);136 137 return rc;138 }139 140 /** Create directory.141 *142 * @param fmgt File management object143 * @param dname Directory name144 * @return EOK on success or an error code145 */146 static errno_t fmgt_create_dir(fmgt_t *fmgt, const char *dname)147 {148 fmgt_io_error_t err;149 fmgt_error_action_t action;150 errno_t rc;151 152 do {153 rc = vfs_link_path(dname, KIND_DIRECTORY, NULL);154 155 /* It is okay if the directory exists. */156 if (rc == EOK || rc == EEXIST)157 break;158 159 /* I/O error */160 err.fname = dname;161 err.optype = fmgt_io_create;162 err.rc = rc;163 164 fmgt_timer_stop(fmgt);165 action = fmgt_io_error_query(fmgt, &err);166 fmgt_timer_start(fmgt);167 } while (action == fmgt_er_retry);168 169 if (rc == EEXIST)170 return EOK;171 172 return rc;173 }174 175 /** Read data from file.176 *177 * @param fmgt File management object178 * @param fd File descriptor179 * @param fname File name (for printing diagnostics)180 * @param pos Pointer to current position (will be updated)181 * @param buffer Data buffer182 * @param nbytes Number of bytes to read183 * @param nr Place to store number of bytes read184 * @return EOK on success or an error code185 */186 static errno_t fmgt_read(fmgt_t *fmgt, int fd, const char *fname,187 aoff64_t *pos, void *buffer, size_t nbytes, size_t *nr)188 {189 char *bp = (char *)buffer;190 fmgt_io_error_t err;191 fmgt_error_action_t action;192 errno_t rc;193 194 do {195 rc = vfs_read(fd, pos, bp, nbytes, nr);196 if (rc == EOK)197 break;198 199 /* I/O error */200 err.fname = fname;201 err.optype = fmgt_io_read;202 err.rc = rc;203 fmgt_timer_stop(fmgt);204 action = fmgt_io_error_query(fmgt, &err);205 fmgt_timer_start(fmgt);206 } while (action == fmgt_er_retry);207 208 /* Not recovered? */209 if (rc != EOK)210 return rc;211 212 return EOK;213 }214 215 /** Write data to file.216 *217 * @param fmgt File management object218 * @param fd File descriptor219 * @param fname File name (for printing diagnostics)220 * @param pos Pointer to current position (will be updated)221 * @param buffer Pointer to data222 * @param nbytes Number of bytes to write223 * @return EOK on success or an error code224 */225 static errno_t fmgt_write(fmgt_t *fmgt, int fd, const char *fname,226 aoff64_t *pos, void *buffer, size_t nbytes)227 {228 size_t total_written;229 char *bp = (char *)buffer;230 fmgt_io_error_t err;231 fmgt_error_action_t action;232 size_t nw;233 errno_t rc;234 235 total_written = 0;236 while (total_written < nbytes) {237 do {238 rc = vfs_write(fd, pos, bp + total_written,239 nbytes - total_written, &nw);240 if (rc == EOK)241 break;242 243 /* I/O error */244 err.fname = fname;245 err.optype = fmgt_io_write;246 err.rc = rc;247 fmgt_timer_stop(fmgt);248 action = fmgt_io_error_query(fmgt, &err);249 fmgt_timer_start(fmgt);250 } while (action == fmgt_er_retry);251 252 /* Not recovered? */253 if (rc != EOK)254 return rc;255 256 total_written += nw;257 }258 259 return EOK;260 }261 52 262 53 /** Copy operation - enter directory.
Note:
See TracChangeset
for help on using the changeset viewer.
