Нейл Мэтью - Основы программирования в Linux
- Название:Основы программирования в Linux
- Автор:
- Жанр:
- Издательство:«БХВ-Петербург»
- Год:2009
- Город:Санкт-Петербург
- ISBN:978-5-9775-0289-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Нейл Мэтью - Основы программирования в Linux краткое содержание
В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стандартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым.
Для начинающих Linux-программистов
Основы программирования в Linux - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
□ telldir
;
□ seekdir
;
□ closedir
.
opendir
Функция opendir
открывает каталог и формирует поток каталога. Если она завершается успешно, то возвращает указатель на структуру DIR
, которая будет использоваться для чтения элементов каталога.
#include
#include
DIR *opendir(const char *name);
В случае неудачи функция opendir возвращает пустой указатель. Имейте в виду, что для доступа к самому каталогу поток каталога использует низкоуровневый дескриптор файла, поэтому opendir может дать сбой, если открыто слишком много файлов.
readdir
Функция readdir
возвращает указатель на структуру, содержащую следующий элемент каталога в потоке каталога dirp
. Успешные вызовы readdir
возвращают следующие элементы каталогов. При возникновении ошибки и в конце каталога readdir
возвращает NULL
. Системы, удовлетворяющие стандарту POSIX, возвращая NULL
, не меняют переменную errno
в случае достижения конца каталога и устанавливают ее значение, если обнаружена ошибка.
#include
#include
struct dirent *readdir(DIR *dirp);
Просмотр каталога с помощью функции readdir
не гарантирует формирование списка всех файлов (и подкаталогов) в каталоге, если в это время выполняются другие процессы, создающие и удаляющие файлы в каталоге.
В состав структуры dirent
, содержащей реквизиты элемента каталога, входят следующие компоненты.
□ ino_t d_ino
— индекс файла;
□ char d_name[]
— имя файла.
Для выяснения других реквизитов файла в каталоге вам необходимо вызвать stat
, который мы обсуждали ранее.
telldir
Функция telldir
возвращает значение, регистрирующее текущую позицию в потоке каталога. Вы можете использовать ее в последующих вызовах функции seekdir
для переустановки просмотра каталога, начиная с текущей позиции.
#include
#include
long int telldir(DIR *dirp);
seekdir
Функция seekdir
устанавливает указатель на элемент каталога в потоке каталога, заданном в параметре dirp
. Значение параметра loc
, применяемого для установки позиции, следует получить из предшествующего вызова функции telldir
.
#include
#include
void seekdir (DIR *dirp, long int loc);
closedir
Функция closedir
закрывает поток каталога и освобождает ресурсы, выделенные ему. Она возвращает 0 в случае успеха и -1 при наличии ошибки.
#include
#include
int closedir(DIR *dirp);
В приведенной далее программе printdir.c (упражнение 3.4) вы соберете вместе множество функций обработки файлов для создания простого перечня содержимого каталога. Каждый файл представлен отдельной строкой. У каждого подкаталога есть имя, за которым следует слэш, и файлы, содержащиеся в подкаталоге, выводятся с отступом шириной в четыре пробела.
Программа превращает каталог в подкаталоги, чтобы у найденных файлов были пригодные для использования имена, т.е. они могут передаваться непосредственно в функцию opendir. Программа будет давать сбои при просмотре структур с большим числом уровней вложенности, поскольку есть ограничение на разрешенное число открытых потоков каталогов.
Мы могли бы сделать программу более универсальной, принимая в качестве аргумента командной строки начальную точку просмотра.
Для того чтобы познакомиться с методами повышения универсальности программ, посмотрите исходный код таких утилит Linux, как ls
и find
.
1. Начните с соответствующих заголовочных файлов и функции printdir
, которая выводит содержимое текущего каталога. Она будет рекурсивно вызываться для вывода подкаталогов, применяя параметр depth
для задания отступа.
#include
#include
#include
#include
#include
#include
void printdir(char *dir, int depth) {
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if ((dp = opendir(dir)) == NULL) {
fprintf(stderr, "cannot open directory: %s\n", dir);
return;
}
chdir(dir);
while((entry = readdir(dp)) != NULL) {
lstat(entry->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
/* Находит каталог, но игнорирует . и .. */
if (strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0)
continue;
printf("%*s%s/\n", depth, "", entry->d_name);
/* Рекурсивный вызов с новый отступом */
printdir(entry->d_name, depth+4);
} else printf("%*s%s\n", depth, " ", entry->d_name);
}
chdir("..");
closedir(dp);
}
2. Теперь переходите к функции main
.
int main() {
/* Обзор каталога /home */
printf("Directory scan of /home:\n");
printdir("/home", 0);
printf("done.\n");
exit(0);
}
Программа просматривает исходные каталоги и формирует вывод, похожий на приведенный далее (отредактированный для краткости). Для того чтобы заглянуть в каталоги других пользователей, вам могут понадобиться права доступа суперпользователя.
$ ./printdir
Directory scan of /home:
neil/
.Xdefaults
.Xmodmap
.Xresources
.bash_history
.bashrc
.kde/
share/
apps/
konqueror/
dirtree/
public_html.desktop
toolbar/
bookmarks.xml
konq_history
kdisplay/
color-schemes/
BLP4e/
Gnu_Public_License
chapter04/
argopt.с
args.с
chapter03/
file.out
mmap.с
printdir
done.
Как это работает
Большинство операций сосредоточено в функции printdir
. После некоторой начальной проверки ошибок с помощью функции opendir
, проверяющей наличие каталога, printdir
выполняет вызов функции chdir
для заданного каталога. До тех пор пока элементы, возвращаемые функцией readdir
, не нулевые, программа проверяет, не является ли очередной элемент каталогом. Если нет, она печатает элемент-файл с отступом, равным depth
.
Если элемент — каталог, вы встречаетесь с рекурсией. После игнорирования элементов .
и ..
(текущего и родительского каталогов) функция printdir
вызывает саму себя и повторяет весь процесс снова. Как она выбирается из этих повторений? Как только цикл while
заканчивается, вызов chdir("..")
возвращает программу вверх по дереву каталогов, и предыдущий перечень можно продолжать. Вызов closedir(dp)
гарантирует, что количество открытых потоков каталогов не больше того, которое должно быть.
Для того чтобы составить представление об окружении в системе Linux, обсуждаемом в главе 4, познакомьтесь с одним из способов, повышающих универсальность программы. Рассматриваемая программа ограничена, потому что привязана каталогу /home. Следующие изменения в функции main
могли бы превратить эту программу в полезный обозреватель каталогов:
Интервал:
Закладка: