]> Kevux Git Server - fll/commitdiff
Update: generalize the pid file creation and deletion.
authorKevin Day <thekevinday@gmail.com>
Sat, 17 Apr 2021 20:27:05 +0000 (15:27 -0500)
committerKevin Day <thekevinday@gmail.com>
Sat, 17 Apr 2021 21:05:38 +0000 (16:05 -0500)
The PID create and delete functions were written as intended specifically for the main controller program.

PID files are to be used by services and utilities, therefore the PID create and delete functions should also be used there.

Detect if the main PID file is created and then only attempt to delete it on exit (and then do not do so for child processes).

level_3/controller/c/controller.c
level_3/controller/c/private-common.c
level_3/controller/c/private-common.h
level_3/controller/c/private-controller.c
level_3/controller/c/private-controller.h

index bfd3829ec52ababd274cb2077dfbfd1c162f8892..3d25bd02876d25f732e86fb32daacfda282545b3 100644 (file)
@@ -368,7 +368,19 @@ extern "C" {
 
     f_signal_close(&data->signal);
 
-    controller_file_pid_delete(*data, setting.path_pid);
+    if (status != F_child && setting.pid_created) {
+      f_status_t status_delete = controller_file_pid_delete(data->pid, setting.path_pid);
+
+      if (F_status_is_error(status_delete) && data->warning.verbosity == f_console_verbosity_debug) {
+        if (F_status_set_fine(status_delete) == F_number_not) {
+          controller_error_pid_bad_match_print(data->warning, setting.path_pid.string, 0);
+        }
+        else {
+          fll_error_file_print(data->warning, F_status_set_fine(status_delete), "controller_file_pid_delete", F_true, setting.path_pid.string, "delete", fll_error_file_type_file);
+        }
+      }
+    }
+
     controller_setting_delete_simple(&setting);
     controller_delete_data(data);
 
index 12c7ccecc295d301731483f9c226f5176a4121ba..a23e5bb8a29ce9787c8a1ad936bf315aba844587 100644 (file)
@@ -96,6 +96,20 @@ extern "C" {
   }
 #endif // _di_controller_error_file_print_
 
+#ifndef _di_controller_error_pid_bad_match_print_
+  void controller_error_pid_bad_match_print(const fll_error_print_t print, const f_string_t path, controller_thread_t *thread) {
+
+    if (thread) f_thread_mutex_lock(&thread->lock.print);
+
+    fprintf(print.to.stream, "%c", f_string_eol_s[0]);
+    fprintf(print.to.stream, "%s%sThe pid file '", print.context.before->string, print.prefix ? print.prefix : f_string_empty_s);
+    fprintf(print.to.stream, "%s%s%s%s", print.context.after->string, print.notable.before->string, path, print.notable.after->string);
+    fprintf(print.to.stream, "%s' doesn't contain the expected number, not deleting file.%s%c", print.context.before->string, print.context.after->string, f_string_eol_s[0]);
+
+    if (thread) controller_print_unlock_flush(print.to.stream, &thread->lock.print);
+  }
+#endif // _di_controller_error_pid_bad_match_print_
+
 #ifndef _di_controller_error_print_
   void controller_error_print(const fll_error_print_t print, const f_status_t status, const f_string_t function, const bool fallback, controller_thread_t *thread) {
 
index 02a860e577b93540303b993ada21f826708d2922..7cb9b312ed040461ae14191bfee53845a9c427e6 100644 (file)
@@ -1024,6 +1024,7 @@ extern "C" {
 
   typedef struct {
     bool interruptable;
+    bool pid_created;
     uint8_t ready;
 
     f_number_unsigned_t timeout_kill;
@@ -1043,6 +1044,7 @@ extern "C" {
 
   #define controller_setting_t_initialize { \
     F_false, \
+    F_false, \
     0, \
     3, \
     3, \
@@ -1284,6 +1286,24 @@ extern "C" {
   extern void controller_error_file_print(const fll_error_print_t print, const f_status_t status, const f_string_t function, const bool fallback, const f_string_t name, const f_string_t operation, const uint8_t type, controller_thread_t *thread) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_error_file_print_
 
+/**
+ * Print the error, locking the print mutex during the print.
+ *
+ * This does not check verbosity.
+ *
+ * @param print
+ *   Designates how printing is to be performed.
+ * @param path
+ *   The path to the PID file.
+ * @param thread
+ *   (optional) The thread data.
+ *   Set to NULL to not use (locking will not be performed).
+ *
+ * @see fll_error_print()
+ */
+#ifndef _di_controller_error_pid_bad_match_print_
+  extern void controller_error_pid_bad_match_print(const fll_error_print_t print, const f_string_t path, controller_thread_t *thread) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_error_pid_bad_match_print_
 
 /**
  * Print the error, locking the print mutex during the print.
index 048ec0210a4673ca92c008205fafc0e8201e29b6..8776cf6836f9a6e5fc5502e1d145872b7a36b502 100644 (file)
@@ -152,18 +152,18 @@ extern "C" {
 #endif // _di_controller_file_load_
 
 #ifndef _di_controller_file_pid_create_
-  f_status_t controller_file_pid_create(const controller_data_t data, const f_string_static_t path_pid) {
+  f_status_t controller_file_pid_create(const pid_t pid, const f_string_static_t path) {
     f_status_t status = F_none;
 
     // the file exists, do not attempt to overwrite.
-    if (f_file_exists(path_pid.string) == F_true) {
+    if (f_file_exists(path.string) == F_true) {
       return F_status_set_error(F_file_found);
     }
 
     {
       f_string_dynamic_t path_directory = f_string_dynamic_t_initialize;
 
-      status = f_file_name_directory(path_pid.string, path_pid.used, &path_directory);
+      status = f_file_name_directory(path.string, path.used, &path_directory);
 
       if (F_status_is_error_not(status)) {
         status = f_directory_exists(path_directory.string);
@@ -183,10 +183,10 @@ extern "C" {
 
     file.flag = f_file_flag_write_only;
 
-    status = f_file_stream_open(path_pid.string, f_file_open_mode_truncate_s, &file);
+    status = f_file_stream_open(path.string, f_file_open_mode_truncate_s, &file);
     if (F_status_is_error(status)) return status;
 
-    fprintf(file.stream, "%llu%c", data.pid, f_string_eol_s[0]);
+    fprintf(file.stream, "%llu%c", pid, f_string_eol_s[0]);
 
     f_file_stream_close(F_true, &file);
 
@@ -197,24 +197,26 @@ extern "C" {
 #endif // _di_controller_file_pid_create_
 
 #ifndef _di_controller_file_pid_delete_
-  void controller_file_pid_delete(const controller_data_t data, const f_string_static_t path_pid) {
+  f_status_t controller_file_pid_delete(const pid_t pid, const f_string_static_t path) {
 
     // only delete if the file exists and there is no error while checking.
-    if (f_file_exists(path_pid.string) != F_true) {
-      return;
+    if (f_file_exists(path.string) != F_true) {
+      return F_none;
     }
 
     f_status_t status = F_none;
     f_file_t pid_file = f_file_t_initialize;
 
-    status = f_file_stream_open(path_pid.string, f_file_open_mode_read_s, &pid_file);
-    if (F_status_is_error(status)) return;
+    status = f_file_stream_open(path.string, f_file_open_mode_read_s, &pid_file);
+    if (F_status_is_error(status)) return status;
 
     f_string_dynamic_t pid_buffer = f_string_dynamic_t_initialize;
 
     status = f_file_stream_read(pid_file, 1, &pid_buffer);
 
-    f_file_stream_close(F_true, &pid_file);
+    if (F_status_is_error_not(status)) {
+      status = f_file_stream_close(F_true, &pid_file);
+    }
 
     if (F_status_is_error_not(status)) {
       f_number_unsigned_t number = 0;
@@ -230,16 +232,17 @@ extern "C" {
 
       status = fl_conversion_string_to_decimal_unsigned(pid_buffer.string, range, &number);
 
-      if (F_status_is_error_not(status) && number == data.pid) {
-        status = f_file_remove(path_pid.string);
-
-        if (F_status_is_error(status) && data.warning.verbosity == f_console_verbosity_debug) {
-          fll_error_file_print(data.warning, F_status_set_fine(status), "f_file_remove", F_true, path_pid.string, "delete", fll_error_file_type_file);
-        }
+      if (F_status_is_error_not(status) && number == pid) {
+        status = f_file_remove(path.string);
+      }
+      else {
+        status = F_status_set_error(F_number_not);
       }
     }
 
     f_macro_string_dynamic_t_delete_simple(pid_buffer);
+
+    return status;
   }
 #endif // _di_controller_file_pid_delete_
 
@@ -350,7 +353,7 @@ extern "C" {
     // only create pid file when not in validate mode.
     if (main.data->parameters[controller_parameter_validate].result == f_console_result_none) {
 
-      status = controller_file_pid_create(*main.data, main.setting->path_pid);
+      status = controller_file_pid_create(main.data->pid, main.setting->path_pid);
 
       // report pid file error but because this could be an "init" program, consider the pid file as optional and continue on.
       if (F_status_is_error(status)) {
@@ -382,6 +385,9 @@ extern "C" {
 
         status = F_none;
       }
+      else {
+        main.setting->pid_created = F_true;
+      }
     }
 
     return status;
index 0788661bdff582c8548593f3c5f890100286b111..5d1edfc6e032353b9d39fdd49e4ab482a78006fa 100644 (file)
@@ -120,9 +120,9 @@ extern "C" {
 /**
  * Create the pid file, if possible.
  *
- * @param data
- *   The program data.
- * @param path_pid
+ * @param pid
+ *   The PID (process id).
+ * @param path
  *   The file path to the pid file to create.
  *
  * @return
@@ -139,7 +139,7 @@ extern "C" {
  * @see f_file_stream_open()
  */
 #ifndef _di_controller_file_pid_create_
-  f_status_t controller_file_pid_create(const controller_data_t data, const f_string_static_t path_pid) f_gcc_attribute_visibility_internal;
+  f_status_t controller_file_pid_create(const pid_t pid, const f_string_static_t path) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_file_pid_create_
 
 /**
@@ -147,13 +147,22 @@ extern "C" {
  *
  * This is meant to be called on exit and avoids checking status codes, returning void.
  *
- * @param data
- *   The program data.
- * @param path_pid
+ * @param pid
+ *   The PID (process id).
+ * @param path
  *   The file path to the pid file to create.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_number_not (with error bit) if the number from the pid file doesn't match the expected pid.
+ *
+ *   Errors (with error bit) from: f_file_stream_close().
+ *   Errors (with error bit) from: f_file_stream_open().
+ *   Errors (with error bit) from: f_file_stream_read().
  */
 #ifndef _di_controller_file_pid_delete_
-  void controller_file_pid_delete(const controller_data_t data, const f_string_static_t path_pid) f_gcc_attribute_visibility_internal;
+  f_status_t controller_file_pid_delete(const pid_t pid, const f_string_static_t path) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_file_pid_delete_
 
 /**