This was started with the intention of providing all of the *_at() functions.
However, the POSIX spec seems to fall short in many areas making this more difficult than this should be.
I partially rolled back some of the planned changes and this changeset is the result.
I have observed that the function return documentation needs to be updated, but this will be done at a later time.
There will need to be some intensive testing later on but for now I am committing and moving forward.
if (errno == EEXIST) return F_status_set_error(F_file_found);
if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EINVAL || errno == EBADF) return F_status_set_error(F_parameter);
+ 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 == 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 == EBADF) return F_status_set_error(F_directory_descriptor);
return F_status_set_error(F_failure);
}
}
#endif // _di_f_directory_exists_
+#ifndef _di_f_directory_exists_at_
+ f_return_status f_directory_exists_at(const int at_id, const f_string path, const int flag) {
+ struct stat file_stat;
+
+ memset(&file_stat, 0, sizeof(struct stat));
+
+ if (fstatat(at_id, path, &file_stat, flag) < 0) {
+ 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_false;
+ if (errno == ENOENT) return 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 ((file_stat.st_mode & S_IFMT) == S_IFDIR) return F_true;
+
+ return F_false;
+ }
+#endif // _di_f_directory_exists_at_
+
#ifndef _di_f_directory_is_
f_return_status f_directory_is(const f_string path) {
struct stat file_stat;
#endif // _di_f_directory_is_
#ifndef _di_f_directory_is_at_
- f_return_status f_directory_is_at(const int file_id, const f_string path, const bool follow) {
+ f_return_status f_directory_is_at(const int at_id, const f_string path, const int flag) {
struct stat file_stat;
memset(&file_stat, 0, sizeof(struct stat));
- if (fstatat(file_id, path, &file_stat, follow ? 0 : AT_SYMLINK_NOFOLLOW) < 0) {
+ if (fstatat(at_id, path, &file_stat, flag) < 0) {
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 == ENOENT) return 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);
}
}
#endif // _di_f_directory_list_
+#ifndef _di_f_directory_open_
+ f_return_status f_directory_open(const f_string path, const bool dereference, int *id) {
+ #ifndef _di_level_0_parameter_checking_
+ if (id == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ int flag = f_directory_flag_directory | f_directory_flag_close_execute | f_directory_flag_path;
+
+ if (dereference) {
+ flag |= f_directory_flag_no_follow;
+ }
+
+ *id = open(path, flag);
+
+ if (*id < 0) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EFBIG || errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
+ if (errno == EINTR) return F_status_set_error(F_interrupted);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENFILE) return F_status_set_error(F_file_open_max);
+ if (errno == ENOENT) return F_status_set_error(F_directory_found_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == ENOSPC) return F_status_set_error(F_space_not);
+ 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 // _di_f_directory_open_
+
+#ifndef _di_f_directory_open_at_
+ f_return_status f_directory_open_at(const int at_id, const f_string path, const bool dereference, int *id) {
+ #ifndef _di_level_0_parameter_checking_
+ if (at_id <= 0) return F_status_set_error(F_parameter);
+ if (id == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ int flag = f_directory_flag_directory | f_directory_flag_close_execute | f_directory_flag_path;
+
+ if (dereference) {
+ flag |= f_directory_flag_no_follow;
+ }
+
+ *id = openat(at_id, path, flag);
+
+ if (*id < 0) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EFBIG || errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
+ if (errno == EINTR) return F_status_set_error(F_interrupted);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENFILE) return F_status_set_error(F_file_open_max);
+ if (errno == ENOENT) return F_status_set_error(F_directory_found_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_out);
+ if (errno == ENOSPC) return F_status_set_error(F_space_not);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_directory_open_at_
+
#ifndef _di_f_directory_remove_
f_return_status f_directory_remove(const f_string path, const int recursion_max, const bool preserve) {
#ifndef _di_level_0_parameter_checking_
#endif
/**
+ * Directory AT_* define related functionality.
+ */
+#ifndef _di_f_directory_at_
+ #define f_directory_at_current_working -100
+ #define f_directory_at_symlink_follow 0x400
+ #define f_directory_at_symlink_follow_no 0x100
+ #define f_directory_at_remove_directory 0x200
+ #define f_directory_at_automount_no 0x800
+ #define f_directory_at_path_empty 0x1000
+ #define f_directory_at_statx_sync_type 0x6000
+ #define f_directory_at_statx_sync_as_stat 0x0000
+ #define f_directory_at_statx_sync_force 0x2000
+ #define f_directory_at_statx_sync_no 0x4000
+#endif // _di_f_directory_at_
+
+/**
+ * Directory flag related functionality.
+ */
+#ifndef _di_f_directory_flag_
+
+ // directory open flags
+ #define f_directory_flag_append O_APPEND
+ #define f_directory_flag_asynchronous O_ASYNC
+ #define f_directory_flag_create O_CREAT
+ #define f_directory_flag_close_execute O_CLOEXEC
+ #define f_directory_flag_direct O_DIRECT
+ #define f_directory_flag_directory O_DIRECTORY
+ #define f_directory_flag_exclusive O_EXCL
+ #define f_directory_flag_large_file O_LARGEFILE
+ #define f_directory_flag_no_access_time O_NOATIME
+ #define f_directory_flag_no_follow O_NOFOLLOW
+ #define f_directory_flag_no_tty O_NOCTTY
+ #define f_directory_flag_non_blocking O_NONBLOCK
+ #define f_directory_flag_path 010000000
+ #define f_directory_flag_read_only O_RDONLY
+ #define f_directory_flag_read_write O_RDWR
+ #define f_directory_flag_synchronous O_SYNC
+ #define f_directory_flag_synchronous_direct O_DSYNC
+ #define f_directory_flag_temporary O_TMPFILE
+ #define f_directory_flag_truncate O_TRUNC
+ #define f_directory_flag_write_only O_WRONLY
+#endif // _di_f_directory_flag_
+
+/**
* Provide limitations and related defines.
*
- * The name max 255 because the directory name size is 256.
- * The last 1 is for the NULL character.
- *
* The directory max descriptors is more of a default than a rule.
* This is generally used for nftw() recursive operations to reduce the number of open file descriptors during recursion.
*/
#ifndef _di_f_directory_limitations_
#define f_directory_default_allocation_step f_memory_default_allocation_step
- #define f_directory_name_max 255
+ #define f_directory_name_max NAME_MAX
#define f_directory_descriptors_max 255
#endif // _di_f_directory_limitations_
* Create a directory at the given path within the directories specified by the file descriptor.
*
* @param at_id
- * The file descriptor in which the directory will be created within.
+ * The parent directory, as an open directory file descriptor, in which path is relative to.
* @param path
* The path file name.
* @param mode
* F_name (with error bit) on path name error.
* F_directory_link_max (with error bit) max links limit reached or exceeded.
* 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.
*
- * @see mkdir()
+ * @see mkdirat()
*/
#ifndef _di_f_directory_create_at_
extern f_return_status f_directory_create_at(const int at_id, const f_string path, const mode_t mode);
* F_loop (with error bit) if a loop occurred.
* F_parameter (with error bit) if a parameter is invalid.
*
- * @see fstat()
+ * @see stat()
*/
#ifndef _di_f_directory_exists_
extern f_return_status f_directory_exists(const f_string path);
#endif // _di_f_directory_exists_
/**
+ * Identify whether or not a file exists at the given path and if that file is a directory or a symlink to a directory.
+ *
+ * @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 flag
+ * Any valid flag, such as f_directory_at_path_empty, f_directory_at_automount_no, or f_directory_at_symlink_follow_no.
+ *
+ * @return
+ * F_true if path was found and path is a directory (or a symlink to a directory).
+ * F_false if path was found and path is not a directory.
+ * F_file_found_not if the path was not found.
+ * F_name (with error bit) if the name is somehow invalid.
+ * F_memory_out (with error bit) if out of memory.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_access_denied (with error bit) if access to the file was denied.
+ * F_loop (with error bit) if a loop occurred.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ *
+ * @see fstatat()
+ */
+#ifndef _di_f_directory_exists_at_
+ extern f_return_status f_directory_exists_at(const int at_id, const f_string path, const int flag);
+#endif // _di_f_directory_exists_at_
+
+/**
* Identify whether or not a file exists at the given path and if that file is a directory.
*
* @param path
* F_loop (with error bit) if a loop occurred.
* F_parameter (with error bit) if a parameter is invalid.
*
- * @see fstat()
+ * @see stat()
*/
#ifndef _di_f_directory_is_
extern f_return_status f_directory_is(const f_string path);
/**
* Identify whether or not a file exists at the given path within the parent directory and if that file is a directory.
*
- * @param file_id
- * The file descriptor representing the parent directory to search within.
+ * @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 follow
- * Set to TRUE to follow symbolic links when determining if path is a file.
- * Set to FALSE to not follow.
+ * @param flag
+ * Any valid flag, such as f_directory_at_path_empty, f_directory_at_automount_no, or f_directory_at_symlink_follow_no.
*
* @return
* F_true if path was found and path is a directory.
* F_access_denied (with error bit) if access to the file was denied.
* F_loop (with error bit) if a loop occurred.
* F_parameter (with error bit) if a parameter is invalid.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
* @see fstatat()
*/
#ifndef _di_f_directory_is_at_
- extern f_return_status f_directory_is_at(const int file_id, const f_string path, const bool follow);
+ extern f_return_status f_directory_is_at(const int at_id, const f_string path, const int flag);
#endif // _di_f_directory_is_at_
/**
#endif // _di_f_directory_list_
/**
+ * Open the directory specified by path.
+ *
+ * This opens with O_PATH and O_CLOEXEC.
+ *
+ * @param path
+ * The path file name.
+ * @param dereference
+ * Set to TRUE to dereferenc symlinks (often is what is desired).
+ * Set to FALSE to operate on the symlink itself.
+ * @param id
+ * The file descriptor.
+ * This is updated with the result of open() or openat().
+ *
+ * @return
+ * F_none on success.
+ * F_failure (with error bit) if failed to read directory information.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see open()
+ */
+#ifndef _di_f_directory_open_
+ extern f_return_status private_f_directory_open(const f_string path, const bool dereference, int *id) f_gcc_attribute_visibility_internal;
+#endif // _di_f_directory_open_
+
+/**
+ * Open the directory specified by path.
+ *
+ * This opens with O_PATH and O_CLOEXEC.
+ *
+ * @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 dereference
+ * Set to TRUE to dereferenc symlinks (often is what is desired).
+ * Set to FALSE to operate on the symlink itself.
+ * @param id
+ * The file descriptor.
+ * This is updated with the result of open() or openat().
+ *
+ * @return
+ * F_none on success.
+ * F_failure (with error bit) if failed to read directory information.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see openat()
+ */
+#ifndef _di_f_directory_open_at_
+ extern f_return_status private_f_directory_open_at(const int at_id, const f_string path, const bool dereference, int *id) f_gcc_attribute_visibility_internal;
+#endif // _di_f_directory_open_at_
+
+/**
* Remove a directory and possibly its contents.
*
* @param path
#endif // _di_f_file_change_mode_
#ifndef _di_f_file_change_mode_at_
- f_return_status f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode, const int flags) {
- return private_f_file_change_mode_at(at_id, path, mode, flags);
+ f_return_status f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode) {
+ return private_f_file_change_mode_at(at_id, path, mode);
}
#endif // _di_f_file_change_mode_at_
#ifndef _di_f_file_change_owner_
f_return_status f_file_change_owner(const f_string path, const uid_t uid, const gid_t gid, const bool dereference) {
+ #ifndef _di_level_0_parameter_checking_
+ if (uid < 0 && gid < 0) 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_
+
return private_f_file_change_owner(path, uid, gid, dereference);
}
#endif // _di_f_file_change_owner_
#ifndef _di_f_file_change_owner_at_
- f_return_status f_file_change_owner_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flags) {
- return private_f_file_change_owner_at(at_id, path, uid, gid, flags);
+ f_return_status f_file_change_owner_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) {
+ #ifndef _di_level_0_parameter_checking_
+ if (uid < 0 && gid < 0) 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_
+
+ return private_f_file_change_owner_at(at_id, path, uid, gid, flag);
}
#endif // _di_f_file_change_owner_at_
+#ifndef _di_f_file_clone_
+ f_return_status f_file_clone(const f_string source, const f_string destination, const bool role, const f_number_unsigned size_block, const bool exclusive) {
+ f_status status = F_none;
+ struct stat source_stat;
+
+ memset(&source_stat, 0, sizeof(struct stat));
+
+ status = private_f_file_stat(source, F_false, &source_stat);
+ if (F_status_is_error(status)) return status;
+
+ if (f_macro_file_type_is_regular(source_stat.st_mode)) {
+ status = private_f_file_create(destination, source_stat.st_mode, exclusive);
+ if (F_status_is_error(status)) return status;
+
+ if (!exclusive) {
+ status = private_f_file_change_mode(destination, source_stat.st_mode);
+ if (F_status_is_error(status)) return status;
+ }
+
+ if (role) {
+ status = private_f_file_change_owner(destination, source_stat.st_uid, source_stat.st_gid, F_false);
+ if (F_status_is_error(status)) return status;
+ }
+
+ return private_f_file_copy_content(source, destination, size_block == 0 ? f_file_default_read_size : size_block);
+ }
+ else if (f_macro_file_type_is_link(source_stat.st_mode)) {
+ status = private_f_file_link(destination, source);
+ if (F_status_set_fine(status) == F_file_found) {
+ if (exclusive) return status;
+ }
+ else if (F_status_is_error(status)) {
+ return status;
+ }
+
+ status = private_f_file_change_mode(destination, source_stat.st_mode);
+ if (F_status_is_error(status)) return status;
+
+ if (role) {
+ status = private_f_file_change_owner(destination, source_stat.st_uid, source_stat.st_gid, F_false);
+ if (F_status_is_error(status)) return status;
+ }
+
+ return F_none;
+ }
+
+ return F_unsupported;
+ }
+#endif // _di_f_file_clone_
+
+#ifndef _di_f_file_close_
+ f_return_status f_file_close(int *id) {
+ #ifndef _di_level_0_parameter_checking_
+ if (id == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_f_file_close(id);
+ }
+#endif // _di_f_file_close_
+
#ifndef _di_f_file_copy_
f_return_status f_file_copy(const f_string source, const f_string destination, const mode_t mode, const f_number_unsigned size_block, const bool exclusive) {
f_status status = F_none;
}
#endif // _di_f_file_copy_
-#ifndef _di_f_file_clone_
- f_return_status f_file_clone(const f_string source, const f_string destination, const f_number_unsigned size_block, const bool exclusive, const bool roles) {
- f_status status = F_none;
- struct stat source_stat;
-
- memset(&source_stat, 0, sizeof(struct stat));
-
- status = private_f_file_stat(source, F_false, &source_stat);
- if (F_status_is_error(status)) return status;
-
- if (f_macro_file_type_is_regular(source_stat.st_mode)) {
- status = private_f_file_create(destination, source_stat.st_mode, exclusive);
- if (F_status_is_error(status)) return status;
-
- if (!exclusive) {
- status = private_f_file_change_mode(destination, source_stat.st_mode);
- if (F_status_is_error(status)) return status;
- }
-
- if (roles) {
- status = private_f_file_change_owner(destination, source_stat.st_uid, source_stat.st_gid, F_false);
- if (F_status_is_error(status)) return status;
- }
-
- return private_f_file_copy_content(source, destination, size_block == 0 ? f_file_default_read_size : size_block);
- }
- else if (f_macro_file_type_is_link(source_stat.st_mode)) {
- status = private_f_file_link(destination, source);
- if (F_status_set_fine(status) == F_file_found) {
- if (exclusive) return status;
- }
- else if (F_status_is_error(status)) {
- return status;
- }
-
- status = private_f_file_change_mode(destination, source_stat.st_mode);
- if (F_status_is_error(status)) return status;
-
- if (roles) {
- status = private_f_file_change_owner(destination, source_stat.st_uid, source_stat.st_gid, F_false);
- if (F_status_is_error(status)) return status;
- }
-
- return F_none;
- }
-
- return F_unsupported;
- }
-#endif // _di_f_file_clone_
-
-#ifndef _di_f_file_close_
- f_return_status f_file_close(int *id) {
- #ifndef _di_level_0_parameter_checking_
- if (id == 0) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- return private_f_file_close(id);
- }
-#endif // _di_f_file_close_
-
#ifndef _di_f_file_create_
f_return_status f_file_create(const f_string path, const mode_t mode, const bool exclusive) {
return private_f_file_create(path, mode, exclusive);
if (errno == ENOENT) return 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);
}
#endif // _di_f_file_link_hard_
#ifndef _di_f_file_link_hard_at_
- f_return_status f_file_link_hard_at(const int at_id_target, const int at_id_point, const f_string target, const f_string point, const int flags) {
+ f_return_status f_file_link_hard_at(const int at_id_target, const int at_id_point, const f_string target, const f_string point, const int flag) {
- if (linkat(at_id_target, target, at_id_point, point, flags) < 0) {
+ if (linkat(at_id_target, target, at_id_point, point, flag) < 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 == ELOOP) return F_status_set_error(F_loop);
if (errno == ENOENT) return F_status_set_error(F_file_found_not);
if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == ENOMEM) return F_status_set_error(F_memory_out);
if (errno == ENOSPC) return F_status_set_error(F_space_not);
if (errno == EPERM) return F_status_set_error(F_prohibited);
if (errno == ENOENT) return 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);
}
#endif // _di_f_file_remove_
#ifndef _di_f_file_remove_at_
- f_return_status f_file_remove_at(const int at_id, const f_string path, const int flags) {
+ f_return_status f_file_remove_at(const int at_id, const f_string path, const int flag) {
- if (unlinkat(at_id, path, flags) < 0) {
+ if (unlinkat(at_id, path, flag) < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EBUSY) return F_status_set_error(F_busy);
if (errno == EIO) return F_status_set_error(F_input_output);
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 == EBADF) return F_status_set_error(F_directory_descriptor);
return F_status_set_error(F_failure);
}
#endif // _di_f_file_stat_
#ifndef _di_f_file_stat_at_
- f_return_status f_file_stat_at(const int at_id, const f_string path, const int flags, struct stat *file_stat) {
+ f_return_status f_file_stat_at(const int at_id, const f_string path, const int flag, struct stat *file_stat) {
#ifndef _di_level_0_parameter_checking_
if (at_id <= 0) return F_status_set_error(F_parameter);
if (file_stat == 0) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
- return private_f_file_stat_at(at_id, path, flags, file_stat);
+ return private_f_file_stat_at(at_id, path, flag, file_stat);
}
#endif // _di_f_file_stat_at_
* Commonly used file related properties.
*
* id: File descriptor.
- * flags: Flags used for opening the file.
+ * flag: Flags used for opening the file.
* size_read: The default number of 1-byte characters to read at a time and is often used for the read buffer size.
* size_write: The default number of 1-byte characters to read at a time and is often used for the write buffer size.
*/
#ifndef _di_f_file_
typedef struct {
int id;
- int flags;
+ int flag;
size_t size_read;
size_t size_write;
} f_file;
- #define f_file_initialize { 0, O_RDONLY, f_file_default_read_size, f_file_default_write_size }
+ #define f_file_initialize { 0, f_file_flag_read_only, f_file_default_read_size, f_file_default_write_size }
#endif // _di_f_file_
/**
- * File mode relation functionality.
+ * File AT_* define related functionality.
*/
-#ifndef _di_f_file_modes_
+#ifndef _di_f_file_at_
+ #define f_file_at_current_working -100
+ #define f_file_at_symlink_follow 0x400
+ #define f_file_at_symlink_follow_no 0x100
+ #define f_file_at_remove_directory 0x200
+ #define f_file_at_automount_no 0x800
+ #define f_file_at_path_empty 0x1000
+ #define f_file_at_statx_sync_type 0x6000
+ #define f_file_at_statx_sync_as_stat 0x0000
+ #define f_file_at_statx_sync_force 0x2000
+ #define f_file_at_statx_sync_no 0x4000
+#endif // _di_f_file_at_
+
+/**
+ * File flag related functionality.
+ */
+#ifndef _di_f_file_flag_
// file open flags
#define f_file_flag_append O_APPEND
#define f_file_flag_no_follow O_NOFOLLOW
#define f_file_flag_no_tty O_NOCTTY
#define f_file_flag_non_blocking O_NONBLOCK
- #define f_file_flag_path O_PATH
+ #define f_file_flag_path 010000000
#define f_file_flag_read_only O_RDONLY
#define f_file_flag_read_write O_RDWR
#define f_file_flag_synchronous O_SYNC
#define f_file_flag_large_async_create_new_ro (O_LARGEFILE | O_ASYNC | O_CREAT | O_EXCL | O_RDONLY)
#define f_file_flag_large_async_create_new_wo (O_LARGEFILE | O_ASYNC | O_CREAT | O_EXCL | O_WRONLY)
#define f_file_flag_large_async_create_new_rw (O_LARGEFILE | O_ASYNC | O_CREAT | O_EXCL | O_RDRW)
+#endif // _di_f_file_flag_
+
+/**
+ * File mode related functionality.
+ */
+#ifndef _di_f_file_mode_
// file permission modes.
#define f_file_mode_owner_rwx S_IRWXU
#define f_file_mode_user_file (f_file_mode_owner_rw | f_file_mode_group_rw)
#define f_file_mode_user_program (f_file_mode_owner_rx | f_file_mode_group_rx)
#define f_file_mode_user_protected (f_file_mode_owner_r | f_file_mode_group_r)
-#endif // _di_f_file_modes_
+#endif // _di_f_file_mode_
/**
* Check if a file can be accessed.
* The path file name.
* @param mode
* The new mode to use.
- * @param flags
- * Any valid flag, such as AT_EMPTY_PATH, AT_NO_AUTOMOUNT, or AT_SYMLINK_NO_FOLLOW.
- * Warning: chmod on a symolic link is currently not supported in POSIX.
- * Therefore AT_SYMLINK_NO_FOLLOW does nothing at this time and is assumed to always be TRUE.
*
* @return
* F_none on success.
* F_input_output (with error bit) on I/O error.
* F_failure (with error bit) for any other (mkdir()) error.
*
- * @see chmod()
+ * @see fchmodat()
*/
#ifndef _di_f_file_change_mode_at_
- extern f_return_status f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode, const int flags);
+ extern f_return_status f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode);
#endif // _di_f_file_change_mode_at_
/**
* Set to FALSE to operate on the symlink itself.
*
* @return
- * F_true if file exists.
- * F_false if file does not exist.
+ * F_none on success.
* F_parameter (with error bit) if a parameter is invalid.
+ * F_access_denied (with error bit) on access denied.
* F_name (with error bit) if the filename is too long.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_loop (with error bit) on loop error.
+ * F_file_found_not (with error bit) if file at path was not found.
* F_memory_out (with error bit) if out of memory.
- * F_number_overflow (with error bit) on overflow error.
* F_directory (with error bit) on invalid directory.
- * F_access_denied (with error bit) on access denied.
- * F_loop (with error bit) on loop error.
- * F_false (with error bit) on unknown/unhandled errors.
+ * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
+ * F_access_group (with error bit) if the current user does not have access to assign the specified group.
+ * F_read_only (with error bit) if file is read-only.
+ * F_input_output (with error bit) on I/O error.
+ * F_failure (with error bit) for any other (chown() or lchown()) error.
*
* @see chown()
+ * @see lchown()
*/
#ifndef _di_f_file_change_owner_
extern f_return_status f_file_change_owner(const f_string path, const uid_t uid, const gid_t gid, const bool dereference);
* The new user id to use.
* @param gid
* The new group id to use.
- * @param flags
- * Any valid flag, such as AT_EMPTY_PATH, AT_NO_AUTOMOUNT, or AT_SYMLINK_NO_FOLLOW.
+ * @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_true if file exists.
- * F_false if file does not exist.
+ * F_none on success.
* F_parameter (with error bit) if a parameter is invalid.
+ * F_access_denied (with error bit) on access denied.
* F_name (with error bit) if the filename is too long.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_loop (with error bit) on loop error.
+ * F_file_found_not (with error bit) if file at path was not found.
* F_memory_out (with error bit) if out of memory.
- * F_number_overflow (with error bit) on overflow error.
* F_directory (with error bit) on invalid directory.
- * F_access_denied (with error bit) on access denied.
- * F_loop (with error bit) on loop error.
- * F_false (with error bit) on unknown/unhandled errors.
+ * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
+ * F_access_group (with error bit) if the current user does not have access to assign the specified group.
+ * F_read_only (with error bit) if file is read-only.
+ * F_input_output (with error bit) on I/O error.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ * F_failure (with error bit) for any other (chown() or lchown()) error.
*
- * @see chown()
+ * @see fchownat()
*/
#ifndef _di_f_file_change_owner_at_
- extern f_return_status f_file_change_owner_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flags);
+ extern f_return_status f_file_change_owner_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag);
#endif // _di_f_file_change_owner_at_
/**
- * Copy a file.
+ * Copy a file, as well as its file mode and possibly the owner and group.
*
* The paths must not contain NULL except for the terminating NULL.
* The paths must be NULL terminated.
*
* This does not copy unknown file types.
*
- * This does not set mode based on umask(), be sure to apply umask if so desired.
- * (such as: mode & ~mask).
+ * @todo provide a return status for when owner/role cannot be assigned.
+ * This will be returned when complete so that caller can decide if this is an error or not.
*
* @param source
* The path to the file to copy from.
* @param destination
* The path to copy to.
- * @param mode
- * The file mode assigned to the destination file.
+ * @param role
+ * If TRUE, will copy the owner and group ids.
+ * If FALSE, will not copy the owner and group ids.
+ * (In both cases the file mode is copied.)
* @param size_block
* The default number of chunks to read at a time with each chunk being 1-byte.
* Set to 0 to use default block read size.
* F_file_read (with error bit) on file read error.
* F_file_write (with error bit) on file write error.
*/
-#ifndef _di_f_file_copy_
- extern f_return_status f_file_copy(const f_string source, const f_string destination, const mode_t mode, const f_number_unsigned size_block, const bool exclusive);
-#endif // _di_f_file_copy_
+#ifndef _di_f_file_clone_
+ extern f_return_status f_file_clone(const f_string source, const f_string destination, const bool role, const f_number_unsigned size_block, const bool exclusive);
+#endif // _di_f_file_clone_
/**
- * Copy a file, as well as its file mode and possibly the owner and group.
+ * Close an open file.
+ *
+ * Will flush before closing.
+ *
+ * @param id
+ * The file descriptor.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_file_descriptor (with error bit) if file descriptor is invalid.
+ * F_interrupted (with error bit) if interrupt was received.
+ * F_input_output (with error bit) on I/O error.
+ * F_filesystem_quota_block (with error bit) if filesystem's disk blocks or inodes are exhausted.
+ * F_space_not (with error bit) if filesystem is out of space (or filesystem quota is reached).
+ * F_file_synchronize (with error bit) on flush failure.
+ * F_file_close (with error bit) if fclose() failed for any other reason.
+ *
+ * @see fclose()
+ */
+#ifndef _di_f_file_close_
+ extern f_return_status f_file_close(int *id);
+#endif // _di_f_file_close_
+
+/**
+ * Copy a file.
*
* The paths must not contain NULL except for the terminating NULL.
* The paths must be NULL terminated.
*
* This does not copy unknown file types.
*
- * @todo provide a return status for when owner/role cannot be assigned.
- * This will be returned when complete so that caller can decide if this is an error or not.
+ * This does not set mode based on umask(), be sure to apply umask if so desired.
+ * (such as: mode & ~mask).
*
* @param source
* The path to the file to copy from.
* @param destination
* The path to copy to.
+ * @param mode
+ * The file mode assigned to the destination file.
* @param size_block
* The default number of chunks to read at a time with each chunk being 1-byte.
* Set to 0 to use default block read size.
* @param exclusive
* If TRUE, will fail when file already exists.
* If FALSE, will not fail if file already exists (existing file will be replaced).
- * @param roles
- * If TRUE, will copy the owner and group ids.
- * If FALSE, will not copy the owner and group ids.
- * (In both cases the file mode is copied.)
*
* @return
* F_none on success.
* F_file_read (with error bit) on file read error.
* F_file_write (with error bit) on file write error.
*/
-#ifndef _di_f_file_clone_
- extern f_return_status f_file_clone(const f_string source, const f_string destination, const f_number_unsigned size_block, const bool exclusive, const bool roles);
-#endif // _di_f_file_clone_
-
-/**
- * Close an open file.
- *
- * Will flush before closing.
- *
- * @param id
- * The file descriptor.
- *
- * @return
- * F_none on success.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_file_descriptor (with error bit) if file descriptor is invalid.
- * F_interrupted (with error bit) if interrupt was received.
- * F_input_output (with error bit) on I/O error.
- * F_filesystem_quota_block (with error bit) if filesystem's disk blocks or inodes are exhausted.
- * F_space_not (with error bit) if filesystem is out of space (or filesystem quota is reached).
- * F_file_synchronize (with error bit) on flush failure.
- * F_file_close (with error bit) if fclose() failed for any other reason.
- *
- * @see fclose()
- */
-#ifndef _di_f_file_close_
- extern f_return_status f_file_close(int *id);
-#endif // _di_f_file_close_
+#ifndef _di_f_file_copy_
+ extern f_return_status f_file_copy(const f_string source, const f_string destination, const mode_t mode, const f_number_unsigned size_block, const bool exclusive);
+#endif // _di_f_file_copy_
/**
* Create a file based on the given path and file mode.
* F_name (with error bit) on path name error.
* F_directory (with error bit) if a supposed directory in path is not actually a directory.
* F_unsupported (with error bit) for unsupported file types.
- * F_file_descriptor (with error bit) for bad file descriptor.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
* @see makedev()
* @see mknodat()
* F_name (with error bit) on path name error.
* F_directory (with error bit) if a supposed directory in path is not actually a directory.
* F_unsupported (with error bit) for unsupported file types.
- * F_file_descriptor (with error bit) for bad file descriptor.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
* @see mkfifoat()
*/
* F_name (with error bit) on path name error.
* F_directory (with error bit) if a supposed directory in path is not actually a directory.
* F_unsupported (with error bit) for unsupported file types.
- * F_file_descriptor (with error bit) for bad file descriptor.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
* @see mknodat()
*/
* The parent directory, as an open directory file descriptor, in which path is relative to.
* @param path
* The path file name.
- * @param flags
- * Additional flags to pass, such as AT_EACCESS or AT_SYMLINK_NOFOLLOW.
+ * @param flag
+ * Additional flag to pass, such as AT_EACCESS or AT_SYMLINK_NOFOLLOW.
*
* @return
* F_true if file exists.
* 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_busy (with error bit) if filesystem is too busy to perforrm write.
- * F_file_descriptor (with error bit) if file descriptor is invalid.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
* F_failure (with error bit) for any other (symlinkat()) error.
*
* @see symlinkat()
* A path that the link points to.
* @param point
* A path to the link that does the pointing.
- * @param flags
- * Any valid flag, such as AT_EMPTY_PATH, AT_NO_AUTOMOUNT, or AT_SYMLINK_NO_FOLLOW.
+ * @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_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_busy (with error bit) if filesystem is too busy to perforrm write.
- * F_file_descriptor (with error bit) if file descriptor is invalid.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
* F_failure (with error bit) for any other (linkat()) error.
*
* @see linkat()
*/
#ifndef _di_f_file_link_hard_at_
- extern f_return_status f_file_link_hard_at(const int at_id_target, const int at_id_point, const f_string target, const f_string point, const int flags);
+ extern f_return_status f_file_link_hard_at(const int at_id_target, const int at_id_point, const f_string target, const f_string point, const int flag);
#endif // _di_f_file_link_hard_at_
/**
* F_file_found_not (with error bit) if the file at path was not found.
* F_memory_out (with error bit) if out of memory.
* F_directory (with error bit) if a supposed directory in path is not actually a directory.
- * F_file_descriptor (with error bit) if file descriptor is invalid.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
* F_failure (with error bit) for any other (readlinkat()) error.
*
* @see readlinkat()
* F_none on success.
* F_file_found_not (with error bit) if the file was not found.
* F_file_open (with error bit) if the file is already open.
- * F_file_descriptor (with error bit) if unable to load the file descriptor (the file pointer may still be valid).
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
* F_parameter (with error bit) if a parameter is invalid.
*
* @see openat()
* The parent directory, as an open directory file descriptor, in which path is relative to.
* @param path
* The path file name.
- * @param flags
- * Any valid flag, such as AT_EMPTY_PATH, AT_NO_AUTOMOUNT, or AT_SYMLINK_NO_FOLLOW.
+ * @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.
* @see unlinkat()
*/
#ifndef _di_f_file_remove_at_
- extern f_return_status f_file_remove_at(const int at_id, const f_string path, const int flags);
+ extern f_return_status f_file_remove_at(const int at_id, const f_string path, const int flag);
#endif // _di_f_file_remove_at_
/**
* The parent directory, as an open directory file descriptor, in which path is relative to.
* @param path
* The path to the file.
- * @param flags
- * Any valid flag, such as AT_EMPTY_PATH, AT_NO_AUTOMOUNT, or AT_SYMLINK_NO_FOLLOW.
+ * @param flag
+ * Any valid flag, such as f_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no.
* @param file_stat
* The statistics read.
*
* @see fstatat()
*/
#ifndef _di_f_file_stat_at_
- extern f_return_status f_file_stat_at(const int at_id, const f_string path, const int flags, struct stat *file_stat);
+ extern f_return_status f_file_stat_at(const int at_id, const f_string path, const int flag, struct stat *file_stat);
#endif // _di_f_file_stat_at_
/**
#endif // !defined(_di_f_file_change_mode_) || !defined(_di_f_file_copy_)
#if !defined(_di_f_file_change_mode_at_) || !defined(_di_f_file_copy_at_)
- f_return_status private_f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode, const int flags) {
+ f_return_status private_f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode) {
- if (fchmodat(at_id, path, mode, flags) < 0) {
+ if (fchmodat(at_id, path, mode, 0) < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
if (errno == EFAULT) return F_status_set_error(F_buffer);
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 == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == EPERM) return F_status_set_error(F_prohibited);
if (errno == EROFS) return F_status_set_error(F_read_only);
if (errno == EIO) return F_status_set_error(F_input_output);
#if !defined(_di_f_file_change_owner_) || !defined(_di_f_file_copy_)
f_return_status private_f_file_change_owner(const f_string path, const uid_t uid, const gid_t gid, const bool dereference) {
+ int result = 0;
+
+ if (dereference) {
+ if (uid != -1) {
+ result = chown(path, uid, -1);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
+ }
+
+ if (result == 0 && gid != -1) {
+ result = chown(path, -1, gid);
- if ((dereference ? chown(path, uid, gid) : lchown(path, uid, gid)) < 0) {
+ if (errno == EPERM) return F_status_set_error(F_access_group);
+ }
+ }
+ else {
+ if (uid != -1) {
+ result = lchown(path, uid, -1);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
+ }
+
+ if (gid != -1) {
+ result = lchown(path, -1, gid);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_group);
+ }
+ }
+
+ if (result < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
if (errno == EFAULT) return F_status_set_error(F_buffer);
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 == 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 == EIO) return F_status_set_error(F_input_output);
#endif // !defined(_di_f_file_change_owner_) || !defined(_di_f_file_copy_)
#if !defined(_di_f_file_change_owner_at_) || !defined(_di_f_file_copy_at_)
- f_return_status private_f_file_change_owner_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flags) {
+ f_return_status private_f_file_change_owner_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) {
+ int result = 0;
- if (fchownat(at_id, path, uid, gid, flags) < 0) {
+ if (uid != -1) {
+ result = fchownat(at_id, path, uid, -1, flag);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_owner);
+ }
+
+ if (gid != -1) {
+ result = fchownat(at_id, path, -1, gid, flag);
+
+ if (result < 0 && errno == EPERM) return F_status_set_error(F_access_group);
+ }
+
+ if (result < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
if (errno == EFAULT) return F_status_set_error(F_buffer);
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 == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
- if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == EROFS) return F_status_set_error(F_read_only);
if (errno == EIO) return F_status_set_error(F_input_output);
if (F_status_is_error(private_f_file_flush(*id))) return F_status_set_error(F_file_synchronize);
if (close(*id) < 0) {
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == EINTR) return F_status_set_error(F_interrupted);
if (errno == EIO) return F_status_set_error(F_input_output);
if (errno == ENOSPC) return F_status_set_error(F_space_not);
f_file file_source = f_file_initialize;
f_file file_destination = f_file_initialize;
- file_source.flags = f_file_flag_read_only;
- file_destination.flags = f_file_flag_write_only | f_file_flag_no_follow;
+ file_source.flag = f_file_flag_read_only;
+ file_destination.flag = f_file_flag_write_only | f_file_flag_no_follow;
f_status status = private_f_file_open(source, 0, &file_source);
if (F_status_is_error(status)) return status;
}
#endif // !defined(_di_f_file_copy_) || !defined(_di_f_file_clone_)
+#if !defined(_di_f_file_copy_at_) || !defined(_di_f_file_clone_at_)
+ f_return_status private_f_file_copy_content_at(const int at_id, const f_string source, const f_string destination, const f_number_unsigned size_block) {
+ f_file file_source = f_file_initialize;
+ f_file file_destination = f_file_initialize;
+
+ file_source.flag = f_file_flag_read_only;
+ file_destination.flag = f_file_flag_write_only | f_file_flag_no_follow;
+
+ f_status status = private_f_file_open_at(at_id, source, 0, &file_source);
+ if (F_status_is_error(status)) return status;
+
+ status = private_f_file_open_at(at_id, destination, 0, &file_destination);
+ if (F_status_is_error(status)) {
+ private_f_file_close(&file_source.id);
+ return status;
+ }
+
+ ssize_t size_read = 0;
+ ssize_t size_write = 0;
+ char *buffer[size_block];
+
+ memset(buffer, 0, size_block);
+
+ while ((size_read = read(file_source.id, buffer, size_block)) > 0) {
+ size_write = write(file_destination.id, buffer, size_read);
+
+ if (size_write < 0 || size_write != size_read) {
+ private_f_file_close(&file_destination.id);
+ private_f_file_close(&file_source.id);
+
+ return F_status_set_error(F_file_write);
+ }
+ } // while
+
+ private_f_file_close(&file_destination.id);
+ private_f_file_close(&file_source.id);
+
+ if (size_read < 0) return F_status_set_error(F_file_read);
+
+ return F_none;
+ }
+#endif // !defined(_di_f_file_copy_at_) || !defined(_di_f_file_clone_at_)
+
#if !defined(_di_f_file_create_) || !defined(_di_f_file_copy_)
f_return_status private_f_file_create(const f_string path, const mode_t mode, const bool exclusive) {
f_file file = f_file_initialize;
- file.flags = O_CLOEXEC | O_CREAT | O_WRONLY;
+ file.flag = f_file_flag_close_execute | f_file_flag_create | f_file_flag_write_only;
if (exclusive) {
- file.flags |= O_EXCL;
+ file.flag |= f_file_flag_exclusive;
}
f_status status = private_f_file_open(path, mode, &file);
f_return_status private_f_file_create_at(const int at_id, const f_string path, const mode_t mode, const bool exclusive) {
f_file file = f_file_initialize;
- file.flags = O_CLOEXEC | O_CREAT | O_WRONLY;
+ file.flag = f_file_flag_close_execute | f_file_flag_create | f_file_flag_write_only;
if (exclusive) {
- file.flags |= O_EXCL;
+ file.flag |= f_file_flag_exclusive;
}
f_status status = private_f_file_open_at(at_id, path, mode, &file);
if (errno == EEXIST) return F_status_set_error(F_file_found);
if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EINVAL || errno == EBADF) return F_status_set_error(F_parameter);
+ 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 == 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 == EBADF) return F_status_set_error(F_directory_descriptor);
return F_status_set_error(F_failure);
}
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 == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
return F_status_set_error(F_failure);
}
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 == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == ENOENT) return F_status_set_error(F_file_found_not);
if (errno == ENOTDIR) return F_status_set_error(F_directory);
if (errno == ENOMEM) return F_status_set_error(F_memory_out);
if (errno == ELOOP) return F_status_set_error(F_loop);
if (errno == ENOENT) return F_status_set_error(F_file_found_not);
if (errno == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == ENOMEM) return F_status_set_error(F_memory_out);
if (errno == ENOSPC) return F_status_set_error(F_space_not);
if (errno == EPERM) return F_status_set_error(F_prohibited);
target->used = link_stat.st_size;
- if (readlink(path, target->string, target->used) < 0) {
+ if (readlinkat(at_id, path, target->string, target->used) < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EFAULT) return F_status_set_error(F_buffer);
if (errno == EINVAL) return F_status_set_error(F_parameter);
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 == ENOTDIR) return F_status_set_error(F_directory);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
return F_status_set_error(F_failure);
}
#if !defined(_di_f_file_open_) || !defined(_di_f_file_copy_)
f_return_status private_f_file_open(const f_string path, const mode_t mode, f_file *file) {
if (mode == 0) {
- file->id = open(path, file->flags);
+ file->id = open(path, file->flag);
}
else {
- file->id = open(path, file->flags, mode);
+ file->id = open(path, file->flag, mode);
}
if (file->id < 0) {
if (errno == ELOOP) return F_status_set_error(F_loop);
if (errno == ENFILE) return F_status_set_error(F_file_open_max);
if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
if (errno == ENOMEM) return F_status_set_error(F_memory_out);
if (errno == ENOSPC) return F_status_set_error(F_space_not);
if (errno == EPERM) return F_status_set_error(F_prohibited);
if (errno == EROFS) return F_status_set_error(F_read_only);
if (errno == ETXTBSY) return F_status_set_error(F_busy);
+ if (errno == EISDIR) return F_status_set_error(F_directory);
+ if (errno == EOPNOTSUPP) return F_status_set_error(F_unsupported);
return F_status_set_error(F_failure);
}
#if !defined(_di_f_file_open_at_) || !defined(_di_f_file_copy_at_)
f_return_status private_f_file_open_at(const int at_id, const f_string path, const mode_t mode, f_file *file) {
if (mode == 0) {
- file->id = openat(at_id, path, file->flags);
+ file->id = openat(at_id, path, file->flag);
}
else {
- file->id = openat(at_id, path, file->flags, mode);
+ file->id = openat(at_id, path, file->flag, mode);
}
if (file->id < 0) {
if (errno == EINVAL) return F_status_set_error(F_parameter);
if (errno == ELOOP) return F_status_set_error(F_loop);
if (errno == ENFILE) return F_status_set_error(F_file_open_max);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOTDIR) return F_status_set_error(F_directory);
+ if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
if (errno == ENOMEM) return F_status_set_error(F_memory_out);
if (errno == ENOSPC) return F_status_set_error(F_space_not);
if (errno == EPERM) return F_status_set_error(F_prohibited);
if (errno == EROFS) return F_status_set_error(F_read_only);
if (errno == ETXTBSY) return F_status_set_error(F_busy);
+ if (errno == EISDIR) return F_status_set_error(F_directory);
+ if (errno == EOPNOTSUPP) return F_status_set_error(F_unsupported);
return F_status_set_error(F_failure);
}
#endif // !defined(_di_f_file_stat_) || !defined(_di_f_file_copy_)
#if !defined(_di_f_file_stat_at_) || !defined(_di_f_file_copy_at_)
- f_return_status private_f_file_stat_at(const int at_id, const f_string path, const int flags, struct stat *file_stat) {
+ f_return_status private_f_file_stat_at(const int at_id, const f_string path, const int flag, struct stat *file_stat) {
- if (fstatat(at_id, path, file_stat, flags) < 0) {
+ if (fstatat(at_id, path, file_stat, flag) < 0) {
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 == 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_file_descriptor);
+ if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == ENOENT) return F_status_set_error(F_file_found_not);
return F_status_set_error(F_file_stat);
* The path file name.
* @param mode
* The new mode to use.
- * @param flags
- * Any valid flag, such as AT_EMPTY_PATH, AT_NO_AUTOMOUNT, or AT_SYMLINK_NO_FOLLOW.
- * Warning: chmod on a symolic link is currently not supported in POSIX.
- * Therefore AT_SYMLINK_NO_FOLLOW does nothing at this time and is assumed to always be TRUE.
*
* @return
* F_none on success.
* F_failure (with error bit) for any other (mkdir()) error.
*
* @see f_file_change_mode_at()
- * @see f_file_copy_at()
*/
-#if !defined(_di_f_file_change_mode_at_) || !defined(_di_f_file_copy_at_)
- extern f_return_status private_f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode, const int flags) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_change_mode_at_) || !defined(_di_f_file_copy_at_)
+#if !defined(_di_f_file_change_mode_at_)
+ extern f_return_status private_f_file_change_mode_at(const int at_id, const f_string path, const mode_t mode) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_file_change_mode_at_)
/**
* Private implementation of f_file_change_owner().
* F_parameter (with error bit) if a parameter is invalid.
* F_access_denied (with error bit) on access denied.
* F_name (with error bit) if the filename is too long.
+ * F_buffer (with error bit) if the buffer is invalid.
* F_loop (with error bit) on loop error.
* F_file_found_not (with error bit) if file at path was not found.
* F_memory_out (with error bit) if out of memory.
* F_directory (with error bit) on invalid directory.
- * F_prohibited (with error bit) if filesystem does not allow for file changes.
+ * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
+ * F_access_group (with error bit) if the current user does not have access to assign the specified group.
* F_read_only (with error bit) if file is read-only.
* F_input_output (with error bit) on I/O error.
- * F_failure (with error bit) for any other (mkdir()) error.
+ * F_failure (with error bit) for any other (chown() or lchown()) error.
+ *
*
* @see f_file_change_owner()
* @see f_file_copy()
* The new user id to use.
* @param gid
* The new group id to use.
- * @param flags
+ * @param flag
* Any valid flag, such as AT_EMPTY_PATH, AT_NO_AUTOMOUNT, or AT_SYMLINK_NO_FOLLOW.
*
* @return
* F_parameter (with error bit) if a parameter is invalid.
* F_access_denied (with error bit) on access denied.
* F_name (with error bit) if the filename is too long.
+ * F_buffer (with error bit) if the buffer is invalid.
* F_loop (with error bit) on loop error.
* F_file_found_not (with error bit) if file at path was not found.
* F_memory_out (with error bit) if out of memory.
* F_directory (with error bit) on invalid directory.
- * F_prohibited (with error bit) if filesystem does not allow for file changes.
+ * F_access_owner (with error bit) if the current user does not have access to assign the specified owner.
+ * F_access_group (with error bit) if the current user does not have access to assign the specified group.
* F_read_only (with error bit) if file is read-only.
* F_input_output (with error bit) on I/O error.
- * F_failure (with error bit) for any other (mkdir()) error.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ * F_failure (with error bit) for any other (chown() or lchown()) error.
*
* @see f_file_change_owner_at()
- * @see f_file_copy_at()
*/
-#if !defined(_di_f_file_change_owner_at_) || !defined(_di_f_file_copy_at_)
- extern f_return_status private_f_file_change_owner_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flags) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_change_owner_at_) || !defined(_di_f_file_copy_at_)
+#if !defined(_di_f_file_change_owner_at_)
+ extern f_return_status private_f_file_change_owner_at(const int at_id, const f_string path, const uid_t uid, const gid_t gid, const int flag) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_file_change_owner_at_)
/**
* Private implementation of f_file_close().
* @param file
* The data related to the file being opened.
* This will be updated with the file descriptor.
- * This will be updated with the create flags (ignoring and overriding existing file.flags).
+ * This will be updated with the create flag (ignoring and overriding existing file.flag).
* @param exclusive
* If TRUE, will fail when file already exists.
* If FALSE, will not fail if file already exists.
* @param file
* The data related to the file being opened.
* This will be updated with the file descriptor.
- * This will be updated with the create flags (ignoring and overriding existing file.flags).
+ * This will be updated with the create flag (ignoring and overriding existing file.flag).
* @param path
* The path file name.
* @param mode
* F_file_open_max (with error bit) when system-wide max open files is reached.
* F_busy (with error bit) if filesystem is too busy to perforrm write.
*
- * @see f_file_copy_at()
* @see f_file_create_at()
*/
-#if !defined(_di_f_file_create_at_) || !defined(_di_f_file_copy_at_)
+#if !defined(_di_f_file_create_at_)
extern f_return_status private_f_file_create_at(const int at_id, const f_string path, const mode_t mode, const bool exclusive) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_create_at_) || !defined(_di_f_file_copy_at_)
+#endif // !defined(_di_f_file_create_at_)
/**
* Private implementation for creating directories.
* F_directory_link_max (with error bit) max links limit reached or exceeded.
* F_directory (with error bit) if a supposed directory in path is not actually a directory.
*
- * @see f_file_copy_at()
* @see mkdirat()
*/
#if !defined(_di_f_file_copy_at_)
* F_name (with error bit) on path name error.
* F_directory (with error bit) if a supposed directory in path is not actually a directory.
* F_unsupported (with error bit) for unsupported file types.
- * F_file_descriptor (with error bit) for bad file descriptor.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
* @see mkfifoat()
*/
* F_name (with error bit) on path name error.
* F_directory (with error bit) if a supposed directory in path is not actually a directory.
* F_unsupported (with error bit) for unsupported file types.
- * F_file_descriptor (with error bit) for bad file descriptor.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
* @see f_file_create_device_at()
* @see f_file_create_node_at()
* 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_busy (with error bit) if filesystem is too busy to perforrm write.
- * F_file_descriptor (with error bit) if file descriptor is invalid.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
* F_failure (with error bit) for any other (symlink()) error.
*
- * @see f_file_copy_at()
* @see f_file_link_at()
*/
-#if !defined(_di_f_file_link_at_) || !defined(_di_f_file_copy_at_)
+#if !defined(_di_f_file_link_at_)
extern f_return_status private_f_file_link_at(const int at_id, const f_string target, const f_string point) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_link_at_) || !defined(_di_f_file_copy_at_)
+#endif // !defined(_di_f_file_link_at_)
/**
* Private implementation of f_file_link_read().
* F_file_found_not (with error bit) if the file at path was not found.
* F_memory_out (with error bit) if out of memory.
* F_directory (with error bit) if a supposed directory in path is not actually a directory.
- * F_file_descriptor (with error bit) if file descriptor is invalid.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
* F_failure (with error bit) for any other (readlinkat()) error.
*
* @see f_file_link_read_at()
* F_none on success.
* F_file_found_not (with error bit) if the file was not found.
* F_file_open (with error bit) if the file is already open.
- * F_file_descriptor (with error bit) if unable to load the file descriptor (the file pointer may still be valid).
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
* F_parameter (with error bit) if a parameter is invalid.
*
- * @see f_file_copy_at()
* @see f_file_open_at()
*/
-#if !defined(_di_f_file_open_at_) || !defined(_di_f_file_copy_at_)
+#if !defined(_di_f_file_open_at_)
extern f_return_status private_f_file_open_at(const int at_id, const f_string path, const mode_t mode, f_file *file) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_open_at_) || !defined(_di_f_file_copy_at_)
+#endif // !defined(_di_f_file_open_at_)
/**
* Private implementation of f_file_close().
* The parent directory, as an open directory file descriptor, in which path is relative to.
* @param file_name
* The name of the file.
- * @param flags
+ * @param flag
* Any valid flag, such as AT_EMPTY_PATH, AT_NO_AUTOMOUNT, or AT_SYMLINK_NO_FOLLOW.
* @param file_stat
* The statistics read.
* F_loop (with error bit) if a loop occurred.
* F_parameter (with error bit) if a parameter is invalid.
*
- * @see f_file_copy_at()
* @see f_file_stat_at()
*/
-#if !defined(_di_f_file_stat_at_) || !defined(_di_f_file_copy_at_)
- extern f_return_status private_f_file_stat_at(const int at_id, const f_string file_name, const int flags, struct stat *file_stat) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_f_file_stat_at_) || !defined(_di_f_file_copy_at_)
+#if !defined(_di_f_file_stat_at_)
+ extern f_return_status private_f_file_stat_at(const int at_id, const f_string file_name, const int flag, struct stat *file_stat) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_file_stat_at_)
/**
* Private implementation of f_file_close().
#endif // _di_F_status_compare_
#ifndef _di_F_status_access_
+ F_access,
F_access_denied,
F_access_denied_execute,
F_access_denied_group,
F_access_granted_user,
F_access_granted_world,
F_access_granted_write,
+ F_access_group,
+ F_access_mode,
+ F_access_owner,
#endif // _di_F_status_access_
// Required.
extern "C" {
#endif
-#ifndef _di_fl_directory_copy_
- f_return_status fl_directory_copy(const f_string source, const f_string destination, const f_string_length source_length, const f_string_length destination_length, const f_directory_mode mode, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) {
+#ifndef _di_fl_directory_clone_
+ f_return_status fl_directory_clone(const f_string source, const f_string destination, const f_string_length source_length, const f_string_length destination_length, const bool role, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) {
f_status status = F_none;
status = f_directory_exists(source);
if (F_status_is_error(status)) return status;
if (status == F_false) return F_status_set_error(F_directory);
- f_directory_listing listing = f_directory_listing_initialize;
+ const f_string_static static_source = { source, source_length, source_length };
+ const f_string_static static_destination = { destination, destination_length, destination_length };
+
+ status = private_fl_directory_clone(static_source, static_destination, role, size_block, exclusive, failures);
+
+ return F_none;
+ }
+#endif // _di_fl_directory_clone_
+
+#ifndef _di_fl_directory_copy_
+ f_return_status fl_directory_copy(const f_string source, const f_string destination, const f_string_length source_length, const f_string_length destination_length, const f_directory_mode mode, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) {
+ f_status status = F_none;
- status = private_fl_directory_list(source, 0, 0, F_false, &listing);
+ status = f_directory_exists(source);
if (F_status_is_error(status)) return status;
+ if (status == F_false) return F_status_set_error(F_directory);
const f_string_static static_source = { source, source_length, source_length };
const f_string_static static_destination = { destination, destination_length, destination_length };
status = private_fl_directory_copy(static_source, static_destination, mode, size_block, exclusive, failures);
- f_macro_directory_listing_destroy(status, listing);
- if (F_status_is_error(status)) return status;
-
return F_none;
}
#endif // _di_fl_directory_copy_
}
#endif // _di_fl_directory_list_
+#ifndef _di_fl_directory_list_at_
+ f_return_status fl_directory_list_at(const int at_id, const f_string path, int (*filter)(const struct dirent *), int (*sort)(const struct dirent **, const struct dirent **), const bool dereference, f_directory_listing *listing) {
+ #ifndef _di_level_2_parameter_checking_
+ if (listing == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_2_parameter_checking_
+
+ // @todo implement a directoy list that passes at_id to scandirat().
+ // but... DIR * appears to be needed, can I just instead pass the path string instead? (char *).
+
+ return private_fl_directory_list(path, filter, sort, dereference, listing);
+ }
+#endif // _di_fl_directory_list_at_
+
#ifndef _di_fl_directory_path_pop_
f_return_status fl_directory_path_pop(f_string_static *path) {
#ifndef _di_level_0_parameter_checking_
#endif
/**
- * Copy a directory and its contents.
+ * Copy a file, as well as its file mode and possibly the owner and group.
*
* The paths must not contain NULL except for the terminating NULL.
* The paths must be NULL terminated.
*
+ * @todo provide a return status for when owner/role cannot be assigned.
+ *
* Symbolic links are not followed, they are copied as the symbolic link itself.
*
* This does not copy unknown file types.
* The length of the source path.
* @param destination_length
* The length of the destination path.
- * @param mode
- * The directory modes.
+ * @param role
+ * If TRUE, will copy the owner and group ids.
+ * If FALSE, will not copy the owner and group ids.
+ * (In both cases the file mode is copied.)
* @param size_block
* The default number of chunks to read at a time with each chunk being 1-byte.
- * Set to 0 to use default block read size.
+ * Must be greater than 0.
* @param exclusive
- * If TRUE, will fail when file already exists.
- * If FALSE, will not fail if file already exists (existing file will be replaced).
- * @param failures
- * A list of paths and their respective status codes for copy failures.
- * If 0, then this and statuses is ignored.
+ * If TRUE, will fail when parent directory already exists.
+ * If FALSE, will not fail if parent directory already exists (existing directory will be updated).
*
* @return
* F_none on success.
* F_loop (with error bit) on loop error.
* F_file_found (with error bit) if a file was found while exclusive is TRUE.
* F_memory_out (with error bit) if out of memory.
+ * F_memory_allocation (with error bit) on memory allocation error.
+ * F_memory_reallocation (with error bit) on memory re-allocation error.
* F_prohibited (with error bit) if filesystem does not allow for removing.
* F_read_only (with error bit) if file is read-only.
* F_failure (with error bit) for any other (mkdir()) error.
* F_busy (with error bit) if filesystem is too busy to perforrm write.
* F_file_read (with error bit) on file read error.
* F_file_write (with error bit) on file write error.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
- * @see f_file_copy()
+ * @see f_directory_create()
+ * @see f_file_clone()
* @see read()
*/
-#ifndef _di_fl_directory_copy_
- extern f_return_status fl_directory_copy(const f_string source, const f_string destination, const f_string_length source_length, const f_string_length destination_length, const f_directory_mode mode, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures);
-#endif // _di_fl_directory_copy_
+#ifndef _di_fl_directory_clone_
+ extern f_return_status fl_directory_clone(const f_string source, const f_string destination, const f_string_length source_length, const f_string_length destination_length, const bool role, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures);
+#endif // _di_fl_directory_clone_
/**
- * Copy a file, as well as its file mode and possibly the owner and group.
+ * Copy a directory and its contents.
*
* The paths must not contain NULL except for the terminating NULL.
* The paths must be NULL terminated.
*
- * @todo provide a return status for when owner/role cannot be assigned.
- * This will be returned when complete so that caller can decide if this is an error or not.
- *
* Symbolic links are not followed, they are copied as the symbolic link itself.
*
* This does not copy unknown file types.
*
* @param source
- * The path to the directory to copy from.
+ * The source file path.
+ * Must be NULL terminated.
* @param destination
- * The path to copy to.
+ * The destination file path.
+ * Must be NULL terminated.
+ * @param source_length
+ * The length of the source path.
+ * @param destination_length
+ * The length of the destination path.
+ * @param mode
+ * The directory modes.
* @param size_block
* The default number of chunks to read at a time with each chunk being 1-byte.
- * Must be greater than 0.
+ * Set to 0 to use default block read size.
* @param exclusive
- * If TRUE, will fail when parent directory already exists.
- * If FALSE, will not fail if parent directory already exists (existing directory will be updated).
- * @param roles
- * If TRUE, will copy the owner and group ids.
- * If FALSE, will not copy the owner and group ids.
- * (In both cases the file mode is copied.)
+ * If TRUE, will fail when file already exists.
+ * If FALSE, will not fail if file already exists (existing file will be replaced).
+ * @param failures
+ * A list of paths and their respective status codes for copy failures.
+ * If 0, then this and statuses is ignored.
*
* @return
* F_none on success.
* F_loop (with error bit) on loop error.
* F_file_found (with error bit) if a file was found while exclusive is TRUE.
* F_memory_out (with error bit) if out of memory.
+ * F_memory_allocation (with error bit) on memory allocation error.
+ * F_memory_reallocation (with error bit) on memory re-allocation error.
* F_prohibited (with error bit) if filesystem does not allow for removing.
* F_read_only (with error bit) if file is read-only.
* F_failure (with error bit) for any other (mkdir()) error.
* F_busy (with error bit) if filesystem is too busy to perforrm write.
* F_file_read (with error bit) on file read error.
* F_file_write (with error bit) on file write error.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
- * @see f_directory_create()
- * @see f_file_clone()
+ * @see f_file_copy()
* @see read()
*/
-#ifndef _di_fl_directory_clone_
- extern f_return_status fl_directory_clone(const f_string source, const f_string destination, const f_number_unsigned size_block, const bool exclusive, const bool roles);
-#endif // _di_fl_directory_clone_
+#ifndef _di_fl_directory_copy_
+ extern f_return_status fl_directory_copy(const f_string source, const f_string destination, const f_string_length source_length, const f_string_length destination_length, const f_directory_mode mode, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures);
+#endif // _di_fl_directory_copy_
/**
* For some given path, print the names of each file and/or directory inside the directory, stored as a directory listing.
#endif // _di_fl_directory_list_
/**
+ * For some given path, print the names of each file and/or directory inside the directory, stored as a directory listing.
+ *
+ * Allows specifying a custom filter and custom sort.
+ *
+ * @param path
+ * Filesystem path to the directory.
+ * @param filter
+ * A filter function of the form: int xxx(const struct direct *).
+ * Set to 0 to not use (NULL).
+ * @param sort
+ * A sort function of the form: int xxx(const struct direct *, const struct direct *).
+ * Set to 0 to not use (NULL).
+ * There are two pre-made libc functions available for this: alphasort() and versionsort().
+ * @param dereference
+ * Set to TRUE to dereferenc symlinks (often is what is desired).
+ * Set to FALSE to operate on the symlink itself.
+ * @param listing
+ * Will be populated with the names of all top-level paths found within the given directory.
+ *
+ * @return
+ * F_none on success.
+ * F_data_not if directory is empty (@fixme: unlikely due to '.' and '..' probably always being returned.).
+ * F_failure (with error bit) if failed to read directory information.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_memory_reallocation (with error bit) on memory reallocation error.
+ * F_directory_open (with error bit) on directory open error.
+ * F_directory_descriptor (with error bit) on directory file descriptor 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.
+ *
+ * @see alphasort()
+ * @see opendir()
+ * @see scandir()
+ * @see versionsort()
+ */
+#ifndef _di_fl_directory_list_at_
+ extern f_return_status fl_directory_list_at(const int at_id, const f_string path, int (*filter)(const struct dirent *), int (*sort)(const struct dirent **, const struct dirent **), const bool dereference, f_directory_listing *listing);
+#endif // _di_fl_directory_list_at_
+
+/**
* Append a path string onto the destination path.
*
* This ensures that there is a trailing '/' after pop.
extern "C" {
#endif
+#if !defined(_di_fl_directory_clone_)
+ f_return_status private_fl_directory_clone(const f_string_static source, const f_string_static destination, const bool role, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) {
+ f_status status = f_directory_exists(source.string);
+
+ if (F_status_is_error(status)) return status;
+ if (status == F_false) return F_status_set_error(F_directory);
+
+ struct stat source_stat;
+
+ memset(&source_stat, 0, sizeof(struct stat));
+
+ status = f_file_stat(source.string, F_false, &source_stat);
+ if (F_status_is_error(status)) return status;
+
+ status = f_directory_exists(destination.string);
+ if (F_status_is_error(status)) return status;
+
+ if (status == F_true) {
+ if (exclusive) {
+ return F_status_set_error(F_directory_found);
+ }
+
+ status = f_file_change_mode(destination.string, source_stat.st_mode);
+ if (F_status_is_error(status)) return status;
+ }
+ else {
+ status = f_directory_create(destination.string, source_stat.st_mode);
+ if (F_status_is_error(status)) return status;
+ }
+
+ if (role) {
+ status = f_file_change_owner(destination.string, source_stat.st_uid, source_stat.st_gid, F_true);
+ if (F_status_is_error(status)) return status;
+ }
+
+ f_directory_listing listing = f_directory_listing_initialize;
+
+ status = private_fl_directory_list(source.string, 0, 0, F_false, &listing);
+ if (F_status_is_error(status)) {
+ f_macro_directory_listing_delete_simple(listing);
+ return status;
+ }
+
+ status = F_none;
+
+ f_array_length i = 0;
+
+ int directory_fd = 0;
+ f_string_length failures_used = failures ? failures->used : 0;
+
+ for (; F_status_is_fine(status) && i < listing.block.used; i++) {
+ status = private_fl_directory_clone_file(listing.block.array[i], source, destination, role, size_block, exclusive, failures);
+ } // for
+
+ f_macro_string_dynamics_delete_simple(listing.block);
+
+ for (i = 0; F_status_is_fine(status) && i < listing.character.used; i++) {
+ status = private_fl_directory_clone_file(listing.character.array[i], source, destination, role, size_block, exclusive, failures);
+ } // for
+
+ f_macro_string_dynamics_delete_simple(listing.character);
+
+ for (i = 0; F_status_is_fine(status) && i < listing.regular.used; i++) {
+ status = private_fl_directory_clone_file(listing.regular.array[i], source, destination, role, size_block, exclusive, failures);
+ } // for
+
+ f_macro_string_dynamics_delete_simple(listing.regular);
+
+ for (i = 0; F_status_is_fine(status) && i < listing.link.used; i++) {
+ status = private_fl_directory_clone_file(listing.link.array[i], source, destination, role, size_block, exclusive, failures);
+ } // for
+
+ f_macro_string_dynamics_delete_simple(listing.link);
+
+ for (i = 0; F_status_is_fine(status) && i < listing.socket.used; i++) {
+ status = private_fl_directory_clone_file(listing.socket.array[i], source, destination, role, size_block, exclusive, failures);
+ } // for
+
+ f_macro_string_dynamics_delete_simple(listing.socket);
+
+ for (i = 0; F_status_is_fine(status) && i < listing.unknown.used; i++) {
+ status = private_fl_directory_clone_file(listing.unknown.array[i], source, destination, role, size_block, exclusive, failures);
+ } // for
+
+ f_macro_string_dynamics_delete_simple(listing.unknown);
+
+ for (i = 0; F_status_is_fine(status) && i < listing.directory.used; i++) {
+ f_string_static source_sub = f_string_static_initialize;
+ f_string_static destination_sub = f_string_static_initialize;
+
+ source_sub.used = source.used + listing.directory.array[i].used + 1;
+ source_sub.size = source_sub.used;
+
+ destination_sub.used = destination.used + listing.directory.array[i].used + 1;
+ destination_sub.size = destination_sub.used;
+
+ char path_source_sub[source_sub.used + 1];
+ char path_destination_sub[destination_sub.used + 1];
+
+ memcpy(path_source_sub, source.string, source.used);
+ memcpy(path_source_sub + source.used + 1, listing.directory.array[i].string, listing.directory.array[i].used);
+
+ memcpy(path_destination_sub, destination.string, destination.used);
+ memcpy(path_destination_sub + destination.used + 1, listing.directory.array[i].string, listing.directory.array[i].used);
+
+ path_source_sub[source.used] = f_path_separator[0];
+ path_source_sub[source_sub.used] = 0;
+
+ path_destination_sub[destination.used] = f_path_separator[0];
+ path_destination_sub[destination_sub.used] = 0;
+
+ source_sub.string = path_source_sub;
+ destination_sub.string = path_destination_sub;
+
+ status = private_fl_directory_clone(source_sub, destination_sub, role, size_block, exclusive, failures);
+ } // for
+
+ f_macro_string_dynamics_delete_simple(listing.directory);
+
+ if (F_status_is_error(status)) return status;
+
+ if (failures && failures_used < failures->used) return F_failure;
+
+ return F_none;
+ }
+#endif // !defined(_di_fl_directory_clone_)
+
+#if !defined(_di_fl_directory_clone_file_)
+ f_return_status private_fl_directory_clone_file(const f_string_static file, const f_string_static source, const f_string_static destination, const bool role, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) {
+ char path_source[source.used + file.used + 2];
+ char path_destination[destination.used + file.used + 2];
+
+ memcpy(path_source, source.string, source.used);
+ memcpy(path_source + source.used + 1, file.string, file.used);
+ path_source[source.used] = f_path_separator[0];
+ path_source[source.used + file.used + 1] = 0;
+
+ memcpy(path_destination, destination.string, destination.used);
+ memcpy(path_destination + destination.used + 1, file.string, file.used);
+ path_destination[destination.used] = f_path_separator[0];
+ path_destination[destination.used + file.used + 1] = 0;
+
+ f_status status = f_file_clone(path_source, path_destination, role, size_block, exclusive);
+
+ if (F_status_is_error(status) || status == F_unsupported) {
+ if (status == F_status_set_error(F_memory_allocation) || status == F_status_set_error(F_memory_reallocation)) {
+ return F_status_set_error(status);
+ }
+
+ if (!failures) return F_failure;
+
+ const f_status status_failure = status;
+
+ if (failures->used + 1 > failures->size) {
+ if (failures->size + f_memory_default_allocation_step > f_array_length_size) {
+ if (failures->size + 1 > f_array_length_size) {
+ return F_status_set_error(F_buffer_too_large);
+ }
+
+ f_macro_directory_statuss_resize(status, (*failures), failures->used + 1);
+ if (F_status_is_error(status)) return status;
+ }
+ else {
+ f_macro_directory_statuss_resize(status, (*failures), failures->used + f_memory_default_allocation_step);
+ if (F_status_is_error(status)) return status;
+ }
+ }
+
+ f_directory_status failure = f_directory_status_initialize;
+ f_string_length size = 0;
+
+ // identify if failure was because of source or destination.
+ struct stat source_stat;
+
+ memset(&source_stat, 0, sizeof(struct stat));
+
+ status = f_file_stat(source.string, F_false, &source_stat);
+ if (F_status_is_error(status)) {
+ if (status == F_status_set_error(F_string_too_large)) {
+ size = f_string_length_size - 1;
+ }
+ else {
+ size = source.used + file.used + 1;
+ }
+
+ f_macro_directory_status_resize(status, failure, size + 1);
+ if (F_status_is_error(status)) return status;
+
+ memcpy(failure.path.string, path_source, size);
+ failure.path.string[size] = 0;
+ }
+ else {
+ if (status == F_status_set_error(F_string_too_large)) {
+ size = f_string_length_size - 1;
+ }
+ else {
+ size = destination.used + file.used + 1;
+ }
+
+ f_macro_directory_status_resize(status, failure, size + 1);
+ if (F_status_is_error(status)) return status;
+
+ memcpy(failure.path.string, path_destination, size);
+ failure.path.string[size] = 0;
+ }
+
+ failures->array[failures->used].path.string = failure.path.string;
+ failures->array[failures->used].path.used = size;
+ failures->array[failures->used].path.size = size + 1;
+ failures->array[failures->used].status = status_failure;
+ failures->used++;
+
+ return F_failure;
+ }
+
+ return F_none;
+ }
+#endif // !defined(_di_fl_directory_clone_file_)
+
#if !defined(_di_fl_directory_copy_)
f_return_status private_fl_directory_copy(const f_string_static source, const f_string_static destination, const f_directory_mode mode, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) {
- f_status status = F_none;
+ f_status status = f_directory_exists(source.string);
- status = f_directory_exists(source.string);
if (F_status_is_error(status)) return status;
if (status == F_false) return F_status_set_error(F_directory);
}
#endif // !defined(_di_fl_directory_copy_)
-#if !defined(_di_fl_directory_copy_)
+#if !defined(_di_fl_directory_copy_file_)
f_return_status private_fl_directory_copy_file(const f_string_static file, const f_string_static source, const f_string_static destination, const mode_t mode, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) {
char path_source[source.used + file.used + 2];
char path_destination[destination.used + file.used + 2];
return F_none;
}
-#endif // !defined(_di_fl_directory_copy_)
+#endif // !defined(_di_fl_directory_copy_file_)
#if !defined(_di_fl_directory_list_)
f_return_status private_fl_directory_list(const f_string path, int (*filter)(const struct dirent *), int (*sort)(const struct dirent **, const struct dirent **), const bool dereference, f_directory_listing *listing) {
#endif
/**
+ * Private implementation of fl_directory_clone().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param source
+ * The source file path.
+ * Must be NULL terminated.
+ * @param destination
+ * The destination file path.
+ * Must be NULL terminated.
+ * @param role
+ * If TRUE, will copy the owner and group ids.
+ * If FALSE, will not copy the owner and group ids.
+ * (In both cases the file mode is copied.)
+ * @param size_block
+ * The default number of chunks to read at a time with each chunk being 1-byte.
+ * Must be greater than 0.
+ * @param exclusive
+ * If TRUE, will fail when file already exists.
+ * If FALSE, will not fail if file already exists (existing file will be replaced).
+ * @param failures
+ * A list of paths and their respective status codes for clone failures.
+ * If 0, then this and statuses is ignored.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_access_denied (with error bit) on access denied.
+ * F_loop (with error bit) on loop error.
+ * F_file_found (with error bit) if a file was found while exclusive is TRUE.
+ * F_memory_out (with error bit) if out of memory.
+ * F_memory_allocation (with error bit) on memory allocation error.
+ * F_memory_reallocation (with error bit) on memory re-allocation error.
+ * F_prohibited (with error bit) if filesystem does not allow for removing.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other (mkdir()) error.
+ * 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_file_found (with error bit) of a directory aleady exists at the path.
+ * F_name (with error bit) on path name error.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_interrupted (with error bit) when program received an interrupt signal, halting create.
+ * F_file_open_max (with error bit) when system-wide max open files is reached.
+ * F_busy (with error bit) if filesystem is too busy to perforrm write.
+ * F_file_read (with error bit) on file read error.
+ * F_file_write (with error bit) on file write error.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ *
+ * @see fl_directory_clone()
+ */
+#if !defined(_di_fl_directory_clone_)
+ extern f_return_status private_fl_directory_clone(const f_string_static source, const f_string_static destination, const bool role, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_directory_clone_)
+
+/**
+ * A special function intended to be used directly by private_fl_directory_clone().
+ *
+ * Will only clone a single file and record any detected errors.
+ *
+ * @param file
+ * The name of the file within source to clone into destination.
+ * Must be NULL terminated.
+ * @param source
+ * The source file path.
+ * Must be NULL terminated.
+ * @param destination
+ * The destination file path.
+ * Must be NULL terminated.
+ * @param role
+ * If TRUE, will copy the owner and group ids.
+ * If FALSE, will not copy the owner and group ids.
+ * (In both cases the file mode is copied.)
+ * @param size_block
+ * The default number of chunks to read at a time with each chunk being 1-byte.
+ * Must be greater than 0.
+ * @param exclusive
+ * If TRUE, will fail when file already exists.
+ * If FALSE, will not fail if file already exists (existing file will be replaced).
+ * @param failures
+ * A list of paths and their respective status codes for clone failures.
+ * If 0, then this and statuses is ignored.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_access_denied (with error bit) on access denied.
+ * F_loop (with error bit) on loop error.
+ * F_file_found (with error bit) if a file was found while exclusive is TRUE.
+ * F_memory_out (with error bit) if out of memory.
+ * F_memory_allocation (with error bit) on memory allocation error.
+ * F_memory_reallocation (with error bit) on memory re-allocation error.
+ * F_prohibited (with error bit) if filesystem does not allow for removing.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other (mkdir()) error.
+ * 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_file_found (with error bit) of a directory aleady exists at the path.
+ * F_name (with error bit) on path name error.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_interrupted (with error bit) when program received an interrupt signal, halting create.
+ * F_file_open_max (with error bit) when system-wide max open files is reached.
+ * F_busy (with error bit) if filesystem is too busy to perforrm write.
+ * F_file_read (with error bit) on file read error.
+ * F_file_write (with error bit) on file write error.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
+ *
+ * @see fl_directory_clone()
+ */
+#if !defined(_di_fl_directory_clone_file_)
+ extern f_return_status private_fl_directory_clone_file(const f_string_static file, const f_string_static source, const f_string_static destination, const bool role, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_directory_clone_file_)
+
+/**
* Private implementation of fl_directory_copy().
*
* Intended to be shared to each of the different implementation variations.
*
* @return
* F_none on success.
- * F_failure on handled error (failures and statuses is updated with failure and status code).
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_access_denied (with error bit) on access denied.
+ * F_loop (with error bit) on loop error.
+ * F_file_found (with error bit) if a file was found while exclusive is TRUE.
+ * F_memory_out (with error bit) if out of memory.
* F_memory_allocation (with error bit) on memory allocation error.
* F_memory_reallocation (with error bit) on memory re-allocation error.
+ * F_prohibited (with error bit) if filesystem does not allow for removing.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other (mkdir()) error.
+ * 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_file_found (with error bit) of a directory aleady exists at the path.
+ * F_name (with error bit) on path name error.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_interrupted (with error bit) when program received an interrupt signal, halting create.
+ * F_file_open_max (with error bit) when system-wide max open files is reached.
+ * F_busy (with error bit) if filesystem is too busy to perforrm write.
+ * F_file_read (with error bit) on file read error.
+ * F_file_write (with error bit) on file write error.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
* @see fl_directory_copy()
*/
*
* @return
* F_none on success.
- * F_failure on handled error (failures and statuses is updated with failure and status code).
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_access_denied (with error bit) on access denied.
+ * F_loop (with error bit) on loop error.
+ * F_file_found (with error bit) if a file was found while exclusive is TRUE.
+ * F_memory_out (with error bit) if out of memory.
* F_memory_allocation (with error bit) on memory allocation error.
* F_memory_reallocation (with error bit) on memory re-allocation error.
+ * F_prohibited (with error bit) if filesystem does not allow for removing.
+ * F_read_only (with error bit) if file is read-only.
+ * F_failure (with error bit) for any other (mkdir()) error.
+ * 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_file_found (with error bit) of a directory aleady exists at the path.
+ * F_name (with error bit) on path name error.
+ * F_directory (with error bit) if a supposed directory in path is not actually a directory.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_interrupted (with error bit) when program received an interrupt signal, halting create.
+ * F_file_open_max (with error bit) when system-wide max open files is reached.
+ * F_busy (with error bit) if filesystem is too busy to perforrm write.
+ * F_file_read (with error bit) on file read error.
+ * F_file_write (with error bit) on file write error.
+ * F_directory_descriptor (with error bit) for bad directory descriptor for at_id.
*
* @see fl_directory_copy()
*/
-#if !defined(_di_fl_directory_copy_)
+#if !defined(_di_fl_directory_copy_file_)
extern f_return_status private_fl_directory_copy_file(const f_string_static file, const f_string_static source, const f_string_static destination, const mode_t mode, const f_number_unsigned size_block, const bool exclusive, f_directory_statuss *failures) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_fl_directory_copy_)
+#endif // !defined(_di_fl_directory_copy_file_)
/**
* A special function intended to be used directly by fl_directory_list().
#endif // _di_F_status_compare_
#ifndef _di_F_status_access_
+ case F_access:
+ *string = FL_status_string_access;
+ break;
case F_access_denied:
*string = FL_status_string_access_denied;
break;
case F_access_granted_super:
*string = FL_status_string_access_granted_super;
break;
+ case F_access_group:
+ *string = FL_status_string_access_group;
+ break;
+ case F_access_mode:
+ *string = FL_status_string_access_mode;
+ break;
+ case F_access_owner:
+ *string = FL_status_string_access_owner;
+ break;
#endif // _di_F_status_access_
case F_status_code_last:
#endif // _di_F_status_compare_
#ifndef _di_F_status_access_
- #define FL_status_string_access_denied "F_access_denied"
- #define FL_status_string_access_denied_user "F_access_denied_user"
- #define FL_status_string_access_denied_group "F_access_denied_group"
- #define FL_status_string_access_denied_world "F_access_denied_world"
- #define FL_status_string_access_denied_read "F_access_denied_read"
- #define FL_status_string_access_denied_write "F_access_denied_write"
- #define FL_status_string_access_denied_execute "F_access_denied_execute"
- #define FL_status_string_access_denied_super "F_access_denied_super"
+ #define FL_status_string_access "F_access"
+ #define FL_status_string_access_denied "F_access_denied"
+ #define FL_status_string_access_denied_user "F_access_denied_user"
+ #define FL_status_string_access_denied_group "F_access_denied_group"
+ #define FL_status_string_access_denied_world "F_access_denied_world"
+ #define FL_status_string_access_denied_read "F_access_denied_read"
+ #define FL_status_string_access_denied_write "F_access_denied_write"
+ #define FL_status_string_access_denied_execute "F_access_denied_execute"
+ #define FL_status_string_access_denied_super "F_access_denied_super"
#define FL_status_string_access_granted "F_access_granted"
#define FL_status_string_access_granted_user "F_access_granted_user"
#define FL_status_string_access_granted_group "F_access_granted_group"
#define FL_status_string_access_granted_write "F_access_granted_write"
#define FL_status_string_access_granted_execute "F_access_granted_execute"
#define FL_status_string_access_granted_super "F_access_granted_super"
+ #define FL_status_string_access_group "F_access_group"
+ #define FL_status_string_access_mode "F_access_mode"
+ #define FL_status_string_access_owner "F_access_owner"
+ #define FL_status_string_access_length 8
#define FL_status_string_access_denied_length 15
#define FL_status_string_access_denied_user_length 20
#define FL_status_string_access_denied_group_length 21
#define FL_status_string_access_granted_write_length 22
#define FL_status_string_access_granted_execute_length 24
#define FL_status_string_access_granted_super_length 22
+ #define FL_status_string_access_group_length 14
+ #define FL_status_string_access_mode_length 13
+ #define FL_status_string_access_owner_length 14
#endif // _di_F_status_access_
#define FL_status_string_status_code_last "F_status_code_last"
#endif // _di_F_status_compare_
#ifndef _di_F_status_access_
+ if (fl_string_compare(string, FL_status_string_access, length, FL_status_string_access_length) == F_equal_to) {
+ *code = F_access;
+ return F_none;
+ }
+
if (fl_string_compare(string, FL_status_string_access_denied, length, FL_status_string_access_denied_length) == F_equal_to) {
*code = F_access_denied;
return F_none;
*code = F_access_granted_super;
return F_none;
}
+
+ if (fl_string_compare(string, FL_status_string_access_group, length, FL_status_string_access_group_length) == F_equal_to) {
+ *code = F_access_mode;
+ return F_none;
+ }
+
+ if (fl_string_compare(string, FL_status_string_access_mode, length, FL_status_string_access_mode_length) == F_equal_to) {
+ *code = F_access_group;
+ return F_none;
+ }
+
+ if (fl_string_compare(string, FL_status_string_access_owner, length, FL_status_string_access_owner_length) == F_equal_to) {
+ *code = F_access_owner;
+ return F_none;
+ }
#endif // _di_F_status_access_
if (fl_string_compare(string, FL_status_string_status_code_last, length, FL_status_string_status_code_last_length) == F_equal_to) {
if (data->parameters[fss_basic_list_write_parameter_file].result == f_console_result_additional) {
f_file output = f_file_initialize;
- output.flags = f_file_flag_append_wo;
+ output.flag = f_file_flag_append_wo;
status = f_file_open(arguments.argv[data->parameters[fss_basic_list_write_parameter_file].additional.array[0]], 0, &output);
if (data->parameters[fss_basic_write_parameter_file].result == f_console_result_additional) {
f_file output = f_file_initialize;
- output.flags = f_file_flag_append_wo;
+ output.flag = f_file_flag_append_wo;
status = f_file_open(arguments.argv[data->parameters[fss_basic_write_parameter_file].additional.array[0]], 0, &output);
if (data->parameters[fss_extended_write_parameter_file].result == f_console_result_additional) {
f_file output = f_file_initialize;
- output.flags = f_file_flag_append_wo;
+ output.flag = f_file_flag_append_wo;
status = f_file_open(arguments.argv[data->parameters[fss_extended_write_parameter_file].additional.array[0]], 0, &output);