]> Kevux Git Server - fll/commitdiff
Feature: add f_file_type() and f_file_type_at() functions.
authorKevin Day <thekevinday@gmail.com>
Sun, 12 Jul 2020 23:23:11 +0000 (18:23 -0500)
committerKevin Day <thekevinday@gmail.com>
Sun, 12 Jul 2020 23:23:11 +0000 (18:23 -0500)
level_0/f_file/c/file.c
level_0/f_file/c/file.h

index 406efaf0887262b3b884501f6af1b98deb9393b7..2c6bbe62d432ba263f94b462b4138cb9820d7377 100644 (file)
@@ -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_
index c8f0bb5d45cbe57585c5ccd8045c4bd76e69c911..fda809ad8bd7065ac65f9f53acd4ce974128181e 100644 (file)
@@ -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.