Linux программирование в примерах
Удивительно, но имеются пять различных функций для создания временных файлов. Три из них работают посредством создания строк, представляющих (предположительно) уникальные имена файлов. Как мы увидим, их обычней следует избегать. Оставшиеся две работают путем создания и открытия временного файла; эти функции предпочтительнее для использования.
12.3.1. Создание временных имен файлов (плохо)
Имеются три функции, назначением которых является создание имени уникального, не существующего файла. Получив такое имя, вы можете использовать его для создания временного файла. Поскольку имя уникально, вам «гарантируется» исключительное использование файла. Вот объявления функций:
#include <stdio.h>char *tmpnam(char *s); /* ISO С */char *tempnam(const char *dir, const char *pfx); /* XSI */char *mktemp(char *template); /* ISO С */Все эти функции предусматривают различные вариации одной и той же темы они заполняют или создают буфер с путем уникального временного имени файла. Файл уникален в том, что создаваемое имя не существует во время создания и возвращения его функциями. Функции работают следующим образом:
char *tmpnam(char *s)Генерирует уникальное имя файла. Если
не равенs, он должен быть размером по крайней мереNULLбайтов, и в него копируется уникальное имя. ЕслиL_tmpnamравенs, имя генерируется во внутреннем статическом буфере, который может быть переписан при последующих вызовах. Префикс каталогов в пути будетNULL. КакP_tmpdir, так иP_tmpdirопределены вL_tmpnam.<stdio.h>char *tempnam(const char *dir, const char *pfx)Подобно
дает вам возможность указать префикс каталогов. Еслиtmpnam()равенdir, используетсяNULL. АргументP_tmpdir, если он не равенpfx, определяет до пяти символов для использования в качестве начальных символов имени файлаNULLвыделяет память для имен файлов, которые она генерирует. Возвращенный указатель может впоследствии использоваться сtempnam()(и это следует сделать, если хотите избежать утечек памяти).free()char *mktemp(char *template)Генерирует уникальные имена файлов на основе шаблона. Последними шестью символами
должны быть 'template'; эти символы замещаются уникальным суффиксом.ХХХХХХЗАМЕЧАНИЕ. Аргумент
функцииtemplateпереписывается. Поэтому он не должен быть строковой константой. Многие компиляторы, предшествовавшие стандарту С, помещают строковые константы в сегмент данных вместе с обычными глобальными переменными. Хотя в исходном коде они определены как константы, их можно переписать, таким образом, нередко встречался такой код:mktemp()/* Код в старом стиле: не используйте его */char *tfile = mktemp("/tmp/myprogXXXXXX");/* ...использование файла... */На современных системах такой код. вероятно, завершится неудачей, в наши дни строковые константы находятся в сегментах памяти только для чтения.
Использование этих функций довольно просто. Файл
демонстрируетch12-mktemp.c; нетрудно изменить его для использования других функций:mktemp()1 /* ch12-mktemp.с --- демонстрирует простое использование mktemp().2 Для краткости проверка ошибок опущена */34 #include <stdio.h>5 #include <fcntl.h> /* для флагов открытия */6 #include <limits.h> /* для PATH_MAX */78 int main(void)9 {10 static char template[] = "/tmp/myfileXXXXXX";11 char fname[PATH_MAX];12 static char mesg[] =13 "Here's lookin' at you, kid'\n"; /* вместо "hello, world" */14 int fd;1516 strcpy(fname, template);17 mktemp(fname);1819 /* ОКНО СОСТОЯНИЯ ГОНКИ ОТКРЫВАЕТСЯ */2021 printf("Filename is %s\n", fname);2223 /* ОКНО СОСТОЯНИЯ ГОНКИ ТЯНЕТСЯ ДОСЮДА */2425 fd = open(fname, O_CREAT|O_RDWR|O_TRUNC, 0600);26 write(fd, mesg, strlen(mesg));27 close(fd);2829 /* unlink(fname); */3031 return 0;32 }Переменная
(строка 10) определяет шаблон имени файла; 'template' будет заменен уникальным значением. Строка 16 копирует шаблон вХХХХХХ, которая не является константой: ее можно изменить. Строка 18 вызываетfnameдля генерирования имени файла, а строка 21 выводит ее, так, чтобы мы могли видеть, что это такое. (Вскоре мы объясним комментарии в строках 19 и 23.)mktemp()Строка 25 открывает файл, создавая его при необходимости. Строка 26 записывает сообщение в
, а строка 27 закрывает файл. В программе, в которой файл должен быть удален после завершения работы с ним, строка 29 была бы не закомментирована. (Иногда временный файл не следует удалять; например, если файл после полной записи будет переименован.) Мы закомментировали ее, чтобы можно было запустить эту программу и посмотреть на файл впоследствии. Вот что происходит при запуске программы:mesg