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