fiss

Friedel's Initialization and Service Supervision
Log | Files | Refs | LICENSE

service.c (1738B)


      1 #include "service.h"
      2 
      3 #include <dirent.h>
      4 #include <errno.h>
      5 #include <limits.h>
      6 #include <stdio.h>
      7 #include <string.h>
      8 #include <sys/stat.h>
      9 #include <sys/wait.h>
     10 #include <unistd.h>
     11 
     12 
     13 struct service services[SV_SERVICE_MAX];
     14 int            services_size = 0;
     15 char           runlevel[SV_NAME_MAX];
     16 int            service_dir;
     17 const char*    service_dir_path;
     18 int            null_fd;
     19 bool           daemon_running;
     20 
     21 struct service* service_get(const char* name) {
     22 	for (int i = 0; i < services_size; i++) {
     23 		if (streq(services[i].name, name))
     24 			return &services[i];
     25 	}
     26 	return NULL;
     27 }
     28 
     29 int service_refresh_directory(void) {
     30 	DIR*            dp;
     31 	struct dirent*  ep;
     32 	struct stat     st;
     33 	struct service* s;
     34 
     35 	if ((dp = opendir(service_dir_path)) == NULL) {
     36 		fprint(1, "error: cannot open service directory: %r\n");
     37 		return -1;
     38 	}
     39 
     40 	for (int i = 0; i < services_size; i++) {
     41 		s = &services[i];
     42 		if (fstat(s->dir, &st) == -1 || !S_ISDIR(st.st_mode)) {
     43 			service_stop(s);
     44 			close(s->dir);
     45 			close(s->control);
     46 		}
     47 	}
     48 
     49 	while ((ep = readdir(dp)) != NULL) {
     50 		if (ep->d_name[0] == '.')
     51 			continue;
     52 
     53 		if (fstatat(service_dir, ep->d_name, &st, 0) == -1 || !S_ISDIR(st.st_mode))
     54 			continue;
     55 
     56 		service_register(service_dir, ep->d_name, false);
     57 	}
     58 
     59 	closedir(dp);
     60 
     61 	for (int i = 0; i < services_size; i++) {
     62 		services[i].children_size = 0;
     63 		services[i].parents_size  = 0;
     64 	}
     65 
     66 	for (int i = 0; i < services_size; i++)
     67 		service_update_dependency(&services[i]);
     68 
     69 	return 0;
     70 }
     71 
     72 
     73 bool service_need_restart(struct service* s) {
     74 	if (!daemon_running)
     75 		return false;
     76 
     77 	if (s->restart == S_RESTART)
     78 		return true;
     79 
     80 	for (int i = 0; i < s->parents_size; i++) {
     81 		if (service_need_restart(s->parents[i]))
     82 			return true;
     83 	}
     84 
     85 	return false;
     86 }