From c4041c86d74a76652a7a33efaa70bc7eb4c6ac3c Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 12 Jul 2020 18:23:11 -0500 Subject: [PATCH] Feature: add f_file_type() and f_file_type_at() functions. --- level_0/f_file/c/file.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ level_0/f_file/c/file.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/level_0/f_file/c/file.c b/level_0/f_file/c/file.c index 406efaf..2c6bbe6 100644 --- a/level_0/f_file/c/file.c +++ b/level_0/f_file/c/file.c @@ -1078,6 +1078,67 @@ extern "C" { } #endif // _di_f_file_touch_at_ +#ifndef _di_f_file_type_ + f_return_status f_file_type(const f_string path, int *type) { + #ifndef _di_level_0_parameter_checking_ + if (path == 0) return F_status_set_error(F_parameter); + if (type == 0) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + struct stat file_stat; + + memset(&file_stat, 0, sizeof(struct stat)); + + if (stat(path, &file_stat) < 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_status_set_error(F_directory); + 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); + + return F_status_set_error(F_file_stat); + } + + *type = f_macro_file_type_get(file_stat.st_mode); + + return F_none; + } +#endif // _di_f_file_type_ + +#ifndef _di_f_file_type_at_ + f_return_status f_file_type_at(const int at_id, const f_string path, const int flag, int *type) { + #ifndef _di_level_0_parameter_checking_ + if (path == 0) return F_status_set_error(F_parameter); + if (type == 0) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + 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_status_set_error(F_directory); + 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); + } + + *type = f_macro_file_type_get(file_stat.st_mode); + + return F_none; + } +#endif // _di_f_file_type_at_ + #ifndef _di_f_file_write_ f_return_status f_file_write(const f_file file, const f_string_static buffer, f_string_length *written) { #ifndef _di_level_0_parameter_checking_ diff --git a/level_0/f_file/c/file.h b/level_0/f_file/c/file.h index c8f0bb5..fda809a 100644 --- a/level_0/f_file/c/file.h +++ b/level_0/f_file/c/file.h @@ -956,7 +956,7 @@ extern "C" { * @param path * The path file name. * @param type - * The type of the file + * The type of the file. * * @return * F_true if path was found and path is type. @@ -984,7 +984,7 @@ extern "C" { * @param path * The path file name. * @param type - * The type of the file + * The type of the file. * @param flag * Any valid flag, such as f_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no. * @@ -1795,6 +1795,63 @@ extern "C" { #endif // _di_f_file_touch_at_ /** + * Get the file type for the file at the given path. + * + * This does not require access on the file itself. + * This only requires access via the parent directories in the path. + * + * @param path + * The path file name. + * @param type + * The type of the file. + * + * @return + * F_none if path was found and and the type was loaded in the type parameter. + * F_file_found_not if the path was not found. + * F_access_denied (with error bit) if access to the file was denied. + * F_directory (with error bit) on invalid directory. + * F_loop (with error bit) on loop error. + * F_memory_out (with error bit) if out of memory. + * F_name (with error bit) on path name error. + * F_number_overflow (with error bit) on overflow error. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see stat() + */ +#ifndef _di_f_file_type_ + extern f_return_status f_file_type(const f_string path, int *type); +#endif // _di_f_file_type_ + +/** + * Get the file type for the file at the given path within the parent 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_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no. + * @param type + * The type of the file. + * + * @return + * F_none if path was found and and the type was loaded in the type parameter. + * F_file_found_not if the path was not found. + * F_access_denied (with error bit) if access to the file was denied. + * F_directory (with error bit) on invalid directory. + * F_loop (with error bit) on loop error. + * F_memory_out (with error bit) if out of memory. + * F_name (with error bit) on path name error. + * F_number_overflow (with error bit) on overflow error. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see fstatat() + */ +#ifndef _di_f_file_type_at_ + extern f_return_status f_file_type_at(const int at_id, const f_string path, const int flag, int *type); +#endif // _di_f_file_type_at_ + +/** * Write until a single block is filled or entire buffer is written. * * To check how much was write into the buffer, record buffer->used before execution and compare to buffer->used after execution. -- 1.8.3.1