fork
if ((*pid = fork()) == 0)
{
/*
* Child process goes here; update stderr as needed...
*/
if (errfd != 2)
{
if (errfd < 0)
errfd = open("/dev/null", O_WRONLY);
if (errfd != 2)
{
dup2(errfd, 2);
close(errfd);
}
}
/*
* Put this process in its own process group so that we can kill any child
* processes it creates.
*/
#ifdef HAVE_SETPGID
if (!RunUser && setpgid(0, 0))
exit(errno + 100);
#else
if (!RunUser && setpgrp())
exit(errno + 100);
#endif /* HAVE_SETPGID */
/*
* Update the remaining file descriptors as needed...
*/
if (infd != 0)
{
if (infd < 0)
infd = open("/dev/null", O_RDONLY);
if (infd != 0)
{
dup2(infd, 0);
close(infd);
}
}
if (outfd != 1)
{
if (outfd < 0)
outfd = open("/dev/null", O_WRONLY);
if (outfd != 1)
{
dup2(outfd, 1);
close(outfd);
}
}
if (backfd != 3 && backfd >= 0)
{
dup2(backfd, 3);
close(backfd);
fcntl(3, F_SETFL, O_NDELAY);
}
if (sidefd != 4 && sidefd >= 0)
{
dup2(sidefd, 4);
close(sidefd);
fcntl(4, F_SETFL, O_NDELAY);
}
/*
* Change the priority of the process based on the FilterNice setting.
* (this is not done for root processes...)
*/
if (!root)
nice(FilterNice);
/*
* Reset group membership to just the main one we belong to.
*/
if (!RunUser && setgid(Group))
exit(errno + 100);
if (!RunUser && setgroups(1, &Group))
exit(errno + 100);
/*
* Change user to something "safe"...
*/
if (!RunUser && user && setuid(user))
exit(errno + 100);
/*
* Change umask to restrict permissions on created files...
*/
umask(077);
/*
* Unblock signals before doing the exec...
*/
#ifdef HAVE_SIGSET
sigset(SIGTERM, SIG_DFL);
sigset(SIGCHLD, SIG_DFL);
sigset(SIGPIPE, SIG_DFL);
#elif defined(HAVE_SIGACTION)
memset(&action, 0, sizeof(action));
sigemptyset(&action.sa_mask);
action.sa_handler = SIG_DFL;
sigaction(SIGTERM, &action, NULL);
sigaction(SIGCHLD, &action, NULL);
sigaction(SIGPIPE, &action, NULL);
#else
signal(SIGTERM, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
#endif /* HAVE_SIGSET */
cupsdReleaseSignals();
/*
* Execute the command; if for some reason this doesn't work, log an error
* exit with a non-zero value...
*/
if (envp)
execve(exec_path, argv, envp);
else
execv(exec_path, argv);
exit(errno + 100);
}
else if (*pid < 0)
{
/*
* Error - couldn't fork a new process!
*/
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to fork %s - %s.", command,
strerror(errno));
*pid = 0;
}
else
{
if (!process_array)
process_array = cupsArrayNew((cups_array_func_t)compare_procs, NULL);
if (process_array)
{
if ((proc = calloc(1, sizeof(cupsd_proc_t) + strlen(command))) != NULL)
{
proc->pid = *pid;
proc->job_id = job ? job->id : 0;
_cups_strcpy(proc->name, command);
cupsArrayAdd(process_array, proc);
}
}
}