]> granicus.if.org Git - fcron/commitdiff
optimizations
authorthib <thib>
Thu, 15 Jun 2000 20:10:11 +0000 (20:10 +0000)
committerthib <thib>
Thu, 15 Jun 2000 20:10:11 +0000 (20:10 +0000)
conf.c
database.c
fcron.c
fcron.h
global.h
job.c

diff --git a/conf.c b/conf.c
index f89df1526276c0f28e9e8ec08df63fa44e34190b..ef7deffb56f121c4ea667c33d4df131dbf2f6c87 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -22,7 +22,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: conf.c,v 1.6 2000-06-11 13:17:29 thib Exp $ */
+ /* $Id: conf.c,v 1.7 2000-06-15 20:10:11 thib Exp $ */
 
 #include "fcron.h"
 
@@ -458,23 +458,15 @@ read_file(const char *file_name, CF *cf)
 
        /* check if the task has not been stopped during execution */
        if (cl->cl_pid > 0) {
-           if (cl->cl_mailpid > 0) {
-               /* job has terminated normally, but mail has not
-                * been sent */
-               warn("output of job '%s' has not been mailed "
-                    "due to daemon's stop", cl->cl_shell);
-               cl->cl_pid = cl->cl_mailfd = cl->cl_mailpid = 0;
-           } else {
-               /* job has been stopped during execution :
-                * launch it again */
-               warn("job '%s' has not terminated : will be executed"
-                    " again now.", cl->cl_shell);
-               /* we don't set cl_nextexe to 0 because this value is 
-                * reserved to the entries based on frequency */
-               cl->cl_nextexe = 1;
-               insert_nextexe(cl);
-               cl->cl_pid = cl->cl_mailfd = cl->cl_mailpid = 0;
-           }
+           /* job has been stopped during execution :
+            * launch it again */
+           warn("job '%s' has not terminated : will be executed"
+                " again now.", cl->cl_shell);
+           /* we don't set cl_nextexe to 0 because this value is 
+            * reserved to the entries based on frequency */
+           cl->cl_nextexe = 1;
+           insert_nextexe(cl);
+           cl->cl_pid = 0;
        }
            
 
index b34bd016ae12ad9ff24788995767e91bf57c8d45..9b106b85d662ef8eaaa8726fb54e0809ac0c56df 100644 (file)
@@ -22,7 +22,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: database.c,v 1.8 2000-06-11 13:18:35 thib Exp $ */
+ /* $Id: database.c,v 1.9 2000-06-15 20:12:38 thib Exp $ */
 
 #include "fcron.h"
 
@@ -72,17 +72,14 @@ wait_chld(void)
     int status;
 
     ////////
