/*
Программа для иллюстрации работы с memory mapped файлом*/
int main(void)
{
int fd; /* Файловый дескриптор для файла, в котором
будет храниться наша информация*/
size_t length; /* Длина отображаемой части файла */
int i;
/* Ниже следует описание типа структуры, которыми
мы забъем файл, и двух указателей на подобный тип. Указатель ptr
будет использоваться в качестве начального адреса выделенной
области памяти, а указатель tmpptr для
перемещения внутри этой области. */
struct A {
double
f;
double f2;
} *ptr, *tmpptr;
/* Открываем файл с одновремееным его созданием (если
такого файла не было). Права доступа к файлу при создании определяем как read-write
для всех категорий пользователей (0666). Из-за ошибки в Linux, мы будем вынуждены
ниже в системном вызове mmap() разрешить
в отображении файла и чтение, и запись, хотя реально нам нужна только запись.
Поэтому и при открытии файла мы вынуждены задавать O_RDWR.
*/
fd = open("mapped.dat", O_RDWR | O_CREAT, 0666);
if( fd == -1){
/* Если файл открыть не удалось, выдаем сообщение
об ошибке и завершаем работу */
printf("File open failed!\n");
exit(1);
}
/* Вычисляем будущую длину файла (мы собираемся записать
в него 100000 структур) */
length = 100000*sizeof(struct A);
/* Вновь созданный файл имеет длину 0. Если мы его
отобразим в память с такой длиной файла, то любая попытка записи в выделенную
память приведет к ошибке. Увеличиваем длину файла до требуемой с помощью вызова
ftruncate().
*/
ftruncate(fd,length);
/* Отображаем файл в память. Разрешенные операции
над отображением указываем как PROT_WRITE | PROT_READ по
уже сказанным причинам. Значение флагов ставим в MAP_SHARED,
так как мы хотим сохранить информацию, которую занесем в отображение, на диске.
Файл отображаем с его начала (offset = 0)
и до конца (length = длине файла). */
ptr = (struct A *)mmap(NULL, length, PROT_WRITE
| PROT_READ, MAP_SHARED, fd, 0);
/* Файловый дескриптор нам более не нужен, и мы его
закрываем */
close(fd);
if( ptr == MAP_FAILED ){
/* Если отобразить файл не удалось, сообщаем об
ошибке и завершаем работу */
printf("Mapping failed!\n");
exit(2);
}
/* В цикле заполняем образ файла числами от 1 до
100000 и их квадратами. Для перемещения по области памяти используем указатель
tmpptr, так как указатель ptr
на начало образа файла нам понадобится для преращения отображения вызовом
munmap(). */
tmpptr = ptr;
for(i = 1; i <=100000; i++){
tmpptr->f
= i;
tmpptr->f2 = tmpptr->f*tmpptr->f;
tmpptr++;
}
/* Прекращаем отображать файл в память, записываем
содержимое отображения на диск и освобождаем память. */
munmap((void *)ptr, length);
return 0;
}