-->

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

На нашем литературном портале можно бесплатно читать книгу Linux программирование в примерах, Роббинс Арнольд-- . Жанр: Программирование / ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
Linux программирование в примерах
Название: Linux программирование в примерах
Дата добавления: 16 январь 2020
Количество просмотров: 552
Читать онлайн

Linux программирование в примерах читать книгу онлайн

Linux программирование в примерах - читать бесплатно онлайн , автор Роббинс Арнольд

В книге рассмотрены вопросы, связанные с программированием под Linux: файловый ввод/вывод, метаданные файлов, основы управления памятью, процессы и сигналы, пользователи и группы, вопросы интернационализации и локализации, сортировка, поиск и многие другие. Много внимания уделено средствам отладки, доступным под GNU Linux. Все темы иллюстрируются примерами кода, взятого из V7 UNIX и GNU. Эта книга может быть полезна любому, кто интересуется программированием под Linux.

 

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

1 ... 33 34 35 36 37 38 39 40 41 ... 253 ВПЕРЕД
Перейти на страницу:

#include <stdio.h> /* для fprintf(), stderr, BUFSIZ */

#include <unistd.h> /* для ssize_t */

int main(int argc, char **argv) {

 printf("max fds: %dn", getdtablesize());

 exit(0);

}

Неудивительно, что после компиляции и запуска эта программа выводит то же значение, что и

ulimit
:

$ <b>ch04-maxfds</b>

max fds: 1024

Дескрипторы файлов содержатся в обычных переменных

int
; для использования с системными вызовами ввода/вывода можно увидеть типичные объявления вида '
int fd
'. Для дескрипторов файлов нет предопределенного типа.

В обычном случае каждая программа начинает свою работу с тремя уже открытыми для нее дескрипторами файлов. Это стандартный ввод, стандартный вывод и стандартная ошибка, с дескрипторами файлов 0, 1 и 2 соответственно. (Если не было использовано перенаправление, каждый из них связан с клавиатурой и с экраном.)

Очевидные символические константы. Оксюморон?

При работе с системными вызовами на основе дескрипторов файлов и стандартных ввода, вывода и ошибки целые константы 0, 1 и 2 обычно используются прямо в коде. В подавляющем большинстве случаев использование таких символических констант (manifest constants) является плохой мыслью. Вы никогда не знаете, каково значение некоторой случайной целой константы и имеет ли к ней какое-нибудь отношение константа с тем же значением, использованная в другой части кода. С этой целью стандарт POSIX требует объявить следующие именованные константы (symbolic constants) в

&lt;unistd.h&gt;
:

STDIN_FILENO  
«Номер файла» для стандартного ввода: 0.

STDOUT_FILENO 
Номер файла для стандартного вывода: 1.

STDERR_FILENO 
Номер файла для стандартной ошибки: 2.

Однако, по нашему скромному мнению, использование этих макросов избыточно. Во-первых, неприятно набирать 12 или 13 символов вместо 1. Во-вторых, использование 0, 1 и 2 так стандартно и так хорошо известно, что на самом деле нет никаких оснований для путаницы в смысле этих конкретных символических констант.

С другой стороны, использование этих констант не оставляет сомнений в намерениях программиста. Сравните это утверждение:

int fd = 0;

Инициализируется ли

fd
значением стандартного ввода, или же программист благоразумно инициализирует свои переменные подходящим значением? Вы не можете этого сказать.

Один из подходов (рекомендованный Джеффом Колье (Geoff Collyer)) заключается в использовании следующего определения

enum
:

enum { Stdin, Stdout, Stderr };

Затем эти константы можно использовать вместо 0, 1 и 2. Их легко читать и печатать.

4.4.2. Открытие и закрытие файлов

Новые дескрипторы файлов получают (наряду с другими источниками) в результате системного вызова

open()
. Этот системный вызов открывает файл для чтения или записи и возвращает новый дескриптор файла для последующих операций с этим файлом. Мы видели объявление раньше:

#include &lt;sys/types.h&gt; /* POSIX */

#include &lt;sys/stat.h&gt;

#include &lt;fcntl.h&gt;

#include &lt;unistd.h&gt;

int open(const char *pathname, int flags, mode_t mode);

Три аргумента следующие:

const char *pathname

Строка С, представляющая имя открываемого файла.

int flags

Поразрядное ИЛИ с одной или более констант, определенных в

&lt;fcntl.h&gt;
. Вскоре мы их рассмотрим.

mode_t mode

Режимы доступа для создаваемого файла. Это обсуждается далее в главе, см. раздел 4.6 «Создание файлов». При открытии существующего файла опустите этот параметр [46].

Возвращаемое open() значение является либо новым дескриптором файла, либо -1, означающим ошибку, в этом случае будет установлена

errno
. Для простого ввода/вывода аргумент
flags
должен быть одним из значений из табл. 4.3.

Таблица 4.3. Значения

flags
для
open()

Именованная константа Значение Комментарий
O_RDONLY
0 Открыть файл только для чтения, запись невозможны
O_WRONLY
1 Открыть файл только для записи, чтение невозможно
O_RDWR
2 Открыть файл для чтения и записи

Вскоре мы увидим пример кода. Дополнительные значения

flags
описаны в разделе 4.6 «Создание файлов». Большой объем ранее написанного кода Unix не использовал эти символические значения. Вместо этого использовались числовые значения. Сегодня это рассматривается как плохая практика, но мы представляем эти значения, чтобы вы их распознали, если встретитесь с ними

Системный вызов

close()
закрывает файл: его элемент в системной таблице дескрипторов файлов помечается как неиспользуемый, и с этим дескриптором нельзя производить никаких дальнейших действий. Объявление следующее:

#include &lt;unistd.h&gt; /* POSIX */

int close(int fd);

В случае успеха возвращается 0, при ошибке (-1). При возникновении ошибки нельзя ничего сделать, кроме сообщения о ней. Ошибки при закрытии файлов являются необычными, но не невозможными, особенно для файлов, доступ к которым осуществляется через сеть. Поэтому хорошей практикой является проверка возвращаемого значения, особенно для файлов, открытых для записи.

Если вы будете игнорировать возвращаемое значение, специально приведите его к типу

void
, чтобы указать, что вам не нужен результат:

(void)close(fd); /* отказ от возвращаемого значения */

Легкомысленность этого совета в том, что слишком большое количество приведений к

void
имеют тенденцию загромождать код. Например, несмотря на принцип «всегда проверять возвращаемое значение», чрезвычайно редко можно увидеть код, проверяющий возвращаемое значение
printf()
или приводящий его к
void
. Как и со многими аспектами программирования на С, здесь также требуются опыт и рассудительность.

1 ... 33 34 35 36 37 38 39 40 41 ... 253 ВПЕРЕД
Перейти на страницу:
Комментариев (0)
название