Browse Source

Merge pull request #35 from asherikov/as_multiple_service_dirs

Allow multiple --services-dir options
Davin McCall 2 years ago
parent
commit
9e6d82a56e

+ 5 - 5
doc/manpages/dinit.8.m4

@@ -38,9 +38,9 @@ DESCRIPTION FILES\fR for details of the service description format.
 .SH OPTIONS
 .TP
 \fB\-d\fR \fIdir\fP, \fB\-\-services\-dir\fR \fIdir\fP
-Specifies \fIdir\fP as the directory containing service definition files.
-The directory specified will be the only directory searched for service
-definitions.
+Specifies \fIdir\fP as the directory containing service definition files, can
+be set multiple times. Default directories are not searched for services when
+this option is provided.
 
 If not specified, the default is \fI$HOME/dinit.d\fR or, for the
 system service manager, each of \fI/etc/dinit.d/fR, \fI/usr/local/lib/dinit.d\fR,
@@ -104,7 +104,7 @@ service names provided on the command line, other than "single", unless they app
 after a "-o" or "-m" options (or their long forms). This is to filter arguments
 that were intended for the kernel and not for \fBinit\fR. If running in a container,
 the "-o" option should be used regardless and will inhibit this filtering for any
-subsequent service names. 
+subsequent service names.
 .\"
 .SH SERVICE DESCRIPTION FILES
 .\"
@@ -144,7 +144,7 @@ changes. See \fBdinitctl\fR(8) for details.
 
 Process-based services are monitored and, if the process terminates, the
 service may be stopped or the process may be re-started, according to the
-configuration in the service description.  
+configuration in the service description.
 
 Once all services stop, the \fBdinit\fR daemon will itself terminate (or, if
 running as PID 1, will perform the appropriate type of system shutdown).

+ 3 - 3
doc/manpages/dinitcheck.8.m4

@@ -31,9 +31,9 @@ same search paths (for service description files) as \fBdinit\fR.
 .SH OPTIONSs
 .TP
 \fB\-d\fR \fIdir\fP, \fB\-\-services\-dir\fR \fIdir\fP
-Specifies \fIdir\fP as the directory containing service definition files.
-The directory specified will be the only directory searched for service
-definitions.
+Specifies \fIdir\fP as the directory containing service definition files, can
+be set multiple times. Default directories are not searched for services when
+this option is provided.
 
 If not specified, the default is \fI$HOME/dinit.d\fR or, for the
 system service manager, each of \fI/etc/dinit.d/fR, \fI/usr/local/lib/dinit.d\fR,

+ 1 - 1
src/dinit.cc

@@ -281,7 +281,7 @@ static int process_commandline_arg(char **argv, int argc, int &i, options &opts)
                     "                              environment variable initialisation file\n"
                     " --services-dir <dir>, -d <dir>\n"
                     "                              set base directory for service description\n"
-                    "                              files\n"
+                    "                              files, can be specified multiple times\n"
                     " --system, -s                 run as the system service manager\n"
                     " --system-mgr, -m             run as system manager (perform shutdown etc)\n"
                     " --user, -u                   run as a user service manager\n"

+ 1 - 1
src/dinitcheck.cc

@@ -96,7 +96,7 @@ int main(int argc, char **argv)
                             " --help                       display help\n"
                             " --services-dir <dir>, -d <dir>\n"
                             "                              set base directory for service description\n"
-                            "                              files\n"
+                            "                              files, can be specified multiple times\n"
                             " <service-name>               check service with name <service-name>\n";
                     return EXIT_SUCCESS;
                 }

+ 2 - 4
src/includes/options-processing.h

@@ -78,9 +78,7 @@ public:
 
 class service_dir_opt
 {
-    const char *service_dir = nullptr;;
-    bool service_dir_dynamic = false;
-
+    std::vector<const char *> service_dirs;
     static const char *user_home_path;
 
     service_dir_pathlist service_dir_paths;
@@ -92,7 +90,7 @@ public:
 
     void set_specified_service_dir(const char *specified_dir)
     {
-        service_dir = specified_dir;
+        service_dirs.push_back(specified_dir);
     }
 
     // Build the set of service directory paths, as per configuration specified thus far. This might be a

+ 27 - 24
src/options-processing.cc

@@ -27,32 +27,35 @@ const char * service_dir_opt::get_user_home()
 
 void service_dir_opt::build_paths(bool am_system_init)
 {
-    /* service directory name */
-    if (service_dir == nullptr && ! am_system_init) {
-        const char * user_home = get_user_home();
-        if (user_home != nullptr) {
-            size_t user_home_len = strlen(user_home);
-            size_t dinit_d_len = strlen("/dinit.d");
-            size_t full_len = user_home_len + dinit_d_len + 1;
-            char *service_dir_w = new char[full_len];
-            std::memcpy(service_dir_w, user_home, user_home_len);
-            std::memcpy(service_dir_w + user_home_len, "/dinit.d", dinit_d_len);
-            service_dir_w[full_len - 1] = 0;
-
-            service_dir = service_dir_w;
-            service_dir_dynamic = true;
+    if (service_dirs.empty()) {
+        bool home_service_dir_set = false;
+
+        /* service directory name */
+        if (! am_system_init) {
+            const char * user_home = get_user_home();
+            if (user_home != nullptr) {
+                size_t user_home_len = strlen(user_home);
+                size_t dinit_d_len = strlen("/dinit.d");
+                size_t full_len = user_home_len + dinit_d_len + 1;
+                char *service_dir_w = new char[full_len];
+                std::memcpy(service_dir_w, user_home, user_home_len);
+                std::memcpy(service_dir_w + user_home_len, "/dinit.d", dinit_d_len);
+                service_dir_w[full_len - 1] = 0;
+
+                service_dir_paths.add_dir(service_dir_w, /*dyn_allocd=*/true);
+                home_service_dir_set = true;
+            }
         }
-    }
 
-    bool add_all_service_dirs = false;
-    if (service_dir == nullptr) {
-        service_dir = "/etc/dinit.d";
-        add_all_service_dirs = true;
+        if (! home_service_dir_set) {
+            service_dir_paths.add_dir("/etc/dinit.d", /*dyn_allocd=*/false);
+            service_dir_paths.add_dir("/usr/local/lib/dinit.d", false);
+            service_dir_paths.add_dir("/lib/dinit.d", false);
+        }
     }
-
-    service_dir_paths.add_dir(service_dir, service_dir_dynamic);
-    if (add_all_service_dirs) {
-        service_dir_paths.add_dir("/usr/local/lib/dinit.d", false);
-        service_dir_paths.add_dir("/lib/dinit.d", false);
+    else {
+        for (const char * dir : service_dirs) {
+            service_dir_paths.add_dir(dir, /*dyn_allocd=*/false);
+        }
     }
 }