This is the same as f_file_touch() and f_file_touch_at(), except that a directory is created if the file does not exist.
#ifndef _di_f_directory_create_
f_return_status f_directory_create(const f_string path, const mode_t mode) {
-
- if (mkdir(path, mode) < 0) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == EDQUOT) return F_status_set_error(F_filesystem_quota_block);
- if (errno == EEXIST) return F_status_set_error(F_file_found);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EINVAL) return F_status_set_error(F_parameter);
- if (errno == ELOOP) return F_status_set_error(F_loop);
- if (errno == EMLINK) return F_status_set_error(F_directory_link_max);
- if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
- if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOMEM) return F_status_set_error(F_memory_out);
- if (errno == ENOSPC) return F_status_set_error(F_space_not);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EPERM) return F_status_set_error(F_prohibited);
- if (errno == EROFS) return F_status_set_error(F_read_only);
-
- return F_status_set_error(F_failure);
- }
-
- return F_none;
+ return private_f_directory_create(path, mode);
}
#endif // _di_f_directory_create_
if (at_id <= 0) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
- if (mkdirat(at_id, path, mode) < 0) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
- if (errno == EDQUOT) return F_status_set_error(F_filesystem_quota_block);
- if (errno == EEXIST) return F_status_set_error(F_file_found);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EINVAL) return F_status_set_error(F_parameter);
- if (errno == ELOOP) return F_status_set_error(F_loop);
- if (errno == EMLINK) return F_status_set_error(F_directory_link_max);
- if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
- if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOMEM) return F_status_set_error(F_memory_out);
- if (errno == ENOSPC) return F_status_set_error(F_space_not);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EPERM) return F_status_set_error(F_prohibited);
- if (errno == EROFS) return F_status_set_error(F_read_only);
-
- return F_status_set_error(F_failure);
- }
-
- return F_none;
+ return private_f_directory_create_at(at_id, path, mode);
}
#endif // _di_f_directory_create_at_
}
#endif // _di_f_directory_remove_custom_
+#ifndef _di_f_directory_touch_
+ f_return_status f_directory_touch(const f_string path, const mode_t mode) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ f_status status = F_none;
+ struct stat file_stat;
+
+ memset(&file_stat, 0, sizeof(struct stat));
+
+ if (stat(path, &file_stat) < 0) {
+
+ if (errno == ENOENT) {
+ return private_f_directory_create(path, mode);
+ }
+
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+
+ return F_status_set_error(F_file_stat);
+ }
+
+ if (utimensat(f_directory_at_current_working, path, 0, 0) < 0) {
+
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+ if (errno == ESRCH) return F_status_set_error(F_search);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_directory_touch_
+
+#ifndef _di_f_directory_touch_at_
+ f_return_status f_directory_touch_at(const int at_id, const f_string path, const mode_t mode, const int flag) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ f_status status = F_none;
+ struct stat file_stat;
+
+ memset(&file_stat, 0, sizeof(struct stat));
+
+ if (fstatat(at_id, path, &file_stat, flag) < 0) {
+
+ if (errno == ENOENT) {
+ return private_f_directory_create_at(at_id, path, mode);
+ }
+
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
+
+ return F_status_set_error(F_file_stat);
+ }
+
+ if (utimensat(at_id, path, 0, flag) < 0) {
+
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+ if (errno == ESRCH) return F_status_set_error(F_search);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_directory_touch_at_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern f_return_status f_directory_remove_custom(const f_string path, const int recursion_max, const bool preserve, int (*custom) (const char *, const struct stat *, int, struct FTW *));
#endif // _di_f_directory_remove_custom_
+/**
+ * Update the files access and modification timestamp, creating the directory if it does not already exist.
+ *
+ * When the file is created, it is created as a directory file.
+ *
+ * @param path
+ * The path file name.
+ * @param mode
+ * The file mode to use when (directory) file is created.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_busy (with error bit) if filesystem is too busy to perforrm write.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ * F_file_found (with error bit) if a file aleady exists at the path.
+ * F_file_open_max (with error bit) when system-wide max open files is reached.
+ * F_filesystem_quota_block (with error bit) if filesystem's disk blocks or inodes are exhausted.
+ * F_filesystem_quota_reached (with error bit) quota reached of filesystem is out of space.
+ * F_interrupted (with error bit) when program received an interrupt signal, halting operation.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if filesystem does not allow for creating or linking.
+ * F_read_only (with error bit) if filesystem is read-only.
+ * F_search (with error bit) if search permission is denied for one of the paths to the file.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see utimensat()
+ */
+#ifndef _di_f_directory_touch_
+ extern f_return_status f_directory_touch(const f_string path, const mode_t mode);
+#endif // _di_f_directory_touch_
+
+/**
+ * Update the files access and modification timestamp, creating the file if it does not already exist.
+ *
+ * When the file is created, it is created as a directory file.
+ *
+ * @param at_id
+ * The parent directory, as an open directory file descriptor, in which path is relative to.
+ * @param path
+ * The path file name.
+ * @param mode
+ * The file mode to use when (directory) file is created.
+ * @param flag
+ * Any valid flag, such as f_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_busy (with error bit) if filesystem is too busy to perforrm write.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ * F_file_found (with error bit) if a file aleady exists at the path (when calling utimensat()).
+ * F_file_open_max (with error bit) when system-wide max open files is reached.
+ * F_filesystem_quota_block (with error bit) if filesystem's disk blocks or inodes are exhausted.
+ * F_filesystem_quota_reached (with error bit) quota reached of filesystem is out of space.
+ * F_interrupted (with error bit) when program received an interrupt signal, halting operation.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if filesystem does not allow for creating or linking.
+ * F_read_only (with error bit) if filesystem is read-only.
+ * F_search (with error bit) if search permission is denied for one of the paths to the file.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see utimensat()
+ */
+#ifndef _di_f_directory_touch_at_
+ extern f_return_status f_directory_touch_at(const int at_id, const f_string path, const mode_t mode, const int flag);
+#endif // _di_f_directory_touch_at_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
+#if !defined(_di_f_directory_create_) || !defined(_di_f_directory_touch_)
+ f_return_status private_f_directory_create(const f_string path, const mode_t mode) {
+
+ if (mkdir(path, mode) < 0) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EDQUOT) return F_status_set_error(F_filesystem_quota_block);
+ if (errno == EEXIST) return F_status_set_error(F_file_found);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == EMLINK) return F_status_set_error(F_directory_link_max);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == ENOSPC) return F_status_set_error(F_space_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // !defined(_di_f_directory_create_) || !defined(_di_f_directory_touch_)
+
+#if !defined(_di_f_directory_create_at_) || !defined(_di_f_directory_touch_at_)
+ f_return_status private_f_directory_create_at(const int at_id, const f_string path, const mode_t mode) {
+
+ if (mkdirat(at_id, path, mode) < 0) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
+ if (errno == EDQUOT) return F_status_set_error(F_filesystem_quota_block);
+ if (errno == EEXIST) return F_status_set_error(F_file_found);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == EMLINK) return F_status_set_error(F_directory_link_max);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == ENOSPC) return F_status_set_error(F_space_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // !defined(_di_f_directory_create_at_) || !defined(_di_f_directory_touch_at_)
+
#if !defined(_di_f_directory_remove_)
int private_f_directory_remove_recursively(const char *path, const struct stat *file_stat, int type, struct FTW *entity) {
if (entity->level == 0) return 0;
#endif
/**
+ * Private implementation of f_directory_create().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param path
+ * The file path to the directory.
+ * @param mode
+ * The directory mode to use when creating.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_directory_link_max (with error bit) max links limit reached or exceeded.
+ * F_file_found (with error bit) of a directory aleady exists at the path.
+ * F_file_found_not (with error bit) if a file within the path is not found (such as a broken symbolic link).
+ * F_filesystem_quota_block (with error bit) if filesystem's disk blocks or inodes are exhausted.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if filesystem does not allow for removing.
+ * F_read_only (with error bit) if file is read-only.
+ * F_space_not (with error bit) if filesystem is out of space (or filesystem quota is reached).
+ * F_failure (with error bit) for any other error.
+ *
+ * @see f_directory_create()
+ * @see f_directory_touch()
+ */
+#if !defined(_di_f_directory_create_) || !defined(_di_f_directory_touch_)
+ extern f_return_status private_f_directory_create(const f_string path, const mode_t mode) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_directory_create_) || !defined(_di_f_directory_touch_)
+
+/**
+ * Private implementation of f_directory_create_at().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param at_id
+ * The parent directory, as an open directory file descriptor, in which path is relative to.
+ * @param path
+ * The file path to the directory.
+ * @param mode
+ * The directory mode to use when creating.
+ *
+ * @return
+ * F_none on success.
+ * F_access_denied (with error bit) on access denied.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ * F_directory_link_max (with error bit) max links limit reached or exceeded.
+ * F_file_found (with error bit) of a directory aleady exists at the path.
+ * F_file_found_not (with error bit) if a file within the path is not found (such as a broken symbolic link).
+ * F_filesystem_quota_block (with error bit) if filesystem's disk blocks or inodes are exhausted.
+ * F_loop (with error bit) on loop error.
+ * F_memory_out (with error bit) if out of memory.
+ * F_name (with error bit) on path name error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if filesystem does not allow for removing.
+ * F_read_only (with error bit) if file is read-only.
+ * F_space_not (with error bit) if filesystem is out of space (or filesystem quota is reached).
+ * F_failure (with error bit) for any other error.
+ *
+ * @see f_directory_create_at()
+ * @see f_directory_touch_at()
+ */
+#if !defined(_di_f_directory_create_at_) || !defined(_di_f_directory_touch_at_)
+ extern f_return_status private_f_directory_create_at(const int at_id, const f_string path, const mode_t mode) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_directory_create_at_) || !defined(_di_f_directory_touch_at_)
+
+/**
* A special function intended to be used directly by nftw().
*
* This is intended to be used by the specified function as a function pointer and therefore follows the required structure.