Книга: Linux программирование в примерах

12.3.2. Создание и открывание временных файлов (хорошо)

12.3.2. Создание и открывание временных файлов (хорошо)

Есть две функции, не имеющие проблем состояния гонки. Одна из них предназначена для использования с библиотекой <stdio.h>:

#include <stdio.h> /* ISO С */
FILE *tmpfile(void);

Другая функция для использования с системными вызовами на основе дескрипторов файлов:

#include <stdio.h> /* XSI */
int mkstemp(char* template);
tmpfile()
возвращает значение FILE*, представляющее уникальный открытый временный файл. Файл открывается в режиме "w+b". w+ означает «открыть для чтения и записи, сначала урезав файл», a b означает двоичный, а не текстовый режим. (На системах GNU/Linux или Unix нет разницы, но на других системах есть.) Файл автоматически удаляется, когда закрывается указатель файла; нет способа получить имя файла, чтобы сохранить его содержимое. Программа в ch12-tmpfile.c демонстрирует tmpfile():

/* ch12-tmpfile.с --- демонстрация tmpfile().
   Проверка ошибок для краткости опущена */
#include <stdio.h>
int main(void) {
 static char mesg[] =
  "Here's lookin' at you, kid!"; /* заменяет "hello, world" */
 FILE *fp;
 char buf[BUFSIZ];
 fp = tmpfile();                 /* Получить временный файл */
 fprintf(fp, "%s", mesg);        /* Записать s него */
 fflush(fp);                     /* Сбросить на диск */
 rewind(fp);                     /* Перейти в начало */
 fgets(buf, sizeof buf, fp);     /* Прочесть содержимое */
 printf("Got back <%s>n", buf); /* Вывести полученные данные */
 fclose(fp);                     /* Закрыть файл, закончить */
 return 0;                       /* Все сделано */
}

Возвращенное значение FILE* не отличается от любого другого FILE*, возвращенного fopen(). При запуске получаем ожидавшиеся результаты:

$ ch12-tmpfile
Got back <Here's lookin' at you, kid!>

Ранее мы видели, что авторы GLIBC рекомендуют использование функции mkstemp():

$ cc ch12-mktemp.с -о ch12-mktemp /* Компилировать программу */
/tmp/cc1XCvD9.о(.text+0x35): In function "main':
: the use of 'mktemp' is dangerous, better use 'mkstemp'

Эта функция похожа на mktemp() в том, что она принимает имя файла, оканчивающееся на 'ХХХХХХ', и заменяет эти символы уникальным суффиксом для создания уникального имени файла. Однако, она идет на один шаг дальше. Она создает и открывает файл. Файл создается с доступом 0600 (т.е. -rw-------). Таким образом, доступ к файлу может получить только пользователь, запустивший программу.

Более того, и это то, что делает mkstemp() более безопасной, файл создается с флагом O_EXCL, который гарантирует, что файл не существует, и не дает никому больше открыть файл.

Возвращаемое значение является дескриптором открытого файла, который может использоваться для чтения и записи. Для удаления файла после завершения работы с ним должно использоваться имя пути, сохраненное теперь в переданном mkstemp() буферу. Все это демонстрируется в ch12-mkstemp.c, который является простой модификацией ch12-tmpfile.с:

/* ch12-mkstemp.с --- демонстрирует mkstemp().
   Проверка ошибок для краткости опущена */
#include <stdio.h>
#include <fcntl.h> /* для флагов открытия */
#include <limits.h> /* для PATH_МАХ */
int main(void) {
 static char template[] = "/tmp/myfileXXXXXX";
 char fname[PATH_MAX];
 static char mesg[] =
  "Here's lookin' at you, kid!n"; /* заменяет "hello, world" */
 int fd;
 char buf[BUFSIZ];
 int n;
 strcpy(fname, template);           /* Копировать шаблон */
 fd = mkstemp(fname);               /* Создать и открыть временный файл */
 printf("Filename is %sn", fname); /* Вывести его для сведений */
 write(fd, mesg, strlen(mesg));     /* Что-нибудь записать в файл */
 lseek(fd, 0L, SEEK_SET);           /* Перейти в начало */
 n = read(fd, buf, sizeof(buf));
  /* Снова прочесть данные; НЕ завышается ''! */
 printf("Got back: %.*s", n, buf);  /* Вывести его для проверки */
 close(fd);                         /* Закрыть файл */
 unlink(fname);                     /* Удалить его */
 return 0;
}

При запуске получаем ожидавшиеся результаты:

$ ch12-mkstemp
Filename is /tmp/myfileuXFWIN
Got back: Here's lookin' at you, kid!

Оглавление книги


Генерация: 1.403. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз