static void addSignals() { app->traceToggle = mprAddSignalHandler(SIGUSR2, traceHandler, 0, 0, MPR_SIGNAL_AFTER); /* Signal to dump memory stats. Must configure with ./configure --set memoryCheck=true */ #if defined(SIGINFO) app->statusCheck = mprAddSignalHandler(SIGINFO, statusCheck, 0, 0, MPR_SIGNAL_AFTER); #elif defined(SIGRTMIN) app->statusCheck = mprAddSignalHandler(SIGRTMIN, statusCheck, 0, 0, MPR_SIGNAL_AFTER); #endif }
static int initialize(cchar *ip, int port) { if ((app->appweb = maCreateAppweb()) == 0) { mprUserError("Can't create HTTP service for %s", mprGetAppName()); return MPR_ERR_CANT_CREATE; } MPR->appwebService = app->appweb; if ((app->server = maCreateServer(app->appweb, "default")) == 0) { mprUserError("Can't create HTTP server for %s", mprGetAppName()); return MPR_ERR_CANT_CREATE; } if (maConfigureServer(app->server, app->configFile, app->home, app->documents, ip, port) < 0) { /* mprUserError("Can't configure the server, exiting."); */ return MPR_ERR_CANT_CREATE; } if (app->workers >= 0) { mprSetMaxWorkers(app->workers); } #if BLD_WIN_LIKE writePort(app->server); #elif BLD_UNIX_LIKE app->traceToggle = mprAddSignalHandler(SIGUSR2, traceHandler, 0, 0, MPR_SIGNAL_AFTER); #endif return 0; }
/* Standard signal handler. The following signals are handled: SIGINT - immediate exit SIGTERM - graceful shutdown SIGPIPE - ignore SIGXFZ - ignore SIGUSR1 - graceful shutdown, then restart SIGUSR2 - toggle trace level (Appweb) All others - default exit */ void mprAddStandardSignals() { MprSignalService *ssp; ssp = MPR->signalService; mprAddItem(ssp->standard, mprAddSignalHandler(SIGINT, standardSignalHandler, 0, 0, MPR_SIGNAL_AFTER)); mprAddItem(ssp->standard, mprAddSignalHandler(SIGQUIT, standardSignalHandler, 0, 0, MPR_SIGNAL_AFTER)); mprAddItem(ssp->standard, mprAddSignalHandler(SIGTERM, standardSignalHandler, 0, 0, MPR_SIGNAL_AFTER)); mprAddItem(ssp->standard, mprAddSignalHandler(SIGPIPE, standardSignalHandler, 0, 0, MPR_SIGNAL_AFTER)); mprAddItem(ssp->standard, mprAddSignalHandler(SIGUSR1, standardSignalHandler, 0, 0, MPR_SIGNAL_AFTER)); #if SIGXFSZ mprAddItem(ssp->standard, mprAddSignalHandler(SIGXFSZ, standardSignalHandler, 0, 0, MPR_SIGNAL_AFTER)); #endif #if MACOSX && BIT_DEBUG mprAddItem(ssp->standard, mprAddSignalHandler(SIGBUS, standardSignalHandler, 0, 0, MPR_SIGNAL_AFTER)); mprAddItem(ssp->standard, mprAddSignalHandler(SIGSEGV, standardSignalHandler, 0, 0, MPR_SIGNAL_AFTER)); #endif }
static int startProcess(MprCmd *cmd) { MprCmdFile *files; int i; files = cmd->files; if (!cmd->signal) { cmd->signal = mprAddSignalHandler(SIGCHLD, cmdChildDeath, cmd, cmd->dispatcher, MPR_SIGNAL_BEFORE); } /* Create the child */ cmd->pid = fork(); if (cmd->pid < 0) { mprLog("error mpr cmd", 0, "Cannot fork a new process to run %s, errno %d", cmd->program, mprGetOsError()); return MPR_ERR_CANT_INITIALIZE; } else if (cmd->pid == 0) { /* Child */ umask(022); if (cmd->flags & MPR_CMD_NEW_SESSION) { setsid(); } if (cmd->dir) { if (chdir(cmd->dir) < 0) { mprLog("error mpr cmd", 0, "Cannot change directory to %s", cmd->dir); return MPR_ERR_CANT_INITIALIZE; } } if (cmd->flags & MPR_CMD_IN) { if (files[MPR_CMD_STDIN].clientFd >= 0) { dup2(files[MPR_CMD_STDIN].clientFd, 0); close(files[MPR_CMD_STDIN].fd); } else { close(0); } } if (cmd->flags & MPR_CMD_OUT) { if (files[MPR_CMD_STDOUT].clientFd >= 0) { dup2(files[MPR_CMD_STDOUT].clientFd, 1); close(files[MPR_CMD_STDOUT].fd); } else { close(1); } } if (cmd->flags & MPR_CMD_ERR) { if (files[MPR_CMD_STDERR].clientFd >= 0) { dup2(files[MPR_CMD_STDERR].clientFd, 2); close(files[MPR_CMD_STDERR].fd); } else { close(2); } } cmd->forkCallback(cmd->forkData); if (cmd->env) { (void) execve(cmd->program, (char**) cmd->argv, (char**) &cmd->env->items[0]); } else { (void) execv(cmd->program, (char**) cmd->argv); } /* Use _exit to avoid flushing I/O any other I/O. */ _exit(-(MPR_ERR_CANT_INITIALIZE)); } else { /* Close the client handles */ for (i = 0; i < MPR_CMD_MAX_PIPE; i++) { if (files[i].clientFd >= 0) { close(files[i].clientFd); files[i].clientFd = -1; } } } return 0; }