Как мне сопоставить файл с mmap, выделяя перед ним пустую страницу? - PullRequest
1 голос
/ 20 апреля 2020

, поэтому мне нужно отобразить файл в память, но в то же время выделить пространство перед ним для хранения вместе с ним некоторых данных.

В основном у меня есть это:

int fd = open(path, O_RDONLY);
if (fd < 0) {
    // error
}

struct stat file_info;
if (fstat(fd, &file_info) == -1) {
    close(fd);
    // error
}

int length = file_info.st_size;
int* data_pointer = mmap((void*) 0, length, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);

и я хотел бы иметь пространство перед памятью, может быть, как одну страницу или что-то, где я могу сделать это:

*data_pointer = length; // store length in space before file

// print out contents of file

const char* p = data_pointer + PAGE_SIZE;
for (int i = 0; i < *data_pointer; i++) {
    printf("%c", p[i]);
} 

printf("\n");

, чтобы я мог сделать это позже:

munmap(data_pointer, *data_pointer + PAGE_SIZE);

например. Я уже пытался выделить необходимое мне пространство с помощью malloc, а затем сказал mmap отобразить это пространство с аргументом addr, но я не думаю, что это будет работать 100% времени, так как это скорее намек, чем порядок, и я боюсь, что на некоторых платформах реализация mmap может полностью игнорировать аргумент addr.

Не могли бы вы узнать какой-нибудь лучший способ выполнить * 1025? * что я хочу, без необходимости отслеживать размер каждого mmap вызова отдельно (я делю эти указатели между динамически загружаемыми библиотеками, некоторые из которых выполняют mmap, некоторые из которых делают munmap и было бы довольно не элегантно иметь дело со всем этим, это какой-то отдельный список)?

Уже поздно ночью, и я не думаю, что здесь есть смысл, но Любая помощь или понимание будет принята с благодарностью. Большое спасибо за ваше время, прочитав это!

1 Ответ

2 голосов
/ 20 апреля 2020

Вы на правильном пути. Вам нужна недостающая часть: MAP_FIXED:

int* data_pointer = mmap((void*) 0, length + PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if(data_pointer == MAP_FAILED) {
    perror("mmap");
    exit(1);
}
if(mmap(data_pointer + PAGE_SIZE, length, PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, 0) == MAP_FAILED) {
    perror("mmap");
    exit(1);
}

Вы правильно указали, что обычно адрес является «скорее подсказкой, чем заказом», но передача MAP_FIXED делает его заказом.

Если вы беспокоитесь о безопасности, man 2 mmap говорит:

Единственное безопасное использование для MAP_FIXED - это когда диапазон адресов, заданный addr и length ранее был зарезервирован с использованием другого сопоставления

И это именно то использование.

...