Daemons are processes that live for a long time.
Started when the system is bootstrapped and terminate only when the system is shut down.
Because they don’t have a controlling terminal, we say that they run in the background.
ps -efj > o //(結果重定向到文件裡方便處理)
//e(every)代表所有進程;f(full)代表現實全部信息;j(job)job模式,結果如下圖:
Kernel processes are special and generally exist for the entire lifetime of the system.
They run with superuser privileges and have no controlling terminal and no command line.
Anything with a parent process ID of 0 is usually a kernel process started as part of the
system bootstrap procedure. (An exception is /sbin/init, which is a user-level command
started by the kernel at boot time.)
The parent of the user-level daemons is the /sbin/init process
Kernel daemons appear with their names in square brackets .
kthreadd
is the parent of the other kernel daemons.
umask
to set the file mode creation mask to a known value, usually 0.fork
and have the parent exit.
setsid
.setsid
to create a new session.#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;
pid = fork(); // 1. fork off the parent process
if (pid < 0 ) {
exit(EXIT_FAILURE);
}
if (pid > 0 ) { // 1. terminates the parent process
exit(EXIT_SUCCESS);
}
if (setsid()< 0 ) { // 2. child process becomes session leader
exit(EXIT_FAILURE);
}
signal(SIGCHLD, SIG_IGN);
signal(SIGHUP,SIG_IGN);
pid = fork(); // 3. fork off the second time
if (pid< 0 ) {
exit(EXIT_FAILURE);
}
if (pid> 0 ) { // terminates the parents
exit(EXIT_SUCCESS);
}
umask( 0 ); // 4. set new file permissions
chdir( " / " ); // 5. change the working directory
int x; // 6. close all open file descriptors
for (x=sysconf(_SC_OPEN_MAX); x> 0 ; x-- )
{
close(x);
}
/*
* 6. Attach file descriptors 0, 1, and 2 to /dev/null.
*/
int fd0, fd1, fd2;
fd0 = open("/dev/null", O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
openlog( " firstdaemon " , LOG_PID, LOG_DAEMON);
}
int main()
{
skeleton_daemon();
while ( 1 )
{
syslog(LOG_NOTICE, " First daemon started. " );
sleep( 20 );
break ;
}
syslog(LOG_NOTICE, " First daemon terminated. " );
closelog();
return EXIT_SUCCESS;
}
We also don’t want each daemon writing its own error messages into a separate file. It would be a headache for anyone administering the system to keep up with which daemon writes to which log file and to check these files on a regular basis. A central daemon error-logging facility is required.
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
int setlogmask(int maskpri);
/* Returns: previous log priority mask value */
openlog
is optional. If it’s not called, the first time syslog is called, openlog is called automatically.closelog
is also optional. It closes the descriptor being used to communicate with the syslogd daemon.openlog
function: void openlog(const char *ident, int option, int facility);
indent
The name of the program.
option
![enter image description here](http://images2015.cnblogs.com/blog/707631/201510/707631-20151030150547419-282654541.jpg)
facility
syslog
function:void syslog(int priority, const char *format, ...);
vsprintf
function for formatting.#include <syslog.h>
int main( int argc, char ** argv)
{
openlog( " test error " , LOG_CONS | LOG_PID, 0 );
syslog(LOG_INFO, " This is a syslog test message generated by program '%s'\n " , argv[ 0 ]);
closelog();
return 0 ;
}
cron
instance…
If each daemon creates a file with a fixed name and places a write lock on the entire file, only one such write lock will be allowed to be created. Successive attempts to create write locks will fail, serving as an indication to successive copies of the daemon that another instance is already running.
Example: https://codeshare.io/rYG2s
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <syslog.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#define LOCKFILE "/var/run/daemon.pid"
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
extern int lockfile(int);
int
already_running(void)
{
int fd;
char buf[16];
fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
if (fd < 0) {
syslog(LOG_ERR, "can't open %s: %s", LOCKFILE, strerror(errno));
exit(1);
}
if (lockfile(fd) < 0) { //lockfile is implement in CH14
if (errno == EACCES || errno == EAGAIN) {
close(fd);
return(1);
}
syslog(LOG_ERR, "can't lock %s: %s", LOCKFILE, strerror(errno));
exit(1);
}
ftruncate(fd, 0);
sprintf(buf, "%ld", (long)getpid());
write(fd, buf, strlen(buf)+1);
return(0);
}
We need to truncate the file, because the previous instance of the daemon might
have had a process ID larger than ours, with a larger string length. For example, if the
previous instance of the daemon was process ID 12345, and the new instance is process
ID 9999, when we write the process ID to the file, we will be left with 99995 in the file.
Truncating the file prevents data from the previous daemon appearing as if it applies to
the current daemon.
The lock file is usually stored in /var/run
.
name.pid
, where name is the name of the daemon or the service. For example, the name of the Linux cron daemon’s lock file is /var/run/crond.pid
.The configuration options are usually stored in /etc
.
name.conf
, where name
is the name of the daemon or the service. For example, the configuration for the syslogd
daemon is usually /etc/syslog.conf
.Daemons can be started from the command line, but they are usually started from one of the system initialization scripts (/etc/rc*
or /etc/init.d/*
).
If a daemon has a configuration file, the daemon reads the file when it starts and won’t look at it again.
To avoid this, some daemons will catch SIGHUP and reread their configuration files when they receive the signal.