]> Kevux Git Server - fll/commitdiff
Update: Improve terminal support in execute functions.
authorKevin Day <thekevinday@gmail.com>
Sat, 23 Oct 2021 16:10:30 +0000 (11:10 -0500)
committerKevin Day <thekevinday@gmail.com>
Sat, 23 Oct 2021 16:44:38 +0000 (11:44 -0500)
The init program calling bash results in "not a tty" error:
- "bash: cannot set terminal process group (-1): Not a tty"
- "bash: no job control in this shell"

This exposed me to the Process Group.
I have learned that I may need to set the Controlling Terminal in this case.

To that end, I have introduced FL_execute_parameter_option_session_d for setting this up.
I have also added an initial setup for FL_execute_parameter_option_terminal_d, but more investigation and research needs to be done.

I've added some basic execute terminal codes that I may or may not need.
I would rather have them now and remove them now rather than not have them and have to add them later.

The controller program needs to utilize this, at least when running as "init".
However, I believe that I should pass control over this to the user as new settings, such as "session new" and "session same".

Provide example to utilize "setsid" program for doing this same thing when directly calling bash.

12 files changed:
level_0/f_execute/c/execute-common.h
level_0/f_execute/c/execute.c
level_0/f_execute/c/execute.h
level_1/fl_execute/c/execute-common.h
level_2/fll_execute/c/execute.c
level_2/fll_execute/c/execute.h
level_2/fll_execute/c/private-execute.c
level_3/controller/c/private-controller.c
level_3/controller/c/private-rule.c
level_3/controller/data/settings/entries/default.entry
level_3/controller/data/settings/entries/maintenance.entry
level_3/controller/data/settings/rules/maintenance/console.rule

