]> Kevux Git Server - kevux-tools/commitdiff
Progress: Continue working on completing the remove program.
authorKevin Day <Kevin@kevux.org>
Thu, 10 Apr 2025 02:48:01 +0000 (21:48 -0500)
committerKevin Day <Kevin@kevux.org>
Thu, 10 Apr 2025 03:55:25 +0000 (22:55 -0500)
I want to remove the multiple `fl_directory_do()` calls.
This means that I need to change how pre-processing and removal is performed.
The pre-processing needs to happen before each remove.
The recursion needs to happen during the remove.

This begins refactoring the code to allow for this design change.
The recursive functions do not use the `main.setting.state.status` and so the functions need to be updated to instead return the status.
I placed a delete on the top level, but recursion is not necessarily properly done yet.
I only partially changed the structure to test out some of the recent changes, primarily trying to confirm/deny if the simulate is working as desired.
I still need to complete/correct the logic for proper deletion with recursion.

Update to utilize the newly added `fll_program_signal_check_loop()` and `fll_program_signal_check_simple()`.

Remove all stale and no longer needed signal check defines.

18 files changed:
data/build/stand_alone/configs/remove-config.h
sources/c/program/kevux/tools/remove/main/common.c
sources/c/program/kevux/tools/remove/main/common/define.h
sources/c/program/kevux/tools/remove/main/common/print.c
sources/c/program/kevux/tools/remove/main/common/print.h
sources/c/program/kevux/tools/remove/main/convert.c
sources/c/program/kevux/tools/remove/main/operate.c
sources/c/program/kevux/tools/remove/main/operate.h
sources/c/program/kevux/tools/remove/main/preprocess.c
sources/c/program/kevux/tools/remove/main/preprocess.h
sources/c/program/kevux/tools/remove/main/remove.c
sources/c/program/kevux/tools/remove/main/signal.c
sources/c/program/kevux/tools/remove/main/signal.h
sources/c/program/kevux/tools/remove/remove/main.c
sources/c/program/kevux/tools/remove/rm/main.c
sources/c/program/kevux/tools/remove/rmdir/main.c
sources/c/program/kevux/tools/remove/unlink/main.c
tests/unit/remove/c/main-test-remove.c

index ef897bc6c3f7507b8b3cc0631de78062a11d1114..7aea9e87093488d1a08e4cbeefe6d8c871b927c8 100644 (file)
 //#define _di_fll_program_print_version_
 //#define _di_fll_program_s_a_
 //#define _di_fll_program_s_e_
+//#define _di_fll_program_signal_check_loop_
+//#define _di_fll_program_signal_check_simple_
+//#define _di_fll_program_signal_d_
 //#define _di_fll_program_standard_set_down_
 //#define _di_fll_program_standard_set_up_
 //#define _di_fll_program_standard_signal_handle_
index 8f15738f5c81c575002ff08ab77bbc421bfb5eb4..be56022a934690fb84529d79d29ad85c88c0bd3e 100644 (file)
@@ -207,7 +207,7 @@ extern "C" {
                 break;
               }
 
