Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

Программирование для Linux. Профессиональный подход - Митчелл М.

Митчелл М., Оулдем Дж., Самьюал А. Программирование для Linux. Профессиональный подход — М.: Вильямс , 2003. — 288 c.
ISBN 5-8459-0243-6
Скачать (прямая ссылка): programmirovaniedlyalinux2003.djvu
Предыдущая << 1 .. 71 72 73 74 75 76 < 77 > 78 79 80 81 82 83 .. 128 >> Следующая

Сначала память доступна только для записи. */ alloc_size = getpagesize ()
; fd - open ("/dev/zero", C_RDONLY>;
memory = mmap (NULL, alloc_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
close (fd);
/* Запись на страницу для получения ее копии в частное исполь з ование.
*/ memoryГОI = 0;
/* Запрет ка запись в память. */ mprotect (memory, alloc_size,
PROT_NONE);
/* Попытка записи в память. */ memory[0) = 1;
/* Удаление памяти. */ printf (*all done\n"); munmap (memory,
alloc_size>; return 0;
}
Программа работает по следующей схеме.
1. Задается обработчик сигнала SIGSEGV.
2- Файл /dev/zero отображается в памяти, из которой выделяется одна
страница. В эту страницу записывается инициализирующее значение,
благодаря чему программе предоставляется частная копия страницы.
3. Программа защищает память, вызывая функцию mprotect () с флагом
PROT_NONE.
4. Когда программа впоследствии обращается к памяти, Linux посылает ей
сигнал SIGSEGV, который обрабатывается в функции segv_handler {).
Обработчик сигнала отменяет защит)' памяти, разрешая выполнить операцию
записи.
5. Программа удаляет область память с помощью функции munmap ().
8.10. Функция nanosleep(): высокоточная пауза
Функция nanosleepO является более точной версией стандартной функции
sleep (), принимая указатель на структуру типа timespec. где время
задается с точностью до наносекунды, а не секунды. Правда, особенности
работы ОС Linux таковы, что реальная точность оказывается равной Юме. но
это все равно выше, чем в функции sleep() - Функцию nanosleepO можно
использовать в приложениях, где требуется запускать различные операции с
короткими интервалами между ними.
В структуре timespec имеются два поля:
¦ t v_s ес - целое число секунд;
¦ tv_nsec - дополнительное число миллисекунд (должно быть меньше, чем
10).
Работа функции nanosleep (), как и функции sleep (), прерывается при
получении сигнала. При этом функция возвращает значение -1, а в
переменную errno записывается код EINTR. По у функции nanosleepO есть
важное преимущество. Она принимает дополнительный аргумент - еще один
указатель на структуру timespec, в которую (если указатель не равен NULL)
заносится величина оставшегося интервала времени (т.е. разница между
запрашиваемым и прошедшим промежутками времени). Благодаря этому можно
легко возобновлять прерванные операции ожидания.
Глава 8. Системные вызовы Linux 165
В листинге 8.8 показана альтернативная реализация функции sleep О. В
отличие от стандартного системного вызова эта функция может принимать
дробное число секунд и возобновлять операцию ожидания в случае прерывания
по сигнал)'.
Листинг 8.8. (better sleep.c) Высокоточная реализация функции alaapO
¦include <errno.h>
¦include <time.h>
int better_sleep (double sleep__time) t
struct timespec tv;
/* Заполнение структуры timespec на основании указанного числа секунд. */
tv.tv_sec = (time_t) sleep_time;
/* добавление неучтенных выше наносекунд. */ tv.tv"nsec = (long)
((sleep_time - tv.tv_sec) * le+9);
while (1)
{
/* пауза, длительность которой указана в переменной tv.
В случае прерывания по сигналу величина оставшегося промежутка времени
заносится обратно в переменную tv. */ int rval = nanosleep (&tv, btv); if
(rval == 0)
/* пауза успешно окончена. */ return 0; else if (errno == EINTR)
/* прерывание по сигналу. Поаторная попытка. */ continue; else
/* Какая-то другая ошибка. */ return rval;
}
return 0;
>
8.11. Функция readlink(): чтение символических ссылок
Функция readlink () определяет адресата символической ссылки. Она
принимает три аргумента: путь к символической ссылке, буфер для записи
адресата и длина буфера- Как ни странно, путевое имя, помещаемое в буфер,
не завершается нулевым символом. Но поскольку в третьем аргументе
возвращается длина буфера, добавить этот символ несложно.
Если первый аргумент ие является символической ссылкой, функция readlink
() воз-вращает-1, а в переменную errno записывается константа EINVAL.
Программа, представленная в листинге 8.9, показывает адресата
символической ссылки, заданной в командной строке.
Листинг 8.9. (prinUsymlink.с) Отображение адресата символической ссылки
¦include <errno.h>
¦include <stdio.h>
¦include <unistd.h>
int main (int argc, char* argvf]) (
char target,path[256);
166 Часть И. Секреты Linux
char* link_path = argv[l);
/* Попытка чтения адресата символической ссылки. */
int len = readlink (lirik_path, target_path, sizeof (target__path));
if (len == -1) {
l* Функция завершилась ошибкой. */ if (errao == EINVAL)
/* Это не символическая ссылка. */
fprintf (stderr, *%s is not a symbolic link\n", link_path); else
/* Произошла какая-то другая ошибка. */ perror ("readlink"); return 1;
)
else {
/• Завершаем путевое имя нулевым символом. */
target_path[len] = '\0'г
/* Выводим результат. */
printf ("%s\n", target__path);
return 0;
)
)
Ниже показано, как создать символическую ссылку и проверить ее с помощью
программы print-symlmk:
% In -s /usr/bin/wc my_link % ./print'-symlank my_lxnk /usr/bin/wc
Предыдущая << 1 .. 71 72 73 74 75 76 < 77 > 78 79 80 81 82 83 .. 128 >> Следующая