From be7d6f3b3156403b62410c50ece65f367366131a Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Wed, 31 Jul 2024 15:37:48 -0400 Subject: [PATCH] Signal handling is better --- lib/modrec.c | 138 +++++++++++++++++++------------------- lib/subrou.c | 3 +- lib/ubrou.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/unisoc.c | 2 - lib/unisoc.h | 2 +- 5 files changed, 258 insertions(+), 73 deletions(-) create mode 100644 lib/ubrou.c diff --git a/lib/modrec.c b/lib/modrec.c index 4851da5..dc62293 100644 --- a/lib/modrec.c +++ b/lib/modrec.c @@ -163,69 +163,26 @@ while (proceed==true) { */ /********************************************************/ /* */ -/* Procedure to kill all child process if necessary*/ +/* Procedure to start a binding+waiting process */ /* */ /********************************************************/ -static void release(SOCTYP **bindings) +PUBLIC pid_t startwaiter(SOCTYP *binding) { -#define OPEP "modrec.c:release" +pid_t waiter; -SOCTYP **ptr; -int phase; -_Bool proceed; - -ptr=bindings; -phase=0; -proceed=true; -while (proceed==true) { - switch (phase) { - case 0 : //making sur the list is defined - if (ptr==(SOCTYP **)0) { - (void) rou_alert(0,"%s bindings list pointer is NULL (Bug!?)",OPEP); - phase=999; //not going further - } - break; - case 1 : //check need to kill a dispatched process - ptr=bindings; - while (*ptr!=(SOCTYP *)0) { - for (int i=0;i<(*ptr)->iteration;i++) { - if ((*ptr)->childs[i]==(pid_t)0) - continue; - if (prc_checkprocess((*ptr)->childs[i])==true) { - (void) rou_alert(0,"JMPDBG sending a SIGTERM process to '%d'", - (*ptr)->childs[i]); - (void) kill((*ptr)->childs[i],SIGTERM); - (void) usleep(1000); - } - } - ptr++; - } - break; - case 2 : //checking if ALL process are now terminated - sleep(1); - (void) prc_nozombie(); - ptr=bindings; - while (*ptr!=(SOCTYP *)0) { - for (int i=0;i<(*ptr)->iteration;i++) { - if ((*ptr)->childs[i]==(pid_t)0) - continue; - if (prc_checkprocess((*ptr)->childs[i])==false) { - (*ptr)->childs[i]=(pid_t)0; - continue; - } - phase=0; //some process still remain killing again? - } - ptr++; - } - break; - default : //SAFE Guard - proceed=false; - break; - } - phase++; +if ((waiter=fork())==(pid_t)0) { + (void) closelog(); + (void) openlog("Waiter",LOG_NDELAY|LOG_PID,LOG_DAEMON); + (void) prc_settitle("Daemon Waiting on %s:%s (Num of channels='%02d')", + binding->ip,binding->port,binding->iteration); + (void) rou_alert(0,"JMPDBG starting waiter"); + (void) sleep(20); + (void) rou_alert(0,"JMPDBG waiter exiting"); + (void) closelog(); + (void) exit(0); } -#undef OPEP +return waiter; } /* @@ -239,11 +196,14 @@ PUBLIC void rec_handlesmtp() { #define OPEP "modrec.c:rec_handlesmtp" +#define LINE "---------------------------------" +int maxretry; //how long checking sub process to be out SOCTYP **bindings; int phase; _Bool proceed; +maxretry=30; //5 seconds max retry bindings=(SOCTYP **)0; bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.1","2525",1); //bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.26","2626",1); @@ -253,32 +213,72 @@ while (proceed==true) { switch (phase) { case 0 : //looping forever email receiving processes (void) prc_settitle("Emlrec Daemon"); - (void) rou_alert(0,"-------------JMPDBG---------------"); + (void) rou_alert(0,LINE); + (void) rou_alert(0,"Starting Emlrec daemon"); + if (bindings==(SOCTYP **)0) { + (void) rou_alert(0,"No bindings definition found!"); + phase=999; //No need to go further + } break; case 1 : //Opening ALL channels - if (soc_mulopen(bindings)==false) - (void) rou_alert(0,"%s, Unable to open ALL socket (config?)",OPEP); + for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { + (void) prc_nozombie(); + if ((*ptr)->waiter==(pid_t)0) + continue; + if (prc_checkprocess((*ptr)->waiter)==false) + (*ptr)->waiter=(pid_t)0; + } break; - case 2 : //Terminating all remaining process - (void) activate(bindings); - if ((hangup==false)&&(reload==false)) - (void) sleep(5); + case 2 : //starting restarting all waiter process + for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { + if ((*ptr)->waiter!=(pid_t)0) + continue; + (*ptr)->waiter=startwaiter(*ptr); + } + break; + case 3 : //relax time + (void) sleep(5); //Waiting for signal if ((hangup==false)&&(reload==false)) - phase--; //normal cycle, lets proceed to actvate again + phase=0; //Normal process, lets restart break; - case 3 : //release current binding - (void) release(bindings); + case 4 : //we got a signal + for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { + if ((*ptr)->waiter==(pid_t)0) + continue; + if (prc_checkprocess((*ptr)->waiter)==false) { + (*ptr)->waiter=(pid_t)0; + continue; + } + if ((hangup==true)||(reload==true)) + (void) kill((*ptr)->waiter,SIGTERM); + } break; - case 4 : //closing all socket currently opened - (void) soc_mulclose(bindings); + case 5 : //making sur all waiter procees are gone + maxretry--; + (void) sleep(1); + //(void) rou_alert(0,"JMPDBG cleanup! maxretry='%d'",maxretry); + for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { + (void) prc_nozombie(); + if ((*ptr)->waiter==(pid_t)0) + continue; + if (prc_checkprocess((*ptr)->waiter)==true) { + if (maxretry>0) + phase--; //retrying + } + else + (*ptr)->waiter=(pid_t)0; + } break; default : //SAFE Guard + (void) rou_alert(0,"Stopping Emlrec daemon"); + (void) rou_alert(0,LINE); proceed=false; break; } phase++; } bindings=soc_freebindinf(bindings); +#undef LINE #undef OPEP } /* diff --git a/lib/subrou.c b/lib/subrou.c index 458ce00..41807fa 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -235,7 +235,8 @@ if (debug>=dlevel) (void) syslog(LOG_INFO,"%s",locline); ptr +=DEBMAX; } - (void) syslog(LOG_INFO,"%s",ptr); + if (strlen(ptr)>0) + (void) syslog(LOG_INFO,"%s",ptr); } } } diff --git a/lib/ubrou.c b/lib/ubrou.c new file mode 100644 index 0000000..90ea5bd --- /dev/null +++ b/lib/ubrou.c @@ -0,0 +1,186 @@ +SYSLOG(3) Linux Programmer’s Manual SYSLOG(3) + +NAME + closelog, openlog, syslog, vsyslog - send messages to the system logger + +SYNOPSIS + #include  + + void openlog(const char *ident, int option, int facility); + void syslog(int priority, const char *format, ...); + void closelog(void); + + void vsyslog(int priority, const char *format, va_list ap); + + Feature Test Macro Requirements for glibc (see feature_test_macros(7)): + + vsyslog(): + Since glibc 2.19: + _DEFAULT_SOURCE + Glibc 2.19 and earlier: + _BSD_SOURCE + +DESCRIPTION + openlog() + openlog() opens a connection to the system logger for a program. + + The string pointed to by ident is prepended to every message, and is typi‐ + cally set to the program name. If ident is NULL, the program name is + used. (POSIX.1‐2008 does not specify the behavior when ident is NULL.) + + The option argument specifies flags which control the operation of open‐ + log() and subsequent calls to syslog(). The facility argument establishes + a default to be used if none is specified in subsequent calls to syslog(). + The values that may be specified for option and facility are described be‐ + low. + + The use of openlog() is optional; it will automatically be called by sys‐ + log() if necessary, in which case ident will default to NULL. + + syslog() and vsyslog() + syslog() generates a log message, which will be distributed by syslogd(8). + + The priority argument is formed by ORing together a facility value and a + level value (described below). If no facility value is ORed into prior‐ + ity, then the default value set by openlog() is used, or, if there was no + preceding openlog() call, a default of LOG_USER is employed. + + The remaining arguments are a format, as in printf(3), and any arguments + required by the format, except that the two‐character sequence %m will be + replaced by the error message string strerror(errno). The format string + need not include a terminating newline character. + + The function vsyslog() performs the same task as syslog() with the differ‐ + ence that it takes a set of arguments which have been obtained using the + stdarg(3) variable argument list macros. + + closelog() + closelog() closes the file descriptor being used to write to the system + logger. The use of closelog() is optional. + + Values for option + The option argument to openlog() is a bit mask constructed by ORing to‐ + gether any of the following values: + + LOG_CONS Write directly to the system console if there is an error + while sending to the system logger. + + LOG_NDELAY Open the connection immediately (normally, the connection + is opened when the first message is logged). This may be + useful, for example, if a subsequent chroot(2) would make + the pathname used internally by the logging facility un‐ + reachable. + + LOG_NOWAIT Don’t wait for child processes that may have been created + while logging the message. (The GNU C library does not + create a child process, so this option has no effect on + Linux.) + + LOG_ODELAY The converse of LOG_NDELAY; opening of the connection is + delayed until syslog() is called. (This is the default, + and need not be specified.) + + LOG_PERROR (Not in POSIX.1‐2001 or POSIX.1‐2008.) Also log the mes‐ + sage to stderr. + + LOG_PID Include the caller’s PID with each message. + + Values for facility + The facility argument is used to specify what type of program is logging + the message. This lets the configuration file specify that messages from + different facilities will be handled differently. + + LOG_AUTH security/authorization messages + + LOG_AUTHPRIV security/authorization messages (private) + + LOG_CRON clock daemon (cron and at) + + LOG_DAEMON system daemons without separate facility value + + LOG_FTP ftp daemon + + LOG_KERN kernel messages (these can’t be generated from user + processes) + + LOG_LOCAL0 through LOG_LOCAL7 + reserved for local use + + LOG_LPR line printer subsystem + + LOG_MAIL mail subsystem + + LOG_NEWS USENET news subsystem + + LOG_SYSLOG messages generated internally by syslogd(8) + + LOG_USER (default) + generic user‐level messages + + LOG_UUCP UUCP subsystem + + Values for level + This determines the importance of the message. The levels are, in order + of decreasing importance: + + LOG_EMERG system is unusable + + LOG_ALERT action must be taken immediately + + LOG_CRIT critical conditions + + LOG_ERR error conditions + + LOG_WARNING warning conditions + + LOG_NOTICE normal, but significant, condition + + LOG_INFO informational message + + LOG_DEBUG debug‐level message + + The function setlogmask(3) can be used to restrict logging to specified + levels only. + +ATTRIBUTES + For an explanation of the terms used in this section, see attributes(7). + ┌───────────────────────┬───────────────┬────────────────────┐ + │ Interface │ Attribute │ Value │ + ├───────────────────────┼───────────────┼────────────────────┤ + │ openlog(), closelog() │ Thread safety │ MT‐Safe │ + ├───────────────────────┼───────────────┼────────────────────┤ + │ syslog(), vsyslog() │ Thread safety │ MT‐Safe env locale │ + └───────────────────────┴───────────────┴────────────────────┘ + +CONFORMING TO + The functions openlog(), closelog(), and syslog() (but not vsyslog()) are + specified in SUSv2, POSIX.1‐2001, and POSIX.1‐2008. + + POSIX.1‐2001 specifies only the LOG_USER and LOG_LOCAL* values for facil‐ + ity. However, with the exception of LOG_AUTHPRIV and LOG_FTP, the other + facility values appear on most UNIX systems. + + The LOG_PERROR value for option is not specified by POSIX.1‐2001 or + POSIX.1‐2008, but is available in most versions of UNIX. + +NOTES + The argument ident in the call of openlog() is probably stored as‐is. + Thus, if the string it points to is changed, syslog() may start prepending + the changed string, and if the string it points to ceases to exist, the + results are undefined. Most portable is to use a string constant. + + Never pass a string with user‐supplied data as a format, use the following + instead: + + syslog(priority, "%s", string); + +SEE ALSO + journalctl(1), logger(1), setlogmask(3), syslog.conf(5), syslogd(8) + +COLOPHON + This page is part of release 5.09 of the Linux man‐pages project. A de‐ + scription of the project, information about reporting bugs, and the latest + version of this page, can be found at + https://www.kernel.org/doc/man-pages/. + +Linux 2017‐09‐15 SYSLOG(3) diff --git a/lib/unisoc.c b/lib/unisoc.c index 71624c1..cbd05a5 100644 --- a/lib/unisoc.c +++ b/lib/unisoc.c @@ -44,7 +44,6 @@ static SOCTYP *freebinding(SOCTYP *binding) if (binding!=(SOCTYP *)0) { binding->port=rou_freestr(binding->port); binding->ip=rou_freestr(binding->ip); - (void) free(binding->childs); (void) free(binding); binding=(SOCTYP *)0; } @@ -179,7 +178,6 @@ bininf->proto=proto; bininf->ip=strdup(ip); bininf->port=strdup(port); bininf->iteration=iteration; -bininf->childs=(pid_t *)calloc(iteration,sizeof(pid_t)); bindings=(SOCTYP **)rou_addlist((void **)bindings,(void *)bininf); return bindings; } diff --git a/lib/unisoc.h b/lib/unisoc.h index d4e3860..f1235e8 100644 --- a/lib/unisoc.h +++ b/lib/unisoc.h @@ -30,7 +30,7 @@ typedef struct { time_t lasttry; //successful binding last time int iteration; //number of soc slot used on the IP int handle; //connexion handle - pid_t *childs; //all process connected to this handle + pid_t waiter; //binding manager }SOCTYP; -- 2.47.3