// mq_server.c #include #include #include #include #include #include #include #include #include #include // POSIX message queues #define MQ_REQUEST "/mq_request" #define MQ_RESPONSE "/mq_response" #define MQ_MAXMSG 10 #define BUFFER_SIZE 4096 // msgsize очереди и размер буферов volatile sig_atomic_t running = 1; void signal_handler(int sig) { (void) sig; running = 0; } // Заменить каждый третий символ на пробел // (позиции 3, 6, 9, ... в исходном тексте) long long process_text(const char *input, size_t len, char *output, size_t out_size) { if (out_size == 0) return -1; long long replacements = 0; size_t out_pos = 0; for (size_t i = 0; i < len && out_pos < out_size - 1; i++) { char c = input[i]; // считаем позиции с 1 size_t pos = i + 1; if (pos % 3 == 0) { output[out_pos++] = ' '; replacements++; } else { output[out_pos++] = c; } } output[out_pos] = '\0'; return replacements; } int main(void) { struct mq_attr attr; mqd_t mq_req = (mqd_t) -1; mqd_t mq_resp = (mqd_t) -1; memset(&attr, 0, sizeof(attr)); attr.mq_flags = 0; attr.mq_maxmsg = MQ_MAXMSG; attr.mq_msgsize = BUFFER_SIZE; attr.mq_curmsgs = 0; mq_unlink(MQ_REQUEST); mq_unlink(MQ_RESPONSE); mq_req = mq_open(MQ_REQUEST, O_CREAT | O_RDONLY, 0666, &attr); if (mq_req == (mqd_t) -1) { fprintf(stderr, "ERROR: mq_open(%s) failed: %s\n", MQ_REQUEST, strerror(errno)); return 1; } mq_resp = mq_open(MQ_RESPONSE, O_CREAT | O_WRONLY, 0666, &attr); if (mq_resp == (mqd_t) -1) { fprintf(stderr, "ERROR: mq_open(%s) failed: %s\n", MQ_RESPONSE, strerror(errno)); mq_close(mq_req); mq_unlink(MQ_REQUEST); return 1; } printf("=== MQ Server started ===\n"); printf("Request queue : %s\n", MQ_REQUEST); printf("Response queue: %s\n", MQ_RESPONSE); signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); char in_buf[BUFFER_SIZE]; char out_buf[BUFFER_SIZE]; while (running) { unsigned int prio = 0; ssize_t bytes_read = mq_receive(mq_req, in_buf, sizeof(in_buf), &prio); if (bytes_read < 0) { if (errno == EINTR && !running) break; if (errno == EINTR) continue; fprintf(stderr, "ERROR: mq_receive failed: %s\n", strerror(errno)); break; } if (bytes_read >= (ssize_t) sizeof(in_buf)) bytes_read = sizeof(in_buf) - 1; in_buf[bytes_read] = '\0'; printf("Received request: %zd bytes\n", bytes_read); long long repl = process_text(in_buf, (size_t) bytes_read, out_buf, sizeof(out_buf)); if (repl < 0) { const char *err_msg = "ERROR: processing failed\n"; mq_send(mq_resp, err_msg, strlen(err_msg), 0); continue; } printf("Replacements done: %lld\n", repl); char resp_buf[BUFFER_SIZE]; size_t processed_len = strlen(out_buf); if (processed_len + 64 >= sizeof(resp_buf)) { const char *err_msg = "ERROR: response too long\n"; mq_send(mq_resp, err_msg, strlen(err_msg), 0); continue; } memcpy(resp_buf, out_buf, processed_len); int n = snprintf(resp_buf + processed_len, sizeof(resp_buf) - processed_len, "\nREPLACEMENTS:%lld\n", repl); if (n < 0) { const char *err_msg = "ERROR: snprintf failed\n"; mq_send(mq_resp, err_msg, strlen(err_msg), 0); continue; } size_t resp_len = processed_len + (size_t) n; if (mq_send(mq_resp, resp_buf, resp_len, 0) == -1) { fprintf(stderr, "ERROR: mq_send failed: %s\n", strerror(errno)); continue; } printf("Response sent: %zu bytes\n\n", resp_len); } printf("Server shutting down...\n"); mq_close(mq_req); mq_close(mq_resp); mq_unlink(MQ_REQUEST); mq_unlink(MQ_RESPONSE); return 0; }