-              if (kt_remove_signal_check(main)) return;
+              if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return;
             } // for
 
             if (j == 12) {
index c8958b87e121a95fbfd07690d97898b489e80d31..26efe6214d401f859e499806132406ad4ede2e3c 100644 (file)
@@ -29,7 +29,6 @@ extern "C" {
  *   - max: The maximum recursion depth to perform when recursing into a directory.
  *
  * kt_remove_signal_*_d:
- *   - check:          When not using threads, this is how often to perform the check (lower numbers incur more kernel I/O).
  *   - check_failsafe: When using threads, how many consecutive failures to check signal before aborting (as a recursion failsafe).
  *
  * kt_remove_time_seconds_in_*_d:
@@ -48,7 +47,6 @@ extern "C" {
 
   #define kt_remove_poll_timeout_d          200
 
-  #define kt_remove_signal_check_d          20000
   #define kt_remove_signal_check_failsafe_d 20000
 
   #define kt_remove_time_seconds_in_day_d        86400
@@ -332,6 +330,17 @@ extern "C" {
   #define kt_remove_print_flag_warning_d 0x40
 #endif // _di_kt_remove_print_flag_d_
 
+/**
+ * A macro wrapping the appropriate signal check function based on threaded/non-threaded support.
+ */
+#ifndef _di_kt_remove_signal_check_d_
+  #ifdef _di_thread_support_
+    #define macro_kt_remove_signal_check(program, state) fll_program_signal_check_loop(program, state)
+  #else
+    #define macro_kt_remove_signal_check(program, state) fll_program_signal_check_simple(program, state)
+  #endif // _di_thread_support_
+#endif // _di_kt_remove_signal_check_d_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 25876b451b93b52a82c63b8c21230e3a6f9d0c56..0a0c84bcd33f3f455cd80408b3b343ecb654c018 100644 (file)
@@ -36,6 +36,7 @@ extern "C" {
     "kt_remove_get_id",
     "kt_remove_modes_resize",
     "kt_remove_operate_memory_save",
+    "kt_remove_preprocess_file",
     "kt_remove_setting_load",
   };
 #endif // _di_kt_remove_f_a_
index 9aabec084ffbd24fd38b0b164d8d9cfd3ee9b90d..d8bda1e68bed8edd9664a6ef281dd25f23358b0a 100644 (file)
@@ -69,6 +69,7 @@ extern "C" {
     kt_remove_f_kt_remove_get_id_e,
     kt_remove_f_kt_remove_modes_resize_e,
     kt_remove_f_kt_remove_operate_memory_save_e,
+    kt_remove_f_kt_remove_preprocess_file_e,
     kt_remove_f_kt_remove_setting_load_e,
   }; // enum
 #endif // _di_kt_remove_f_e_
index 9d108d1f33ccfde99685fd32a974082aaab93015..b4fda783f66c1b0339b265a7f972bd9d2aeec871 100644 (file)
@@ -63,7 +63,7 @@ extern "C" {
 
       for (; range.start <= range.stop; range.start += width, width_max -= width) {
 
-        if (kt_remove_signal_check(main)) return;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return;
 
         // Skip past NULL characters.
         if (!buffer.string[range.start]) {
@@ -325,7 +325,7 @@ extern "C" {
 
       for (f_number_unsigned_t i = 0; i < 15; ++i) {
 
-        if (kt_remove_signal_check(main)) return;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return;
 
         memset(&time, 0, sizeof(struct tm));
 
index 00e2c2c1c7c67975e6f187ec2a4655792bcdf530..658e3215c54e49ff061428f5ad37822d8efe4211 100644 (file)
@@ -17,77 +17,68 @@ extern "C" {
     recurse.state.interrupt = &kt_remove_signal_check_recurse;
 
     recurse.depth_max = main->setting.flag & kt_remove_main_flag_recurse_d ? kt_remove_depth_max_d : 0;
-    recurse.flag = main->setting.flag & kt_remove_main_flag_recurse_d ? f_directory_recurse_do_flag_top_after_e : 0;
+    recurse.flag = 0;
     recurse.path_top = &path;
 
     recurse.action = &kt_remove_operate_recurse_action;
     recurse.handle = &kt_remove_operate_recurse_handle;
 
     fl_directory_do(path, &recurse);
+    if (F_status_is_error(recurse.state.status)) return recurse.state.status;
 
-    const f_status_t status = f_directory_recurse_do_delete(&recurse);
+    f_status_t status_remove = F_no;
 
-    return F_status_is_error(recurse.state.status)
-      ? recurse.state.status
-      : F_status_is_error(status)
-        ? status
-        : F_yes;
+    // Remove the directory, if not simulating.
+    if (!(main->setting.flag & kt_remove_main_flag_simulate_d)) {
+      status_remove = kt_remove_operate_remove(main, path, flag_operate);
+    }
+
+    {
+      const f_status_t status = f_directory_recurse_do_delete(&recurse);
+      if (F_status_is_error(status)) return status;
+    }
+
+    return status_remove;
   }
 #endif // _di_kt_remove_operate_directory_
 
 #ifndef _di_kt_remove_operate_file_
-  void kt_remove_operate_file(kt_remove_main_t * const main, const f_string_static_t path) {
+  f_status_t kt_remove_operate_file(kt_remove_main_t * const main, const f_string_static_t path) {
 
-    if (!main) return;
-
-    if (!path.used) {
-      main->setting.state.status = F_data_not;
-
-      return;
-    }
+    if (!main) return F_status_set_error(F_parameter);
+    if (!path.used) return F_data_not;
+    if (F_status_is_error(main->setting.state.status)) return F_no;
 
-    if (kt_remove_signal_check(main)) return;
+    if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return F_status_set_error(F_interrupt);
 
     const uint32_t flag_operate = kt_remove_preprocess_file(main, path, 0);
-    f_status_t status = F_no;
 
-    if (F_status_is_error_not(main->setting.state.status) && !(flag_operate & kt_remove_flag_file_operate_processed_d)) {
-      if (flag_operate & kt_remove_flag_file_operate_missing_d) {
-        if (main->setting.flag & kt_remove_main_flag_force_simulate_d) {
-          status = main->setting.state.status = F_no;
-        }
-        else {
-          main->setting.state.status = F_status_set_error(F_file_found_not);
+    if (F_status_is_error(main->setting.state.status)) return main->setting.state.status;
+    if (flag_operate & kt_remove_flag_file_operate_processed_d) return F_no;
 
-          kt_remove_print_error_file(&main->program.error, macro_kt_remove_f(f_file_exists), path, f_file_operation_delete_s, fll_error_file_type_file_e);
-        }
-      }
-      else {
-        kt_remove_operate_file_prompt(main, path, flag_operate);
+    f_status_t status_remove = F_no;
 
-        if (!(main->setting.flag & kt_remove_main_flag_simulate_d)) {
-          if (F_status_is_error_not(main->setting.state.status) && main->setting.state.status != F_skip) {
-            main->setting.state.status = F_okay;
+    if (flag_operate & kt_remove_flag_file_operate_missing_d) {
+      if (!(main->setting.flag & kt_remove_main_flag_force_simulate_d)) {
+        main->setting.state.status = F_status_set_error(F_file_found_not);
 
-            status = main->setting.state.status = (flag_operate & kt_remove_flag_file_operate_directory_d)
-              ? kt_remove_operate_directory(main, path, flag_operate)
-              : kt_remove_operate_remove(main, path, flag_operate);
-          }
-        }
-      }
-    }
-
-    if (F_status_is_error_not(main->setting.state.status)) {
-      kt_remove_operate_memory_save(main, path, flag_operate);
+        kt_remove_print_error_file(&main->program.error, macro_kt_remove_f(kt_remove_preprocess_file), path, f_file_operation_delete_s, fll_error_file_type_file_e);
 
-      if (F_status_is_error(main->setting.state.status)) {
-        kt_remove_print_error_file(&main->program.error, macro_kt_remove_f(kt_remove_operate_memory_save), path, f_file_operation_process_s, fll_error_file_type_path_e);
+        return main->setting.state.status;
       }
     }
+    else if (main->setting.state.status != F_skip) {
+      main->setting.state.status = kt_remove_operate_file_prompt(main, path, flag_operate);
+      if (F_status_is_error(main->setting.state.status)) return main->setting.state.status;
 
-    if (F_status_is_error_not(main->setting.state.status)) {
-      main->setting.state.status = status;
+      return (flag_operate & kt_remove_flag_file_operate_directory_d)
+        ? kt_remove_operate_directory(main, path, flag_operate)
+        : !(main->setting.flag & kt_remove_main_flag_simulate_d)
+          ? kt_remove_operate_remove(main, path, flag_operate)
+          : F_no;
     }
+
+    return F_no;
   }
 #endif // _di_kt_remove_operate_file_
 
@@ -102,7 +93,7 @@ extern "C" {
       return;
     }
 
-    if (kt_remove_signal_check(main)) return;
+    if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return;
 
     const uint32_t flag_operate = kt_remove_preprocess_file(main, path, kt_remove_flag_file_operate_parent_d);
 
@@ -130,44 +121,36 @@ extern "C" {
 #endif // _di_kt_remove_operate_file_parent_
 
 #ifndef _di_kt_remove_operate_file_prompt_
-  void kt_remove_operate_file_prompt(kt_remove_main_t * const main, const f_string_static_t path, const uint flag_operate) {
-
-    if (!main) return;
-
-    if (!(main->setting.flag & kt_remove_main_flag_prompt_all_d) || (main->setting.flag & kt_remove_main_flag_prompt_never_d)) {
-      main->setting.state.status = F_okay;
-
-      return;
-    }
-
-    if (!path.used) {
-      main->setting.state.status = F_data_not;
+  f_status_t kt_remove_operate_file_prompt(kt_remove_main_t * const main, const f_string_static_t path, const uint flag_operate) {
 
-      return;
-    }
+    if (!main) return F_status_set_error(F_parameter);
+    if (!(main->setting.flag & kt_remove_main_flag_prompt_all_d) || (main->setting.flag & kt_remove_main_flag_prompt_never_d)) return F_okay;
+    if (!path.used) return F_data_not;
 
     if (main->setting.flag & kt_remove_main_flag_prompt_once_d) {
-      if (main->setting.prompt) return;
+      if (main->setting.prompt) return F_okay;
 
       main->setting.prompt = 1;
     }
     else if (main->setting.flag & kt_remove_main_flag_prompt_follow_d) {
-      if (!(flag_operate & kt_remove_flag_file_operate_link_d)) return;
+      if (!(flag_operate & kt_remove_flag_file_operate_link_d)) return F_okay;
     }
 
-    if (main->setting.flag & kt_remove_main_flag_simulate_d) return;
+    if (main->setting.flag & kt_remove_main_flag_simulate_d) return F_okay;
+
+    f_status_t status = F_okay;
 
     main->cache.input.used = 0;
 
     kt_remove_print_message_remove_confirm(&main->program.message, path);
 
     if (!main->cache.polls.size) {
-      main->setting.state.status = f_memory_array_increase(1, sizeof(f_poll_t), (void **) &main->cache.polls.array, &main->cache.polls.used, &main->cache.polls.size);
+      status = f_memory_array_increase(1, sizeof(f_poll_t), (void **) &main->cache.polls.array, &main->cache.polls.used, &main->cache.polls.size);
 
-      if (F_status_is_error(main->setting.state.status)) {
+      if (F_status_is_error(status)) {
         kt_remove_print_error(&main->program.error, macro_kt_remove_f(f_memory_array_increase));
 
-        return;
+        return status;
       }
 
       // This is only every used here so assign this once and never again.
@@ -179,23 +162,23 @@ extern "C" {
 
     // Use polling to read input while allowing interrupt signals to be received (the read() function blocks signals).
     do {
-      main->setting.state.status = f_file_poll(main->cache.polls, kt_remove_poll_timeout_d);
+      status = f_file_poll(main->cache.polls, kt_remove_poll_timeout_d);
 
-      if (F_status_is_error(main->setting.state.status)) {
+      if (F_status_is_error(status)) {
         kt_remove_print_error(&main->program.error, macro_kt_remove_f(f_file_poll));
 
-        return;
+        return status;
       }
 
-      if (kt_remove_signal_check(main)) return;
-    } while (F_status_set_fine(main->setting.state.status) == F_time_out);
+      if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return F_status_set_error(F_interrupt);
+    } while (F_status_set_fine(status) == F_time_out);
 
-    main->setting.state.status = f_file_read_block(main->program.input, &main->cache.input);
+    status = f_file_read_block(main->program.input, &main->cache.input);
 
-    if (F_status_is_error(main->setting.state.status)) {
+    if (F_status_is_error(status)) {
       kt_remove_print_error_file(&main->program.error, macro_kt_remove_f(f_file_read_block), f_string_empty_s, f_file_operation_read_s, fll_error_file_type_input_e);
 
-      return;
+      return status;
     }
 
     // Skip past any NULL characters in the input.
@@ -203,19 +186,18 @@ extern "C" {
       f_number_unsigned_t i = 0;
 
       for (; i < main->cache.input.used && !main->cache.input.string[i]; ++i) {
-        if (kt_remove_signal_check(main)) return;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return F_status_set_error(F_interrupt);
       } // for
 
       // Only 'y' and 'Y' are treated as confimation and all others equate to 'no'.
       if (main->cache.input.string[i] == f_string_ascii_y_s.string[0] || main->cache.input.string[i] == f_string_ascii_Y_s.string[0]) {
-        main->setting.state.status = F_okay;
 
         // Shrink an oversized input buffer.
         if (main->cache.input.size > kt_remove_allocation_large_d) {
           f_memory_array_resize(0, sizeof(f_char_t), (void **) &main->cache.input.string, &main->cache.input.used, &main->cache.input.size);
         }
 
-        return;
+        return F_okay;
       }
     }
 
@@ -224,7 +206,7 @@ extern "C" {
       f_memory_array_resize(0, sizeof(f_char_t), (void **) &main->cache.input.string, &main->cache.input.used, &main->cache.input.size);
     }
 
-    main->setting.state.status = (main->setting.flag & kt_remove_main_flag_prompt_once_d) ? F_status_set_error(F_skip) : F_skip;
+    return (main->setting.flag & kt_remove_main_flag_prompt_once_d) ? F_status_set_error(F_skip) : F_skip;
   }
 #endif // _di_kt_remove_operate_file_prompt_
 
@@ -251,7 +233,7 @@ extern "C" {
     if (main->setting.flag & kt_remove_main_flag_recurse_d) {
       for (; i < main->cache.memory.used; ++i) {
 
-        if (kt_remove_signal_check(main)) return;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return;
         if (!main->cache.memory.array[i].used) continue;
 
         // The memory cache is nulless and top-most directories end in slashes.
@@ -290,7 +272,7 @@ extern "C" {
       // Only perform exact matches when not using recursion.
       for (; i < main->cache.memory.used; ++i) {
 
-        if (kt_remove_signal_check(main)) return;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return;
 
         if (f_compare_dynamic(main->cache.memory.array[i], path) == F_equal_to) {
           *flag_operate |= kt_remove_flag_file_operate_processed_d;
@@ -303,32 +285,22 @@ extern "C" {
 #endif // _di_kt_remove_operate_memory_check_
 
 #ifndef _di_kt_remove_operate_memory_save_
-  void kt_remove_operate_memory_save(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate) {
-
-    if (!main) return;
-
-    if (!path.used) {
-      main->setting.state.status = F_data_not;
+  f_status_t kt_remove_operate_memory_save(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate) {
 
-      return;
-    }
-
-    if (!(main->setting.flag & kt_remove_main_flag_remember_d)) {
-      main->setting.state.status = F_okay;
-
-      return;
-    }
+    if (!main) return F_status_set_error(F_parameter);
+    if (!path.used) return F_data_not;
+    if (!(main->setting.flag & kt_remove_main_flag_remember_d)) return F_okay;
 
-    main->setting.state.status = f_memory_array_increase(main->setting.state.step_small, sizeof(f_string_dynamic_t), (void **) &main->cache.memory.array, &main->cache.memory.used, &main->cache.memory.size);
+    f_status_t status = f_memory_array_increase(main->setting.state.step_small, sizeof(f_string_dynamic_t), (void **) &main->cache.memory.array, &main->cache.memory.used, &main->cache.memory.size);
 
     // Find any child paths that would be included by this and remove them from the paths list.
-    if (F_status_is_error_not(main->setting.state.status) && (flag_operate & kt_remove_flag_file_operate_directory_d)) {
+    if (F_status_is_error_not(status) && (flag_operate & kt_remove_flag_file_operate_directory_d)) {
       const f_range_t range = macro_f_range_t_initialize_2(path.used);
       f_number_unsigned_t i = 0;
 
       for (; i < main->cache.memory.used; ++i) {
 
-        if (kt_remove_signal_check(main)) return;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return F_status_set_error(F_interrupt);
         if (path.used > main->cache.memory.array[i].used) continue;
 
         if (f_compare_dynamic_partial_dynamic(path, main->cache.memory.array[i], range) == F_equal_to) break;
@@ -348,14 +320,17 @@ extern "C" {
       }
     }
 
-    if (F_status_is_error_not(main->setting.state.status)) {
-      main->setting.state.status = f_string_dynamic_append_nulless(path, &main->cache.memory.array[main->cache.memory.used]);
+    if (F_status_is_error_not(status)) {
+      status = f_string_dynamic_append_nulless(path, &main->cache.memory.array[main->cache.memory.used]);
     }
 
-    if (F_status_is_error_not(main->setting.state.status)) {
+    if (F_status_is_error_not(status)) {
       ++main->cache.memory.used;
-      main->setting.state.status = F_okay;
+
+      status = F_okay;
     }
+
+    return status;
   }
 #endif // _di_kt_remove_operate_memory_save_
 
@@ -365,25 +340,13 @@ extern "C" {
     if (!recurse || !recurse->state.custom || F_status_set_fine(recurse->state.status) == F_interrupt) return;
     if (!kt_remove_operate_shall_remove(recurse->state.code) || !(flag & f_directory_recurse_do_flag_action_e)) return;
 
-    const f_string_static_t path = flag & f_directory_recurse_do_flag_top_after_e
-      ? recurse->path_top
-        ? *recurse->path_top
-        : f_string_null_s
-      : recurse->path;
-
     kt_remove_main_t * const main = (kt_remove_main_t *) recurse->state.custom;
 
-    recurse->state.status = F_okay;
+    if (main->setting.flag & kt_remove_main_flag_simulate_d) {
+      f_print_dynamic(f_string_eol_s, main->program.output.to);
+    }
 
-    recurse->state.status = kt_remove_operate_remove(
-      main,
-      path,
-      flag & f_directory_recurse_do_flag_top_after_e
-        ? (uint32_t) recurse->state.code
-        : flag & f_directory_recurse_do_flag_directory_e
-          ? (((uint32_t) recurse->state.code) | kt_remove_flag_file_operate_child_d | kt_remove_flag_file_operate_directory_d) & ~kt_remove_flag_file_operate_parent_d
-          : (((uint32_t) recurse->state.code) | kt_remove_flag_file_operate_child_d) & ~kt_remove_flag_file_operate_directory_parent_d
-    );
+    recurse->state.status = kt_remove_operate_file(main, recurse->path);
 
     if (F_status_is_error_not(recurse->state.status)) {
       recurse->state.status = F_okay;
@@ -451,9 +414,11 @@ extern "C" {
       }
     }
 
+    const f_string_static_t target = (flag_operate & kt_remove_flag_file_operate_follow_d) ? main->cache.buffer : path;
+
     status = flag_operate & kt_remove_flag_file_operate_directory_d
-      ? f_directory_remove((flag_operate & kt_remove_flag_file_operate_follow_d) ? main->cache.buffer : path, (main->setting.state.status & kt_remove_main_flag_recurse_d) ? kt_remove_depth_max_d : 0, F_false)
-      : f_file_remove((flag_operate & kt_remove_flag_file_operate_follow_d) ? main->cache.buffer : path);
+      ? f_directory_remove(target, (main->setting.flag & kt_remove_main_flag_recurse_d) ? kt_remove_depth_max_d : 0, F_false)
+      : f_file_remove(target);
 
     if (F_status_is_error(status)) {
       if (F_status_set_fine(status) == F_directory_empty_not && (flag_operate & kt_remove_flag_file_operate_remove_not_d)) {
@@ -481,7 +446,16 @@ extern "C" {
     }
 
     if (status == F_yes) {
-      kt_remove_print_verbose_operate_file_remove(&main->program.output, path, flag_operate);
+      kt_remove_print_verbose_operate_file_remove(&main->program.output, target, flag_operate);
+
+      status = kt_remove_operate_memory_save(main, target, flag_operate);
+
+      if (F_status_is_error(status)) {
+        kt_remove_print_error_file(&main->program.error, macro_kt_remove_f(kt_remove_operate_memory_save), path, f_file_operation_process_s, fll_error_file_type_path_e);
+      }
+      else {
+        status = F_yes;
+      }
     }
 
     return status;
index 6043de695862ca793b26b3a97bff4b2b1c42a87b..e9e587e5a41163546354049df8d7aed548e41258 100644 (file)
@@ -53,23 +53,36 @@ extern "C" {
  *
  *   Must not be NULL.
  *
- *   This alters main.setting.state.status:
- *     F_no on success and not removed.
- *     F_data_not on success but path is an empty string.
- *
- *     Success from: kt_remove_operate_directory()
- *     Success from: kt_remove_operate_remove()
- *
- *     Errors (with error bit) from: kt_remove_operate_directory().
- *     Errors (with error bit) from: kt_remove_operate_memory_save().
- *     Errors (with error bit) from: kt_remove_operate_remove().
- *     Errors (with error bit) from: kt_remove_preprocess_file().
+ *   This does not directly alter main.setting.state.status.
  * @param path
  *   The path to the file to operate on.
  *
  *   This should always be TRUE when calling from the top level.
  *   This should always be FALSE if calling from within a fl_directory_do() callback.
  *   This is because fl_directory_do() handles directory traversal and processing.
+ * @param state
+ *   The state information for processing.
+ *   A new state should be created rather than using the main.setting.state to prevent conflicts during recursion.
+ *   The first state outside of recursion can use main.setting.state.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   F_yes on success and removed.
+ *   F_no on success and not removed.
+ *   F_data_not on success but path is an empty string.
+ *
+ *   F_file_found_not (with error bit) on file not found.
+ *   F_interrupt (with error bit) on interrupt.
+ *   F_parameter (with error bit) on invalid parameter.
+ *
+ *   Success from: kt_remove_operate_directory()
+ *   Success from: kt_remove_operate_remove()
+ *
+ *   Errors (with error bit) from: kt_remove_operate_directory().
+ *   Errors (with error bit) from: kt_remove_operate_memory_save().
+ *   Errors (with error bit) from: kt_remove_operate_remove().
+ *   Errors (with error bit) from: kt_remove_preprocess_file().
  *
  * @see kt_remove_operate_directory()
  * @see kt_remove_operate_memory_save()
@@ -77,7 +90,7 @@ extern "C" {
  * @see kt_remove_preprocess_file()
  */
 #ifndef _di_kt_remove_operate_file_
-  extern void kt_remove_operate_file(kt_remove_main_t * const main, const f_string_static_t path);
+  extern f_status_t kt_remove_operate_file(kt_remove_main_t * const main, const f_string_static_t path);
 #endif // _di_kt_remove_operate_file_
 
 /**
@@ -120,17 +133,26 @@ extern "C" {
  *
  *   Must not be NULL.
  *
- *   This alters main.setting.state.status:
- *     F_okay on success or if prompting is not requested.
- *     F_data_not on success but path is an empty string.
- *     F_skip on success and the file is not to be removed (skipped).
+ *   This does not alter main.setting.state.status.
  *
- *     F_skip (with error bit) if skipping should be applied to all paths to be removed from this point forward.
  * @param path
  *   The path to the file to operate on.
+ *
+ * @return
+ *   F_okay on success or if prompting is not requested.
+ *   F_data_not on success but path is an empty string.
+ *   F_skip on success and the file is not to be removed (skipped).
+ *
+ *   F_interrupt (with error bit) on interrupt.
+ *   F_parameter (with error bit) on invalid parameter.
+ *   F_skip (with error bit) if skipping should be applied to all paths to be removed from this point forward.
+ *
+ *   Errors (with error bit) from: f_file_poll().
+ *   Errors (with error bit) from: f_file_read_block().
+ *   Errors (with error bit) from: f_memory_array_increase().
  */
 #ifndef _di_kt_remove_operate_file_prompt_
-  extern void kt_remove_operate_file_prompt(kt_remove_main_t * const main, const f_string_static_t path, const uint flag_operate);
+  extern f_status_t kt_remove_operate_file_prompt(kt_remove_main_t * const main, const f_string_static_t path, const uint flag_operate);
 #endif // _di_kt_remove_operate_file_prompt_
 
 /**
@@ -171,20 +193,27 @@ extern "C" {
  *
  *   Must not be NULL.
  *
- *   This alters main.setting.state.status:
- *     F_okay on success.
- *     F_data_not on success but path is an empty string.
- *
- *     Errors (with error bit) from: f_string_dynamic_append().
+ *   This does not alter main.setting.state.status.
  * @param path
  *   The path to the file to operate on.
  * @param flag_operate
  *   The operate file specific flags from kt_remove_flag_file_operate_*_e.
  *
- * @see f_string_dynamic_append()
+ * @return
+ *   F_okay on success.
+ *   F_data_not on success but path is an empty string.
+ *
+ *   F_interrupt (with error bit) on interrupt.
+ *   F_parameter (with error bit) on invalid parameter.
+ *
+ *   Errors (with error bit) from: f_memory_array_increase().
+ *   Errors (with error bit) from: f_string_dynamic_append_nulless().
+ *
+ * @see f_memory_array_increase()
+ * @see f_string_dynamic_append_nulless()
  */
 #ifndef _di_kt_remove_operate_memory_save_
-  extern void kt_remove_operate_memory_save(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate);
+  extern f_status_t kt_remove_operate_memory_save(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate);
 #endif // _di_kt_remove_operate_memory_save_
 
 /**
index 2b2f236e40fda952250f23bddd920357ac258940..42656425ceed3385047e561ea5c37dbd96fd2cf1 100644 (file)
@@ -15,7 +15,7 @@ extern "C" {
       return 0;
     }
 
-    if (kt_remove_signal_check(main)) return 0;
+    if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return 0;
 
     uint32_t flag_out = (main->setting.flag & kt_remove_main_flag_option_type_used_d) ? 0 : kt_remove_flag_file_operate_remove_d;
 
@@ -64,7 +64,7 @@ extern "C" {
       return 0;
     }
 
-    if (kt_remove_signal_check(main)) return 0;
+    if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return 0;
 
     if (main->setting.flag & kt_remove_main_flag_follow_d) {
       flag_out |= kt_remove_flag_file_operate_follow_d;
@@ -109,7 +109,7 @@ extern "C" {
     if (main->setting.flag & kt_remove_main_flag_user_d) {
       for (i = 0; i < main->setting.users.used; ++i) {
 
-        if (kt_remove_signal_check(main)) return flag_out;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return flag_out;
         if (statistics.st_uid == (uid_t) main->setting.users.array[i]) break;
       } // for
 
@@ -139,7 +139,7 @@ extern "C" {
     if (main->setting.flag & kt_remove_main_flag_group_d) {
       for (i = 0; i < main->setting.groups.used; ++i) {
 
-        if (kt_remove_signal_check(main)) return flag_out;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return flag_out;
         if (statistics.st_gid == (gid_t) main->setting.groups.array[i]) break;
       } // for
 
@@ -171,7 +171,7 @@ extern "C" {
 
       for (i = 0; i < main->setting.modes.used; ++i) {
 
-        if (kt_remove_signal_check(main)) return flag_out;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return flag_out;
 
         if (main->setting.modes.array[i].type == kt_remove_flag_mode_different_d) {
           if (main->setting.modes.array[i].mode ^ mode) break;
@@ -319,16 +319,6 @@ extern "C" {
       }
     }
 
-    // At this point, the remove situation should be known so recurse into parent or child paths as appropriate before returning.
-    if (flag_out & kt_remove_flag_file_operate_directory_d) {
-      main->setting.state.status = F_okay;
-
-      // Recurse only on non-parent directories.
-      if ((main->setting.flag & kt_remove_main_flag_recurse_d) && !(flag_operate & kt_remove_flag_file_operate_parent_d)) {
-        main->setting.state.status = kt_remove_preprocess_file_recurse(main, path, flag_out);
-      }
-    }
-
     if (F_status_is_error_not(main->setting.state.status)) {
       main->setting.state.status = F_okay;
     }
@@ -337,38 +327,6 @@ extern "C" {
   }
 #endif // _di_kt_remove_preprocess_file_
 
-#ifndef _di_kt_remove_preprocess_file_recurse_
-  f_status_t kt_remove_preprocess_file_recurse(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate) {
-
-    if (!kt_remove_operate_shall_remove(flag_operate)) return (flag_operate & kt_remove_flag_file_operate_remove_fail_d) ? F_status_set_error(F_no) : F_no;
-
-    f_directory_recurse_do_t recurse = f_directory_recurse_do_t_initialize;
-
-    // The recurse.state.code flags represent the top-level directory being recursed on.
-    recurse.state.code = flag_operate;
-    recurse.state.custom = (void *) main;
-    recurse.state.interrupt = &kt_remove_signal_check_recurse;
-
-    // The pre-process does not need the fl_directory_do() to operate on the top-level because it is already doing this and so the top_after recurse.flag must not be set.
-    recurse.depth_max = main->setting.flag & kt_remove_main_flag_recurse_d ? kt_remove_depth_max_d : 0;
-    recurse.flag = 0;
-    recurse.path_top = &path;
-
-    recurse.action = &kt_remove_preprocess_recurse_action;
-    recurse.handle = &kt_remove_operate_recurse_handle;
-
-    fl_directory_do(path, &recurse);
-
-    const f_status_t status = f_directory_recurse_do_delete(&recurse);
-
-    return F_status_is_error(recurse.state.status)
-      ? recurse.state.status
-      : F_status_is_error(status)
-        ? status
-        : F_yes;
-  }
-#endif // _di_kt_remove_preprocess_file_recurse_
-
 #ifndef _di_kt_remove_preprocess_file_dates_
   void kt_remove_preprocess_file_dates(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate, const struct stat statistics) {
 
@@ -419,7 +377,7 @@ extern "C" {
 
       for (j = 0; j < dates[i]->used; ++j) {
 
-        if (kt_remove_signal_check(main)) return;
+        if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) return;
 
         match_nanosecond = times[i].tv_nsec;
         match_second = times[i].tv_sec % kt_remove_time_seconds_in_year_d;
@@ -649,23 +607,6 @@ extern "C" {
   }
 #endif // _di_kt_remove_preprocess_file_type_
 
-#ifndef _di_kt_remove_preprocess_recurse_action_
-  void kt_remove_preprocess_recurse_action(f_directory_recurse_do_t * const recurse, const f_string_static_t name, const uint32_t flag) {
-
-    if (!recurse || !recurse->state.custom || F_status_set_fine(recurse->state.status) == F_interrupt) return;
-
-    if (flag & f_directory_recurse_do_flag_action_e) {
-      kt_remove_preprocess_file(
-        (kt_remove_main_t *) recurse->state.custom,
-        recurse->path,
-        flag & f_directory_recurse_do_flag_directory_e
-          ? (recurse->state.code | kt_remove_flag_file_operate_child_d | kt_remove_flag_file_operate_directory_d) & ~kt_remove_flag_file_operate_parent_d
-          : (recurse->state.code | kt_remove_flag_file_operate_child_d) & ~kt_remove_flag_file_operate_directory_parent_d
-      );
-    }
-  }
-#endif // _di_kt_remove_preprocess_recurse_action_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 4f48405b0027492659c6c7a796de5d1a88029223..3720c6b2ebe97cc6a485fdeb2c053d48ca209a68 100644 (file)
@@ -48,38 +48,6 @@ extern "C" {
 #endif // _di_kt_remove_preprocess_file_
 
 /**
- * Perform actual file removal for directory files.
- *
- * @param main
- *   The main program and settings data.
- *
- *   Must not be NULL.
- *
- *   This does not directly alter main.setting.state.status.
- * @param path
- *   The path to the file to operate on.
- * @param flag_operate
- *   The operate file specific flags from kt_remove_flag_file_operate_*_e.
- *
- * @return
- *   F_yes on success and file remove.
- *   F_no on success and file not removed.
- *   F_data_not on success but path is an empty string.
- *
- *   F_no (with error bit) on failure and file is not to be removed or cannot be removed.
- *   F_recurse (with error bit) on max recursion depth reached.
- *
- *   Errors (with error bit) from: f_directory_recurse_do_delete()
- *   Errors (with error bit) from: fl_directory_do()
- *
- * @see f_directory_recurse_do_delete()
- * @see fl_directory_do()
- */
-#ifndef _di_kt_remove_preprocess_file_recurse_
-  extern f_status_t kt_remove_preprocess_file_recurse(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate);
-#endif // _di_kt_remove_preprocess_file_recurse_
-
-/**
  * Perform pre-processing (including simulation) of the file operation, specifically handling dates.
  *
  * @param main
@@ -134,27 +102,6 @@ extern "C" {
   extern void kt_remove_preprocess_file_type(kt_remove_main_t * const main, const f_string_static_t path, const bool is, f_string_static_t name, const uint64_t type, const uint8_t code, uint32_t * const flag_out);
 #endif // _di_kt_remove_preprocess_file_type_
 
-/**
- * Perform directory recursion for a single file operation action.
- *
- * @param recurse
- *   The directory recurse data.
- *
- *   Must not be NULL.
- * @param name
- *   The name of the file or directory the action is being performed on.
- *   Does not have the parent directory path.
- *   May be empty at the top level.
- * @param flag
- *   A flag representing the particular directory action being performed.
- *
- * @see f_directory_remove()
- * @see fl_directory_do()
- */
-#ifndef _di_kt_remove_preprocess_recurse_action_
-  extern void kt_remove_preprocess_recurse_action(f_directory_recurse_do_t * const recurse, const f_string_static_t name, const uint32_t flag);
-#endif // _di_kt_remove_preprocess_recurse_action_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 523bca8fd8f59c14822a7825f63212a51f27fb89..5b1750e8f749d528f0e9e4408d2ae90962379209 100644 (file)
@@ -33,7 +33,7 @@ extern "C" {
 
     kt_remove_normal_operate(main);
 
-    if (kt_remove_signal_check(main)) {
+    if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) {
       fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
     }
   }
@@ -65,7 +65,7 @@ extern "C" {
 
     for (; i < main->setting.files.used; ++i) {
 
-      kt_remove_operate_file(main, main->setting.files.array[i]);
+      main->setting.state.status = kt_remove_operate_file(main, main->setting.files.array[i]);
 
       if ((main->setting.flag & kt_remove_main_flag_simulate_d) && i + 1 < main->setting.files.used && (F_status_is_error_not(main->setting.state.status) || F_status_set_fine(main->setting.state.status) == F_interrupt)) {
         f_print_dynamic(f_string_eol_s, main->program.output.to);
index 805d7c4c4ee080819233d1cd762b0fb1aeeff7d5..2d5a3a70d6be324f7f0fd0427d87394bb2622e9b 100644 (file)
@@ -4,41 +4,6 @@
 extern "C" {
 #endif
 
-#if !defined(_di_kt_remove_signal_check_) && defined(_di_thread_support_)
-  f_status_t kt_remove_signal_check(kt_remove_main_t * const main) {
-
-    if (!main) return F_false;
-    if (main->program.signal_received) return F_true;
-
-    if (!((++main->program.signal_check) % kt_remove_signal_check_d)) {
-      if (F_status_set_fine(fll_program_standard_signal_received(&main->program)) == F_interrupt) {
-        main->setting.state.status = F_status_set_error(F_interrupt);
-
-        return F_true;
-      }
-
-      main->program.signal_check = 0;
-    }
-
-    return F_false;
-  }
-#endif // !defined(_di_kt_remove_signal_check_) && defined(_di_thread_support_)
-
-#if !defined(_di_kt_remove_signal_check_) && !defined(_di_thread_support_)
-  f_status_t kt_remove_signal_check(kt_remove_main_t * const main) {
-
-    if (!main) return F_false;
-
-    if (main->program.signal_received) {
-      main->setting.state.status = F_status_set_error(F_interrupt);
-
-      return F_true;
-    }
-
-    return F_false;
-  }
-#endif // !defined(_di_kt_remove_signal_check_) && !defined(_di_thread_support_)
-
 #ifndef _di_kt_remove_signal_check_recurse_
   void kt_remove_signal_check_recurse(f_state_t * const state, void * const internal) {
 
@@ -48,7 +13,9 @@ extern "C" {
 
     if (!recurse->state.custom) return;
 
-    if (kt_remove_signal_check((kt_remove_main_t *) recurse->state.custom)) {
+    kt_remove_main_t * const main = (kt_remove_main_t *) recurse->state.custom;
+
+    if (macro_kt_remove_signal_check(&main->program, &main->setting.state)) {
       recurse->state.status = F_status_set_error(F_interrupt);
     }
   }
index 3b5edf5bb80ae5f5e638d1e11a7db5c4f3794e73..e7ad5fc4927b092cccf7ed8d48c785bf06e40f3a 100644 (file)
@@ -13,40 +13,6 @@ extern "C" {
 #endif
 
 /**
- * Check to see if a signal is received.
- *
- * If main.signal is non-zero, then this handles the following signals:
- *   - F_signal_abort
- *   - F_signal_broken_pipe
- *   - F_signal_hangup
- *   - F_signal_interrupt
- *   - F_signal_quit
- *   - F_signal_termination
- *
- * There is a threaded and a non-threaded version of this.
- * The non-threaded version checks periodically using kt_remove_signal_check_d and updates main->signal_check as needed.
- * The threaded version checks the flag state which is set by a separate thread that is blocking until signal is received.
- *
- * @param main
- *   The main program and settings data.
- *
- *   Must not be NULL.
- *
- *   This does not alter main.setting.state.status.
- *
- * @return
- *   F_true on signal received.
- *   F_false otherwise.
- *
- * @see kt_remove_signal_handler()
- *
- * @see fll_program_standard_signal_received()
- */
-#ifndef _di_kt_remove_signal_check_
-  extern f_status_t kt_remove_signal_check(kt_remove_main_t * const main);
-#endif // _di_kt_remove_signal_check_
-
-/**
  * Check to see if a signal is received, for a recursive directory function.
  *
  * This is intended to be passed as a state.interrupt function for use in the fl_directory_do() recursion process.
@@ -66,8 +32,6 @@ extern "C" {
  *
  *   This alters recurse.state.status:
  *     F_interrupt (with error bit) on interrupt signal received.
- *
- * @see kt_remove_signal_check()
  */
 #ifndef _di_kt_remove_signal_check_recurse_
   extern void kt_remove_signal_check_recurse(f_state_t * const state, void * const internal);
index 1b927e4fd19c6bd02c59d81ed554fe9235ec03b8..751f2c1790ee0fdd29483213684baf88396b62ec 100644 (file)
@@ -74,7 +74,7 @@ int
           kt_remove_setting_load(arguments, &data);
         }
 
-        if (!kt_remove_signal_check(&data)) {
+        if (!macro_kt_remove_signal_check(&data.program, &data.setting.state)) {
           kt_remove_main(&data);
         }
 
index 60a1c66844b3f8a6a641504b3f48b2febbd0d41c..cd15282f93c5db588858a79c24a77dbc71d27df8 100644 (file)
@@ -68,7 +68,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
           kt_remove_rm_setting_load(arguments, &data);
         }
 
-        if (!kt_remove_signal_check(&data)) {
+        if (!macro_kt_remove_signal_check(&data.program, &data.setting.state)) {
           kt_remove_main(&data);
         }
 
index f7022bd316fcde2136768f5c5fadf31c70d44e76..4d824af5a96e5a057bb8964d0ea7720c0859cdc3 100644 (file)
@@ -68,7 +68,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
           kt_remove_rmdir_setting_load(arguments, &data);
         }
 
-        if (!kt_remove_signal_check(&data)) {
+        if (!macro_kt_remove_signal_check(&data.program, &data.setting.state)) {
           kt_remove_main(&data);
         }
 
index 81e9bd229183023ad11204e09439f29c2bace82d..e6fc1de882bc055fcf8c2affb95a0ed368346b7c 100644 (file)
@@ -68,7 +68,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
           kt_remove_unlink_setting_load(arguments, &data);
         }
 
-        if (!kt_remove_signal_check(&data)) {
+        if (!macro_kt_remove_signal_check(&data.program, &data.setting.state)) {
           kt_remove_main(&data);
         }
 
index ad36ce54b8ba2dc0864a0517dabc50338bb79096..a41d352d51b676a565cf55512c53ee955ca4dae3 100644 (file)
@@ -67,7 +67,7 @@ int main_test__remove(const int argc, const f_string_t *argv, const f_string_t *
           kt_remove_setting_load(arguments, &data);
         }
 
-        if (!kt_remove_signal_check(&data)) {
+        if (!macro_kt_remove_signal_check(&data.program, &data.setting.state)) {
           kt_remove_main(&data);
         }
 
@@ -81,7 +81,11 @@ int main_test__remove(const int argc, const f_string_t *argv, const f_string_t *
 
   fll_program_standard_set_down(&data.program);
 
-  return (F_status_is_error(data.setting.state.status) || data.setting.state.status == F_false) ? 1 : 0;
+  if (F_status_is_error(data.setting.state.status)) {
+    return F_status_set_fine(data.setting.state.status) == F_support_not ? 2 : 1;
+  }
+
+  return data.setting.state.status == F_false ? 1 : 0;
 }
 
 #ifdef __cplusplus