-    debug("wait_chld");
+//    debug("wait_chld");
     ///////
 
     while ( (pid = wait3(&status, WNOHANG, NULL)) > 0 ) {
        for (j = exe_base; j != NULL ; j = j->j_next) {
            if (pid < 0 || pid == j->j_line->cl_pid) {
-               end_job(j->j_line, status);
-               goto nextloop;
-           }
-           else if ( pid == j->j_line->cl_mailpid ) {
-               end_mailer(j->j_line, status);
+               j->j_line->cl_pid = 0;
+               j->j_line->cl_file->cf_running -= 1;
 
                /* remove file from exe list */
                if (jprev != NULL)
@@ -115,11 +112,9 @@ wait_all(int *counter)
     while ( (*counter > 0) && (pid = wait3(&status, 0, NULL)) > 0 ) {
        for (j = exe_base; j != NULL ; j = j->j_next) {
            if (pid < 0 || pid == j->j_line->cl_pid) {
-               end_job(j->j_line, status);
-               goto nextloop;
-           }
-           else if ( pid == j->j_line->cl_mailpid ) {
-               end_mailer(j->j_line, status);
+
+               j->j_line->cl_pid = 0;
+               j->j_line->cl_file->cf_running -= 1;
 
                /* remove file from exe list */
                if (jprev != NULL)
diff --git a/fcron.c b/fcron.c
index 4c76511be5cad7c0b1a51db57cea3606fbc80129..64dee6602556c0f318499768c27ae2518e53c866 100644 (file)
--- a/fcron.c
+++ b/fcron.c
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fcron.c,v 1.11 2000-06-11 13:18:55 thib Exp $ */
+ /* $Id: fcron.c,v 1.12 2000-06-15 20:12:57 thib Exp $ */
 
 #include "fcron.h"
 
-char rcs_info[] = "$Id: fcron.c,v 1.11 2000-06-11 13:18:55 thib Exp $";
+char rcs_info[] = "$Id: fcron.c,v 1.12 2000-06-15 20:12:57 thib Exp $";
 
 void main_loop(void);
 void info(void);
@@ -314,8 +314,8 @@ main(int argc, char **argv)
 
     /* parse options */
 
-    if (strrchr(argv[0],'/')==NULL) prog_name = argv[0];
-    else prog_name = strrchr(argv[0],'/')+1;
+    if ( strrchr(argv[0], '/') == NULL) prog_name = argv[0];
+    else prog_name = strrchr(argv[0], '/') + 1;
 
     daemon_uid = getuid();
 
@@ -432,7 +432,6 @@ void main_loop()
   /* main loop - get the time to sleep until next job execution,
    *             sleep, and then test all jobs and execute if needed. */
 {
-    extern time_t begin_sleep; /* time at the beginning of sleeping */
     time_t save;               /* time remaining until next save */
     struct timeval tv;         /* we use usec field to get more precision */
     time_t stime = 0;          /* time to sleep until next job
@@ -440,7 +439,7 @@ void main_loop()
 
     debug("Entering main loop");
 
-    now = begin_sleep = time(NULL);
+    now = time(NULL);
 
     synchronize_dir(".");
 
@@ -450,20 +449,14 @@ void main_loop()
     stime = time_to_sleep(save);
 
     for (;;) {
-
+       
        sleep(stime - 1);
        gettimeofday(&tv, NULL);
        usleep( 1000000 - tv.tv_usec );
 
-       now = time(NULL);
-
        if (sig_chld > 0) {
-
-           /* sleep has been stopped too early :
-            * sleep the remaining time */
            wait_chld();
            sig_chld = 0;
-
        }
        else if (sig_conf > 0) {
 
@@ -477,9 +470,9 @@ void main_loop()
            sig_conf = 0;
        }
        else {
-
            debug("\n");
-           debug("slept: %lds", now - begin_sleep);
+
+           now = time(NULL);
 
            test_jobs(now);
 
@@ -493,13 +486,6 @@ void main_loop()
 
        stime = time_to_sleep(save);
 
-       begin_sleep = now;
-
-       if ( sig_chld == 1 ) {
-           wait_chld();
-           sig_chld = 0;
-       }
-
     }
 
 }
diff --git a/fcron.h b/fcron.h
index e5bf2b29c43a37005f53facdd09a5712a9773775..c9e59c7bc7d1f7f6783cd5fdf7e3d20cb45a0d4d 100644 (file)
--- a/fcron.h
+++ b/fcron.h
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fcron.h,v 1.6 2000-06-11 13:18:58 thib Exp $ */
+ /* $Id: fcron.h,v 1.7 2000-06-15 20:16:38 thib Exp $ */
 
 #ifndef __FCRONH__
 #define __FCRONH__
@@ -94,8 +94,6 @@ extern void save_file(CF *file_name, char *path);
 
 /* job.c */
 extern void run_job(CL *line);
-extern void end_job(CL *line, int status);
-extern void end_mailer(CL *line, int status);
 /* end of job.c */
 
 
index c93d35a2bbdc9ad595aafe28f6a8c82902ac42f4..9ba517108e24ea8e8d021719dee3e17d8c7a7789 100644 (file)
--- a/global.h
+++ b/global.h
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: global.h,v 1.6 2000-06-11 13:19:01 thib Exp $ */
+ /* $Id: global.h,v 1.7 2000-06-15 20:17:52 thib Exp $ */
 
 
 /* 
@@ -57,7 +57,7 @@
 #include "option.h"
 
 
-#define FILEVERSION "003"  /* syntax's version of fcrontabs : 
+#define FILEVERSION "004"  /* syntax's version of fcrontabs : 
                            * must have a length of 3 characters */
 
 
@@ -73,7 +73,6 @@
 
 #define debug if(debug_opt) Debug
 
-
 typedef struct env_t {
     char         *e_name;       /* env name                             */
     char         *e_val;        /* env value                            */
@@ -85,7 +84,6 @@ typedef struct CF {
     struct CL    *cf_line_base;
     char        *cf_user;      /* user-name                            */
     char         *cf_mailto;    /* mail output's to mail_user           */
-    short int   cf_mailpos;    /* 'empty mail file' size               */
     struct env_t *cf_env_base;  /* list of all env variables to set     */
     int                 cf_running;    /* number of jobs running               */
 } CF;
@@ -98,8 +96,6 @@ typedef struct CL {
     char         option;        /* options for that line (see option.h) */
     char        *cl_shell;     /* shell command                        */
     pid_t       cl_pid;        /* running pid, 0, or armed (-1)        */
-    pid_t       cl_mailpid;    /* mailer pid or 0                      */
-    int                 cl_mailfd;     /* running pid is for mail              */
     time_t       cl_nextexe;     /* time and date of the next execution */
     short int    cl_remain;      /* remaining until next execution      */
     time_t       cl_timefreq;    /* Run every n seconds                 */
diff --git a/job.c b/job.c
index acc8f25969a1d4b1b8e23beb06be9568e1be4d4b..7df3eb38bceba3459dc5a8abd4392307c5d10132 100644 (file)
--- a/job.c
+++ b/job.c
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: job.c,v 1.7 2000-06-11 13:19:17 thib Exp $ */
+ /* $Id: job.c,v 1.8 2000-06-15 20:18:15 thib Exp $ */
 
 #include "fcron.h"
 
 int temp_file(void);
 void xwrite(int fd, char *string);
-void launch_mailer(CL *line);
+void launch_mailer(CL *line, int mailfd);
 int change_user(const char *user, short dochdir);
+void sig_dfl(void);
+void end_job(CL *line, int status, int mailfd, short mailpos);
+void end_mailer(CL *line, int status);
 
 
 int
@@ -70,6 +73,15 @@ change_user(const char *user, short dochdir)
 }
 
 
+void
+sig_dfl(void)
+    /* set signals handling to its default */
+{
+       signal(SIGTERM, SIG_DFL);
+       signal(SIGCHLD, SIG_DFL);
+       signal(SIGHUP, SIG_DFL);
+       signal(SIGUSR1, SIG_DFL);
+}
 
 void 
 run_job(CL *line)
@@ -77,40 +89,36 @@ run_job(CL *line)
 {
 
     pid_t pid = 0;
-    char *shell = NULL;
-    char *home = NULL;
-    env_t *env = NULL;
     struct job *j = NULL;
 
-    /* create temporary file for stdout and stderr of the job */
-    line->cl_mailfd = temp_file();
-
-    /* write mail header */
-    xwrite(line->cl_mailfd,"To: ");
-    xwrite(line->cl_mailfd, line->cl_file->cf_user);
-    xwrite(line->cl_mailfd, "\nSubject: Output of fcron job: '");
-    xwrite(line->cl_mailfd, line->cl_shell);
-    xwrite(line->cl_mailfd,"'\n\n");
-    if ( ! line->cl_file->cf_mailpos ) 
-       line->cl_file->cf_mailpos = ( lseek(line->cl_mailfd, 0, SEEK_END)
-           - strlen(line->cl_shell) );
-
-
     /* append job to the list of executed job */
     Alloc(j, job);
     j->j_line = line;
     j->j_next = exe_base;
     exe_base = j;
 
+    /* prepare the job execution */
     switch ( pid = fork() ) {
+    case -1:
+       error_e("Fork error : could not exec '%s'", line->cl_shell);
+       break;
 
     case 0:
        /* child */
+    {
+       char *shell = NULL;
+       char *home = NULL;
+       env_t *env = NULL;
+       int mailfd = 0;
+       short int mailpos = 0;  /* 'empty mail file' size */
+       int status = 0;
 
        foreground = 0;
        if (change_user(line->cl_file->cf_user, 1) < 0)
            return ;
 
+       sig_dfl();
+
        /* stdin is already /dev/null, setup stdout and stderr */
        if ( close(1) != 0 )
            die_e("Can't close file descriptor %d",1);
@@ -120,14 +128,26 @@ run_job(CL *line)
        if ( line->cl_file->cf_mailto != NULL &&
             strcmp(line->cl_file->cf_mailto, "") == 0 ) {
 
-           if ( close(line->cl_mailfd) != 0 )
-               die_e("Can't close file descriptor %d", line->cl_mailfd);
-           if ( (line->cl_mailfd = open("/dev/null", O_RDWR)) < 0 )
+           if ( close(mailfd) != 0 )
+               die_e("Can't close file descriptor %d", mailfd);
+           if ( (mailfd = open("/dev/null", O_RDWR)) < 0 )
                die_e("open: /dev/null:");
 
        }
+       else {
+           /* create temporary file for stdout and stderr of the job */
+           mailfd = temp_file();
+
+           /* write mail header */
+           xwrite(mailfd,"To: ");
+           xwrite(mailfd, line->cl_file->cf_user);
+           xwrite(mailfd, "\nSubject: Output of fcron job: '");
+           xwrite(mailfd, line->cl_shell);
+           xwrite(mailfd,"'\n\n");
+           mailpos = ( lseek(mailfd, 0, SEEK_END) - strlen(line->cl_shell) );
+       }
 
-       if (dup2(line->cl_mailfd, 1) != 1 || dup2(line->cl_mailfd, 2) != 2)
+       if (dup2(mailfd, 1) != 1 || dup2(mailfd, 2) != 2)
            die_e("dup2() error");    /* dup2 also clears close-on-exec flag */
 
        foreground = 1; 
@@ -155,36 +175,51 @@ run_job(CL *line)
            shell = SHELL;
        }
 
+
+       /* now, run the job */
+       switch ( fork() ) {
+       case -1:
+           error_e("Fork error : could not exec '%s'", line->cl_shell);
+           break;
+
+       case 0:
+           /* child */
+
 #ifdef CHECKJOBS
-       /* this will force to mail a message containing at least the exact
-        * and complete command executed for each execution of all jobs */
-       debug("Execing '%s -c %s'", shell, line->cl_shell);
+           /* this will force to mail a message containing at least the exact
+            * and complete command executed for each execution of all jobs */
+           debug("Execing '%s -c %s'", shell, line->cl_shell);
 #endif /* CHECKJOBS */
 
-       execl(shell, shell, "-c", line->cl_shell, NULL);
+           execl(shell, shell, "-c", line->cl_shell, NULL);
 
-       /* execl returns only on error */
-       die_e("execl() '%s -c %s' error", shell, line->cl_shell);
+           /* execl returns only on error */
+           die_e("execl() '%s -c %s' error", shell, line->cl_shell);
 
-       /* execution never gets here */
+           /* execution never gets here */
 
-    case -1:
-       error_e("Fork error : could not exec '%s'", line->cl_shell);
-       break;
+       default:
+           /* parent */
+           /* we use a while because an possible interruption by a signal */
+           while ( (pid = wait3(&status, 0, NULL)) > 0) {
+               end_job(line, status, mailfd, mailpos);
+
+               /* execution never gets here */
+
+           }
+           
+       }
+    }
 
     default:
        /* parent */
 
        ////////
-       debug("run job - parent");
+//     debug("run job - parent");
        ////////
 
        line->cl_pid = pid;
 
-       ////////////
-       debug("   cf_running: %d", line->cl_file->cf_running);
-       ///////////
-
        line->cl_file->cf_running += 1;
 
        explain("  Job `%s' started (pid %d)", line->cl_shell, line->cl_pid);
@@ -194,7 +229,7 @@ run_job(CL *line)
 }
 
 void 
-end_job(CL *line, int status)
+end_job(CL *line, int status, int mailfd, short mailpos)
     /* if task have made some output, mail it to user */
 {
 
@@ -205,8 +240,7 @@ end_job(CL *line, int status)
     debug("   end_job");
 //////
 
-    if ( ( lseek(line->cl_mailfd, 0, SEEK_END) - strlen (line->cl_shell) )
-        > line->cl_file->cf_mailpos ) {
+    if ( ( lseek(mailfd, 0, SEEK_END) - strlen (line->cl_shell) ) > mailpos ){
        if ( line->cl_file->cf_mailto != NULL &&
             line->cl_file->cf_mailto[0] == '\0' )
            /* there is a mail output, but it will not be mail */
@@ -231,23 +265,18 @@ end_job(CL *line, int status)
     else /* is this possible? */
        error("Job `%s' terminated abnormally %s", line->cl_shell, m);
 
-    if (mail_output == 1) launch_mailer(line);
+    if (mail_output == 1) launch_mailer(line, mailfd);
 
     /* if MAILTO is "", temp file is already closed */
-    if ( mail_output != 2 && close(line->cl_mailfd) != 0 )
-       die_e("Can't close file descriptor %d", line->cl_mailfd);
-
-    line->cl_pid = 0;
+    if ( mail_output != 2 && close(mailfd) != 0 )
+       die_e("Can't close file descriptor %d", mailfd);
 
-    ////////////
-    debug("    cf_running: %d", line->cl_file->cf_running);
-
-    line->cl_file->cf_running -= 1;
+    exit(0);
 
 }
 
 void
-launch_mailer(CL *line)
+launch_mailer(CL *line, int mailfd)
     /* mail the output of a job to user */
 {
     char *mailto = NULL;
@@ -255,70 +284,28 @@ launch_mailer(CL *line)
 ////////
     debug("   launch mailer");
 ////////
-    switch ( line->cl_mailpid = fork() ) {
-    case 0:
-       /* child */
 
-       foreground = 0;
+    foreground = 0;
 
-       /* set stdin to the job's output */
-       if ( close(0) != 0 )
-           die_e("Can't close file descriptor %d",0);
-           
+    /* set stdin to the job's output */
+    if ( close(0) != 0 )
+       die_e("Can't close file descriptor %d",0);          
 
-       if (dup2(line->cl_mailfd,0)!=0) die_e("Can't dup2()");
-       if (lseek(0,0,SEEK_SET)!=0) die_e("Can't lseek()");
+    if (dup2(mailfd,0)!=0) die_e("Can't dup2()");
+    if (lseek(0,0,SEEK_SET)!=0) die_e("Can't lseek()");
 
-       xcloselog();
+    xcloselog();
 
-       /* determine which will be the mail receiver */
-       if ( (mailto = line->cl_file->cf_mailto) == NULL )
-           mailto = line->cl_file->cf_user;
+    /* determine which will be the mail receiver */
+    if ( (mailto = line->cl_file->cf_mailto) == NULL )
+       mailto = line->cl_file->cf_user;
 
-       /* change permissions */
-       if (change_user(line->cl_file->cf_user, 1) < 0)
-           return ;
-
-       /* run sendmail with mail file as standard input */
-       execl(SENDMAIL, SENDMAIL, SENDMAIL_ARGS, mailto, NULL);
-       die_e("Can't exec " SENDMAIL);
-       break;
-
-    case -1:
-       error_e("Could not exec '%s'", line->cl_shell);
-       break;
+    /* run sendmail with mail file as standard input */
+    execl(SENDMAIL, SENDMAIL, SENDMAIL_ARGS, mailto, NULL);
+    die_e("Can't exec " SENDMAIL);
 
-    default:
-       /* parent */
-
-    }
-}
-
-void
-end_mailer(CL *line, int status)
-    /* take care of a finished mailer */
-{
-////////
-    debug("   end mailer");
-////////
-
-    if (WIFEXITED(status) && WEXITSTATUS(status)!=0)
-       error("Tried to mail output of job `%s', "
-                "but mailer process (" SENDMAIL ") exited with status %d",
-                line->cl_shell, WEXITSTATUS(status) );
-    else if (!WIFEXITED(status) && WIFSIGNALED(status))
-       error("Tried to mail output of job `%s', "
-                "but mailer process (" SENDMAIL ") got signal %d",
-                line->cl_shell, WTERMSIG(status) );
-    else if (!WIFEXITED(status) && !WIFSIGNALED(status))
-       error("Tried to mail output of job `%s', "
-                "but mailer process (" SENDMAIL ") terminated abnormally"
-                , line->cl_shell);
-
-    line->cl_mailpid = 0;
 }
 
-
 int
 temp_file(void)
     /* Open a temporary file and return its file descriptor */