What Will You Learn?
In this tutorial, you will understand what a daemon process is, how it differs from regular processes, why daemons are important in Linux systems, and see real-world examples of daemons you already use every day.
Key Concepts
A daemon is a special type of process in Linux/Unix systems. Think of a daemon as a servant (the word comes from Greek mythology โ a helper spirit) that quietly does work in the background without bothering the user.
A daemon has two defining characteristics:
A daemon is usually created at system startup and keeps running until the system shuts down. It is not a short command that exits after doing one task.
A daemon runs in the background and has no terminal attached to it. This means the kernel will never send terminal-related signals like SIGINT (Ctrl+C), SIGTSTP (Ctrl+Z), or SIGHUP to it.
Because a daemon has no controlling terminal, you cannot interact with it directly. It does its work silently. This is by design โ daemons are meant to provide services, not to have conversations with users.
Your Linux system is running many daemons right now. Here are the most important ones:
| Daemon Name | Purpose | Runs As |
|---|---|---|
cron |
Executes scheduled commands (cron jobs) | root |
sshd |
Accepts remote logins via SSH protocol | root |
inetd |
Internet superserver โ listens on TCP/IP ports and launches server programs | root |
httpd / nginx |
Web server daemon serving HTTP pages | www-data / nobody |
syslogd |
System log daemon โ collects and stores log messages | root |
bluetoothd |
Manages Bluetooth connections and profiles | root |
Notice that most daemons have names ending with the letter ‘d’. This is a naming convention (not a rule) โ sshd, httpd, crond, syslogd. The ‘d’ stands for daemon.
Some daemons in Linux are not user-space programs at all โ they are kernel threads. Their code lives inside the kernel itself, and they are usually created during system boot.
When you run ps aux or ps -ef, kernel thread daemons appear with their names inside square brackets [ ]:
$ ps aux | head -20
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 169584 13132 ? Ss 09:00 0:01 /sbin/init
root 2 0.0 0.0 0 0 ? S 09:00 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 09:00 0:00 [rcu_gp]
root 9 0.0 0.0 0 0 ? I< 09:00 0:00 [mm_percpu_wq]
root 10 0.0 0.0 0 0 ? S 09:00 0:00 [ksoftirqd/0]
root 11 0.0 0.0 0 0 ? I 09:00 0:00 [rcu_sched]
root 15 0.0 0.0 0 0 ? S 09:00 0:00 [migration/0]
root 90 0.0 0.0 0 0 ? S 09:00 0:00 [kswapd0]
root 120 0.0 0.0 0 0 ? S 09:00 0:00 [pdflush]
The [pdflush] daemon is a classic example โ it periodically flushes dirty memory pages (modified data in the buffer cache) to disk to prevent data loss. Another example is [kswapd0] which manages memory swapping.
| Property | Regular Process | Daemon Process |
|---|---|---|
| Controlling Terminal | Has one (stdin/stdout/stderr connected) | None โ detached |
| Lifetime | Lives as long as the user runs it | From system boot to shutdown |
| Parent Process | Shell that launched it | init (PID 1) |
| Session | Same session as the terminal | Its own session (setsid) |
| Signals (SIGINT etc.) | Receives terminal signals | Never receives terminal signals |
| Working Directory | Current shell directory | / (root) โ never blocks unmount |
This is one of the most important things to understand. When a process has a controlling terminal:
Sent when user presses Ctrl+C โ kills the process
Sent when user presses Ctrl+Z โ suspends the process
Sent when terminal closes โ normally kills the process
A daemon must never be killed accidentally by terminal events. By detaching from any terminal, the kernel simply has no way to send these signals to the daemon โ making it robust and always-running.
This program checks if the current process has a controlling terminal. A daemon should have none. We use ctermid() and open() to test this.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
/*
* is_daemon() - returns 1 if process has no controlling terminal
* A daemon should always return 1 from this function
*/
int is_daemon(void)
{
/* Try to open the controlling terminal.
* /dev/tty always refers to the process's controlling terminal.
* If the open fails with ENXIO, there is no controlling terminal. */
int fd = open("/dev/tty", O_RDWR);
if (fd == -1) {
/* No controlling terminal โ this is a daemon */
return 1;
}
close(fd);
return 0;
}
int main(void)
{
if (is_daemon()) {
printf("This process IS a daemon (no controlling terminal)\n");
} else {
printf("This process is NOT a daemon (has a controlling terminal)\n");
printf("Try running: nohup ./a.out & to simulate daemon behavior\n");
}
/* Show process details */
printf("PID = %d\n", getpid());
printf("PPID = %d\n", getppid());
printf("SID = %d\n", getsid(0));
return 0;
}
How to compile and test:
gcc -o check_daemon check_daemon.c
./check_daemon
# Output: This process is NOT a daemon (has a controlling terminal)
# Now run it as a background process after detaching from terminal:
nohup ./check_daemon &
# Check the output file: cat nohup.out
This program reads /proc to find all processes that have no controlling terminal (TT = ‘?’), which is the hallmark of daemon processes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <ctype.h>
/*
* Read a field from /proc/[pid]/stat
* The 7th field (index 6) is the tty_nr โ 0 means no controlling terminal
*/
int has_controlling_terminal(int pid)
{
char path[64];
FILE *f;
char buf[512];
snprintf(path, sizeof(path), "/proc/%d/stat", pid);
f = fopen(path, "r");
if (!f) return -1;
if (!fgets(buf, sizeof(buf), f)) {
fclose(f);
return -1;
}
fclose(f);
/* Parse stat file: pid (comm) state ppid pgrp session tty_nr ... */
int tty_nr;
/* Skip past the comm field which may contain spaces in () */
char *p = strrchr(buf, ')');
if (!p) return -1;
p += 2; /* skip ') ' */
/* Now we have: state ppid pgrp session tty_nr */
char state;
int ppid, pgrp, session;
sscanf(p, "%c %d %d %d %d", &state, &ppid, &pgrp, &session, &tty_nr);
return tty_nr != 0; /* nonzero tty_nr means has a terminal */
}
int main(void)
{
DIR *dir;
struct dirent *entry;
dir = opendir("/proc");
if (!dir) {
perror("opendir /proc");
return 1;
}
printf("%-8s %-30s %s\n", "PID", "NAME", "STATUS");
printf("%-8s %-30s %s\n", "---", "----", "------");
while ((entry = readdir(dir)) != NULL) {
/* Only process numeric entries (PIDs) */
int pid = atoi(entry->d_name);
if (pid <= 0) continue;
/* Read process name from /proc/[pid]/comm */
char comm_path[64], name[256];
snprintf(comm_path, sizeof(comm_path), "/proc/%d/comm", pid);
FILE *f = fopen(comm_path, "r");
if (!f) continue;
if (!fgets(name, sizeof(name), f)) { fclose(f); continue; }
fclose(f);
name[strcspn(name, "\n")] = 0; /* strip newline */
int has_tty = has_controlling_terminal(pid);
if (has_tty == 0) {
/* No controlling terminal = likely a daemon */
printf("%-8d %-30s DAEMON (no tty)\n", pid, name);
}
}
closedir(dir);
return 0;
}
Compile and run:
gcc -o list_daemons list_daemons.c
sudo ./list_daemons | head -30
Answer: A daemon is (1) long-lived โ it typically runs from system startup to shutdown, and (2) it has no controlling terminal โ it runs in the background detached from any terminal.
Answer: Without a controlling terminal, the kernel never automatically generates job-control or terminal-related signals such as SIGINT, SIGTSTP, and SIGHUP for the process. This prevents the daemon from being accidentally killed or suspended by terminal events.
Answer: Kernel thread daemons are shown with their names inside square brackets [ ] in ps output. For example:
[pdflush], [kswapd0], [kthreadd].Answer: By convention (not a strict rule), daemon programs have names ending with the letter ‘d’. Examples: sshd, httpd, crond, syslogd, bluetoothd. The ‘d’ stands for daemon.
Answer: Most daemons are children of the init process (PID 1). This happens because during daemon creation, the original parent exits, and the child (which continues as the daemon) gets re-parented to init. init is responsible for managing orphaned processes.
Answer: A kernel thread daemon runs entirely within the kernel โ its code is part of the kernel, it has no user-space memory mapping, and it is shown in ps with square brackets. A user-space daemon is a normal process that has been programmed to detach from its terminal and run in the background, like sshd or httpd.
Answer: The
/proc/[pid]/stat file contains the tty_nr field (7th field). If tty_nr is 0, the process has no controlling terminal โ indicating a daemon. You can also check the TT column in ps output โ a ‘?’ means no controlling terminal.Chapter Summary
A daemon is a long-lived background process with no controlling terminal. It is typically created at system startup, runs as a child of init, and is never affected by keyboard signals. Real daemons include cron, sshd, and syslogd. Kernel thread daemons appear in square brackets in ps output.
