sm

sysmgr implemented in C
git clone git://git.ckyln.com/sm
Log | Files | Refs | README | LICENSE

runsyssv.c (2335B)


      1 /* runsyssv -- Run and control service scripts
      2  *
      3  * Copyright (C) 2020 Cem Keylan <cem@ckyln.com>
      4  *
      5  * This program is free software: you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation, either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License
     16  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
     17  */
     18 #include <sys/types.h>
     19 #include <sys/stat.h>
     20 #include <sys/wait.h>
     21 
     22 #include <unistd.h>
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #include <signal.h>
     26 #include <libgen.h>
     27 #include <string.h>
     28 #include <dirent.h>
     29 
     30 #include "util.h"
     31 #include "config.h"
     32 static char *argv0, *lockfile, *svrundir;
     33 static pid_t syspid, svpid;
     34 
     35 void
     36 usage(int exitnum)
     37 {
     38 	printf("usage: %s [svfile]\n\nsysmgr-%s\n", argv0, VERSION);
     39 	exit(exitnum);
     40 }
     41 
     42 void
     43 term(int sig)
     44 {
     45 	switch(sig) {
     46 	case SIGUSR1:
     47 		kill(svpid, SIGKILL);
     48 		break;
     49 	default:
     50 		kill(svpid, SIGTERM);
     51 		break;
     52 	}
     53 	if (sv_writelock(lockfile, sig) != 0)
     54 		rm_rf(svrundir);
     55 	exit(0);
     56 }
     57 
     58 
     59 int
     60 main(int argc, char *argv[])
     61 {
     62 	/* Variables used by other functions but not in this file itself */
     63 	(void)(sysdir_default);
     64 	(void)(rundir_default);
     65 
     66 	argv0 = argv[0];
     67 
     68 	if (argc == 2) {
     69 		if (strncmp(argv[1], "-", 1) == 0)
     70 			usage(0);
     71 	} else
     72 		usage(1);
     73 
     74 	syspid = getpid();
     75 
     76 	struct service sv;
     77 	sv_init(&sv, basename(argv[1]));
     78 
     79 	DIR *dir;
     80 	if ((dir = opendir(sv.svrundir)) != NULL) {
     81 		closedir(dir);
     82 		return 1;
     83 	}
     84 
     85 	mkdirp(sv.svrundir);
     86 
     87 	int sv_signals[] = {SIGTERM, SIGINT, SIGHUP, SIGQUIT, SIGABRT};
     88 	lockfile = sv.lockfile;
     89 	svrundir = sv.svrundir;
     90 
     91 	svpid = fork();
     92 	switch(svpid) {
     93 	case -1:
     94 		die("fork:");
     95 		break;
     96 	case 0:
     97 		execvp(sv.svfile, argv);
     98 		perror(sv.svfile);
     99 		break;
    100 	default:
    101 		writesvpid(sv.syspidfile, syspid);
    102 		writesvpid(sv.pidfile, svpid);
    103 		for (long unsigned int i=0; i < sizeof(sv_signals); i++)
    104 			signal(sv_signals[i], term);
    105 		wait(NULL);
    106 		if (rm_rf(sv.svrundir) != 0)
    107 			return 1;
    108 		break;
    109 	}
    110 	return 0;
    111 }