// 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; } // во всех парах одинаковых подряд символов второй -> пробел 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]; output[out_pos++] = c; if (i + 1 < len && input[i] == input[i + 1]) { // вторая буква пары if (out_pos < out_size - 1) { output[out_pos++] = ' '; replacements++; } i++; // пропускаем второй символ исходного текста } } 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; }