extern "C" {
#endif
+#ifndef _di_f_directory_create_
+ f_return_status f_directory_create(const f_string path, const mode_t modes) {
+ if (mkdir(path, modes) < 0) {
+ if (errno == EACCES) {
+ return f_status_set_error(f_access_denied);
+ }
+ else if (errno == EDQUOT) {
+ return f_status_set_error(f_filesystem_quota_blocks);
+ }
+ else if (errno == EEXIST) {
+ return f_status_set_error(f_file_found);
+ }
+ else if (errno == ENAMETOOLONG || errno == EFAULT) {
+ return f_status_set_error(f_invalid_name);
+ }
+ else if (errno == EINVAL) {
+ return f_status_set_error(f_invalid_parameter);
+ }
+ else if (errno == ELOOP) {
+ return f_status_set_error(f_loop);
+ }
+ else if (errno == EMLINK) {
+ return f_status_set_error(f_directory_error_link_max);
+ }
+ else if (errno == ENOENT) {
+ return f_status_set_error(f_file_not_found);
+ }
+ else if (errno == ENOMEM) {
+ return f_status_set_error(f_out_of_memory);
+ }
+ else if (errno == ENOSPC) {
+ return f_status_set_error(f_filesystem_quota_reached);
+ }
+ else if (errno == ENOTDIR) {
+ return f_status_set_error(f_invalid_directory);
+ }
+ else if (errno == EPERM) {
+ return f_status_set_error(f_prohibited);
+ }
+ else 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_create_
+
+/* @todo
+#ifndef _di_f_directory_create_at_
+ f_return_status f_directory_create_at(const int at_id, const f_string path, const mode_t modes) {
+ #ifndef _di_level_0_parameter_checking_
+ if (at_id <= 0) return f_status_set_error(f_invalid_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (mkdirat(path, modes) < 0) {
+ if (errno == EACCES) {
+ return f_status_set_error(f_access_denied);
+ }
+ else if (errno == EDQUOT) {
+ return f_status_set_error(f_filesystem_quota_blocks);
+ }
+ else if (errno == EEXIST) {
+ return f_status_set_error(f_file_found);
+ }
+ else if (errno == ENAMETOOLONG || errno == EFAULT) {
+ return f_status_set_error(f_invalid_name);
+ }
+ else if (errno == EINVAL || errno == EBADF) {
+ return f_status_set_error(f_invalid_parameter);
+ }
+ else if (errno == ELOOP) {
+ return f_status_set_error(f_loop);
+ }
+ else if (errno == EMLINK) {
+ return f_status_set_error(f_directory_error_link_max);
+ }
+ else if (errno == ENOENT) {
+ return f_status_set_error(f_file_not_found);
+ }
+ else if (errno == ENOMEM) {
+ return f_status_set_error(f_out_of_memory);
+ }
+ else if (errno == ENOSPC) {
+ return f_status_set_error(f_filesystem_quota_reached);
+ }
+ else if (errno == ENOTDIR) {
+ return f_status_set_error(f_invalid_directory);
+ }
+ else if (errno == EPERM) {
+ return f_status_set_error(f_prohibited);
+ }
+ else 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_create_at_
+*/
+
+#ifndef _di_f_directory_is_
+ f_return_status f_directory_is(const f_string path) {
+ struct stat file_stat;
+
+ memset(&file_stat, 0, sizeof(file_stat));
+
+ if (stat(path, &file_stat) < 0) {
+ if (errno == ENAMETOOLONG || errno == EFAULT) {
+ return f_status_set_error(f_invalid_name);
+ }
+ else if (errno == ENOMEM) {
+ return f_status_set_error(f_out_of_memory);
+ }
+ else if (errno == EOVERFLOW) {
+ return f_status_set_error(f_number_overflow);
+ }
+ else if (errno == ENOTDIR) {
+ return f_false;
+ }
+ else if (errno == ENOENT) {
+ return f_file_not_found;
+ }
+ else if (errno == EACCES) {
+ return f_status_set_error(f_access_denied);
+ }
+ else if (errno == ELOOP) {
+ return f_status_set_error(f_loop);
+ }
+
+ return f_status_set_error(f_file_error_stat);
+ }
+
+ if ((file_stat.st_mode & S_IFMT) == S_IFDIR) return f_true;
+
+ return f_false;
+ }
+#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) {
+ struct stat file_stat;
+
+ memset(&file_stat, 0, sizeof(file_stat));
+
+ if (fstatat(file_id, path, &file_stat, follow ? 0 : AT_SYMLINK_NOFOLLOW) < 0) {
+ if (errno == ENAMETOOLONG || errno == EFAULT) {
+ return f_status_set_error(f_invalid_name);
+ }
+ else if (errno == ENOMEM) {
+ return f_status_set_error(f_out_of_memory);
+ }
+ else if (errno == EOVERFLOW) {
+ return f_status_set_error(f_number_overflow);
+ }
+ else if (errno == ENOTDIR) {
+ return f_false;
+ }
+ else if (errno == ENOENT) {
+ return f_file_not_found;
+ }
+ else if (errno == EACCES) {
+ return f_status_set_error(f_access_denied);
+ }
+ else if (errno == ELOOP) {
+ return f_status_set_error(f_loop);
+ }
+
+ return f_status_set_error(f_file_error_stat);
+ }
+
+ if ((file_stat.st_mode & S_IFMT) == S_IFDIR) return f_true;
+
+ return f_false;
+ }
+#endif // _di_f_directory_is_at_
+
#ifndef _di_f_directory_list_
f_return_status f_directory_list(const f_string path, int (*filter)(const struct dirent *), int (*sort)(const struct dirent **, const struct dirent **), f_string_dynamics *names) {
#ifndef _di_level_0_parameter_checking_
// libc includes
#include <dirent.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
// work-around for out-dated systems.
*
* The name max 255 because the directory name size is 256.
* The last 1 is for the NULL character.
+ *
+ * The directory max recursion is more of a default than a rule.
*/
#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 255
+ #define f_directory_max_recursion 2048
#endif // _di_f_directory_limitations_
/**
#endif // _di_f_directory_
/**
+ * Create a directory at the given path.
+ *
+ * @param path
+ * The path file name.
+ * @param modes
+ * The directory modes to use when creating.
+ *
+ * @return
+ * f_none on success.
+ * f_invalid_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_not_found (with error bit) if a file within the path is not found (such as a broken symbolic link).
+ * f_out_of_memory (with error bit) if out of memory.
+ * 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_blocks (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_invalid_name (with error bit) on path name error.
+ * f_directory_error_link_max (with error bit) max links limit reached or exceeded.
+ * f_invalid_directory (with error bit) if a supposed directory in path is not actually a directory.
+ *
+ * @see mkdir()
+ */
+#ifndef _di_f_directory_create_
+ extern f_return_status f_directory_create(const f_string path, const mode_t modes);
+#endif // _di_f_directory_create_
+
+/**
+ * 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.
+ * @param path
+ * The path file name.
+ * @param modes
+ * The directory modes to use when creating.
+ *
+ * @return
+ * f_none on success.
+ * f_invalid_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_not_found (with error bit) if a file within the path is not found (such as a broken symbolic link).
+ * f_out_of_memory (with error bit) if out of memory.
+ * 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_blocks (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_invalid_name (with error bit) on path name error.
+ * f_directory_error_link_max (with error bit) max links limit reached or exceeded.
+ * f_invalid_directory (with error bit) if a supposed directory in path is not actually a directory.
+ *
+ * @see mkdir()
+ *
+#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 modes);
+#endif // _di_f_directory_create_at_
+
+/**
+ * Identify whether or not a file exists at the given path and if that file is a directory.
+ *
+ * @param path
+ * The path file name.
+ *
+ * @return
+ * t_true if path was found and path is a directory.
+ * f_false if path was found and path is not a directory.
+ * f_file_not_found if the path was not found.
+ * f_invalid_name (with error bit) if the name is somehow invalid.
+ * f_out_of_memory (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_invalid_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fstat()
+ */
+#ifndef _di_f_directory_is_
+ extern f_return_status f_directory_is(const f_string path);
+#endif // _di_f_directory_is_
+
+/**
+ * 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 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.
+ *
+ * @return
+ * t_true if path was found and path is a directory.
+ * f_false if path was found and path is not a directory.
+ * f_file_not_found if the path was not found.
+ * f_invalid_name (with error bit) if the name is somehow invalid.
+ * f_out_of_memory (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_invalid_parameter (with error bit) if a parameter is invalid.
+ *
+ * @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);
+#endif // _di_f_directory_is_at_
+
+/**
* For some given path, print the names of each file and/or directory inside the directory.
*
* Allows specifying a custom filter and custom sort.
}
#endif // _di_f_file_flush_
+#ifndef _di_f_file_is_
+ f_return_status f_file_is(const f_string path, const int type) {
+ struct stat file_stat;
+
+ memset(&file_stat, 0, sizeof(file_stat));
+
+ if (stat(path, &file_stat) < 0) {
+ if (errno == ENAMETOOLONG || errno == EFAULT) {
+ return f_status_set_error(f_invalid_name);
+ }
+ else if (errno == ENOMEM) {
+ return f_status_set_error(f_out_of_memory);
+ }
+ else if (errno == EOVERFLOW) {
+ return f_status_set_error(f_number_overflow);
+ }
+ else if (errno == ENOTDIR) {
+ return f_status_set_error(f_invalid_directory);
+ }
+ else if (errno == ENOENT) {
+ return f_file_not_found;
+ }
+ else if (errno == EACCES) {
+ return f_status_set_error(f_access_denied);
+ }
+ else if (errno == ELOOP) {
+ return f_status_set_error(f_loop);
+ }
+
+ return f_status_set_error(f_file_error_stat);
+ }
+
+ if (f_macro_file_type_get(file_stat.st_mode) == type) return f_true;
+
+ return f_false;
+ }
+#endif // _di_f_file_is_
+
+#ifndef _di_f_file_is_at_
+ f_return_status f_file_is_at(const int file_id, const f_string path, const int type, const bool follow) {
+ struct stat file_stat;
+
+ memset(&file_stat, 0, sizeof(file_stat));
+
+ if (fstatat(file_id, path, &file_stat, follow ? 0 : AT_SYMLINK_NOFOLLOW) < 0) {
+ if (errno == ENAMETOOLONG || errno == EFAULT) {
+ return f_status_set_error(f_invalid_name);
+ }
+ else if (errno == ENOMEM) {
+ return f_status_set_error(f_out_of_memory);
+ }
+ else if (errno == EOVERFLOW) {
+ return f_status_set_error(f_number_overflow);
+ }
+ else if (errno == ENOTDIR) {
+ return f_status_set_error(f_invalid_directory);
+ }
+ else if (errno == ENOENT) {
+ return f_file_not_found;
+ }
+ else if (errno == EACCES) {
+ return f_status_set_error(f_access_denied);
+ }
+ else if (errno == ELOOP) {
+ return f_status_set_error(f_loop);
+ }
+
+ return f_status_set_error(f_file_error_stat);
+ }
+
+ if (file_stat.st_mode == (S_IFMT & S_IFDIR)) return f_true;
+
+ return f_false;
+ }
+#endif // _di_f_file_is_at_
+
#ifndef _di_f_file_read_
f_return_status f_file_read(f_file *file, f_string_dynamic *buffer) {
#ifndef _di_level_0_parameter_checking_
if (file_id <= 0) return f_status_set_error(f_invalid_parameter);
#endif // _di_level_0_parameter_checking_
- int result = fstatat(file_id, path, file_stat, flags);
-
- if (result < 0) {
+ if (fstatat(file_id, path, file_stat, flags) < 0) {
if (errno == ENAMETOOLONG || errno == EFAULT) {
return f_status_set_error(f_invalid_name);
}
#define f_file_type_link S_IFLNK
#define f_file_type_socket S_IFSOCK
- #define f_macro_file_type_is(mode) f_file_type_mask & S_IFIFO
-
- #define f_macro_file_type_is_pipe(mode) f_macro_file_type_is(mode) == f_file_type_pipe
- #define f_macro_file_type_is_character(mode) f_macro_file_type_is(mode) == f_file_type_character
- #define f_macro_file_type_is_directory(mode) f_macro_file_type_is(mode) == f_file_type_directory
- #define f_macro_file_type_is_block(mode) f_macro_file_type_is(mode) == f_file_type_block
- #define f_macro_file_type_is_file(mode) f_macro_file_type_is(mode) == f_file_type_file
- #define f_macro_file_type_is_link(mode) f_macro_file_type_is(mode) == f_file_type_link
- #define f_macro_file_type_is_socket(mode) f_macro_file_type_is(mode) == f_file_type_socket
+ #define f_macro_file_type_get(mode) (f_file_type_mask & mode)
+
+ #define f_macro_file_type_is_pipe(mode) f_macro_file_type_get(mode) == f_file_type_pipe
+ #define f_macro_file_type_is_character(mode) f_macro_file_type_get(mode) == f_file_type_character
+ #define f_macro_file_type_is_directory(mode) f_macro_file_type_get(mode) == f_file_type_directory
+ #define f_macro_file_type_is_block(mode) f_macro_file_type_get(mode) == f_file_type_block
+ #define f_macro_file_type_is_file(mode) f_macro_file_type_get(mode) == f_file_type_file
+ #define f_macro_file_type_is_link(mode) f_macro_file_type_get(mode) == f_file_type_link
+ #define f_macro_file_type_is_socket(mode) f_macro_file_type_get(mode) == f_file_type_socket
#endif // _di_f_file_type_
/**
#define f_file_mode_world_rw (S_IROTH | S_IWOTH)
#define f_file_mode_world_rx (S_IROTH | S_IXOTH)
#define f_file_mode_world_wx (S_IWOTH | S_IXOTH)
+
+ #define f_file_mode_all_rwx (f_file_mode_owner_rwx | f_file_mode_group_rwx | f_file_mode_world_rwx)
+ #define f_file_mode_all_rw (f_file_mode_owner_rw | f_file_mode_group_rw | f_file_mode_world_rw)
+ #define f_file_mode_all_wx (f_file_mode_owner_wx | f_file_mode_group_wx | f_file_mode_world_wx)
+ #define f_file_mode_all_rx (f_file_mode_owner_rx | f_file_mode_group_rx | f_file_mode_world_rx)
+ #define f_file_mode_all_r (f_file_mode_owner_r | f_file_mode_group_r | f_file_mode_world_r)
+ #define f_file_mode_all_w (f_file_mode_owner_w | f_file_mode_group_w | f_file_mode_world_w)
+ #define f_file_mode_all_x (f_file_mode_owner_x | f_file_mode_group_x | f_file_mode_world_x)
+
+ // file mode sticky-bits and all bits.
+ #define f_file_mode_special_user S_ISUID
+ #define f_file_mode_special_group S_ISGID
+ #define f_file_mode_special_world S_ISVTX
+ #define f_file_mode_special_all (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
+
+ // special file mode combinations.
+ #define f_file_mode_user_access (f_file_mode_owner_rwx | f_file_mode_group_rwx | f_file_mode_world_x)
+ #define f_file_mode_user_directory (f_file_mode_owner_rwx | f_file_mode_group_rwx)
+ #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_flush_
/**
+ * Identify whether or not a file exists at the given path and if that file is a specific type.
+ *
+ * @param path
+ * The path file name.
+ * @param type
+ * The type of the file
+ *
+ * @return
+ * t_true if path was found and path is type.
+ * f_false if path was found and path is not type.
+ * f_file_not_found if the path was not found.
+ * f_invalid_name (with error bit) if the name is somehow invalid.
+ * f_out_of_memory (with error bit) if out of memory.
+ * f_number_overflow (with error bit) on overflow error.
+ * f_invalid_directory (with error bit) on invalid directory.
+ * f_access_denied (with error bit) if access to the file was denied.
+ * f_loop (with error bit) if a loop occurred.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fstat()
+ */
+#ifndef _di_f_file_is_
+ extern f_return_status f_file_is(const f_string path, const int type);
+#endif // _di_f_file_is_
+
+/**
+ * Identify whether or not a file exists at the given path within the parent directory and if that file is a specific type.
+ *
+ * @param file_id
+ * The file descriptor representing the parent directory to search within.
+ * @param path
+ * The path file name.
+ * @param type
+ * The type of the file
+ * @param follow
+ * Set to TRUE to follow symbolic links when determining if path is a file.
+ * Set to FALSE to not follow.
+ *
+ * @return
+ * t_true if path was found and path is type.
+ * f_false if path was found and path is not type.
+ * f_file_not_found if the path was not found.
+ * f_invalid_name (with error bit) if the name is somehow invalid.
+ * f_out_of_memory (with error bit) if out of memory.
+ * f_number_overflow (with error bit) on overflow error.
+ * f_invalid_directory (with error bit) on invalid directory.
+ * f_access_denied (with error bit) if access to the file was denied.
+ * f_loop (with error bit) if a loop occurred.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fstatat()
+ */
+#ifndef _di_f_file_is_at_
+ extern f_return_status f_file_is_at(const int file_id, const f_string path, const int type, const bool follow);
+#endif // _di_f_file_is_at_
+
+/**
* Read until a single block is filled or EOF is reached.
*
* This does not allocate space to the buffer, so be sure enough space exists (file->size_chunk * file->size_block).
f_file_max_open,
#endif // _di_f_status_file_
+ #ifndef _di_f_status_filesystem_
+ f_filesystem_error,
+ f_filesystem_quota_blocks,
+ f_filesystem_quota_reached,
+ #endif // _di_f_status_filesystem_
+
// Most of these are a guess until I get around to researching & implementing linux directory I/O.
#ifndef _di_f_status_directory_
f_directory_error,
f_directory_error_close,
f_directory_error_descriptor,
f_directory_error_flush,
+ f_directory_error_link_max,
f_directory_error_open,
f_directory_error_purge,
f_directory_error_read,
break;
#endif // _di_fl_status_file_
+ #ifndef _di_f_status_filesystem_
+ case f_filesystem_error:
+ *string = fl_status_string_filesystem_error;
+ break;
+ case f_filesystem_quota_blocks:
+ *string = fl_status_string_filesystem_quota_blocks;
+ break;
+ case f_filesystem_quota_reached:
+ *string = fl_status_string_filesystem_quota_reached;
+ break;
+ #endif // _di_f_status_filesystem_
+
#ifndef _di_fl_status_directory_
case f_directory_error_read:
*string = fl_status_string_directory_read_error;
case f_directory_error_flush:
*string = fl_status_string_directory_flush_error;
break;
+ case f_directory_error_link_max:
+ *string = fl_status_string_directory_error_link_max;
+ break;
case f_directory_error_purge:
*string = fl_status_string_directory_purge_error;
break;
#define fl_status_string_file_max_open_length 15
#endif // _di_fl_status_file_
+ #ifndef _di_f_status_filesystem_
+ #define fl_status_string_filesystem_error "f_filesystem_error"
+ #define fl_status_string_filesystem_error_length 18
+
+ #define fl_status_string_filesystem_quota_blocks "f_filesystem_quota_blocks"
+ #define fl_status_string_filesystem_quota_blocks_length 25
+
+ #define fl_status_string_filesystem_quota_reached "f_filesystem_quota_reached"
+ #define fl_status_string_filesystem_quota_reached_length 26
+ #endif // _di_f_status_filesystem_
+
#ifndef _di_fl_status_directory_
#define fl_status_string_directory_read_error "f_directory_error_read"
#define fl_status_string_directory_read_error_length 22
#define fl_status_string_directory_flush_error "f_directory_error_flush"
#define fl_status_string_directory_flush_error_length 23
+ #define fl_status_string_directory_error_link_max "f_directory_error_link_max"
+ #define fl_status_string_directory_error_link_max_length 26
+
#define fl_status_string_directory_purge_error "f_directory_error_purge"
#define fl_status_string_directory_purge_error_length 23
status = f_file_stat_at(parent_fd, entity[i]->d_name, &file_stat, 0);
if (f_status_is_error(status)) break;
- mode = f_macro_file_type_is(file_stat.d_type);
+ mode = f_macro_file_type_get(file_stat.st_mode);
if (mode == f_file_type_block) {
names = &listing->block;
}
#endif // _di_fll_status_file_
+ #ifndef _di_f_status_filesystem_
+ if (fl_string_compare(string, fl_status_string_filesystem_error, length, fl_status_string_filesystem_error_length) == f_equal_to) {
+ *code = f_filesystem_error;
+ return f_none;
+ }
+
+ if (fl_string_compare(string, fl_status_string_filesystem_quota_blocks, length, fl_status_string_filesystem_quota_blocks_length) == f_equal_to) {
+ *code = f_filesystem_quota_blocks;
+ return f_none;
+ }
+
+ if (fl_string_compare(string, fl_status_string_filesystem_quota_reached, length, fl_status_string_filesystem_quota_reached_length) == f_equal_to) {
+ *code = f_filesystem_quota_reached;
+ return f_none;
+ }
+ #endif // _di_f_status_filesystem_
+
#ifndef _di_fll_status_directory_
if (fl_string_compare(string, fl_status_string_directory_read_error, length, fl_status_string_directory_read_error_length) == f_equal_to) {
*code = f_directory_error_read;
return f_none;
}
+ if (fl_string_compare(string, fl_status_string_directory_error_link_max, length, fl_status_string_directory_error_link_max_length) == f_equal_to) {
+ *code = f_directory_error_link_max;
+ return f_none;
+ }
+
if (fl_string_compare(string, fl_status_string_directory_purge_error, length, fl_status_string_directory_purge_error_length) == f_equal_to) {
*code = f_directory_error_purge;
return f_none;