Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  master_sig.c

  Sprache: C
 

/*++
/* NAME
/* master_sig 3
/* SUMMARY
/* Postfix master - signal processing
/* SYNOPSIS
/* #include "master.h"
/*
/* int master_gotsighup;
/* int master_gotsigchld;
/*
/* int master_sigsetup()
/* DESCRIPTION
/* This module implements the master process signal handling interface.
/*
/* master_gotsighup (master_gotsigchld) is set to SIGHUP (SIGCHLD)
/* when the process receives a hangup (child death) signal.
/*
/* master_sigsetup() enables processing of hangup and child death signals.
/* Receipt of SIGINT, SIGQUIT, SIGSEGV, SIGILL, or SIGTERM
/* is interpreted as a request for termination.  Child processes are
/* notified of the master\'s demise by sending them a SIGTERM signal.
/* DIAGNOSTICS
/* BUGS
/* Need a way to register cleanup actions.
/* SEE ALSO
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/


/* System libraries. */

#include <sys_defs.h>
#include <signal.h>
#include <unistd.h>

/* Utility library. */

#include <msg.h>
#include <posix_signals.h>
#include <killme_after.h>

/* Application-specific. */

#include "master.h"

#ifdef USE_SIG_RETURN
#include <sys/syscall.h>
#undef USE_SIG_PIPE
#else
#define USE_SIG_PIPE
#endif

/* Local stuff. */

#ifdef USE_SIG_PIPE
#include <errno.h>
#include <fcntl.h>
#include <iostuff.h>
#include <events.h>

int     master_sig_pipe[2];

#define SIG_PIPE_WRITE_FD master_sig_pipe[1]
#define SIG_PIPE_READ_FD master_sig_pipe[0]
#endif

int     master_gotsigchld;
int     master_gotsighup;

#ifdef USE_SIG_RETURN

/* master_sighup - register arrival of hangup signal */

static void master_sighup(int sig)
{

    /*
     * WARNING WARNING WARNING.
     * 
     * This code runs at unpredictable moments, as a signal handler. Don't put
     * any code here other than for setting a global flag.
     */

    master_gotsighup = sig;
}

/* master_sigchld - register arrival of child death signal */

static void master_sigchld(int sig, int code, struct sigcontext * scp)
{

    /*
     * WARNING WARNING WARNING.
     * 
     * This code runs at unpredictable moments, as a signal handler. Don't put
     * any code here other than for setting a global flag, or code that is
     * intended to be run within a signal handler.
     */

    master_gotsigchld = sig;
    if (scp != NULL && scp->sc_syscall == SYS_select) {
 scp->sc_syscall_action = SIG_RETURN;
#ifndef SA_RESTART
    } else if (scp != NULL) {
 scp->sc_syscall_action = SIG_RESTART;
#endif
    }
}

#else

/* master_sighup - register arrival of hangup signal */

static void master_sighup(int sig)
{
    int     saved_errno = errno;

    /*
     * WARNING WARNING WARNING.
     * 
     * This code runs at unpredictable moments, as a signal handler. Don't put
     * any code here other than for setting a global flag, or code that is
     * intended to be run within a signal handler. Restore errno in case we
     * are interrupting the epilog of a failed system call.
     */

    master_gotsighup = sig;
    if (write(SIG_PIPE_WRITE_FD, ""1) != 1)
 msg_warn("write to SIG_PIPE_WRITE_FD failed: %m");
    errno = saved_errno;
}

/* master_sigchld - force wakeup from select() */

static void master_sigchld(int unused_sig)
{
    int     saved_errno = errno;

    /*
     * WARNING WARNING WARNING.
     * 
     * This code runs at unpredictable moments, as a signal handler. Don't put
     * any code here other than for setting a global flag, or code that is
     * intended to be run within a signal handler. Restore errno in case we
     * are interrupting the epilog of a failed system call.
     */

    master_gotsigchld = 1;
    if (write(SIG_PIPE_WRITE_FD, ""1) != 1)
 msg_warn("write to SIG_PIPE_WRITE_FD failed: %m");
    errno = saved_errno;
}

