Mstdlib-1.24.0
m_fs.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_FS_H__
25#define __M_FS_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31#include <mstdlib/base/m_list_str.h>
32#include <mstdlib/base/m_time.h>
33
34/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
35
36__BEGIN_DECLS
37
38/*! \defgroup m_fs File System
39 * \ingroup mstdlib_base
40 *
41 * File sytem routines.
42 *
43 * Example (check if a file exists):
44 *
45 * \code{.c}
46 * if (M_fs_perms_can_access("/file.txt", 0) == M_FS_ERROR_SUCCESS) {
47 * M_printf("path exists\n");
48 * } else {
49 * M_printf("path does not exist\n");
50 * }
51 * \endcode
52 *
53 * Example (information about a file or directory):
54 *
55 * \code{.c}
56 * M_fs_info_t *info = NULL;
57 *
58 * if (M_fs_info(&info, "/file.txt", M_FS_PATH_INFO_FLAGS_BASIC) == M_FS_ERROR_SUCCESS) {
59 * M_printf("user='%s'\n", M_fs_info_get_user(info));
60 * } else {
61 * M_printf("Failed to get file information\n");
62 * }
63 * M_fs_info_destroy(info);
64 * \endcode
65 *
66 * Example (normalize path):
67 *
68 * \code{.c}
69 * const char *p1 = "./abc def/../xyz/./1 2 3/./xyr/.";
70 * const char *n1 = "xyz/1 2 3/xyr";
71 * const char *p2 = "C:\\\\var\\log\\.\\mysql\\\\\\5.1\\..\\..\\mysql.log";
72 * const char *n2 = "C:\\var\\log\\mysql.log";
73 * char *out = NULL;
74 *
75 * if (M_fs_path_norm(&out, p1, M_FS_PATH_NORM_NONE, M_FS_SYSTEM_UNIX) == M_FS_ERROR_SUCCESS) {
76 * if (M_str_eq(out, n1)) {
77 * M_printf("p1 normalized correctly\n")
78 * } else {
79 * M_printf("p1 did not normalize correctly\n");
80 * }
81 * } else {
82 * M_printf("failed to normalize p1\n");
83 * }
84 * M_free(out);
85 *
86 * if (M_fs_path_norm(&out, p2, M_FS_PATH_NORM_ABSOLUTE, M_FS_SYSTEM_WINDOWS) == M_FS_ERROR_SUCCESS) {
87 * if (M_str_eq(out, n2)) {
88 * M_printf("p2 normalized correctly\n")
89 * } else {
90 * M_printf("p2 did not normalize correctly\n");
91 * }
92 * } else {
93 * M_printf("failed to normalize p2\n");
94 * }
95 * M_free(out);
96 * \endcode
97 *
98 * Example (listing files in a directory):
99 *
100 * \code{.c}
101 * M_list_str_t *l = NULL;
102 * size_t len;
103 * size_t i;
104 *
105 * l = M_fs_dir_walk_strs("~", "*.txt", M_FS_DIR_WALK_FILTER_FILE|M_FS_DIR_WALK_FILTER_READ_INFO_BASIC);
106 * len = M_list_str_len(l);
107 * for (i=0; i<len; i++) {
108 * M_printf("%s\n", M_list_str_at(l, i));
109 * }
110 * M_list_str_destroy(l);
111 * \endcode
112 */
113
114/*! \addtogroup m_fs_common Common
115 * \ingroup m_fs
116 *
117 * @{
118 */
119
120/*! Permissions. */
121struct M_fs_perms;
122typedef struct M_fs_perms M_fs_perms_t;
123
124
125/*! Information. */
126struct M_fs_info;
127typedef struct M_fs_info M_fs_info_t;
128
129
130/*! An open file. */
131struct M_fs_file;
132typedef struct M_fs_file M_fs_file_t;
133
134
135/*! An entry in a directory. */
136struct M_fs_dir_entry;
137typedef struct M_fs_dir_entry M_fs_dir_entry_t;
138
139
140/*! A list of directory entries. */
141struct M_fs_dir_entries;
142typedef struct M_fs_dir_entries M_fs_dir_entries_t;
143
144
145/*! File operation progress information. */
146struct M_fs_progress;
147typedef struct M_fs_progress M_fs_progress_t;
148
149
150/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
151
152/*! Error codes. */
153
154typedef enum {
155 M_FS_ERROR_SUCCESS = 0, /*!< Operation completed successfully */
156 M_FS_ERROR_GENERIC, /*!< Generic, uncategorized error */
157 M_FS_ERROR_INVALID, /*!< Invalid argument */
158 M_FS_ERROR_PERMISSION, /*!< Operation not permitted */
159 M_FS_ERROR_NOT_SUPPORTED, /*!< Operation not supported */
160 M_FS_ERROR_IO, /*!< Input/output error */
161 M_FS_ERROR_SEEK, /*!< Invalid seek */
162 M_FS_ERROR_READONLY, /*!< Read-only file system */
163 M_FS_ERROR_QUOTA, /*!< Disk quota exceeded */
164 M_FS_ERROR_DNE, /*!< No such file or directory */
165 M_FS_ERROR_NAMETOOLONG, /*!< Filename too long */
166 M_FS_ERROR_FILE_EXISTS, /*!< File exists */
167 M_FS_ERROR_FILE_2BIG, /*!< File too large */
168 M_FS_ERROR_FILE_2MANY, /*!< Too many open files */
169 M_FS_ERROR_ISDIR, /*!< Is a directory */
170 M_FS_ERROR_NOTDIR, /*!< Not a directory */
171 M_FS_ERROR_DIR_NOTEMPTY, /*!< Directory not empty */
172 M_FS_ERROR_LINK_LOOP, /*!< Too many levels of symbolic links */
173 M_FS_ERROR_LINK_2MANY, /*!< Too many links */
174 M_FS_ERROR_NOT_SAMEDEV, /*!< Cannot move across mount points. */
175 M_FS_ERROR_CANCELED /*!< The operation was canceled (typically by user interaction). */
177
178
179/*! Standard streams for input and output. */
180typedef enum {
185
186
187/*! File permissions. Based on POSIX file permissions. */
188typedef enum {
189 M_FS_PERMS_MODE_NONE = 0, /*!< No perms. */
190 M_FS_PERMS_MODE_READ = 1 << 0, /*!< Read. */
191 M_FS_PERMS_MODE_WRITE = 1 << 1, /*!< Write. */
192 M_FS_PERMS_MODE_EXEC = 1 << 2 /*!< Execute. */
194
195
196/*! How should the perms be modified. */
197typedef enum {
198 M_FS_PERMS_TYPE_EXACT = 0, /*!< Perms are exactly what is set. */
199 M_FS_PERMS_TYPE_ADD, /*!< Perms will be added to existing perms. */
200 M_FS_PERMS_TYPE_REMOVE /*!< Perms will be removed from existing perms. */
202
203
204/*! Who do the given perms apply to. Based on POSIX file permissions. */
205typedef enum {
206 M_FS_PERMS_WHO_USER = 0, /*!< User/owner. */
207 M_FS_PERMS_WHO_GROUP, /*!< Group. */
208 M_FS_PERMS_WHO_OTHER /*!< Other. */
210
211
212/*! How should the path be normalized. */
213typedef enum {
215 M_FS_PATH_NORM_ABSOLUTE = 1 << 0, /*!< Use the current working directory to determine absolute
216 path if provided path is relative. */
217 M_FS_PATH_NORM_FOLLOWSYMLINKS = 1 << 1, /*!< Follow sym links. This will succeed if even if the path
218 pointed by by the symlink does not exist. */
219 M_FS_PATH_NORM_SYMLINKS_FAILDNE = 1 << 2, /*!< Follow sym links. Fail if the location pointed to by the
220 link does not exist excluding the last location in the path. */
221 M_FS_PATH_NORM_SYMLINKS_FAILDNELAST = 1 << 3, /*!< Follow sym links. Fail if only the last location pointed
222 to by the link does not exist. */
223 M_FS_PATH_NORM_HOME = 1 << 4, /*!< Normalize ~/ to $HOME. */
224 M_FS_PATH_NORM_NOPARENT = 1 << 5 /*!< Do NOT Normalize ../ paths. */
226
227/* Default/common flags */
228#define M_FS_PATH_NORM_RESDIR M_FS_PATH_NORM_HOME|M_FS_PATH_NORM_FOLLOWSYMLINKS|M_FS_PATH_NORM_SYMLINKS_FAILDNE
229#define M_FS_PATH_NORM_RESALL M_FS_PATH_NORM_HOME|M_FS_PATH_NORM_FOLLOWSYMLINKS|M_FS_PATH_NORM_SYMLINKS_FAILDNE|M_FS_PATH_NORM_SYMLINKS_FAILDNELAST
230
231
232/*! How should a path's info be read. */
233typedef enum {
234 M_FS_PATH_INFO_FLAGS_NONE = 0, /*!< Normal operation. Get all info for the given location. */
235 M_FS_PATH_INFO_FLAGS_FOLLOW_SYMLINKS = 1 << 0, /*!< If the location is symlink get the info for the location pointed
236 to by the link and not the link itself. */
237 M_FS_PATH_INFO_FLAGS_BASIC = 1 << 1 /*!< Get basic info only.
238 Excludes:
239 - User and group.
240 - Permissions. */
242
243
244/*! File interaction. */
245typedef enum {
246 M_FS_FILE_MODE_NONE = 0, /*!< No mode specified. */
247 M_FS_FILE_MODE_READ = 1 << 0, /*!< Read. */
248 M_FS_FILE_MODE_WRITE = 1 << 1, /*!< Write. */
249 M_FS_FILE_MODE_NOCREATE = 1 << 2, /*!< Do not create the file if it does not exist. */
250 M_FS_FILE_MODE_APPEND = 1 << 3, /*!< Only write at the end of the file. */
251 M_FS_FILE_MODE_OVERWRITE = 1 << 4, /*!< Overwrite the file (truncate) if it exists. */
252 M_FS_FILE_MODE_PRESERVE_PERMS = 1 << 5, /*!< Move/Copy use the perms from the original file.
253 This only preserves permissions that can be expressed
254 by an M_fs_perms_t object. ACLs for example will not be
255 persevered. */
256 M_FS_FILE_MODE_NOCLOSEEXEC = 1 << 6 /*!< Allow sharing of file descriptors with fork executed processes. */
258
259
260/*! Read / Write behavior */
261typedef enum {
262 M_FS_FILE_RW_NORMAL = 0, /*!< Normal operation */
263 M_FS_FILE_RW_FULLBUF = 1 << 0 /*!< Read until the given buffer is full or until there is no more data to read.
264 Write all data in the buffer. Normal operation is to return after the system
265 reads/writes what it can. This will cause the read/write to retry until the
266 given all data is read/written. */
268
269
270/*! Seeking within a file. */
271typedef enum {
272 M_FS_FILE_SEEK_BEGIN = 0, /*!< Seek relative to the beginning of the file. */
273 M_FS_FILE_SEEK_END, /*!< Seek relative to the end of the file .*/
274 M_FS_FILE_SEEK_CUR /*!< Seek relative to the current location */
276
277
278/*! How should data be synced to disk. */
279typedef enum {
280 M_FS_FILE_SYNC_NONE = 0, /*!< No sync. */
281 M_FS_FILE_SYNC_BUFFER = 1 << 0, /*!< Internal write buffer should be synced (fflush) */
282 M_FS_FILE_SYNC_OS = 1 << 1 /*!< OS buffer should be synced (fsync) */
284
285/*! Controls the behavior of walk. Specifies how the walk should be performed and what should be stored in the
286 * result of the walk.
287 */
288typedef enum {
289 M_FS_DIR_WALK_FILTER_NONE = 0, /*!< No filters. */
290 /* Types. */
291 M_FS_DIR_WALK_FILTER_FILE = 1 << 0, /*!< Include files in the list of entries.
292 Anything that is not another type is considered a file. */
293 M_FS_DIR_WALK_FILTER_DIR = 1 << 1, /*!< Include directories in the list of entries. */
294 M_FS_DIR_WALK_FILTER_PIPE = 1 << 2, /*!< Include pipes in the list of entries. */
295 M_FS_DIR_WALK_FILTER_SYMLINK = 1 << 3, /*!< Include symlinks in the list of entries. */
296 /* Attributes. */
297 M_FS_DIR_WALK_FILTER_HIDDEN = 1 << 4, /*!< Include hidden locations in the list of entries. */
298 /* Behaviors. */
299 M_FS_DIR_WALK_FILTER_RECURSE = 1 << 5, /*!< Recurse into directories and include their contents.
300 File system loops (infinite redirects due to symlinks) will be
301 ignored. */
302 M_FS_DIR_WALK_FILTER_FOLLOWSYMLINK = 1 << 6, /*!< Should symlinks be followed. */
303 M_FS_DIR_WALK_FILTER_JAIL_FAIL = 1 << 7, /*!< Fail walk if redirection outside of base path. */
304 M_FS_DIR_WALK_FILTER_JAIL_SKIP = 1 << 8, /*!< Skip entry if redirection outside of base path. */
305 M_FS_DIR_WALK_FILTER_AS_SET = 1 << 9, /*!< Only include a given entry once. Symlinks could cause a file
306 or directory to show up multiple times in a walk this will
307 exclude the additional entries. Also, only one symlink to
308 a given entry will be included. For example, if there are two
309 symlinks to the same file one symlink will be ingored. */
310 /* Read and store the file info in each entry.
311 * The info is specific to the type. Meaning if the type if a symlink then the info will for the symlink not what
312 * the symlink points to. Depending on the other options you could have two entires in the list one for the symlink
313 * and one for the file. The path will be the same but the type and the info will be different. If READ_INFO is not
314 * set this doesn't guarantee the info won't be read (some cases and options it is necessary) but even if it is
315 * read it won't be set in the entry. Assume that if not set the info won't be available. */
316 M_FS_DIR_WALK_FILTER_READ_INFO_BASIC = 1 << 10, /*!< Read/store basic info about the entry.
317 Specifically:
318 - Is dir.
319 - Is hidden.
320 - File size.
321 - Access time.
322 - Last modification time.
323 - Creation time. */
324 M_FS_DIR_WALK_FILTER_READ_INFO_FULL = 1 << 11, /*!< Read/Store all info about the entry.
325 Specifically:
326 - All basic info.
327 - User and Group.
328 - Permissions. */
329 M_FS_DIR_WALK_FILTER_CASECMP = 1 << 12 /*!< The pattern matching should be compared to the path in
330 a case insensitive manner. */
332
333/* Include all "files" in a walk. */
334#define M_FS_DIR_WALK_FILTER_ALL M_FS_DIR_WALK_FILTER_FILE|M_FS_DIR_WALK_FILTER_DIR|M_FS_DIR_WALK_FILTER_SYMLINK|M_FS_DIR_WALK_FILTER_HIDDEN
335
336
337/*! Sorting methods. Some of these methods require the file info. If the file info was not retrieved (walk did not
338 * have a M_FS_DIR_WALK_FILTER_READ_INFO_* filter set) all files are considered equal.
339 */
340typedef enum {
341 M_FS_DIR_SORT_NAME_CASECMP = 0, /*!< Sort by name case insensitive. */
342 M_FS_DIR_SORT_NAME_CMP, /*!< Sort by name case sensitive. */
343 M_FS_DIR_SORT_ISDIR, /*!< Sort by is directory. */
344 M_FS_DIR_SORT_ISHIDDEN, /*!< Sort by hidden status. */
345 M_FS_DIR_SORT_NONE, /*!< Don't sort. This is an option because sorting can have primary and secondary.
346 This allows only a primary sort to be applied. */
347 /* Requires info. */
348 M_FS_DIR_SORT_SIZE, /*!< Sort by file size. */
349 M_FS_DIR_SORT_ATIME, /*!< Sort by last access time. */
350 M_FS_DIR_SORT_MTIME, /*!< Sort by last modification time. */
351 M_FS_DIR_SORT_CTIME /*!< Sort by create time. */
353
354
355/*! Determines what progress information should be reported to the progress callback. Size reporting will
356 * increase the amount of time required for processing due to needing to get and calculate totals. */
357typedef enum {
358 M_FS_PROGRESS_NOEXTRA = 0, /*!< Don't provide optional reporting. Will be overridden by other flags. */
359 M_FS_PROGRESS_COUNT = 1 << 0, /*!< Report on number of operations total and completed. */
360 M_FS_PROGRESS_SIZE_TOTAL = 1 << 1, /*!< Report the total size for all file operations and the total completed. */
361 M_FS_PROGRESS_SIZE_CUR = 1 << 2 /*!< Report the total size for the current file being processed and the total
362 size of the file completed. */
364
365
366/*! Controls how path should be constructed. */
367typedef enum {
368 M_FS_SYSTEM_AUTO = 0, /*!< Automatically set based on current system. */
369 M_FS_SYSTEM_WINDOWS, /*!< Forcibly use windows logic. */
370 M_FS_SYSTEM_UNIX /*!< Forcibly use Unix logic. */
372
373
374/*! Types of file objects. */
375typedef enum {
376 M_FS_TYPE_UNKNOWN = 0, /*!< The location is an unknown type. Typically this means it was not read. */
377 M_FS_TYPE_FILE, /*!< The location is a regular file. */
378 M_FS_TYPE_DIR, /*!< The location is a directory. */
379 M_FS_TYPE_PIPE, /*!< The location is a fifo (pipe). */
380 M_FS_TYPE_SYMLINK /*!< The location is a symbolic link. */
382
383
384/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
385
386/* 1 KB default buffer size. */
387#define M_FS_BUF_SIZE 1024
388
389/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
390
391/*! Walk callback function prototype.
392 *
393 * \param[in] path The path passed into walk.
394 * \param[in] entry The entry created for the location. The cb will have ownership of the entry. It is up to the
395 * cb to save or destroy the entry.
396 * \param[in] res The status of the entry. A success should be treat the entry as a good entry for the purpose
397 * of the callback. Any other result should be treated as an error condition and it is up to the
398 * callback as to how it should be handled. For example and infinite recursion loop due to circular
399 * symlinks will have an entry denoting which link causes the loop and a result of M_FS_ERROR_LINK_LOOP.
400 * \param[in] thunk Additional data passed to walk for use in this callback.
401 *
402 * \return M_TRUE if walk should continue. M_FALSE if the walk should be cancelled.
403 */
404typedef M_bool (*M_fs_dir_walk_cb_t)(const char *path, M_fs_dir_entry_t *entry, M_fs_error_t res, void *thunk);
405
406
407/*! File operation progress callback function prototype.
408 *
409 * Many file and directory operations (move, copy, delete...) can report their progress as the operation is run.
410 *
411 * \param p The progress object. Contains information about the status of the operation. The object is only valid
412 * until the callback returns; it should not be stored.
413 *
414 * \return M_TRUE if the operation should continue. M_FALSE if the operation should be cancelled.
415 */
416typedef M_bool (*M_fs_progress_cb_t)(const M_fs_progress_t *p);
417
418/*! @} */
419
420
421/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
422
423/*! \addtogroup m_fs_perms Permissions
424 * \ingroup m_fs
425 *
426 * @{
427 */
428
429/*! Create a perms object.
430 *
431 * \return A perms object.
432 */
433M_API M_fs_perms_t *M_fs_perms_create(void) M_MALLOC;
434
435
436/*! Duplicate a perms object.
437 *
438 * \param[in] perms The perms object to duplicate.
439 *
440 * \return A new perms object with the same information as the original.
441 */
442M_API M_fs_perms_t *M_fs_perms_dup(const M_fs_perms_t *perms) M_MALLOC;
443
444
445/*! Merge two perms objects together.
446 *
447 * The second (src) perms will be destroyed automatically upon completion of this function.
448 *
449 * This is intended for dest to hold exact permissions. In this case, when src is exact then
450 * src will replace the permissions in dest. If src is an add or remove it will modify dest
451 * accordingly.
452 *
453 * When the perms in dest are not set then the permissions from src will be used.
454 *
455 * When dest is a modifier (add or remove) then the permissions from src will replace the
456 * permission in dest. This happens regardless of the permissions in src being exact or
457 * a modifier.
458 *
459 * When the permissions in src are not set then dest will not be modified.
460 *
461 * \param[in,out] dest Pointer by reference to the perms receiving the values.
462 * if this is NULL, the pointer will simply be switched out for src.
463 * \param[in,out] src Pointer to the perms giving up its values.
464 */
465M_API void M_fs_perms_merge(M_fs_perms_t **dest, M_fs_perms_t *src) M_FREE(2);
466
467
468/*! Destroy a perms object.
469 *
470 * \param[in] perms The perms.
471 */
472M_API void M_fs_perms_destroy(M_fs_perms_t *perms) M_FREE(1);
473
474
475/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
476
477/*! Can the process access the path with the given perms.
478 *
479 * \warning using this function incorrectly can lead to security issues. This is an
480 * implementation of the POSIX access() function and the security considerations
481 * apply.
482 *
483 * This function should not be used to make access control decisions due to
484 * Time-of-check Time-of-use (TOCTOU) race condition attacks.
485 *
486 * \param[in] path The path to access.
487 * \param[in] mode M_fs_perms_mode_t permissions to be checked. Optional, pass
488 * 0 if only checking if the path exists.
489 *
490 * \return Result.
491 */
492M_API M_fs_error_t M_fs_perms_can_access(const char *path, M_uint32 mode);
493
494
495/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
496
497/*! Apply perms to a path.
498 *
499 * This will set/change/modify the perms on a path.
500 *
501 * \param[in] perms The perms.
502 * \param[in] path The path.
503 *
504 * \return Result.
505 */
506M_API M_fs_error_t M_fs_perms_set_perms(const M_fs_perms_t *perms, const char *path);
507
508
509/*! Apply perms to open file.
510 *
511 * This will set/change/modify the perms on a file.
512 *
513 * \param[in] perms The perms.
514 * \param[in] fd The file.
515 *
516 * \return Result.
517 */
519
520
521/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
522
523/*! Get the user associated with the perms.
524 *
525 * \param[in] perms The perms.
526 *
527 * \return The user. NULL if no user is set.
528 */
529M_API const char *M_fs_perms_get_user(const M_fs_perms_t *perms);
530
531
532/*! Get the group associated with the perms.
533 *
534 * \param[in] perms The perms.
535 *
536 * \return The group. NULL if not group is set.
537 */
538M_API const char *M_fs_perms_get_group(const M_fs_perms_t *perms);
539
540
541/*! Get the mode associated with the perms for the given permission.
542 *
543 * \param[in] perms The perms.
544 * \param[in] who The permissions this applies to.
545 *
546 * \return A bit map of M_fs_perms_mode_t values which are the permissions that are set.
547 */
548M_API M_uint32 M_fs_perms_get_mode(const M_fs_perms_t *perms, M_fs_perms_who_t who);
549
550
551/*! Get the type (exact/add/remove) associated with the perms for the given permission.
552 *
553 * \param[in] perms The perms.
554 * \param[in] who The permissions this applies to.
555 *
556 * \return The permission type.
557 */
559
560
561/*! Check if a given permission is set.
562 *
563 * If not set the permission will be ignored during merge, set and other operation that use the permissions.
564 *
565 * \param[in] perms The perms.
566 * \param[in] who The permissions this applies to.
567 *
568 * \return M_TRUE if the permission are set. Otherwise M_FALSE.
569 */
570M_API M_bool M_fs_perms_get_isset(const M_fs_perms_t *perms, M_fs_perms_who_t who);
571
572
573/*! Get the directory override mode associated with the perms for the given permission.
574 *
575 * \param[in] perms The perms.
576 * \param[in] who The permissions this applies to.
577 *
578 * \return A bit map of M_fs_perms_mode_t values which are the permissions that are set.
579 */
580M_API M_uint32 M_fs_perms_get_dir_mode(const M_fs_perms_t *perms, M_fs_perms_who_t who);
581
582
583/*! Get the directory override type (exact/add/remove) associated with the perms for the given permission.
584 *
585 * \param[in] perms The perms.
586 * \param[in] who The permissions this applies to.
587 *
588 * \return The permission type.
589 */
591
592
593/*! Check if a given directory override permission is set.
594 *
595 * If not set the permission will be ignored during merge, set and other operation that use the permissions.
596 *
597 * \param[in] perms The perms.
598 * \param[in] who The permissions this applies to.
599 *
600 * \return M_TRUE if the permission are set. Otherwise M_FALSE.
601 */
603
604
605/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
606
607/*! Set the user.
608 *
609 * \param[in] perms The perms.
610 * \param[in] user The user.
611 *
612 * \return Result.
613 */
614M_API M_fs_error_t M_fs_perms_set_user(M_fs_perms_t *perms, const char *user);
615
616
617/*! Set the group.
618 *
619 * \param[in] perms The perms.
620 * \param[in] group The group.
621 *
622 * \return Result.
623 */
624M_API M_fs_error_t M_fs_perms_set_group(M_fs_perms_t *perms, const char *group);
625
626
627/*! Set the mode for the perms.
628 *
629 * \param[in] perms The perms.
630 * \param[in] mode M_fs_file_mode_t modes.
631 * \param[in] who Who this applies to.
632 * \param[in] type The type permissions being set.
633 */
634M_API void M_fs_perms_set_mode(M_fs_perms_t *perms, M_uint32 mode, M_fs_perms_who_t who, M_fs_perms_type_t type);
635
636
637/*! Set the directory override mode for the perms.
638 *
639 * \param[in] perms The perms.
640 * \param[in] mode M_fs_file_mode_t modes.
641 * \param[in] who Who this applies to.
642 * \param[in] type The type permissions being set.
643 */
644M_API void M_fs_perms_set_dir_mode(M_fs_perms_t *perms, M_uint32 mode, M_fs_perms_who_t who, M_fs_perms_type_t type);
645
646
647/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
648
649/*! Unset permissions.
650 *
651 * This is different than setting _no_ permissions.
652 *
653 * This will also unset the equivalent directory override permissions.
654 *
655 * \param[in] perms The perms.
656 * \param[in] who Who this applies to.
657 */
659
660
661/*! Unset directory override permissions.
662 *
663 * This is different than setting _no_ permissions.
664 *
665 * \param[in] perms The perms.
666 * \param[in] who Who this applies to.
667 */
669
670/*! @} */
671
672
673/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
674
675/*! \addtogroup m_fs_path Path
676 * \ingroup m_fs
677 *
678 * @{
679 */
680
681/*! Determine the max path length for the system.
682 *
683 * \param[in] sys_type The system type used to determine the maximum path length.
684 *
685 * \return The maximum path length.
686 */
688
689
690/*! Check if a path is an absolute path.
691 *
692 * A path is absolute if it's Unix and starts with /. Or Windows and starts with \\\\ (UNC) or a drive letter.
693 *
694 * \param[in] p The path.
695 * \param[in] sys_type The system type.
696 *
697 * \return M_TRUE if an absolute path. Otherwise M_FALSE.
698 */
699M_API M_bool M_fs_path_isabs(const char *p, M_fs_system_t sys_type);
700
701
702/*! Check if a path is a UNC path.
703 *
704 * A path is UNC if it's Windows and starts with "\\\\".
705 *
706 * \param[in] p The path.
707 *
708 * \return M_TRUE if an UNC path. Otherwise M_FALSE.
709 */
710M_API M_bool M_fs_path_isunc(const char *p);
711
712
713/*! Check if the path is considered hidden by the OS.
714 *
715 * Either the path or info parameters can be NULL. Both cannot be NULL.
716 *
717 * \param[in] path The path.
718 * \param[in] info The info.
719 *
720 * \return Whether the path is considered hidden.
721 */
722M_API M_bool M_fs_path_ishidden(const char *path, const M_fs_info_t *info);
723
724
725/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
726
727/*! Take a path and split it into components.
728 *
729 * This will remove empty parts. An absolute path (Unix) starting with / will have the / replaced with an empty to
730 * start the list. The same is true for UNC paths. An empty at the start of the path list should be treated as an
731 * absolute path.
732 *
733 * \param[in] path The path.
734 * \param[in] sys_type The system type.
735 *
736 * \return A list of path parts.
737 */
738M_API M_list_str_t *M_fs_path_componentize_path(const char *path, M_fs_system_t sys_type);
739
740
741/*! Join two parts into one path.
742 *
743 * If either part is empty the separator won't be added. Unlike M_fs_path_join_parts this does not have special
744 * handling (using an empty string) for absolute paths. This is a convenience function to write the appropriate system
745 * separator between two paths.
746 *
747 * \param[in] p1 First part.
748 * \param[in] p2 Second part.
749 * \param[in] sys_type The system type.
750 *
751 *
752 * \return The path as a single string.
753 */
754M_API char *M_fs_path_join(const char *p1, const char *p2, M_fs_system_t sys_type);
755
756
757/*! Take a list of path components and join them into a string separated by the system path separator.
758 *
759 * Empty parts (except the first on Unix and UNC) will be ignored. An empty part at the start is used on Unix and UNC to
760 * denote an absolute path.
761 *
762 * \param[in] path The path.
763 * \param[in] sys_type The system type.
764 *
765 * \return The path as a single string.
766 */
767M_API char *M_fs_path_join_parts(const M_list_str_t *path, M_fs_system_t sys_type);
768
769
770/*! Take a list of path components and join them into a string separated by the system path separator.
771 *
772 * Empty parts (except the first on Unix and UNC) will be ignored. An empty part at the start is used on Unix and UNC to
773 * denote an absolute path.
774 *
775 * \param[in] sys_type The system type.
776 * \param[in] num The number of parts.
777 * \param[in] ... char * parts to be joined.
778 *
779 * \return The path as a single string.
780 */
781M_API char *M_fs_path_join_vparts(M_fs_system_t sys_type, size_t num, ...);
782
783/*! Join a base path, the name and the resolved name into the full resolved path.
784 *
785 * This is a helper for dealing with M_fs_dir_walk in order to determine the resolved path
786 * when the entry returned by the callback is a symlink.
787 *
788 * We have three parts: path, entry_name, resolved_name.
789 * The entry_name needs to have the last part removed because it is a symlink. Then
790 * we need to put path and resolved_name on either size to get the real name.
791 *
792 * For example:
793 * path = /usr/share/zoneinfo/America
794 * part = Indiana/Indianapolis
795 * resolved_name = ../../posix/America/Indiana/Indianapolis
796 *
797 * We need:
798 * /usr/share/zoneinfo/America/Indiana/../../posix/America/Indiana/Indianapolis
799 *
800 * \param[in] path The base path.
801 * \param[in] part The path component under the base.
802 * \param[in] resolved_name The resolved path for a symlink that needs to be combined with the base and part.
803 * \param[in] sys_type The system type.
804 * \return The resolved path.
805 */
806M_API char *M_fs_path_join_resolved(const char *path, const char *part, const char *resolved_name, M_fs_system_t sys_type);
807
808
809/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
810
811/*! Strip last component from a filename.
812 *
813 * Remove last full non-slash component. Output will not include trailing slashes.
814 * E.g: /usr/bin/echo.exe -> /usr/bin
815 *
816 * A path without a dir component will output NULL as there is no directory and
817 * cannot be assumed to be a relative path.
818 *
819 * \param[in] path The path.
820 * \param[in] sys_type The system path logic and separator to use.
821 *
822 * \return The path component from a filename.
823 */
824M_API char *M_fs_path_dirname(const char *path, M_fs_system_t sys_type);
825
826
827/*! Strip all but the last component from a filename.
828 *
829 * Remove all but the last full non-slash component. Output will not include trailing slashes.
830 *
831 * E.g: /usr/bin/ -> bin
832 *
833 * E.g: bin -> bin
834 *
835 * \param[in] path The path.
836 * \param[in] sys_type The system path logic and separator to use.
837 *
838 * \return The path last component from a filename.
839 */
840M_API char *M_fs_path_basename(const char *path, M_fs_system_t sys_type);
841
842
843/*! The user's configuration directory.
844 *
845 * This is a user level _not_ system level directory.
846 * This is the OS standard directory for application
847 * configuration files.
848 *
849 * \param[in] sys_type The system path logic and separator to use.
850 *
851 * \return The path to the config dir, otherwise NULL on error.
852 */
854
855
856
857/*! Temporary directory set by the system that the application can use for temporary storage.
858 *
859 * \warning This is _NOT_ a secure location.
860 *
861 * Other processes on the system can share this directory.
862 * It's recommend to create an applications specific subdirectory to use for temporary
863 * files. Again, this is _NOT_ intended to be used for secure files or when secure files
864 * are necessary.
865 *
866 * This should only be used for temporary storage
867 * of files being manipulated. For example, unpacking a compressed archive then moving
868 * the files to the destination. Or saving to a temporary file then using M_fs_move to
869 * ensure an atomic write.
870 *
871 * \param[in] sys_type The system path logic and separator to use.
872 *
873 * \return The path to a temporary dir, otherwise NULL on error.
874 */
875M_API char *M_fs_path_tmpdir(M_fs_system_t sys_type);
876
877
878/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
879
880/*! Get the current working directory for the calling process.
881 *
882 * \param[in] cwd An allocated string with the cwd.
883 *
884 * \return result.
885 */
887
888
889/*! Set the current working directory for the calling process.
890 *
891 * \param[in] path The path to set as the cwd.
892 *
893 * \return result.
894 */
895M_API M_fs_error_t M_fs_path_set_cwd(const char *path);
896
897
898/*! Resolve a symlink.
899 *
900 * Reads the value pointed to by a symlink.
901 *
902 * \param[out] out An allocated string with the normalized path.
903 * \param[in] path The path to resolve.
904 *
905 * \return Result.
906 */
907M_API M_fs_error_t M_fs_path_readlink(char **out, const char *path);
908
909
910/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
911
912/*! Normalize a path.
913 *
914 * This typically does not need to be called because all functions that take a path (file) will
915 * call this internally using the appropriate parameters. This is provided as a convenience for
916 * displaying paths to a user.
917 *
918 * Supported features on all OS's;
919 * - Home dir (~) expansion.
920 * - Environment variable expansion (both $var and \%var\%).
921 *
922 * Supported feature Unix only:
923 * - Symlink resolution.
924 *
925 * \param[out] out An allocated string with the normalized path.
926 * \param[in] path The path to normalize.
927 * \param[in] flags M_fs_path_norm_t flags to control the normalization behavior.
928 * \param[in] sys_type The system path format to the path is in. This denotes the
929 * path type and how it should be normalized. For example, a Windows
930 * path with "C:\..." passed with the UNIX type will do strange things
931 * because it is not a Unix formatted path. The purpose of this argument
932 * is to specify the path type if known. Allows a Windows path on a Unix
933 * system to be parsed properly even though it's not the standard path
934 * type for the system. Note that if the path is not the same as the
935 * system standard type the M_FS_PATH_NORM_ABSOLUTE my give unexpected
936 * results for non-absolute paths. For example this relative path specified
937 * as a Windows path run on a Unix system:
938 * ".\\abc.\\\\\\..\\xyz\\\\.\\123\\.\\xyr\\." may result in something like
939 * May give a result like:
940 * "home\jschember\svn\mstdlib-trunk\build\xyz\123\xyr"
941 * Notice there is no '\' or drive letter because they are not technically
942 * valid. However, the path was properly converted to an absolute path.
943 *
944 *
945 *
946 * \return Result.
947 */
948M_API M_fs_error_t M_fs_path_norm(char **out, const char *path, M_uint32 flags, M_fs_system_t sys_type);
949
950/*! @} */
951
952
953/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
954
955/*! \addtogroup m_fs_info Info
956 * \ingroup m_fs
957 *
958 * @{
959 */
960
961/*! Get information about a given path.
962 *
963 * \param[out] info Allocated info object with the info about the path. If passed as NULL then
964 * this only verifies that a path exists. However, M_fs_perms_can_access is
965 * more useful for checking for file existence.
966 * \param[in] path The path.
967 * \param[in] flags M_fs_info_flags_t defining behavior of how and what info to read.
968 *
969 * \return Result.
970 */
971M_API M_fs_error_t M_fs_info(M_fs_info_t **info, const char *path, M_uint32 flags);
972
973
974/*! Get information about an open file.
975 *
976 * \param[out] info Allocated info object with the info about the path. If passed as NULL then
977 * this only verifies that a path exists. However, the file is already open
978 * so it exists!
979 * \param[in] fd The file.
980 * \param[in] flags M_fs_info_flags_t defining behavior of how and what info to read.
981 *
982 * \return Result.
983 */
984M_API M_fs_error_t M_fs_info_file(M_fs_info_t **info, M_fs_file_t *fd, M_uint32 flags);
985
986
987/*! Destroy an info object.
988 *
989 * \param[in] info The info object.
990 */
991M_API void M_fs_info_destroy(M_fs_info_t *info) M_FREE(1);
992
993
994/*! Get the user from a path info.
995 *
996 * \param[in] info The info object.
997 *
998 * \return The user/owner.
999 */
1000M_API const char *M_fs_info_get_user(const M_fs_info_t *info);
1001
1002
1003/*! Get the group from a path info.
1004 *
1005 * \param[in] info The info object.
1006 *
1007 * \return The group.
1008 */
1009M_API const char *M_fs_info_get_group(const M_fs_info_t *info);
1010
1011
1012/*! Location type.
1013 *
1014 * \param[in] info The info object.
1015 *
1016 * \return The path type.
1017 */
1019
1020
1021/*! Is this a hidden file?
1022 *
1023 * \param[in] info The info object.
1024 *
1025 * \return M_TRUE if this is a hidden file. Otherwise M_FALSE.
1026 */
1027M_API M_bool M_fs_info_get_ishidden(const M_fs_info_t *info);
1028
1029
1030/*! The size of the path.
1031 *
1032 * \param[in] info The info object.
1033 *
1034 * \return The size.
1035 */
1036M_API M_uint64 M_fs_info_get_size(const M_fs_info_t *info);
1037
1038
1039/*! The last access time.
1040 *
1041 * \param[in] info The info object.
1042 *
1043 * \return The time.
1044 */
1046
1047
1048/*! The last modify time.
1049 *
1050 * \param[in] info The info object.
1051 *
1052 * \return The time.
1053 */
1055
1056
1057/*! The last status change time.
1058 *
1059 * \param[in] info The info object.
1060 *
1061 * \return The time.
1062 */
1064
1065
1066/*! The file birth/creation time.
1067 *
1068 * This time is not updated after append operations. In Linux terms, it's the time the inode was created.
1069 *
1070 * Note that birth/creation times aren't available on all platforms - if you're on one of those platforms,
1071 * this method will always return 0.
1072 *
1073 * \param[in] info object created by M_fs_info()
1074 *
1075 * \return Time when file was created, or 0 if time couldn't be retrieved
1076 */
1078
1079
1080/*! Get the permissions associated with the path.
1081 *
1082 * \param[in] info The info object.
1083 *
1084 * \return A perms object belonging to the info object. The perms object will be
1085 * destroyed when the info object is destroyed.
1086 */
1088
1089/*! @} */
1090
1091
1092/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1093
1094/*! \addtogroup m_fs_file File
1095 * \ingroup m_fs
1096 *
1097 * @{
1098 */
1099
1100/*! Open a file.
1101 *
1102 * The set of flags you pass to \a mode must include M_FS_FILE_MODE_READ and/or M_FS_FILE_MODE_WRITE.
1103 * System umask is honored when creating a file.
1104 *
1105 * The other M_fs_file_mode_t flags can be used as well, they just need to be OR'd with M_FS_FILE_MODE_READ and/or
1106 * M_FS_FILE_MODE_WRITE.
1107 *
1108 * \param[out] fd The file object created upon success. Will be set to \c NULL if there was an error.
1109 * \param[in] path The path to open.
1110 * \param[in] buf_size Set a buffer size to enable buffered read and write. Use 0 to disable buffering.
1111 * \param[in] mode M_fs_file_mode_t open mode.
1112 * \param[in] perms Additional perms to apply to the file if it does not exist and is created.
1113 Umake is honored when perms are set. E.g. perms & ~umask is used.
1114 If perms is NULL a default of rw-rw-r-- & ~umask is used.
1115 *
1116 * \return Result.
1117 */
1118M_API M_fs_error_t M_fs_file_open(M_fs_file_t **fd, const char *path, size_t buf_size, M_uint32 mode, const M_fs_perms_t *perms);
1119
1120
1121/*! Open a standard IO stream.
1122 *
1123 * \param[out] fd The file object created upon success. Will be set to \c NULL if there was an error.
1124 * \param[in] stream The stream to open.
1125 *
1126 * \return Result.
1127 */
1129
1130
1131/*! Close an open file.
1132 *
1133 * \param[in] fd The file object.
1134 */
1136
1137
1138/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1139
1140/*! Read from a file.
1141 *
1142 * \param[in] fd The file object.
1143 * \param[out] buf A buffer to put the read data into.
1144 * \param[in] buf_len The size of the buffer.
1145 * \param[out] read_len How much data was read into buf.
1146 * \param[in] flags M_fs_file_read_write_t flags to control the read.
1147 *
1148 * \return Result.
1149 */
1150M_API M_fs_error_t M_fs_file_read(M_fs_file_t *fd, unsigned char *buf, size_t buf_len, size_t *read_len, M_uint32 flags);
1151
1152
1153/*! Write data to a file.
1154 *
1155 * \param[in] fd The file object.
1156 * \param[in] buf The data to write.
1157 * \param[in] count The length of the data to write.
1158 * \param[out] wrote_len The amount of data written to the file.
1159 * \param[in] flags M_fs_file_read_write_t flags to control the write.
1160 * \return Result.
1161 */
1162M_API M_fs_error_t M_fs_file_write(M_fs_file_t *fd, const unsigned char *buf, size_t count, size_t *wrote_len, M_uint32 flags);
1163
1164
1165/*! Move/Set the read/write offset within an file.
1166 *
1167 * \param[in] fd The file object.
1168 * \param[in] offset How much to move the offset relative to from. Can be negative to move backwards.
1169 * \param[in] from Where the offset is relative to.
1170 *
1171 * \return Result.
1172 */
1174
1175
1176/*! Flush file buffer to disk.
1177 *
1178 * \param[in] fd The file object.
1179 * \param[in] type M_fs_file_sync_t type of sync to perform.
1180 *
1181 * \return Result.
1182 */
1183M_API M_fs_error_t M_fs_file_sync(M_fs_file_t *fd, M_uint32 type);
1184
1185
1186/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1187
1188/*! Read a file into a buffer as a str.
1189 *
1190 * \param[in] path The path to read from.
1191 * \param[in] max_read A maximum of bytes to read. 0 for no maximum.
1192 * \param[out] buf A buffer that will be allocated and contain the file contents. It will be NULL terminated
1193 * on success.
1194 * \param[out] bytes_read The number of bytes read and contained in the buffer excluding the NULL terminator.
1195 *
1196 * \return Result.
1197 */
1198M_API M_fs_error_t M_fs_file_read_bytes(const char *path, size_t max_read, unsigned char **buf, size_t *bytes_read);
1199
1200
1201/*! Write a str to a file.
1202 *
1203 * \param[in] path The path of the file to write into.
1204 * \param[in] buf Buffer containing the data to write into the file.
1205 * \param[in] write_len The number of bytes from buf to write. Optional, pass 0 to use M_str_len to determine
1206 * length of a NULL terminated buffer to write.
1207 * \param[in] mode M_fs_file_mode_t mode. Only supports APPEND. Used to control appending vs overwriting.
1208 * The default is to overwrite the file.
1209 * \param[out] bytes_written The number of bytes from buf written to the file. Optional, pass NULL if not needed.
1210 *
1211 * \return Result.
1212 */
1213M_API M_fs_error_t M_fs_file_write_bytes(const char *path, const unsigned char *buf, size_t write_len, M_uint32 mode, size_t *bytes_written);
1214
1215/*! @} */
1216
1217
1218/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1219
1220/*! \addtogroup m_fs_dir Directory
1221 * \ingroup m_fs
1222 *
1223 * @{
1224 */
1225
1226/*! Destroy a directory entry.
1227 *
1228 * \param[in] entry The entry to destroy.
1229 */
1230M_API void M_fs_dir_entry_destroy(M_fs_dir_entry_t *entry) M_FREE(1);
1231
1232
1233/*! Get the type of the entry.
1234 *
1235 * \param[in] entry The entry.
1236 *
1237 * \return The type.
1238 */
1240
1241
1242/*! Get whether this entry is considered hidden by the OS.
1243 *
1244 * \param[in] entry The entry.
1245 *
1246 * \return Whether this entry is considered hidden.
1247 */
1249
1250
1251/*! Get the filename of the entry.
1252 *
1253 * The path/filename is relative to the directory that was walked.
1254 *
1255 * \param[in] entry The entry.
1256 *
1257 * \return The name.
1258 */
1259M_API const char *M_fs_dir_entry_get_name(const M_fs_dir_entry_t *entry);
1260
1261
1262/*! Get the resolved filename.
1263 *
1264 * This only applies if the entry is a symlink. The resolved name is the path that the symlink points to. This is
1265 * relative to the filename.
1266 *
1267 * \param[in] entry The entry.
1268 *
1269 * \return The resolved name.
1270 */
1272
1273
1274/*! Get the file information about the entry.
1275 *
1276 * This may be NULL if reading file info was not requested during walk.
1277 *
1278 * \param[in] entry The entry.
1279 *
1280 * \return The file info.
1281 */
1283
1284
1285/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1286
1287/*! Destroy a list of directory entries.
1288 *
1289 * \param[in] d The entry list to destroy.
1290 */
1292
1293
1294/*! Sort a list of directory entries.
1295 *
1296 * This does an in place sort and does not keep list sorted for subsequent insertions.
1297 *
1298 * \param[in] d The entry list.
1299 * \param[in] primary_sort Primary sort method.
1300 * \param[in] primary_asc Should the primary sorting be ascending.
1301 * \param[in] secondary_sort The secondary sort method that should be used when entries are considered equal according
1302 * to the primary_sort method.
1303 * \param[in] secondary_asc Should the secondary sorting be ascending.
1304 */
1305M_API void M_fs_dir_entries_sort(M_fs_dir_entries_t *d, M_fs_dir_sort_t primary_sort, M_bool primary_asc, M_fs_dir_sort_t secondary_sort, M_bool secondary_asc);
1306
1307
1308/*! Get the number of entries in the list.
1309 *
1310 * \param[in] d The entry list.
1311 *
1312 * \return The length of the list.
1313 */
1315
1316
1317/*! Get the entry at at the specified index.
1318 *
1319 * The entry remains part of the list.
1320 *
1321 * \param[in] d The entry list.
1322 * \param[in] idx The index.
1323 *
1324 * \return The entry.
1325 */
1327
1328
1329/*! Take the entry from the list.
1330 *
1331 * The entry will be removed from the list. It is up to the caller to free the entry.
1332 *
1333 * \param[in] d The entry list.
1334 * \param[in] idx The index.
1335 *
1336 * \return The entry.
1337 *
1338 * \see M_fs_dir_entry_destroy
1339 */
1341
1342
1343/*! Remove and destroy the entry at the given index.
1344 *
1345 * \param[in] d The entry list.
1346 * \param[in] idx The index.
1347 *
1348 * \return M_TRUE if the entry was destroyed. Otherwise M_FALSE.
1349 */
1351
1352
1353/*! Remove and destroy all entries in a given range.
1354 *
1355 * \param[in] d The entry list.
1356 * \param[in] start The starting index. Inclusive.
1357 * \param[in] end The ending index. Inclusive.
1358 *
1359 * \return M_TRUE if the entry was destroyed. Otherwise M_FALSE.
1360 */
1361M_API M_bool M_fs_dir_entries_remove_range(M_fs_dir_entries_t *d, size_t start, size_t end);
1362
1363
1364/*! Merge two directory entry lists together.
1365 *
1366 * The second (src) list will be destroyed automatically upon completion of this function. Any value pointers for the
1367 * list will be directly copied over to the destination list, they will not be duplicated.
1368 *
1369 * \param[in,out] dest Pointer by reference to the list receiving the values.
1370 * if this is NULL, the pointer will simply be switched out for src.
1371 * \param[in,out] src Pointer to the list giving up its values.
1372 */
1374
1375
1376/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1377
1378/*! List the contents of a directory by walking the tree.
1379 *
1380 * The tree will be walked depth first. When searching for both directory and file contents, the directory entry
1381 * will come after entries for the directories contents. Support for modifying while walking is OS and filesystem
1382 * dependent. Thus, behavior while modifying the contents of a directory during a walk is undefined.
1383 *
1384 * \param[in] path The path to walk.
1385 * \param[in] pat Glob style pattern to filter entries in the tree. Only entries matching the pattern will
1386 * be included in the output. NULL, "", and "*" will match all entries.
1387 * \param[in] filter M_fs_dir_walk_filter_t flags controlling the behavior of the walk.
1388 * \param[in] cb Callback for entries.
1389 * \param[in] thunk Additional data passed to the callback.
1390 */
1391M_API void M_fs_dir_walk(const char *path, const char *pat, M_uint32 filter, M_fs_dir_walk_cb_t cb, void *thunk);
1392
1393
1394/*! List the contents of a directory by walking the tree.
1395 *
1396 * \param[in] path The path to walk.
1397 * \param[in] pat Glob style pattern to filter entries in the tree. Only entries matching the pattern will
1398 * be included in the output. NULL, "", and "*" will match all entries.
1399 * \param[in] filter M_fs_dir_walk_filter_t flags controlling the behavior of the walk.
1400 *
1401 * \return A list of entries in the dir. The entries are relative to the specified path.
1402 */
1403M_API M_fs_dir_entries_t *M_fs_dir_walk_entries(const char *path, const char *pat, M_uint32 filter);
1404
1405
1406/*! List the contents of a directory as a list of string paths by walking the tree.
1407 *
1408 * \param[in] path The path to walk.
1409 * \param[in] pat Glob style pattern to filter entries in the tree. Only entries matching the pattern will
1410 * be included in the output. NULL, "", and "*" will match all entries.
1411 * \param[in] filter M_fs_dir_walk_filter_t flags controlling the behavior of the walk.
1412 *
1413 * \return A list of string paths that are the contents of the dir. The entries are relative to the specified
1414 * path. Directory entries in the output list will end with the OS path separator.
1415 */
1416M_API M_list_str_t *M_fs_dir_walk_strs(const char *path, const char *pat, M_uint32 filter);
1417
1418
1419/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1420
1421/*! Create a directory.
1422 *
1423 * \param[in] path The directory to create.
1424 * \param[in] create_parents When M_TRUE create the any parents of the last directory if they do not exist instead of
1425 * erroring.
1426 * \param[in] perms Additional perms to apply to the created directory.
1427 If perms is NULL a default perms of rw-rw-r-- & ~umask is used.
1428 *
1429 * \return Result.
1430 */
1431M_API M_fs_error_t M_fs_dir_mkdir(const char *path, M_bool create_parents, M_fs_perms_t *perms);
1432
1433/*! @} */
1434
1435
1436/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1437
1438/*! \addtogroup m_fs_progress Progress
1439 * \ingroup m_fs
1440 *
1441 * @{
1442 */
1443
1444/*! Get the path.
1445 *
1446 * \param[in] p Progress.
1447 *
1448 * \return The path.
1449 */
1450M_API const char *M_fs_progress_get_path(const M_fs_progress_t *p);
1451
1452
1453/*! Get file type.
1454 *
1455 * \param[in] p Progress.
1456 *
1457 * \return The type.
1458 */
1460
1461
1462/*! Get result of the operation at this stage for the current file being processed.
1463 *
1464 * \param[in] p Progress.
1465 *
1466 * \return The result.
1467 */
1469
1470
1471/*! Get total number of files to process.
1472 *
1473 * \param[in] p Progress.
1474 *
1475 * \return The total number of files.
1476 */
1478
1479
1480/*! Get current number being processing.
1481 *
1482 * \param[in] p Progress.
1483 *
1484 * \return The current number being processed.
1485 */
1487
1488
1489/*! Get the total size of all files.
1490 *
1491 * \param[in] p Progress.
1492 *
1493 * \return The total size.
1494 */
1496
1497
1498/*! Get total number of bytes that have been processed.
1499 *
1500 * \param[in] p Progress.
1501 *
1502 * \return The number of bytes processed.
1503 */
1505
1506
1507/*! Get size of the current file.
1508 *
1509 * \param[in] p Progress.
1510 *
1511 * \return The size of the current file.
1512 */
1514
1515
1516/*! Get number of bytes of the current file that have been processed.
1517 *
1518 * \param[in] p Progress.
1519 *
1520 * \return The number of bytes processed for the current file.
1521 */
1523
1524/*! @} */
1525
1526
1527/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1528
1529/*! \addtogroup m_fs_operations File System Operations
1530 * \ingroup m_fs
1531 *
1532 * @{
1533 */
1534
1535/*! Create a soft link.
1536 *
1537 * \param[in] target The target to link.
1538 * \param[in] link_name The link to create.
1539 *
1540 * \return Result.
1541 */
1542M_API M_fs_error_t M_fs_symlink(const char *target, const char *link_name);
1543
1544
1545/*! Move a file or directory from one location to another.
1546 *
1547 * If moving a file to an existing directory the file will be copied into the directory with the same name.
1548 *
1549 * \param[in] path_old The file to move.
1550 * \param[in] path_new The location the file should be moved to.
1551 * \param[in] mode M_fs_file_mode_t mode. Only supports OVERWRITE. If overwrite is set the move will
1552 * overwrite the file if it exists. Without this set the move operation will fail if
1553 * the file exists.
1554 * \param[in] cb Progress callback that should be called.
1555 * \param[in] progress_flags M_fs_progress_flags_t flags to control what data should be set in the progress callback.
1556 *
1557 * \return Result.
1558 */
1559M_API M_fs_error_t M_fs_move(const char *path_old, const char *path_new, M_uint32 mode, M_fs_progress_cb_t cb, M_uint32 progress_flags);
1560
1561
1562/*! Copy a file or directory to a new location.
1563 *
1564 * If copying a file to an existing directory the file will be copied into the directory with the same name.
1565 *
1566 * \param[in] path_old The file to move.
1567 * \param[in] path_new The location the file should be copied to.
1568 * \param[in] mode M_fs_file_mode_t mode. Only supports OVERWRITE. If overwrite is set the move will
1569 * overwrite the file if it exists. Without this set the move operation will fail if
1570 * the file exists.
1571 * \param[in] cb Progress callback that should be called.
1572 * \param[in] progress_flags M_fs_progress_flags_t flags to control what data should be set in the progress callback.
1573 *
1574 * \return Result.
1575 */
1576M_API M_fs_error_t M_fs_copy(const char *path_old, const char *path_new, M_uint32 mode, M_fs_progress_cb_t cb, M_uint32 progress_flags);
1577
1578
1579/*! Delete a file or directory.
1580 *
1581 * \param[in] path The file to delete.
1582 * \param[in] remove_children Only applies to directories. If M_TRUE all contents of the directory will be removed in
1583 * addition to the directory itself. If M_FALSE and the directory is not empty an error
1584 * will be returned.
1585 * \param[in] cb Progress callback function. Most useful when deleting a directory with children
1586 * and remove_children is M_TRUE. Will be called after a delete action is completed (each
1587 * child is deleted and the passed path itself is deleted).
1588 * \param[in] progress_flags M_fs_progress_flags_t flags to control what data should be set in the progress callback.
1589 *
1590 * \return Result.
1591 */
1592M_API M_fs_error_t M_fs_delete(const char *path, M_bool remove_children, M_fs_progress_cb_t cb, M_uint32 progress_flags);
1593
1594/*! @} */
1595
1596__END_DECLS
1597
1598#endif /* __M_FS_H__ */
M_bool(* M_fs_dir_walk_cb_t)(const char *path, M_fs_dir_entry_t *entry, M_fs_error_t res, void *thunk)
Definition: m_fs.h:404
M_fs_perms_who_t
Definition: m_fs.h:205
struct M_fs_info M_fs_info_t
Definition: m_fs.h:127
M_fs_file_read_write_t
Definition: m_fs.h:261
struct M_fs_perms M_fs_perms_t
Definition: m_fs.h:122
struct M_fs_progress M_fs_progress_t
Definition: m_fs.h:147
struct M_fs_dir_entry M_fs_dir_entry_t
Definition: m_fs.h:137
M_fs_info_flags_t
Definition: m_fs.h:233
M_fs_dir_walk_filter_t
Definition: m_fs.h:288
M_fs_file_seek_t
Definition: m_fs.h:271
M_bool(* M_fs_progress_cb_t)(const M_fs_progress_t *p)
Definition: m_fs.h:416
M_fs_dir_sort_t
Definition: m_fs.h:340
struct M_fs_file M_fs_file_t
Definition: m_fs.h:132
M_fs_file_mode_t
Definition: m_fs.h:245
M_fs_type_t
Definition: m_fs.h:375
M_fs_progress_flags_t
Definition: m_fs.h:357
M_fs_error_t
Definition: m_fs.h:154
struct M_fs_dir_entries M_fs_dir_entries_t
Definition: m_fs.h:142
M_fs_iostream_t
Definition: m_fs.h:180
M_fs_perms_type_t
Definition: m_fs.h:197
M_fs_path_norm_t
Definition: m_fs.h:213
M_fs_file_sync_t
Definition: m_fs.h:279
M_fs_system_t
Definition: m_fs.h:367
M_fs_perms_mode_t
Definition: m_fs.h:188
@ M_FS_PERMS_WHO_GROUP
Definition: m_fs.h:207
@ M_FS_PERMS_WHO_OTHER
Definition: m_fs.h:208
@ M_FS_PERMS_WHO_USER
Definition: m_fs.h:206
@ M_FS_FILE_RW_FULLBUF
Definition: m_fs.h:263
@ M_FS_FILE_RW_NORMAL
Definition: m_fs.h:262
@ M_FS_PATH_INFO_FLAGS_NONE
Definition: m_fs.h:234
@ M_FS_PATH_INFO_FLAGS_FOLLOW_SYMLINKS
Definition: m_fs.h:235
@ M_FS_PATH_INFO_FLAGS_BASIC
Definition: m_fs.h:237
@ M_FS_DIR_WALK_FILTER_HIDDEN
Definition: m_fs.h:297
@ M_FS_DIR_WALK_FILTER_AS_SET
Definition: m_fs.h:305
@ M_FS_DIR_WALK_FILTER_SYMLINK
Definition: m_fs.h:295
@ M_FS_DIR_WALK_FILTER_RECURSE
Definition: m_fs.h:299
@ M_FS_DIR_WALK_FILTER_JAIL_FAIL
Definition: m_fs.h:303
@ M_FS_DIR_WALK_FILTER_READ_INFO_FULL
Definition: m_fs.h:324
@ M_FS_DIR_WALK_FILTER_JAIL_SKIP
Definition: m_fs.h:304
@ M_FS_DIR_WALK_FILTER_READ_INFO_BASIC
Definition: m_fs.h:316
@ M_FS_DIR_WALK_FILTER_FOLLOWSYMLINK
Definition: m_fs.h:302
@ M_FS_DIR_WALK_FILTER_PIPE
Definition: m_fs.h:294
@ M_FS_DIR_WALK_FILTER_DIR
Definition: m_fs.h:293
@ M_FS_DIR_WALK_FILTER_CASECMP
Definition: m_fs.h:329
@ M_FS_DIR_WALK_FILTER_NONE
Definition: m_fs.h:289
@ M_FS_DIR_WALK_FILTER_FILE
Definition: m_fs.h:291
@ M_FS_FILE_SEEK_END
Definition: m_fs.h:273
@ M_FS_FILE_SEEK_BEGIN
Definition: m_fs.h:272
@ M_FS_FILE_SEEK_CUR
Definition: m_fs.h:274
@ M_FS_DIR_SORT_ISHIDDEN
Definition: m_fs.h:344
@ M_FS_DIR_SORT_MTIME
Definition: m_fs.h:350
@ M_FS_DIR_SORT_CTIME
Definition: m_fs.h:351
@ M_FS_DIR_SORT_ISDIR
Definition: m_fs.h:343
@ M_FS_DIR_SORT_NAME_CMP
Definition: m_fs.h:342
@ M_FS_DIR_SORT_ATIME
Definition: m_fs.h:349
@ M_FS_DIR_SORT_SIZE
Definition: m_fs.h:348
@ M_FS_DIR_SORT_NONE
Definition: m_fs.h:345
@ M_FS_DIR_SORT_NAME_CASECMP
Definition: m_fs.h:341
@ M_FS_FILE_MODE_READ
Definition: m_fs.h:247
@ M_FS_FILE_MODE_NOCLOSEEXEC
Definition: m_fs.h:256
@ M_FS_FILE_MODE_PRESERVE_PERMS
Definition: m_fs.h:252
@ M_FS_FILE_MODE_OVERWRITE
Definition: m_fs.h:251
@ M_FS_FILE_MODE_NONE
Definition: m_fs.h:246
@ M_FS_FILE_MODE_APPEND
Definition: m_fs.h:250
@ M_FS_FILE_MODE_NOCREATE
Definition: m_fs.h:249
@ M_FS_FILE_MODE_WRITE
Definition: m_fs.h:248
@ M_FS_TYPE_SYMLINK
Definition: m_fs.h:380
@ M_FS_TYPE_DIR
Definition: m_fs.h:378
@ M_FS_TYPE_UNKNOWN
Definition: m_fs.h:376
@ M_FS_TYPE_FILE
Definition: m_fs.h:377
@ M_FS_TYPE_PIPE
Definition: m_fs.h:379
@ M_FS_PROGRESS_NOEXTRA
Definition: m_fs.h:358
@ M_FS_PROGRESS_SIZE_CUR
Definition: m_fs.h:361
@ M_FS_PROGRESS_SIZE_TOTAL
Definition: m_fs.h:360
@ M_FS_PROGRESS_COUNT
Definition: m_fs.h:359
@ M_FS_ERROR_READONLY
Definition: m_fs.h:162
@ M_FS_ERROR_QUOTA
Definition: m_fs.h:163
@ M_FS_ERROR_CANCELED
Definition: m_fs.h:175
@ M_FS_ERROR_IO
Definition: m_fs.h:160
@ M_FS_ERROR_NAMETOOLONG
Definition: m_fs.h:165
@ M_FS_ERROR_ISDIR
Definition: m_fs.h:169
@ M_FS_ERROR_INVALID
Definition: m_fs.h:157
@ M_FS_ERROR_NOT_SUPPORTED
Definition: m_fs.h:159
@ M_FS_ERROR_SEEK
Definition: m_fs.h:161
@ M_FS_ERROR_GENERIC
Definition: m_fs.h:156
@ M_FS_ERROR_NOTDIR
Definition: m_fs.h:170
@ M_FS_ERROR_LINK_LOOP
Definition: m_fs.h:172
@ M_FS_ERROR_DIR_NOTEMPTY
Definition: m_fs.h:171
@ M_FS_ERROR_FILE_EXISTS
Definition: m_fs.h:166
@ M_FS_ERROR_FILE_2BIG
Definition: m_fs.h:167
@ M_FS_ERROR_FILE_2MANY
Definition: m_fs.h:168
@ M_FS_ERROR_DNE
Definition: m_fs.h:164
@ M_FS_ERROR_PERMISSION
Definition: m_fs.h:158
@ M_FS_ERROR_NOT_SAMEDEV
Definition: m_fs.h:174
@ M_FS_ERROR_LINK_2MANY
Definition: m_fs.h:173
@ M_FS_ERROR_SUCCESS
Definition: m_fs.h:155
@ M_FS_IOSTREAM_OUT
Definition: m_fs.h:182
@ M_FS_IOSTREAM_IN
Definition: m_fs.h:181
@ M_FS_IOSTREAM_ERR
Definition: m_fs.h:183
@ M_FS_PERMS_TYPE_EXACT
Definition: m_fs.h:198
@ M_FS_PERMS_TYPE_REMOVE
Definition: m_fs.h:200
@ M_FS_PERMS_TYPE_ADD
Definition: m_fs.h:199
@ M_FS_PATH_NORM_ABSOLUTE
Definition: m_fs.h:215
@ M_FS_PATH_NORM_SYMLINKS_FAILDNE
Definition: m_fs.h:219
@ M_FS_PATH_NORM_FOLLOWSYMLINKS
Definition: m_fs.h:217
@ M_FS_PATH_NORM_NONE
Definition: m_fs.h:214
@ M_FS_PATH_NORM_NOPARENT
Definition: m_fs.h:224
@ M_FS_PATH_NORM_SYMLINKS_FAILDNELAST
Definition: m_fs.h:221
@ M_FS_PATH_NORM_HOME
Definition: m_fs.h:223
@ M_FS_FILE_SYNC_NONE
Definition: m_fs.h:280
@ M_FS_FILE_SYNC_BUFFER
Definition: m_fs.h:281
@ M_FS_FILE_SYNC_OS
Definition: m_fs.h:282
@ M_FS_SYSTEM_AUTO
Definition: m_fs.h:368
@ M_FS_SYSTEM_WINDOWS
Definition: m_fs.h:369
@ M_FS_SYSTEM_UNIX
Definition: m_fs.h:370
@ M_FS_PERMS_MODE_READ
Definition: m_fs.h:190
@ M_FS_PERMS_MODE_WRITE
Definition: m_fs.h:191
@ M_FS_PERMS_MODE_EXEC
Definition: m_fs.h:192
@ M_FS_PERMS_MODE_NONE
Definition: m_fs.h:189
M_fs_error_t M_fs_dir_mkdir(const char *path, M_bool create_parents, M_fs_perms_t *perms)
void M_fs_dir_entries_merge(M_fs_dir_entries_t **dest, M_fs_dir_entries_t *src) M_FREE(2)
size_t M_fs_dir_entries_len(const M_fs_dir_entries_t *d)
M_bool M_fs_dir_entries_remove_at(M_fs_dir_entries_t *d, size_t idx)
void M_fs_dir_entries_sort(M_fs_dir_entries_t *d, M_fs_dir_sort_t primary_sort, M_bool primary_asc, M_fs_dir_sort_t secondary_sort, M_bool secondary_asc)
M_bool M_fs_dir_entry_get_ishidden(const M_fs_dir_entry_t *entry)
M_list_str_t * M_fs_dir_walk_strs(const char *path, const char *pat, M_uint32 filter)
const M_fs_info_t * M_fs_dir_entry_get_info(const M_fs_dir_entry_t *entry)
const char * M_fs_dir_entry_get_resolved_name(const M_fs_dir_entry_t *entry)
void M_fs_dir_entry_destroy(M_fs_dir_entry_t *entry) M_FREE(1)
M_fs_type_t M_fs_dir_entry_get_type(const M_fs_dir_entry_t *entry)
void M_fs_dir_entries_destroy(M_fs_dir_entries_t *d) M_FREE(1)
const M_fs_dir_entry_t * M_fs_dir_entries_at(const M_fs_dir_entries_t *d, size_t idx)
M_fs_dir_entries_t * M_fs_dir_walk_entries(const char *path, const char *pat, M_uint32 filter)
void M_fs_dir_walk(const char *path, const char *pat, M_uint32 filter, M_fs_dir_walk_cb_t cb, void *thunk)
M_bool M_fs_dir_entries_remove_range(M_fs_dir_entries_t *d, size_t start, size_t end)
const char * M_fs_dir_entry_get_name(const M_fs_dir_entry_t *entry)
M_fs_dir_entry_t * M_fs_dir_entries_take_at(M_fs_dir_entries_t *d, size_t idx)
void M_fs_file_close(M_fs_file_t *fd)
M_fs_error_t M_fs_file_seek(M_fs_file_t *fd, M_int64 offset, M_fs_file_seek_t from)
M_fs_error_t M_fs_file_read(M_fs_file_t *fd, unsigned char *buf, size_t buf_len, size_t *read_len, M_uint32 flags)
M_fs_error_t M_fs_file_read_bytes(const char *path, size_t max_read, unsigned char **buf, size_t *bytes_read)
M_fs_error_t M_fs_file_open_iostream(M_fs_file_t **fd, M_fs_iostream_t stream)
M_fs_error_t M_fs_file_open(M_fs_file_t **fd, const char *path, size_t buf_size, M_uint32 mode, const M_fs_perms_t *perms)
M_fs_error_t M_fs_file_sync(M_fs_file_t *fd, M_uint32 type)
M_fs_error_t M_fs_file_write_bytes(const char *path, const unsigned char *buf, size_t write_len, M_uint32 mode, size_t *bytes_written)
M_fs_error_t M_fs_file_write(M_fs_file_t *fd, const unsigned char *buf, size_t count, size_t *wrote_len, M_uint32 flags)
void M_fs_info_destroy(M_fs_info_t *info) M_FREE(1)
M_time_t M_fs_info_get_mtime(const M_fs_info_t *info)
M_time_t M_fs_info_get_btime(const M_fs_info_t *info)
const char * M_fs_info_get_group(const M_fs_info_t *info)
M_uint64 M_fs_info_get_size(const M_fs_info_t *info)
M_fs_error_t M_fs_info_file(M_fs_info_t **info, M_fs_file_t *fd, M_uint32 flags)
M_time_t M_fs_info_get_atime(const M_fs_info_t *info)
M_fs_type_t M_fs_info_get_type(const M_fs_info_t *info)
M_bool M_fs_info_get_ishidden(const M_fs_info_t *info)
M_time_t M_fs_info_get_ctime(const M_fs_info_t *info)
M_fs_error_t M_fs_info(M_fs_info_t **info, const char *path, M_uint32 flags)
const char * M_fs_info_get_user(const M_fs_info_t *info)
const M_fs_perms_t * M_fs_info_get_perms(const M_fs_info_t *info)
M_fs_error_t M_fs_move(const char *path_old, const char *path_new, M_uint32 mode, M_fs_progress_cb_t cb, M_uint32 progress_flags)
M_fs_error_t M_fs_copy(const char *path_old, const char *path_new, M_uint32 mode, M_fs_progress_cb_t cb, M_uint32 progress_flags)
M_fs_error_t M_fs_symlink(const char *target, const char *link_name)
M_fs_error_t M_fs_delete(const char *path, M_bool remove_children, M_fs_progress_cb_t cb, M_uint32 progress_flags)
char * M_fs_path_user_confdir(M_fs_system_t sys_type)
M_fs_error_t M_fs_path_get_cwd(char **cwd)
M_fs_error_t M_fs_path_set_cwd(const char *path)
size_t M_fs_path_get_path_max(M_fs_system_t sys_type)
M_fs_error_t M_fs_path_readlink(char **out, const char *path)
char * M_fs_path_basename(const char *path, M_fs_system_t sys_type)
M_bool M_fs_path_ishidden(const char *path, const M_fs_info_t *info)
char * M_fs_path_tmpdir(M_fs_system_t sys_type)
M_bool M_fs_path_isunc(const char *p)
M_bool M_fs_path_isabs(const char *p, M_fs_system_t sys_type)
char * M_fs_path_join_parts(const M_list_str_t *path, M_fs_system_t sys_type)
char * M_fs_path_join_vparts(M_fs_system_t sys_type, size_t num,...)
char * M_fs_path_join_resolved(const char *path, const char *part, const char *resolved_name, M_fs_system_t sys_type)
M_list_str_t * M_fs_path_componentize_path(const char *path, M_fs_system_t sys_type)
char * M_fs_path_join(const char *p1, const char *p2, M_fs_system_t sys_type)
M_fs_error_t M_fs_path_norm(char **out, const char *path, M_uint32 flags, M_fs_system_t sys_type)
char * M_fs_path_dirname(const char *path, M_fs_system_t sys_type)
const char * M_fs_perms_get_group(const M_fs_perms_t *perms)
M_bool M_fs_perms_get_isset(const M_fs_perms_t *perms, M_fs_perms_who_t who)
const char * M_fs_perms_get_user(const M_fs_perms_t *perms)
M_bool M_fs_perms_get_dir_isset(const M_fs_perms_t *perms, M_fs_perms_who_t who)
M_fs_error_t M_fs_perms_set_group(M_fs_perms_t *perms, const char *group)
void M_fs_perms_destroy(M_fs_perms_t *perms) M_FREE(1)
M_fs_error_t M_fs_perms_set_perms(const M_fs_perms_t *perms, const char *path)
M_fs_perms_t * M_fs_perms_create(void) M_MALLOC
M_fs_error_t M_fs_perms_can_access(const char *path, M_uint32 mode)
void M_fs_perms_unset_dir_mode(M_fs_perms_t *perms, M_fs_perms_who_t who)
void M_fs_perms_set_dir_mode(M_fs_perms_t *perms, M_uint32 mode, M_fs_perms_who_t who, M_fs_perms_type_t type)
void M_fs_perms_merge(M_fs_perms_t **dest, M_fs_perms_t *src) M_FREE(2)
M_fs_perms_type_t M_fs_perms_get_dir_type(const M_fs_perms_t *perms, M_fs_perms_who_t who)
M_fs_error_t M_fs_perms_set_user(M_fs_perms_t *perms, const char *user)
void M_fs_perms_unset_mode(M_fs_perms_t *perms, M_fs_perms_who_t who)
M_fs_perms_type_t M_fs_perms_get_type(const M_fs_perms_t *perms, M_fs_perms_who_t who)
M_uint32 M_fs_perms_get_dir_mode(const M_fs_perms_t *perms, M_fs_perms_who_t who)
M_uint32 M_fs_perms_get_mode(const M_fs_perms_t *perms, M_fs_perms_who_t who)
void M_fs_perms_set_mode(M_fs_perms_t *perms, M_uint32 mode, M_fs_perms_who_t who, M_fs_perms_type_t type)
M_fs_error_t M_fs_perms_set_perms_file(const M_fs_perms_t *perms, M_fs_file_t *fd)
M_fs_perms_t * M_fs_perms_dup(const M_fs_perms_t *perms) M_MALLOC
M_uint64 M_fs_progress_get_size_total(const M_fs_progress_t *p)
const char * M_fs_progress_get_path(const M_fs_progress_t *p)
M_fs_type_t M_fs_progress_get_type(const M_fs_progress_t *p)
M_uint64 M_fs_progress_get_size_current_progress(const M_fs_progress_t *p)
M_uint64 M_fs_progress_get_size_current(const M_fs_progress_t *p)
M_uint64 M_fs_progress_get_size_total_progess(const M_fs_progress_t *p)
M_uint64 M_fs_progress_get_count_total(const M_fs_progress_t *p)
M_fs_error_t M_fs_progress_get_result(const M_fs_progress_t *p)
M_uint64 M_fs_progress_get_count(const M_fs_progress_t *p)
struct M_list_str M_list_str_t
Definition: m_list_str.h:80
M_int64 M_time_t
Definition: m_time.h:161