|
Packit |
6639f8 |
// Copyright(c) 2017-2020, Intel Corporation
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
6639f8 |
// modification, are permitted provided that the following conditions are met:
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
6639f8 |
// this list of conditions and the following disclaimer.
|
|
Packit |
6639f8 |
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
6639f8 |
// this list of conditions and the following disclaimer in the documentation
|
|
Packit |
6639f8 |
// and/or other materials provided with the distribution.
|
|
Packit |
6639f8 |
// * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
6639f8 |
// may be used to endorse or promote products derived from this software
|
|
Packit |
6639f8 |
// without specific prior written permission.
|
|
Packit |
6639f8 |
//
|
|
Packit |
6639f8 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
6639f8 |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
6639f8 |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
6639f8 |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
6639f8 |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
6639f8 |
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
6639f8 |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
6639f8 |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
6639f8 |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
6639f8 |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
6639f8 |
// POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
/*
|
|
Packit |
6639f8 |
* daemonize.c : routine to become a system daemon process.
|
|
Packit |
6639f8 |
*/
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
#include <stdlib.h>
|
|
Packit |
6639f8 |
#include <string.h>
|
|
Packit |
6639f8 |
#include <errno.h>
|
|
Packit |
6639f8 |
#include <sys/types.h>
|
|
Packit |
6639f8 |
#include <sys/stat.h>
|
|
Packit |
6639f8 |
#include <unistd.h>
|
|
Packit |
6639f8 |
#include <fcntl.h>
|
|
Packit |
6639f8 |
#include <signal.h>
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
int daemonize(void (*hndlr)(int, siginfo_t *, void *), mode_t mask, const char *dir)
|
|
Packit |
6639f8 |
{
|
|
Packit |
6639f8 |
pid_t pid;
|
|
Packit |
6639f8 |
pid_t sid;
|
|
Packit |
6639f8 |
int res;
|
|
Packit |
6639f8 |
int fd;
|
|
Packit |
6639f8 |
struct sigaction sa;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
pid = fork();
|
|
Packit |
6639f8 |
if (pid < 0) // fork() failed.
|
|
Packit |
6639f8 |
return errno;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// 1) Orphan the child process so that it runs in the background.
|
|
Packit |
6639f8 |
if (pid > 0)
|
|
Packit |
6639f8 |
exit(0);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// 2) Become leader of a new session and process group leader of new process
|
|
Packit |
6639f8 |
// group. The process is now detached from its controlling terminal.
|
|
Packit |
6639f8 |
sid = setsid();
|
|
Packit |
6639f8 |
if (sid < 0)
|
|
Packit |
6639f8 |
return errno;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// 3) Establish signal handler.
|
|
Packit |
6639f8 |
memset(&sa, 0, sizeof(sa));
|
|
Packit |
6639f8 |
sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
|
|
Packit |
6639f8 |
sa.sa_sigaction = hndlr;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = sigaction(SIGINT, &sa, NULL);
|
|
Packit |
6639f8 |
if (res < 0)
|
|
Packit |
6639f8 |
return errno;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
res = sigaction(SIGTERM, &sa, NULL);
|
|
Packit |
6639f8 |
if (res < 0)
|
|
Packit |
6639f8 |
return errno;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// 4) Orphan the child again - the session leading process terminates.
|
|
Packit |
6639f8 |
// (only session leaders can request TTY).
|
|
Packit |
6639f8 |
pid = fork();
|
|
Packit |
6639f8 |
if (pid < 0) // fork() failed.
|
|
Packit |
6639f8 |
return errno;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
if (pid > 0)
|
|
Packit |
6639f8 |
exit(0);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// 5) Set new file mode mask.
|
|
Packit |
6639f8 |
umask(mask);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// 6) change directory
|
|
Packit |
6639f8 |
res = chdir(dir);
|
|
Packit |
6639f8 |
if (res < 0)
|
|
Packit |
6639f8 |
return errno;
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
// 7) Close all open file descriptors
|
|
Packit |
6639f8 |
fd = sysconf(_SC_OPEN_MAX);
|
|
Packit |
6639f8 |
while (fd >= 0)
|
|
Packit |
6639f8 |
close(fd--);
|
|
Packit |
6639f8 |
|
|
Packit |
6639f8 |
return 0;
|
|
Packit |
6639f8 |
}
|