/* master_sig_event - called upon return from select() */

static void master_sig_event(int unused_event, void *unused_context)
{
    char    c[1];

    while (read(SIG_PIPE_READ_FD, c, 1) > 0)
  /* void */ ;
}

#endif

/* master_sigdeath - die, women and children first */

static void master_sigdeath(int sig)
{
    const char *myname = "master_sigdeath";
    struct sigaction action;
    pid_t   pid = getpid();

    /*
     * Set alarm clock here for suicide after 5s.
     */

    killme_after(5);

    /*
     * Terminate all processes in our process group, except ourselves.
     */

    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;
    action.sa_handler = SIG_IGN;
    if (sigaction(SIGTERM, &action, (struct sigaction *) 0) < 0)
 msg_fatal("%s: sigaction: %m", myname);
    if (kill(-pid, SIGTERM) < 0)
 msg_fatal("%s: kill process group: %m", myname);

    /*
     * XXX We're running from a signal handler, and should not call complex
     * routines at all, but it would be even worse to silently terminate
     * without informing the sysadmin. For this reason, msg(3) was made safe
     * for usage by signal handlers that terminate the process.
     */

    msg_info("terminating on signal %d", sig);

    /*
     * Undocumented: when a process runs with PID 1, Linux won't deliver a
     * signal unless the process specifies a handler (i.e. SIG_DFL is treated
     * as SIG_IGN).
     */

    if (init_mode)
 /* Don't call exit() from a signal handler. */
 _exit(0);

    /*
     * Deliver the signal to ourselves and clean up. XXX We're running as a
     * signal handler and really should not be doing complicated things...
     */

    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;
    action.sa_handler = SIG_DFL;
    if (sigaction(sig, &action, (struct sigaction *) 0) < 0)
 msg_fatal("%s: sigaction: %m", myname);
    if (kill(pid, sig) < 0)
 msg_fatal("%s: kill myself: %m", myname);
}

/* master_sigsetup - set up signal handlers */

void    master_sigsetup(void)
{
    const char *myname = "master_sigsetup";
    struct sigaction action;
    static int sigs[] = {
 SIGINT, SIGQUIT, SIGILL, SIGBUS, SIGSEGV, SIGTERM,
    };
    unsigned i;

    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;

    /*
     * Prepare to kill our children when we receive any of the above signals.
     */

    action.sa_handler = master_sigdeath;
    for (i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
 if (sigaction(sigs[i], &action, (struct sigaction *) 0) < 0)
     msg_fatal("%s: sigaction(%d): %m", myname, sigs[i]);

#ifdef USE_SIG_PIPE
    if (pipe(master_sig_pipe))
 msg_fatal("pipe: %m");
    non_blocking(SIG_PIPE_WRITE_FD, NON_BLOCKING);
    non_blocking(SIG_PIPE_READ_FD, NON_BLOCKING);
    close_on_exec(SIG_PIPE_WRITE_FD, CLOSE_ON_EXEC);
    close_on_exec(SIG_PIPE_READ_FD, CLOSE_ON_EXEC);
    event_enable_read(SIG_PIPE_READ_FD, master_sig_event, (void *) 0);
#endif

    /*
     * Intercept SIGHUP (re-read config file) and SIGCHLD (child exit).
     */

#ifdef SA_RESTART
    action.sa_flags |= SA_RESTART;
#endif
    action.sa_handler = master_sighup;
    if (sigaction(SIGHUP, &action, (struct sigaction *) 0) < 0)
 msg_fatal("%s: sigaction(%d): %m", myname, SIGHUP);

    action.sa_flags |= SA_NOCLDSTOP;
    action.sa_handler = master_sigchld;
    if (sigaction(SIGCHLD, &action, (struct sigaction *) 0) < 0)
 msg_fatal("%s: sigaction(%d): %m", myname, SIGCHLD);
}

Messung V0.5 in Prozent
C=71 H=95 G=83

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=738142