Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

% client

accessing server backup-server.elsewhere.net

2.1.7. Временные файлы

Иногда программе требуется создать временный файл, например для промежуточного хранения большого объема данных или для передачи данных другой программе. В системах GNU/Linux временные файлы хранятся в каталоге

/tmp
. Работая с временными файлами, необходимо помнить о следующих ловушках.

■ Одновременно может быть запущено несколько экземпляров программы (одним и тем же пользователем или разными пользователями). Все они должны использовать разные имена временных

файлов, чтобы не было конфликтов.

■ Права доступа к временным файлам должны задаваться таким образом, чтобы неавторизованные пользователи не могли влиять на работу программы путем модификации или замены временного файла.

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

В Linux имеются функции

mkstemp
и
tmpfile
, решающие все вышеперечисленные проблемы. Выбор между ними делается на основании того, должен ли временный файл передаваться другой программе и какие функции ввода-вывода будут применяться при работе с файлом: низкоуровневые (
read
,
write
и т.д.) или потоковые (
fopen
,
fprintf
и т.д.).

Функция mkstemp

Функция

mkstemp
генерирует уникальное имя файла на основании переданного ей шаблона, создает временный файл с правами, разрешающими доступ к нему только для текущего пользователя, и открывает файл в режиме чтения/записи. Шаблон имени — это строка, оканчивающаяся последовательностью "XXXXXX" (шесть прописных букв "X"). Функция
mkstemp
заменяет каждую букву произвольным символом таким образом, чтобы получилось уникальное имя, и возвращает дескриптор файла. Запись в файл осуществляется с помощью функций семейства
write
.

Временные файлы, создаваемые функцией

mkstemp
, не удаляются автоматически. Ответственность за это возлагается на того, кто запускает программу. (Программисты должны внимательно следить за удалением временных файлов, иначе файловая система
/tmp
рано или поздно переполнится, приведя всю систему в нерабочее состояние.) Если файл создан для внутреннего использования и не предназначен для передачи другой программе, по окончании работы с ним нужно сразу же вызвать функцию
unlink
. Она удаляет из каталога ссылку на файл, но сам файл остается до тех пор, пока не будут закрыты все ссылающиеся на него дескрипторы. Таким образом, программа может продолжать использовать временный файл; он будет удален автоматически сразу после закрытия дескриптора. Операционная система закрывает дескрипторы файлов по окончании работы программы, так что временный файл будет удален даже в случае аварийного завершения программы.

В листинге 2.5 показаны две функции, работающие с временным файлом. Будучи примененными в связке, они позволяют легко переносить содержимое буферов из операторной памяти во временный файл (это дает возможность освобождать и повторно использовать память), а затем загружать данные из файла обратно в память.

Листинг 2.5. (temp_file.c) Использование функции
mkstemp

#include <stdlib.h>

#include <unistd.h>

/* дескриптор временного файла, созданного в функции

write_temp_file. */

typedef int temp_file_handle;

/*
Запись указанного числа байтов из буфера во временный файл.

Ссылка на временный файл немедленно удаляется. Возвращается

дескриптор временного файла. */

temp_file_handle write_temp_file(char* buffer, size_t length) {

 /* Создание имени файла и самого файла. Цепочка XXXXXX будет

заменена символами, которые сделают имя уникальным. */

 char temp_filename = "/tmp/temp_file.XXXXXX";

 int fd = mkstemp(temp_filename);

 /* немедленное удаление ссылки на файл, благодаря чему он будет

удален сразу же после закрытия дескриптора файла. */

 unlink(temp_filename);

 /* Сначала в файл записывается число, определяющее размер

буфера. */

 write(fd, &length, sizeof(length));

 /* теперь записываем сами данные. */

 write(fd, buffer, length);

 /* Возвращаем дескриптор файла. */

 return fd;

}

/* Чтение содержимого временного файла, созданного в функции

write_temp_file. Создается и возвращается буфер с содержимым

файла. Этот буфер должен быть удален в вызывающей подпрограмме

с помощью функции free. В параметр LENGTH записывается размер

буфера в байтах. В конце временный файл удаляется. */

char* read_temp_file(temp_file_handle temp_file, size_t* length) {

 char* buffer;

 /* TEMP_FILE -- это дескриптор временного файла. */

 int fd = temp_file;

 /* переход в начало файла. */

 lseek(fd, 0, SEEK_SET);

 /* Определение объема данных, содержащихся во временном файле. */

 read(fd, length, sizeof(*length));

 /* Выделение буфера и чтение данных. */

 buffer = (char*)malloc(*length);

 read(fd, buffer, *length);

 /* Закрытие дескриптора файла, что приведет к уничтожению

временного файла. */

 close(fd);

 return buffer;

}

Функция tmpfile

Если в программе используются функции потокового ввода-вывода библиотеки языка С и передавать временный файл другой программе не нужно, то для работы с временным файлом больше подойдет функция

tmpfile
. Она создает и открывает временный файл, возвращая файловый указатель на него. Ссылка на файл уже оказывается удаленной, благодаря чему он уничтожается автоматически при закрытии указателя (с помощью функции
fclose
) или при завершении программы.

Поделиться:
Популярные книги

Мастер...

Чащин Валерий
1. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
6.50
рейтинг книги
Мастер...

Жених из гроба

Сотис Майя
1. Гробокопательница
Фантастика:
юмористическое фэнтези
сказочная фантастика
фэнтези
5.00
рейтинг книги
Жених из гроба

Ищу жену с прицепом

Рам Янка
2. Спасатели
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Ищу жену с прицепом

Гримуар тёмного лорда I

Грехов Тимофей
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар тёмного лорда I

Заклятие предков

Прозоров Александр Дмитриевич
3. Ведун
Фантастика:
фэнтези
альтернативная история
8.49
рейтинг книги
Заклятие предков

Крепость над бездной

Лисина Александра
4. Гибрид
Фантастика:
боевая фантастика
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Крепость над бездной

Рота Его Величества

Дроздов Анатолий Федорович
Новые герои
Фантастика:
боевая фантастика
8.55
рейтинг книги
Рота Его Величества

Экспансия: Сотрудничество. Том 5

Белов Артем
5. Планетарный десант
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Экспансия: Сотрудничество. Том 5

Отверженный III: Вызов

Опсокополос Алексис
3. Отверженный
Фантастика:
фэнтези
альтернативная история
7.73
рейтинг книги
Отверженный III: Вызов

Князь Серединного мира

Земляной Андрей Борисович
4. Страж
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Князь Серединного мира

Возвышение Меркурия. Книга 8

Кронос Александр
8. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 8

Эволюционер из трущоб. Том 5

Панарин Антон
5. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 5

Локки 7. Потомок бога

Решетов Евгений Валерьевич
7. Локки
Фантастика:
аниме
эпическая фантастика
фэнтези
5.00
рейтинг книги
Локки 7. Потомок бога

Черный Маг Императора 4

Герда Александр
4. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 4