Читаем Linux программирование в примерах полностью

Со слегка более высоким уровнем риска мы можем сами испечь свое пирожное и съесть его. Это осуществляется путем открытия файла без указания флагов O_xSYNC, но с последующим использованием одного из следующих двух системных вызовов в любой момент, когда это необходимо для безопасного перемещения данных на физический носитель:

#include

int fsync(int fd); /* POSIX FSC */

int fdatasync(int fd); /* POSIX SIO */

Системный вызов fdatasync() подобен O_DSYNC: он форсирует запись данных на конечное физическое устройство. Системный вызов fsync() подобен O_SYNC, форсируя запись на физическое устройство не только данных файла, но и вспомогательных данных. Вызов fsync() более переносим; он существовал в мире Unix в течение более продолжительного времени, и вероятность его наличия среди широкого ряда систем больше.

Можно использовать эти вызовы с указателями файлов , вызвав сначала fflush(), а затем fileno() для получения дескриптора нижележащего файла. Вот функция fpsync(), которая может использоваться для заключения обеих операций в один вызов. Она возвращает в случае успеха 0:

/* fpsync --- синхронизация переменной stdio FILE* */

int fpsync(FILE *fp) {

 if (fp == NULL || fflush(fp) == EOF || fsync(fileno(fp)) < 0)

  return -1;

 return 0;

}

Технически оба этих вызова являются расширениями базового стандарта POSIX: fsync() в расширении «Синхронизация файлов» (FSC), a fdatasync() в расширении «Синхронизированный ввод и вывод». Тем не менее, можно без проблем использовать их в системе GNU/Linux

<p>4.8. Установка длины файла</p>

Два системных вызова позволяют настраивать размер файла:

#include

#include

int truncate(const char *path, off_t length); /* XSI */

int ftruncate(int fd, off_t length); /* POSIX */

Как должно быть очевидно из параметров, truncate() принимает аргумент имени файла, тогда как ftruncate() работает с дескриптором открытого файла. (Обычным является соглашение по именованию пар системных вызовов xxx() и fxxxx(), работающих с именами файлов и дескрипторами файлов. Мы увидим несколько примеров в данной и последующих главах.) В обоих случаях аргумент length является новым размером файла.

Этот системный вызов происходит от 4.2 BSD Unix, и на ранних системах мог использоваться лишь для сокращения длины файла, отсюда и название. (Он был создан, чтобы облегчить реализацию операции урезания в Фортране.) На современных системах, включая Linux, имя является неправильным, поскольку с помощью этих вызовов можно также увеличить, а не только сократить длину файла. (Однако, POSIX указывает, что возможность увеличения размера файла относится к расширению XSI.)

Для этих вызовов сокращаемый файл должен иметь разрешение на запись (для truncate()), или должен быть открыт для записи (для ftruncate()). Если файл сокращается, все данные после нового конца файла теряются. (Поэтому вы не можете сократить файл, снова удлинить его и найти там первоначальные данные.) Если файл-расширен, как в случае записи данных после lseek(), данные между старым концом файла и новым концом файла читаются как нули.

Эти вызовы сильно отличаются от 'open(file, ... | O_TRUNC, mode)', который полностью урезает файл, отбрасывая все его данные. Эти же вызовы просто устанавливают абсолютную длину файла в данное значение.

Эти функции довольно специализированы; они используются лишь четыре раза во всем коде GNU Coreutils. Мы представляем пример использования ftruncate() в разделе 5.5.3 «Изменение отметок времени: utime()».

<p>4.9. Резюме</p>

• Когда системный вызов завершается неудачей, он обычно возвращает -1, а в глобальной переменной errno устанавливается предопределенное значение, указывающее на проблему. Для сообщений об ошибках могут использоваться функции perror() и strerror().

• Доступ к файлам осуществляется через небольшие целые, которые называются дескрипторами. Дескрипторы файлов для стандартного ввода, стандартного вывода и стандартной ошибки наследуются от родительского процесса программы. Другие получаются через open() или creat(). Для их закрытия используется close(), a getdtablesize() возвращает разрешенное максимальное число открытых файлов. Значение umask (устанавливаемое с помощью umask()) влияет на права доступа, получаемые новыми файлами при создании с помощью creat() или с флагом O_CREAT для open().

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных