Linux Daemon Writing HOWTO
http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
int main(void) {
/* Our process ID and Session ID */
pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* Daemon-specific initialization goes here */
/* The Big Loop */
while (1) {
/* Do some task here ... */
sleep(30); /* wait 30 seconds */
}
exit(EXIT_SUCCESS);
}
From here, you can use this skeleton to write your own daemons. Be sure to add in your own logging (or use the syslog facility), and code defensively, code defensively, code defensively!
#include
#include
#include
#include
#include
#include
int main(int argc, char* argv[])
{
FILE *fp= NULL;
pid_t process_id = 0;
pid_t sid = 0;
// Create child process
process_id = fork();
// Indication of fork() failure
if (process_id < 0)
{
printf("fork failed!\n");
// Return failure in exit status
exit(1);
}
// PARENT PROCESS. Need to kill it.
if (process_id > 0)
{
printf("process_id of child process %d \n", process_id);
// return success in exit status
exit(0);
}
//unmask the file mode
umask(0);
//set new session
sid = setsid();
if(sid < 0)
{
// Return failure
exit(1);
}
// Change the current working directory to root.
chdir("/");
// Close stdin. stdout and stderr
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// Open a log file in write mode.
fp = fopen ("Log.txt", "w+");
while (1)
{
//Dont block context switches, let the process sleep for some time
sleep(1);
fprintf(fp, "Logging info...\n");
fflush(fp);
// Implement and call some function that does core work for this daemon.
}
fclose(fp);
return (0);
}
$ gcc -Wall deamon.c -o deamon
$ sudo ./deamon
process_id of child process 2936
$ tail -f /Log.txt
Logging info...
Logging info...
Logging info...
Logging info...
Logging info...
Logging info...
Logging info...
Logging info...
Logging info...
創建 Daemon 程式
http://felix-lin.com/linux/%E5%89%B5%E5%BB%BA-daemon-%E7%A8%8B%E5%BC%8F/
#include <syslog.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#define MAXFD 64
void
daemon_init(
const
char
*pname,
int
facility)
{
int
i;
pid_t pid;
if
( (pid = fork()) != 0)
exit
(0);
setsid();
signal
(SIGHUP, SIG_IGN);
if
( (pid = fork()) != 0)
exit
(0);
chdir(
"/"
);
umask(0);
for
(i=0; i
close(i);
openlog(pname, LOG_PID, facility);
}
int
main()
{
int
ii = 10;
daemon_init(
"TEST"
, 0);
while
(ii) {
syslog(LOG_INFO,
"daemon example ... %d"
, ii--);
sleep(10);
}
exit
(0);
}
/*
* daemonize.c
* This example daemonizes a process, writes a few log messages,
* sleeps 20 seconds and terminates afterwards.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
static void skeleton_daemon()
{
pid_t pid;
/* Fork off the parent process */
pid = fork();
/* An error occurred */
if (pid < 0)
exit(EXIT_FAILURE);
/* Success: Let the parent terminate */
if (pid > 0)
exit(EXIT_SUCCESS);
/* On success: The child process becomes session leader */
if (setsid() < 0)
exit(EXIT_FAILURE);
/* Catch, ignore and handle signals */
//TODO: Implement a working signal handler */
signal(SIGCHLD, SIG_IGN);
signal(SIGHUP, SIG_IGN);
/* Fork off for the second time*/
pid = fork();
/* An error occurred */
if (pid < 0)
exit(EXIT_FAILURE);
/* Success: Let the parent terminate */
if (pid > 0)
exit(EXIT_SUCCESS);
/* Set new file permissions */
umask(0);
/* Change the working directory to the root directory */
/* or another appropriated directory */
chdir("/");
/* Close all open file descriptors */
int x;
for (x = sysconf(_SC_OPEN_MAX); x>0; x--)
{
close (x);
}
/* Open the log file */
openlog ("firstdaemon", LOG_PID, LOG_DAEMON);
}
/* firstdaemon.c */
int main()
{
skeleton_daemon();
while (1)
{
//TODO: Insert daemon code here.
syslog (LOG_NOTICE, "First daemon started.");
sleep (20);
break;
}
syslog (LOG_NOTICE, "First daemon terminated.");
closelog();
return EXIT_SUCCESS;
}
+------+------+------+------+-----+-------+------+------+------+-----+
| PPID | PID | PGID | SID | TTY | TPGID | STAT | UID | TIME | CMD |
+------+------+------+------+-----+-------+------+------+------+-----+
| 1 | 3387 | 3386 | 3386 | ? | -1 | S | 1000 | 0:00 | ./ |
+------+------+------+------+-----+-------+------+------+------+-----+
What you should see here is:
- The daemon has no controlling terminal (TTY = ?)
- The parent process ID (PPID) is 1 (The init process)
- The PID != SID which means that our process is NOT the session leader
(because of the second fork())
- Because PID != SID our process can't take control of a TTY again
Reading the syslog:
firstdaemon[3387]: First daemon started.
firstdaemon[3387]: First daemon terminated.
daemon(3) - Linux man page
http://linux.die.net/man/3/daemon
int daemon(int nochdir, int noclose);
If nochdir is zero, daemon() changes the calling process's current working directory to the root directory ("/"); otherwise, the current working directory is left unchanged.
If
noclose is zero,
daemon() redirects standard input, standard output and standard error to
/dev/null; otherwise, no changes are made to these file descriptors.
example
Calling daemon() will detach your process from a controlling tty, close stdin/stdout, and will also fork & exit the parent so that your process becomes a child of init. For debugging, I added a -f option. If you specify -f, the program won't call daemon() so that you'll get your printfs. If you don't specify -f, the application will call daemon() and you won't see any more printfs.
#include
#include
#include
#include
#include
int main(int argc, char** argv)
{
bool run_in_foreground;
int loop_count;
int c;
opterr = 0;
while((c = getopt(argc, argv, "f")) != -1)
{
switch(c)
{
case 'f':
run_in_foreground = true;
break;
case '?':
printf("Unrecognized option '%c'.\n", optopt);
return 1;
default:
abort();
}
}
printf("This is my application...\n");
if(!run_in_foreground)
{
printf("This is the last message you'll see, since I'm going to call daemon()\n");
daemon(0,0);
}
else
{
printf("I'm in the foreground, so you'll still see my printfs\n");
}
for(loop_count = 0; loop_count < 10; loop_count++)
{
printf("Loop count is %d\n", loop_count);
sleep(1);
}
return 0;
}
Upstart Intro, Cookbook and Best Practises
http://upstart.ubuntu.com/getting-started.html
http://upstart.ubuntu.com/cookbook/
Runit
http://smarden.org/runit/
http://smarden.org/runit/runsv.8.html
start-stop-daemon - start and stop system daemon programs
http://manpages.ubuntu.com/manpages/precise/man8/start-stop-daemon.8.html
systemd is a system and service manager for Linux
https://wiki.archlinux.org/index.php/systemd
Making scripts run at boot time with Debian
https://www.debian-administration.org/article/28/Making_scripts_run_at_boot_time_with_Debian
http://xmodulo.com/how-to-automatically-start-program-on-boot-in-debian.html
https://help.ubuntu.com/community/UbuntuBootupHowto
How to run a program when boot up?
http://en.kioskea.net/faq/3348-ubuntu-executing-a-script-at-startup-and-shutdown
To execute a script at startup of Ubuntu
- Edit /etc/rc.local and add your commands
- The script must always end with exit 0
To execute a script upon rebooting Ubuntu
- Put your script in /etc/rc0.d
- Make it executable (sudo chmod +x myscript)
- Note: The scripts in this directory are executed in alphabetical order
The name of your script must begin with K99 to run at the right time.
To execute a script at shutdown
- Put your script in /etc/rc6.d
- Make it executable (sudo chmod +x myscript)
- Note: The scripts in this directory are executed in alphabetical order
The name of your script must begin with K99 to run at the right time