The move function should operate as a move would expect, which includes cross-filesystem.
Rename the f_file_move() to f_file_rename() and ensure the limitations are documented.
The fll_file_move() calls f_file_rename() and if that fails due to being across filesystems, then call the appropriate clone and remove functions depending on whether or not the source is a file or directory.
I try to avoid having any output strings in the project that is below level 3 (but level 2 may have exceptions).
Rewrite parts of the directory copy and clone functions to use passed functions instead of directly printing.
Cleanup some function's documentation.
#endif // _di_f_directory_open_at_
#ifndef _di_f_directory_remove_
- f_return_status f_directory_remove(const f_string_t path, const int recursion_max, const bool preserve) {
+ f_return_status f_directory_remove(const f_string_t path, const int depth_max, const bool preserve) {
#ifndef _di_level_0_parameter_checking_
- if (recursion_max < 0) return F_status_set_error(F_parameter);
+ if (depth_max < 0) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
int result = 0;
- if (recursion_max) {
- result = nftw(path, private_f_directory_remove_recursively, recursion_max, FTW_DEPTH | FTW_PHYS);
+ if (depth_max) {
+ result = nftw(path, private_f_directory_remove_recursively, depth_max, FTW_DEPTH | FTW_PHYS);
if (result == 0 && !preserve) {
result = remove(path);
#endif // _di_f_directory_remove_
#ifndef _di_f_directory_remove_custom_
- f_return_status f_directory_remove_custom(const f_string_t path, const int recursion_max, const bool preserve, int (*custom) (const char *, const struct stat *, int, struct FTW *)) {
+ f_return_status f_directory_remove_custom(const f_string_t path, const int depth_max, const bool preserve, int (*custom) (const char *, const struct stat *, int, struct FTW *)) {
#ifndef _di_level_0_parameter_checking_
- if (recursion_max < 0) return F_status_set_error(F_parameter);
+ if (depth_max < 0) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
int result = 0;
- if (recursion_max) {
- result = nftw(path, custom, recursion_max, FTW_DEPTH | FTW_PHYS);
+ if (depth_max) {
+ result = nftw(path, custom, depth_max, FTW_DEPTH | FTW_PHYS);
if (result == 0 && !preserve) {
result = remove(path);
*
* @param path
* The file path to the directory.
- * @param recursion_max
+ * @param depth_max
* Represents the max recursion depth, set to 0 to disable recursive delete.
* @param preserve
- * When recursion_max > 0, this designates whether or not to preserve the directory at path.
+ * When depth_max > 0, this designates whether or not to preserve the directory at path.
* If TRUE, then only the content within the directory is deleted.
* If FALSE, then the directory at path and its content are deleted.
- * When recursion_max is 0, then this should only be FALSE (setting this to TRUE would be a no-op).
+ * When depth_max is 0, then this should only be FALSE (setting this to TRUE would be a no-op).
*
* @return
* F_none on success.
* @see remove()
*/
#ifndef _di_f_directory_remove_
- extern f_return_status f_directory_remove(const f_string_t path, const int recursion_max, const bool preserve);
+ extern f_return_status f_directory_remove(const f_string_t path, const int depth_max, const bool preserve);
#endif // _di_f_directory_remove_
/**
*
* @param path
* The file path to the directory.
- * @param recursion_max
+ * @param depth_max
* Represents the max recursion depth, set to 0 to disable recursive delete.
* @param preserve
- * When recursion_max > 0, this designates whether or not to preserve the directory at path.
+ * When depth_max > 0, this designates whether or not to preserve the directory at path.
* If TRUE, then only the content within the directory is deleted.
* If FALSE, then the directory at path and its content are deleted.
- * When recursion_max is 0, then this should only be FALSE (setting this to TRUE would be a no-op).
+ * When depth_max is 0, then this should only be FALSE (setting this to TRUE would be a no-op).
* @param custom
* A custom function to pass to nftw() instead of using the internal one.
* Such as a custom function for verbose printing of removed files.
* @see remove()
*/
#ifndef _di_f_directory_remove_custom_
- extern f_return_status f_directory_remove_custom(const f_string_t path, const int recursion_max, const bool preserve, int (*custom) (const char *, const struct stat *, int, struct FTW *));
+ extern f_return_status f_directory_remove_custom(const f_string_t path, const int depth_max, const bool preserve, int (*custom) (const char *, const struct stat *, int, struct FTW *));
#endif // _di_f_directory_remove_custom_
/**
}
#endif // _di_f_file_mode_to_mode_
-#ifndef _di_f_file_move_
- f_return_status f_file_move(const f_string_t source, const f_string_t destination) {
+#ifndef _di_f_file_rename_
+ f_return_status f_file_rename(const f_string_t source, const f_string_t destination) {
#ifndef _di_level_0_parameter_checking_
if (source == 0) return F_status_set_error(F_parameter);
if (destination == 0) return F_status_set_error(F_parameter);
return F_none;
}
-#endif // _di_f_file_move_
+#endif // _di_f_file_rename_
-#ifndef _di_f_file_move_at_
- f_return_status f_file_move_at(const int at_id, const int to_id, const f_string_t source, const f_string_t destination) {
+#ifndef _di_f_file_rename_at_
+ f_return_status f_file_rename_at(const int at_id, const int to_id, const f_string_t source, const f_string_t destination) {
#ifndef _di_level_0_parameter_checking_
if (source == 0) return F_status_set_error(F_parameter);
if (destination == 0) return F_status_set_error(F_parameter);
return F_none;
}
-#endif // _di_f_file_move_at_
+#endif // _di_f_file_rename_at_
#ifndef _di_f_file_name_base_
f_return_status f_file_name_base(const f_string_t path, const f_string_length_t length, f_string_dynamic_t *name_base) {
#endif // _di_f_file_mode_to_mode_
/**
- * Move a file.
+ * Rename a file.
*
* The paths must not contain NULL except for the terminating NULL.
* The paths must be NULL terminated.
*
- * This essentially renames a file but can also change the file's path, which is therefore a move.
+ * This essentially renames a file but can also change the file's path, which is identical to a move.
+ * However, renames only work within a filesystem and cannot be moved to another filesystem.
*
* If destination already exists, then according to rename(), destination will be atomically replaced.
- * Which, if destination is a directory must either not exist or be empty.
- *
- * It is recommended to perform an existence test on destination to not have to consider the details on how rename() operates with an existing destination.
- *
- * @todo consider handling F_mount error internally, copying across filesystem and then removing file on success.
+ * Which, if destination is a directory, then that directory must either not exist or be empty.
*
* @param source
* The path to the file to copy from.
*
* @see rename()
*/
-#ifndef _di_f_file_move_
- extern f_return_status f_file_move(const f_string_t source, const f_string_t destination);
-#endif // _di_f_file_move_
+#ifndef _di_f_file_rename_
+ extern f_return_status f_file_rename(const f_string_t source, const f_string_t destination);
+#endif // _di_f_file_rename_
/**
- * Move a file.
+ * Rename a file.
*
* The paths must not contain NULL except for the terminating NULL.
* The paths must be NULL terminated.
*
- * This essentially renames a file but can also change the file's path, which is therefore a move.
+ * This essentially renames a file but can also change the file's path, which is identical to a move.
+ * However, renames only work within a filesystem and cannot be moved to another filesystem.
*
* If destination already exists, then according to rename(), destination will be atomically replaced.
- * Which, if destination is a directory must either not exist or be empty.
- *
- * It is recommended to perform an existence test on destination to not have to consider the details on how rename() operates with an existing destination.
- *
- * @todo consider handling F_mount error internally, copying across filesystem and then removing file on success.
+ * Which, if destination is a directory, then that directory must either not exist or be empty.
*
* @param at_id
* The parent directory, as an open directory file descriptor, in which the source is relative to.
*
* @see renameat()
*/
-#ifndef _di_f_file_move_at_
- extern f_return_status f_file_move_at(const int at_id, const int to_id, const f_string_t source, const f_string_t destination);
-#endif // _di_f_file_move_at_
+#ifndef _di_f_file_rename_at_
+ extern f_return_status f_file_rename_at(const int at_id, const int to_id, const f_string_t source, const f_string_t destination);
+#endif // _di_f_file_rename_at_
/**
* Get the base name of a file path.
if (F_status_is_error(status)) return status;
}
- if (recurse.verbose) {
- fprintf(recurse.verbose, "Cloned '%s' to '%s'.%c", source, destination, f_string_eol[0]);
- }
-
f_string_static_t static_source = { source, source_length, source_length };
f_string_static_t static_destination = { destination, destination_length, destination_length };
} // for
}
- if (recurse.depth_max == 0) {
- return status;
+ if (recurse.depth_max) {
+ status = private_fl_directory_clone(static_source, static_destination, role, recurse, 1);
+ }
+
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source, destination);
}
- return private_fl_directory_clone(static_source, static_destination, role, recurse, 1);
+ return status;
}
#endif // _di_fl_directory_clone_
return status;
}
- return private_fl_directory_clone(static_source, static_destination, role, recurse, 1);
+ if (recurse.depth_max) {
+ status = private_fl_directory_clone(static_source, static_destination, role, recurse, 1);
+ }
+
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source, destination);
+ }
+
+ return status;
}
#endif // _di_fl_directory_clone_content_
if (F_status_is_error(status)) return status;
}
- if (recurse.verbose) {
- fprintf(recurse.verbose, "Copied '%s' to '%s'.%c", source, destination, f_string_eol[0]);
- }
-
f_string_static_t static_source = { source, source_length, source_length };
f_string_static_t static_destination = { destination, destination_length, destination_length };
} // for
}
- if (recurse.depth_max == 0) {
- return status;
+ if (recurse.depth_max) {
+ status = private_fl_directory_copy(static_source, static_destination, mode, recurse, 1);
+ }
+
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source, destination);
}
- return private_fl_directory_copy(static_source, static_destination, mode, recurse, 1);
+ return status;
}
#endif // _di_fl_directory_copy_
} // for
}
- if (recurse.depth_max == 0) {
- return status;
+ if (recurse.depth_max) {
+ status = private_fl_directory_copy(static_source, static_destination, mode, recurse, 1);
+ }
+
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source, destination);
}
- return private_fl_directory_copy(static_source, static_destination, mode, recurse, 1);
+ return status;
}
#endif // _di_fl_directory_copy_content_
* exclusive:
* If TRUE, will fail when file already exists.
* If FALSE, will not fail if file already exists (existing file will be replaced).
+ * output:
+ * Set to 0 to not print on successful operation.
+ * Set to a valid file pointer to print to on successful operation.
+ * This is passed to the verbose function if that function pointer is not 0.
* verbose:
- * Set to 0 to not print copy operation values on successful copy.
- * Set to a valid file pointer, such as f_type_output (stdout), to print on successful copy.
+ * Set to 0 to not print on successful operation.
+ * Set to address of a function to be called for printing such that:
+ * - The first parameter represents the file pointer from the output variable.
+ * - The second parameter represents the source string.
+ * - The third parameter represents the destination string.
* failures:
* A list of paths and their respective status codes for clone failures.
* If 0, then this and statuses are ignored.
f_number_unsigned_t depth_max;
f_number_unsigned_t size_block;
bool exclusive;
- FILE *verbose;
+ FILE *output;
+ void (*verbose)(FILE *, const f_string_t, const f_string_t);
f_directory_statuss_t *failures;
} fl_directory_recurse_t;
- #define fl_directory_recurse_t_initialize { fl_directory_recurse_depth_max, f_file_default_read_size, F_false, 0, 0 }
+ #define fl_directory_recurse_t_initialize { fl_directory_recurse_depth_max, f_file_default_read_size, F_false, 0, 0, 0 }
#endif // _di_fl_directory_recurse_t_
/**
*
* @return
* F_none on success.
- * F_data_not if directory is empty.
- * F_directory_descriptor (with error bit) on directory file descriptor error.
- * F_directory_open (with error bit) on directory open error.
- * F_directory_stream (with error bit) on directory stream error.
- * F_directory_unsupported (with error bit) on directory file descriptor not supported.
- * F_file_descriptor_max (with error bit) if max file descriptors was reached.
- * F_file_open_max (with error bit) too many open files.
- * F_memory_reallocation (with error bit) on memory reallocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_string_too_large (with error bit) if appended string length is too large to store in the buffer.
* F_failure (with error bit) for any other failure, failures might be populated with individual status codes.
*
* Errors from (with error bit): f_directory_create().
*
* @return
* F_none on success.
- * F_data_not if directory is empty.
- * F_directory_descriptor (with error bit) on directory file descriptor error.
- * F_directory_open (with error bit) on directory open error.
- * F_directory_stream (with error bit) on directory stream error.
- * F_directory_unsupported (with error bit) on directory file descriptor not supported.
- * F_file_descriptor_max (with error bit) if max file descriptors was reached.
- * F_file_open_max (with error bit) too many open files.
- * F_memory_reallocation (with error bit) on memory reallocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_string_too_large (with error bit) if appended string length is too large to store in the buffer.
* F_failure (with error bit) for any other failure, failures might be populated with individual status codes.
*
* Errors from (with error bit): f_directory_exists().
*
* @return
* F_none on success.
- * F_data_not if directory is empty.
- * F_directory_descriptor (with error bit) on directory file descriptor error.
- * F_directory_open (with error bit) on directory open error.
- * F_directory_stream (with error bit) on directory stream error.
- * F_directory_unsupported (with error bit) on directory file descriptor not supported.
- * F_file_descriptor_max (with error bit) if max file descriptors was reached.
- * F_file_open_max (with error bit) too many open files.
- * F_memory_reallocation (with error bit) on memory reallocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_string_too_large (with error bit) if appended string length is too large to store in the buffer.
* F_failure (with error bit) for any other failure, failures might be populated with individual status codes.
*
* Errors from (with error bit): f_directory_create().
*
* @return
* F_none on success.
- * F_data_not if directory is empty.
- * F_directory_descriptor (with error bit) on directory file descriptor error.
- * F_directory_open (with error bit) on directory open error.
- * F_directory_stream (with error bit) on directory stream error.
- * F_directory_unsupported (with error bit) on directory file descriptor not supported.
- * F_file_descriptor_max (with error bit) if max file descriptors was reached.
- * F_file_open_max (with error bit) too many open files.
- * F_memory_reallocation (with error bit) on memory reallocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_string_too_large (with error bit) if appended string length is too large to store in the buffer.
* F_failure (with error bit) for any other failure, failures might be populated with individual status codes.
*
* Errors from (with error bit): f_directory_exists().
if (depth < recurse.depth_max) {
status = private_fl_directory_clone(source_sub, destination_sub, role, recurse, depth + 1);
+
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source_sub.string, destination_sub.string);
+ }
}
} // for
return F_failure;
}
- if (recurse.verbose) {
- fprintf(recurse.verbose, "Cloned '%s' to '%s'.%c", path_source, path_destination, f_string_eol[0]);
+ if (recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, path_source, path_destination);
}
return F_none;
if (depth < recurse.depth_max) {
status = private_fl_directory_copy(source_sub, destination_sub, mode, recurse, depth + 1);
+
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source_sub.string, destination_sub.string);
+ }
}
} // for
return F_failure;
}
- if (recurse.verbose) {
- fprintf(recurse.verbose, "Copied '%s' to '%s'.%c", path_source, path_destination, f_string_eol[0]);
+ if (recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, path_source, path_destination);
}
return F_none;
*
* @return
* F_none on success.
- * F_data_not if directory is empty.
- * F_directory_descriptor (with error bit) on directory file descriptor error.
- * F_directory_open (with error bit) on directory open error.
- * F_directory_stream (with error bit) on directory stream error.
- * F_directory_unsupported (with error bit) on directory file descriptor not supported.
- * F_file_descriptor_max (with error bit) if max file descriptors was reached.
- * F_file_open_max (with error bit) too many open files.
- * F_memory_reallocation (with error bit) on memory reallocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_string_too_large (with error bit) if appended string length is too large to store in the buffer.
* F_failure (with error bit) for any other failure, failures might be populated with individual status codes.
*
* @see fl_directory_clone()
*
* @return
* F_none on success.
- * F_data_not if directory is empty.
- * F_buffer_too_large (with error bit) if a buffer would exceed max length.
- * F_directory_descriptor (with error bit) on directory file descriptor error.
- * F_directory_open (with error bit) on directory open error.
- * F_directory_stream (with error bit) on directory stream error.
- * F_directory_unsupported (with error bit) on directory file descriptor not supported.
- * F_file_descriptor_max (with error bit) if max file descriptors was reached.
- * F_file_open_max (with error bit) too many open files.
- * F_memory_reallocation (with error bit) on memory reallocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_string_too_large (with error bit) if appended string length is too large to store in the buffer.
* F_failure (with error bit) for any other failure, failures might be populated with individual status codes.
*
* @see fl_directory_clone()
*
* @return
* F_none on success.
- * F_data_not if directory is empty.
- * F_directory_descriptor (with error bit) on directory file descriptor error.
- * F_directory_open (with error bit) on directory open error.
- * F_directory_stream (with error bit) on directory stream error.
- * F_directory_unsupported (with error bit) on directory file descriptor not supported.
- * F_file_descriptor_max (with error bit) if max file descriptors was reached.
- * F_file_open_max (with error bit) too many open files.
- * F_memory_reallocation (with error bit) on memory reallocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_string_too_large (with error bit) if appended string length is too large to store in the buffer.
* F_failure (with error bit) for any other failure, failures might be populated with individual status codes.
*
* @see fl_directory_copy()
*
* @return
* F_none on success.
- * F_data_not if directory is empty.
- * F_directory_descriptor (with error bit) on directory file descriptor error.
- * F_directory_open (with error bit) on directory open error.
- * F_directory_stream (with error bit) on directory stream error.
- * F_directory_unsupported (with error bit) on directory file descriptor not supported.
- * F_file_descriptor_max (with error bit) if max file descriptors was reached.
- * F_file_open_max (with error bit) too many open files.
- * F_memory_reallocation (with error bit) on memory reallocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_string_too_large (with error bit) if appended string length is too large to store in the buffer.
* F_failure (with error bit) for any other failure, failures might be populated with individual status codes.
*
* @see fl_directory_copy()
#ifndef _di_fll_file_mode_set_all_
f_return_status fll_file_mode_set_all(const f_string_t path, const mode_t mode, const f_number_unsigned_t depth_max) {
- #ifndef _di_level_0_parameter_checking_
- if (path == 0) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
+ #ifndef _di_level_2_parameter_checking_
+ if (!path) return F_status_set_error(F_parameter);
+ #endif // _di_level_2_parameter_checking_
return private_fll_file_mode_set_all(path, mode, depth_max, 0);
}
-#endif // _di_fll_file_mode_set_all__
+#endif // _di_fll_file_mode_set_all_
+
+#ifndef _di_fll_file_move_
+ f_return_status fll_file_move(const f_string_t source, const f_string_t destination, const f_string_length_t source_length, const f_string_length_t destination_length, const fl_directory_recurse_t recurse) {
+ #ifndef _di_level_2_parameter_checking_
+ if (!source) return F_status_set_error(F_parameter);
+ if (!destination) return F_status_set_error(F_parameter);
+ #endif // _di_level_2_parameter_checking_
+
+ f_status_t status = f_file_rename(source, destination);
+
+ if (F_status_set_fine(status) != F_mount) {
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source, destination);
+ }
+
+ return status;
+ }
+
+ status = f_file_is(source, f_file_type_directory, F_false);
+
+ if (status == F_file_found_not) {
+ return F_status_set_error(status);
+ }
+
+ if (F_status_is_error(status)) {
+ return status;
+ }
+
+ if (status == F_true) {
+ status = fl_directory_clone(source, destination, source_length, destination_length, F_true, recurse);
+
+ if (F_status_is_error(status)) {
+ return status;
+ }
+
+ status = f_directory_remove(source, recurse.depth_max, F_false);
+
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source, destination);
+ }
+ }
+ else {
+ status = f_file_clone(source, destination, F_true, recurse.size_block, recurse.exclusive);
+
+ if (F_status_is_error(status)) {
+ return status;
+ }
+
+ status = f_file_remove(source);
+
+ if (status == F_none && recurse.output && recurse.verbose) {
+ recurse.verbose(recurse.output, source, destination);
+ }
+ }
+
+ return status;
+ }
+#endif // _di_fll_file_move_
#ifndef _di_fll_file_role_change_all_
f_return_status fll_file_role_change_all(const f_string_t path, const uid_t uid, const gid_t gid, const bool dereference, const f_number_unsigned_t depth_max) {
- #ifndef _di_level_0_parameter_checking_
- if (path == 0) return F_status_set_error(F_parameter);
+ #ifndef _di_level_2_parameter_checking_
+ if (!path) return F_status_set_error(F_parameter);
if (uid == -1 && gid == -1) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
+ #endif // _di_level_2_parameter_checking_
return private_fll_file_role_change_all(path, uid, gid, dereference, depth_max, 0);
}
#endif // _di_fll_file_mode_set_all_
/**
+ * Move a file.
+ *
+ * The paths must not contain NULL except for the terminating NULL.
+ * The paths must be NULL terminated.
+ *
+ * This attempts to rename a file but if the file is on another filesystem then it tries to clone the file or directory.
+ * If the file or directory is cloned, then the original is deleted after a successful copy.
+ *
+ * When this calls the additional functions, if the clone succeeds but the remove fails the source may exist.
+ * Therefore, if there is an error during remove, then the file should be checked for existence and possibly be manually removed.
+ *
+ * @param source
+ * The path to the file to copy from.
+ * @param destination
+ * The path to copy to.
+ * @param source_length
+ * The length of the source path.
+ * @param destination_length
+ * The length of the destination path.
+ * @param recurse
+ * The directory recurse data.
+ *
+ * @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 perform write.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_directory_empty_not (with error bit) if the destination is a non-empty directory.
+ * F_file_found_not (with error bit) if file at path was not found.
+ * F_file_type_directory (with error bit) if destination is a directory but source is not.
+ * F_filesystem_quota_block (with error bit) if filesystem's disk blocks or inodes are exhausted.
+ * F_link (with error bit) if source or destination has the maxiumum associated links.
+ * 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 making changes.
+ * 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, failures might be populated with individual status codes.
+ *
+ * Errors from (with error bit): f_directory_remove_custom().
+ * Errors from (with error bit): f_file_is().
+ * Errors from (with error bit): f_file_remove().
+ * Errors from (with error bit): f_file_rename().
+ * Errors from (with error bit): fl_directory_clone().
+ *
+ * @see f_directory_remove()
+ * @see f_directory_remove_custom()
+ * @see f_file_is()
+ * @see f_file_remove()
+ * @see f_file_rename()
+ * @see fl_directory_clone()
+ */
+#ifndef _di_fll_file_move_
+ extern f_return_status fll_file_move(const f_string_t source, const f_string_t destination, const f_string_length_t source_length, const f_string_length_t destination_length, const fl_directory_recurse_t recurse);
+#endif // _di_fll_file_move_
+
+/**
* Change owner and/or group of a given file at the specified path.
*
* At least one of uid or gid must not be -1.
fl_directory_recurse_t recurse = fl_directory_recurse_t_initialize;
if (data.verbosity == fake_verbosity_verbose) {
- recurse.verbose = f_type_output;
+ recurse.output = f_type_output;
+ recurse.verbose = fake_verbose_print_copy;
}
recurse.failures = &failures;
}
#endif // _di_fake_validate_parameter_directories_
+#ifndef _di_fake_verbose_print_clone_
+ void fake_verbose_print_clone(FILE *output, const f_string_t source, const f_string_t destination) {
+ fprintf(output, "Cloned '%s' to '%s'.%c", source, destination, f_string_eol[0]);
+ }
+#endif // _di_fake_verbose_print_clone_
+
+#ifndef _di_fake_verbose_print_copy_
+ void fake_verbose_print_copy(FILE *output, const f_string_t source, const f_string_t destination) {
+ fprintf(output, "Copied '%s' to '%s'.%c", source, destination, f_string_eol[0]);
+ }
+#endif // _di_fake_verbose_print_copy_
+
+#ifndef _di_fake_verbose_print_move_
+ void fake_verbose_print_move(FILE *output, const f_string_t source, const f_string_t destination) {
+ fprintf(output, "Moved '%s' to '%s'.%c", source, destination, f_string_eol[0]);
+ }
+#endif // _di_fake_verbose_print_move_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern f_return_status fake_validate_parameter_directories(const f_console_arguments_t arguments, const fake_data_t data) f_gcc_attribute_visibility_internal;
#endif // _di_fake_validate_parameter_directories_
+/**
+ * Helper function for performing a verbose print for a file clone operation.
+ *
+ * @param output
+ * A file pointer to print to, such as stdout.
+ * @param source
+ * The source string.
+ * @param destination
+ * The destination string.
+ */
+#ifndef _di_fake_verbose_print_clone_
+ extern void fake_verbose_print_clone(FILE *output, const f_string_t source, const f_string_t destination) f_gcc_attribute_visibility_internal;
+#endif // _di_fake_verbose_print_clone_
+
+/**
+ * Helper function for performing a verbose print for a file copy operation.
+ *
+ * @param output
+ * A file pointer to print to, such as stdout.
+ * @param source
+ * The source string.
+ * @param destination
+ * The destination string.
+ */
+#ifndef _di_fake_verbose_print_copy_
+ extern void fake_verbose_print_copy(FILE *output, const f_string_t source, const f_string_t destination) f_gcc_attribute_visibility_internal;
+#endif // _di_fake_verbose_print_copy_
+
+/**
+ * Helper function for performing a verbose print for a file move operation.
+ *
+ * @param output
+ * A file pointer to print to, such as stdout.
+ * @param source
+ * The source string.
+ * @param destination
+ * The destination string.
+ */
+#ifndef _di_fake_verbose_print_move_
+ extern void fake_verbose_print_move(FILE *output, const f_string_t source, const f_string_t destination) f_gcc_attribute_visibility_internal;
+#endif // _di_fake_verbose_print_move_
+
#ifdef __cplusplus
} // extern "C"
#endif
f_string_length_t destination_length = 0;
if (data.verbosity == fake_verbosity_verbose) {
- recurse.verbose = f_type_output;
+ recurse.output = f_type_output;
+ recurse.verbose = fake_verbose_print_clone;
}
bool existing = F_true;
f_macro_mode_t_set_default_umask(mode, data.umask);
if (data.verbosity == fake_verbosity_verbose) {
- recurse.verbose = f_type_output;
+ recurse.output = f_type_output;
+ recurse.verbose = fake_verbose_print_copy;
}
bool existing = F_true;
const f_array_length_t total = arguments.used -1;
f_status_t status_file = F_none;
+ fl_directory_recurse_t recurse = fl_directory_recurse_t_initialize;
+
f_string_length_t destination_length = 0;
+ if (data.verbosity == fake_verbosity_verbose) {
+ recurse.output = f_type_output;
+ recurse.verbose = fake_verbose_print_move;
+ }
+
bool existing = F_true;
// in this case, the destination could be a file, so confirm this.
destination[destination_length] = 0;
- status_file = f_file_move(arguments.array[i].string, destination);
+ status_file = fll_file_move(arguments.array[i].string, destination, arguments.array[i].used, destination_length, recurse);
if (F_status_is_error(status_file)) {
- fake_print_message_file(data, F_status_set_fine(status_file), "f_file_move", arguments.array[i].string, "move", F_false, F_true, data_make->print);
+ fake_print_message_file(data, F_status_set_fine(status_file), "fll_file_move", arguments.array[i].string, "move", F_false, F_true, data_make->print);
*status = F_status_set_error(F_failure);
}
- else if (data.verbosity == fake_verbosity_verbose) {
- printf("Moved '%s' to '%s'.%c", arguments.array[i].string, destination, f_string_eol[0]);
- }
} // for
return;