+++ /dev/null
-/*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-//
-// demon - support code for writing UNIXoid demons
-//
-#include <security_utilities/daemon.h>
-#include <security_utilities/logging.h>
-#include <security_utilities/debugging.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-namespace Security {
-namespace Daemon {
-
-
-//
-// Daemonize this process, the UNIX way.
-//
-bool incarnate(bool doFork /*=true*/)
-{
- if (doFork) {
- // fork with slight resilience
- for (int forkTries = 1; forkTries <= 5; forkTries++) {
- switch (fork()) {
- case 0: // child
- // we are the daemon process (Har! Har!)
- break;
- case -1: // parent: fork failed
- switch (errno) {
- case EAGAIN:
- case ENOMEM:
- Syslog::warning("fork() short on resources (errno=%d); retrying", errno);
- sleep(forkTries);
- continue;
- default:
- Syslog::error("fork() failed (errno=%d)", errno);
- return false;
- }
- default: // parent
- // @@@ we could close an assurance loop here, but we don't (yet?)
- exit(0);
- }
- }
- // fork succeeded; we are the child; parent is terminating
- }
-
- // create new session (the magic set-me-apart system call)
- setsid();
-
- // redirect standard channels to /dev/null
- close(0); // fail silently in case 0 is closed
- if (open("/dev/null", O_RDWR, 0) == 0) { // /dev/null could be missing, I suppose...
- dup2(0, 1);
- dup2(0, 2);
- }
-
- // ready to roll
- return true;
-}
-
-
-//
-// Re-execute myself.
-// This is a pretty bad hack for libraries that are pretty broken and (essentially)
-// don't work after a fork() unless you also exec().
-//
-// WARNING: Don't even THINK of doing this in a setuid-anything program.
-//
-bool executeSelf(char **argv)
-{
- static const char reExecEnv[] = "_RE_EXECUTE";
- if (getenv(reExecEnv)) { // was re-executed
- secdebug("daemon", "self-execution complete");
- unsetenv(reExecEnv);
- return true;
- } else {
- setenv(reExecEnv, "go", 1);
- secdebug("daemon", "self-executing (ouch!)");
- execv(argv[0], argv);
- perror("re-execution");
- Syslog::error("Re-execution attempt failed");
- return false;
- }
-}
-
-
-} // end namespace Daemon
-} // end namespace Security