Files
CS-LABS/mine/lab_2/old/task12.c
2025-12-10 16:50:28 +07:00

97 lines
2.9 KiB
C

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#define RBUFSZ 4096
#define WBUFSZ 4096
static void die_perror(const char *what, const char *path, int exit_code) {
int saved = errno;
char msg[512];
if (path) {
snprintf(msg, sizeof(msg), "%s: %s: %s\n", what, path, strerror(saved));
} else {
snprintf(msg, sizeof(msg), "%s: %s\n", what, strerror(saved));
}
(void) write(STDERR_FILENO, msg, strlen(msg));
_exit(exit_code);
}
static long long parse_ll(const char *s) {
char *end = NULL;
errno = 0;
long long v = strtoll(s, &end, 10);
if (errno != 0 || end == s || *end != '\0' || v < 0) {
errno = EINVAL;
return -1;
}
return v;
}
int main(int argc, char *argv[]) {
if (argc != 5) {
const char *usage =
"Usage: lab2_var12 <input.txt> <output.txt> <max_replacements> <library.so>\n"
"Variant 12: Load text processing library dynamically and process file.\n"
"Library should provide 'process_text' function.\n";
(void) write(STDERR_FILENO, usage, strlen(usage));
return -1;
}
const char *in_path = argv[1];
const char *out_path = argv[2];
long long cap = parse_ll(argv[3]);
const char *lib_path = argv[4];
if (cap < 0) {
die_perror("invalid max_replacements", argv[3], -1);
}
// Динамически загружаем библиотеку
void *lib_handle = dlopen(lib_path, RTLD_LAZY);
if (!lib_handle) {
const char *error_msg = dlerror();
char msg[512];
snprintf(msg, sizeof(msg), "dlopen failed: %s\n", error_msg ? error_msg : "unknown error");
(void) write(STDERR_FILENO, msg, strlen(msg));
return -1;
}
// Получаем указатель на функцию обработки текста
long long (*process_text)(const char*, const char*, long long) =
(long long (*)(const char*, const char*, long long)) dlsym(lib_handle, "process_text");
if (!process_text) {
const char *error_msg = dlerror();
char msg[512];
snprintf(msg, sizeof(msg), "dlsym failed: %s\n", error_msg ? error_msg : "unknown error");
(void) write(STDERR_FILENO, msg, strlen(msg));
dlclose(lib_handle);
return -1;
}
// Вызываем функцию из библиотеки
long long result = process_text(in_path, out_path, cap);
if (result < 0) {
die_perror("process_text failed", NULL, -1);
}
// Закрываем библиотеку
dlclose(lib_handle);
// Выводим результат
char res[64];
int m = snprintf(res, sizeof(res), "%lld\n", result);
if (m > 0) {
(void) write(STDOUT_FILENO, res, (size_t) m);
}
return 0;
}