index 8f42c4f905a946241cf2e41c698925363da18027..a2f774fcc8320e1cc1db8d023ebbdc40a50a4137 100644 (file)
@@ -59,6 +59,11 @@ extern "C" {
     F_execute_prohibited,
     F_execute_resource_not,
     F_execute_schedule,
+    F_execute_terminal,
+    F_execute_terminal_known_not,
+    F_execute_terminal_not,
+    F_execute_terminal_prohibited,
+    F_execute_terminal_valid_not,
     F_execute_too_large,
     F_execute_user,
     F_execute_valid_not,
index 1b03ad3a2e0a89f818f7515f9dcaffd5dfa565dd..15f5fc1833d0920cb90fa979572a31953d4c615a 100644 (file)
@@ -115,6 +115,26 @@ extern "C" {
       return F_execute_schedule;
     }
 
+    if (F_status_set_fine(status) == F_terminal) {
+      return F_execute_terminal;
+    }
+
+    if (F_status_set_fine(status) == F_terminal_known_not) {
+      return F_execute_terminal_known_not;
+    }
+
+    if (F_status_set_fine(status) == F_terminal_not) {
+      return F_execute_terminal_not;
+    }
+
+    if (F_status_set_fine(status) == F_terminal_prohibited) {
+      return F_execute_terminal_prohibited;
+    }
+
+    if (F_status_set_fine(status) == F_terminal_valid_not) {
+      return F_execute_terminal_valid_not;
+    }
+
     if (F_status_set_fine(status) == F_too_large) {
       return F_execute_too_large;
     }
@@ -242,6 +262,26 @@ extern "C" {
       return F_schedule;
     }
 
+    if (status == F_execute_terminal) {
+      return F_terminal;
+    }
+
+    if (status == F_execute_terminal_known_not) {
+      return F_terminal_known_not;
+    }
+
+    if (status == F_execute_terminal_not) {
+      return F_terminal_not;
+    }
+
+    if (status == F_execute_terminal_prohibited) {
+      return F_terminal_prohibited;
+    }
+
+    if (status == F_execute_terminal_valid_not) {
+      return F_terminal_valid_not;
+    }
+
     if (status == F_execute_too_large) {
       return F_too_large;
     }
index 0b721463a916436e7ccc362a294be6ccca19cd4d..cc6369beb8e4caf6661de2dc7876a9522a2dad2c 100644 (file)
@@ -15,6 +15,9 @@
 
 // libc includes
 #include <sched.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 // fll-0 includes
 #include <fll/level_0/type.h>
index 5bbf7e902d1e4b5c1e5b3e2db49d14ca42f6dd1a..7aa497551f0464bfc71882b31ff0faebb24f9559 100644 (file)
@@ -20,12 +20,12 @@ extern "C" {
  * A structure for containing additional parameters for the execute functions that call the execv() family of functions.
  *
  * FL_execute_parameter_option_*:
- * - exit:       used to desginate to exit after calling child otherwise child process will return.
- * - path:       used to designate that the full path to the program is to be passed in argument[0] instead of the program name (such as '/bin/bash' instead of 'bash').
- * - threadsafe: used to designate that threadsafe functions are to be used (such as: f_thread_signal_mask instead of f_signal_mask).
- * - return:     used to designate that the parent process will immediately return instead of waiting for the child process to complete.
- *
- * If thread support is disabled in the library, then FL_execute_parameter_option_threadsafe_d will fallback to non-threadsafe.
+ * - exit:       Used to desginate to exit after calling child otherwise child process will return.
+ * - path:       Used to designate that the full path to the program is to be passed in argument[0] instead of the program name (such as '/bin/bash' instead of 'bash').
+ * - return:     Used to designate that the parent process will immediately return instead of waiting for the child process to complete.
+ * - session:    Start a new session, set the process of the child as the controlling terminal.
+ * - terminal:   (Not Implemented) open() a terminal (tty) before executing. @todo determine if and how to setup the terminal properly (this needs research and planning and may require further structural changes).
+ * - threadsafe: Used to designate that threadsafe functions are to be used (such as: f_thread_signal_mask instead of f_signal_mask).
  *
  * option:      Accepts the bitwise options
  * wait:        Represents options passed to waitpid(), such as WUNTRACED.
@@ -34,10 +34,12 @@ extern "C" {
  * data:        The data to pipe to the child process, set to 0 to not use.
  */
 #ifndef _di_fl_execute_parameter_t_
-  #define FL_execute_parameter_option_exit_d       0x1
-  #define FL_execute_parameter_option_path_d       0x2
-  #define FL_execute_parameter_option_threadsafe_d 0x4
-  #define FL_execute_parameter_option_return_d     0x8
+  #define FL_execute_parameter_option_exit_d        0x1
+  #define FL_execute_parameter_option_path_d        0x2
+  #define FL_execute_parameter_option_return_d      0x4
+  #define FL_execute_parameter_option_session_d     0x8
+  #define FL_execute_parameter_option_terminal_d    0x10
+  #define FL_execute_parameter_option_threadsafe_d  0x20
 
   typedef struct {
     uint8_t option;
index 3c10731c67a6b62a09cf7adda7dbab67496e95b0..1798fca9d3a2211dd4e4effba9c6a6695c4bd74f 100644 (file)
@@ -148,6 +148,10 @@ extern "C" {
 
     int code = 0;
 
+    if (option & FL_execute_parameter_option_session_d) {
+      setsid();
+    }
+
     // full path is explicitly requested.
     if (option & FL_execute_parameter_option_path_d) {
       f_string_dynamic_t path = f_string_dynamic_t_initialize;
index 041996041063dc6f9bc4d04a5214d4bd9bf47c9c..f82ce2250d4399d46ebb3661260335b2949a91a5 100644 (file)
@@ -363,6 +363,7 @@ extern "C" {
  *   A bitwise set of options, such as: FL_execute_parameter_option_exit_d and FL_execute_parameter_option_path_d.
  *   If FL_execute_parameter_option_exit_d: this will call exit() at the end of execution (be it success or failure).
  *   If FL_execute_parameter_option_path_d: use the whole program path (such as "/bin/bash" instead "bash" when populating argument[0].
+ *   If FL_execute_parameter_option_session_d: will start a new session, setting process group id.
  * @param environment
  *   (optional) An map of strings representing the environment variable names and their respective values.
  *   Completely clears the environment and then creates environment variables for each name and value pair in this map.
@@ -479,6 +480,7 @@ extern "C" {
  * @see memcpy()
  * @see nice()
  * @see pipe()
+ * @see setsid()
  * @see sched_setaffinity()
  * @see sched_setscheduler()
  * @see setgid()
index 3cb1f1d6e4681e317428b2ec827be43103e099c9..957c2e4c06303011ddb5c2b827ec445b83773f32 100644 (file)
@@ -272,7 +272,6 @@ extern "C" {
     }
 
     if (id_process) {
-
       if (as) {
 
         // close the read pipe for the parent.
@@ -329,6 +328,10 @@ extern "C" {
       return F_none;
     }
 
+    if (parameter && parameter->option & FL_execute_parameter_option_session_d) {
+      setsid();
+    }
+
     if (as) {
 
       // close the write pipe for the child.
@@ -520,6 +523,10 @@ extern "C" {
       return F_none;
     }
 
+    if (parameter && parameter->option & FL_execute_parameter_option_session_d) {
+      setsid();
+    }
+
     // close the write pipe for the child.
     close(descriptors[1]);
 
index d75368d25975ea373593050219c56724482f0a70..7ae82baa47300cf63b8cf79ffa40efa57f528e49 100644 (file)
@@ -1194,8 +1194,13 @@ extern "C" {
           controller_thread_process_cancel(is_entry, is_entry ? controller_thread_cancel_execute : controller_thread_cancel_exit_execute, global, process);
 
           int result = 0;
+          int option = FL_execute_parameter_option_path_d;
 
-          status = fll_execute_into(0, entry_action->parameters, FL_execute_parameter_option_path_d, 0, (void *) &result);
+          if (global->main->as_init) {
+            option |= FL_execute_parameter_option_session_d; // @todo need "session new" and "session same".
+          }
+
+          status = fll_execute_into(0, entry_action->parameters, option, 0, (void *) &result);
 
           if (F_status_is_error(status)) {
             if (F_status_set_fine(status) == F_file_found_not) {
index 795a4539d187a177daeb7b7f884781aa39446df3..bfc81b138f8fa1dd25f7b47c2a747dffe48d4b7d 100644 (file)
@@ -1198,6 +1198,21 @@ extern "C" {
         else if (code == F_execute_schedule) {
           fl_print_format("%[' failed to setup scheduler.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]);
         }
+        else if (code == F_execute_terminal) {
+          fl_print_format("%[' failed while processing the terminal.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]);
+        }
+        else if (code == F_execute_terminal_known_not) {
+          fl_print_format("%[' cannot process terminal, unknown terminal control command.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]);
+        }
+        else if (code == F_execute_terminal_not) {
+          fl_print_format("%[' cannot process terminal, not a known terminal.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]);
+        }
+        else if (code == F_execute_terminal_prohibited) {
+          fl_print_format("%[' insufficient permissions to process the terminal.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]);
+        }
+        else if (code == F_execute_terminal_valid_not) {
+          fl_print_format("%[' invalid parameter while processing the terminal.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]);
+        }
         else if (code == F_execute_too_large) {
           fl_print_format("%[' too many arguments or arguments are too large.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]);
         }
@@ -1352,6 +1367,10 @@ extern "C" {
           execute_set.parameter.option |= FL_execute_parameter_option_path_d;
         }
 
+        if (global.main->as_init) {
+          execute_set.parameter.option |= FL_execute_parameter_option_session_d; // @todo need "session new" and "session same".
+        }
+
         if (process->rule.items.array[i].type == controller_rule_item_type_command) {
           for (;;) {
 
index 34da6747e3f1136c61a939e530d3e19440039f8d..d2dd9ea0768b788f1ba7e7572a72f816a7a8fe32 100644 (file)
@@ -51,5 +51,6 @@ console:
 
 
 maintenance:
-  #execute /bin/agetty -8 -i -J - linux
+  #execute /bin/agetty -8 -i -J tty1 linux
+  #execute /bin/setsid -c /bin/bash --login
   execute /bin/bash --login
index ab0c4898efae6bec96cd51a2e49f2d002a5b6203..15a948b987e5e2755fb39a2aceacae6fb71ed26d 100644 (file)
@@ -8,5 +8,6 @@ setting:
   show init
 
 main:
-  #execute /bin/agetty -8 -i -J - linux
+  #execute /bin/agetty -8 -i -J tty1 linux
+  #execute /bin/setsid -c /bin/bash --login
   execute /bin/bash --login
index 52e7b823ae86a988842daa75139387cb6356dc1d..d23082105ec09f105d53977b1459108e4313407b 100644 (file)
@@ -7,4 +7,5 @@ setting:
   name "Maintenance Console"
 
 command:
+  #start setsid -c bash --login
   start bash --login