О демонах
Прежде чем писать настоящих демонов попробуем начать с чего-то попроще.
Надо понимать, что демон — это программа, которая работает потенциально бесконечно долго и ждет указаний.
Возможно самый близкий вам пример демона будет СУБД. То есть это некий сервис, у которого есть набор файлов, которыми он управляет, а если его хорошо попросить он с вами еще и какой-то информацией поделится
Попробуем написать программу которая будет мониторить папку и сообщать об изменениях которые в ней происходит.
Для отслеживания изменений в linux используется механизм inotify
, про него даже можно прочитать в мануале
но там много английских непонятных слов, так что давайте рассмотрим, как с ним работать на примере.
Создаем болванку проекта
Создадим проект
создадим файлик main.cpp и запишем в него
#include <iostream>
#include <sys/inotify.h> // для работы с inotify
#include <unistd.h> // для чтения изменений
using namespace std;
int main(int argc, char* argv[]) {
cout << "проверка" << endl;
return 0;
}
можно скомпилировать и убедится, что все работает
Создаем Makefile
Кстати, давайте, чтобы не тратить время постоянно на пересборку и запуск программы, создадим специальный файлик Makefile и пропишем в него команды которые соберут проект, а потом запустят

и напишем в него
build:
g++ main.cpp -o main
./main
очень важно чтобы отступы были сделаны табами.
А теперь смотрите, достаточно написать
и наша программа автоматически соберется и запуститься.

если вы не хотите, чтобы писались команды, которые использовались для сборки или запуска, добавьте перед ними @
build:
@g++ main.cpp -o main
@./main

Вообще, Makefile – это специальные файлы с помощью которых упрощают процесс сборки для С/C++ проектов, в том числе и ядро линукс использует Makefile, но они как правило очень большие. И есть даже специальные утилиты для генерации Makefile`ов
Мониторим папку с inotify
Схема работы с inotify в принципе достаточно простая
#include <iostream>
#include <sys/inotify.h>
#include <unistd.h>
using namespace std;
int main(int argc, char* argv[]) {
// создаем файловый дескриптор для отслеживания
int inotify_fd = inotify_init();
// подключаем к inotify_fd мониторинг,
// "/home/m" -- эта папка которую мониторим
// IN_MODIFY | IN_CREATE | IN_DELETE -- события которые мониторим
int watch_fd = inotify_add_watch(inotify_fd, "/home/m", IN_MODIFY | IN_CREATE | IN_DELETE);
// А ТУТ СЕЙЧАС ХИТРОСТИ НАЧНУТЬСЯ
return 0;
}
так как мы пишем демон, а демон работает бесконечно долго, то мы заводим бесконечный цикл и в этом цикле просто пытаемся читать с файлового дескриптора inotify_fd
// это мы выше написали
int inotify_fd = inotify_init();
int watch_fd = inotify_add_watch(inotify_fd, "/home/m", IN_MODIFY | IN_CREATE | IN_DELETE);
// а тут новое пошло
// сначала бесконечный цикл
while(true) {
char buffer[10000]; // буфер под события изменений
// подключаемся к inotify_fd на чтение
// эта строчка блокирует программу,
// пока не произойдет какое-нибудь изменение
int length = read(inotify_fd, buffer, 10000);
// так как событие может прийти несколько то надо их все обойти
int i = 0;
while (i < length) {
// вытаскиваем инфу по событию
struct inotify_event *event = (struct inotify_event *)&buffer[i];
// проверим тип события
if (event->mask & IN_MODIFY) {
// и выведем сообщение о событии
// в event->name лежит имя файла
cout << "изменился" << event->name << endl;
}
else if (event->mask & IN_CREATE) {
cout << "создали файл" << event->name << endl;
}
// сдвигаемся на следующее событие
i += sizeof(struct inotify_event) + event->len;
}
}
inotify_rm_watch(inotify_fd, watch_fd);
close(inotify_fd);
return 0;
можно потестить

Теперь попробуйте сделать задание. Так как в задании надо читать и писать в файл, вот вам болванки кода, под эти операции.
Чтобы прочитать содержимое файла, используйте следующий код
std::ifstream ifs("/home/m/file.txt"); // читаем файл по пути
std::string content; // переменная под содержимое файл
if (ifs.is_open()) {
// считываем содержимое файла в переменную
content.assign((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
ifs.close();
}
чтобы записать что-нибудь в файл использует такой код
ofstream ofs("/home/m/file.txt");
if (ofs.is_open()) {
ofs << str << endl;
ofs.close();
}
Задание
Напишите программу, которая мониторит папку и пишет информацию об изменениях в этой папке в файл лога, примерно в таком виде
---
Файл file.txt добавлен
---
Файл file.txt изменился, его новое содержимое:
очень длинной содержимое файла
в несколько строк даже
---
Файл file.txt удален
...