rgz!
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
// fifo_server_daemon.c
|
||||
#include <stdio.h> // fprintf, stderr (для отладки)
|
||||
#include <stdio.h> // fprintf (для ошибок до старта)
|
||||
#include <stdlib.h> // malloc, free, exit, strtoll
|
||||
#include <string.h> // strlen, strerror
|
||||
#include <unistd.h> // read, write, close, unlink, getpid, chdir
|
||||
#include <fcntl.h> // open, флаги O_RDONLY/O_WRONLY
|
||||
#include <unistd.h> // read, write, close, unlink
|
||||
#include <fcntl.h> // open, O_RDONLY, O_WRONLY
|
||||
#include <sys/types.h> // типы для системных вызовов
|
||||
#include <sys/stat.h> // mkfifo, права доступа, umask
|
||||
#include <errno.h> // errno
|
||||
#include <signal.h> // signal, SIGINT, SIGTERM, SIGPIPE, SIGHUP
|
||||
#include <signal.h> // signal, SIGINT, SIGTERM, SIGPIPE
|
||||
#include <syslog.h> // syslog, openlog, closelog
|
||||
|
||||
#define FIFO_REQUEST "/tmp/fifo_request"
|
||||
@@ -18,6 +18,7 @@ volatile sig_atomic_t running = 1;
|
||||
|
||||
void signal_handler(int sig) {
|
||||
(void)sig;
|
||||
syslog(LOG_INFO, "Signal %d received, stopping...", sig);
|
||||
running = 0;
|
||||
}
|
||||
|
||||
@@ -32,7 +33,7 @@ static long long parse_ll(const char *s) {
|
||||
return v;
|
||||
}
|
||||
|
||||
// логика обработки текста
|
||||
// логика обработки текста (как в исходном сервере)
|
||||
long long process_data(const char *input, size_t input_len,
|
||||
char *output, size_t output_size,
|
||||
long long max_replacements) {
|
||||
@@ -65,50 +66,7 @@ long long process_data(const char *input, size_t input_len,
|
||||
return total_replacements;
|
||||
}
|
||||
|
||||
static void daemonize(void) {
|
||||
pid_t pid;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
exit(1);
|
||||
if (pid > 0)
|
||||
exit(0);
|
||||
|
||||
if (setsid() < 0)
|
||||
exit(1);
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
exit(1);
|
||||
if (pid > 0)
|
||||
exit(0);
|
||||
|
||||
if (chdir("/") < 0)
|
||||
exit(1);
|
||||
|
||||
umask(0);
|
||||
|
||||
// аккуратно закрыть дескрипторы:
|
||||
for (int fd = 0; fd < 1024; fd++)
|
||||
close(fd);
|
||||
|
||||
int devnull = open("/dev/null", O_RDWR);
|
||||
if (devnull >= 0) {
|
||||
dup2(devnull, STDIN_FILENO);
|
||||
dup2(devnull, STDOUT_FILENO);
|
||||
dup2(devnull, STDERR_FILENO);
|
||||
if (devnull > 2)
|
||||
close(devnull);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// debug-вывод в stderr, до превращения в демона
|
||||
fprintf(stderr, "DEBUG: starting main, argc=%d\n", argc);
|
||||
fflush(stderr);
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <max_replacements>\n", argv[0]);
|
||||
return 1;
|
||||
@@ -120,12 +78,11 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// превращаемся в демона
|
||||
daemonize();
|
||||
/* работаем в foreground, демонизацию делает systemd (Type=simple) */
|
||||
|
||||
// настраиваем syslog
|
||||
openlog("fifo_server_daemon", LOG_PID | LOG_NDELAY, LOG_DAEMON);
|
||||
syslog(LOG_INFO, "Server daemon started, max_replacements=%lld", max_replacements);
|
||||
syslog(LOG_INFO, "Server started (systemd), max_replacements=%lld",
|
||||
max_replacements);
|
||||
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
@@ -152,6 +109,11 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
while (running) {
|
||||
int fd_req = open(FIFO_REQUEST, O_RDONLY);
|
||||
if (!running) { // сигнал пришёл во время open
|
||||
if (fd_req != -1)
|
||||
close(fd_req);
|
||||
break;
|
||||
}
|
||||
if (fd_req == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
@@ -166,15 +128,23 @@ int main(int argc, char *argv[]) {
|
||||
close(fd_req);
|
||||
free(input_buffer);
|
||||
free(output_buffer);
|
||||
continue;
|
||||
break; // выходим, не крутимся дальше
|
||||
}
|
||||
|
||||
ssize_t bytes_read = read(fd_req, input_buffer, BUFFER_SIZE - 1);
|
||||
close(fd_req);
|
||||
|
||||
if (!running) { // сигнал во время read
|
||||
free(input_buffer);
|
||||
free(output_buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytes_read <= 0) {
|
||||
free(input_buffer);
|
||||
free(output_buffer);
|
||||
if (!running)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -193,6 +163,8 @@ int main(int argc, char *argv[]) {
|
||||
syslog(LOG_ERR, "open response FIFO failed: %s", strerror(errno));
|
||||
free(input_buffer);
|
||||
free(output_buffer);
|
||||
if (!running)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -211,7 +183,7 @@ int main(int argc, char *argv[]) {
|
||||
free(output_buffer);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "Server daemon stopping, cleaning up");
|
||||
syslog(LOG_INFO, "Server stopping, cleaning up");
|
||||
unlink(FIFO_REQUEST);
|
||||
unlink(FIFO_RESPONSE);
|
||||
closelog();
|
||||
|
||||
4
rgz/input.txt
Normal file
4
rgz/input.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
abacaba
|
||||
hello
|
||||
abcaa
|
||||
aaaaa
|
||||
Reference in New Issue
Block a user