Пример: упрощение с помощью макросов
Пример: упрощение с помощью макросов
В листинге 9.3 установка и снятие блокировки занимали шесть строк кода. Мы должны выделить место под структуру, инициализировать ее и затем вызвать fcntl. Программы можно упростить, если определить следующие семь макросов, которые взяты из раздела 12.3 [21]:
#define read_lock(fd, offset, whence, len)
lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len)
#define readw_lock(fd, offset, whence, len)
lock_reg(fd, F_SETLKW, F_RDlCK, offset, whence, len)
#define write_lock(fd, offset, whence, len)
lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len)
#define writew_lock(fd, offset, whence, len)
lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len)
#define un_lock(fd, offset, whence, len)
lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len)
#define is_read_lockable(fd, offset, whence, len)
lock_test(fd, F_RDLCK, offset, whence, len)
#define is_write_lockable(fd, offset, whence, len)
lock_test(fd, F_WRLCK, offset, whence, len)
Эти макросы используют наши функции lock_reg и lock_test, текст которых приведен в листингах 9.4 и 9.5. С ними нам уже не нужно заботиться об инициализации структур и вызове функций. Первые три аргумента специально сделаны совпадающими с первыми тремя аргументами функции lseek.
Мы также определяем две функции-обертки, Lock_reg и Lock_test, завершающие свое выполнение с возвратом ошибки fcntl, и семь макросов с именами, начинающимися с заглавной буквы, чтобы эти функции вызывать.
С помощью новых макросов мы можем записать функции my_lock и my_unlock из листинга 9.3 как
#define my_lock(fd) (Writew_lock(fd, 0, SEEK_SET, 0))
#define my_unlock(fd) (Un_lock(fd, 0, SEEK_SET, 0))
Листинг 9.4. Вызов fcntl для получения и снятия блокировки
//lib/lock_reg.c
1 #include "unpipc.h"
2 int
3 lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
4 {
5 struct flock lock;
6 lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */
7 lock.l_start = offset; /* сдвиг по отношению к l_whence */
8 lock.l_whence = whence; /* SEEK SET. SEEK CUR, SEEK END */
9 lock.l_len = len; /* количество байтов (0 – до конца файла) */
10 return(fcnt(fd, cmd, &lock)"); /* –1 в случае ошибки */
11 }
Листинг 9.5. Вызов fcntl для проверки состояния блокировки
//lib/lock_test.c
1 #include "unpipc.h"
2 pid_t
3 lock_test(int fd, int type, off_t offset, int whence, off_t len)
4 {
5 struct flock lock;
6 lock.l_type = type; /* F_RDLCK or F_WRLCK */
7 lock.l_start = offset; /* сдвиг по отношению к l_whence */
8 lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
9 lock.l_len = len; /* количество байтов. 0 – до конца файла */
10 if (fcntl(fd, F_GETLK, &lock) == –1)
11 return(-1); /* непредвиденная ошибка */
12 if (lock.l_type == F_UNLCK)
13 return(0); /* false, область не заблокирована другим процессом */
14 return(lock.l_pid); /* true, возвращается положительный PID процесса. заблокировавшего ресурс */
15 }
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Безопасное упрощение
Безопасное упрощение Как и в примере с фотогалереей, который обсуждался ранее в этой главе, брызги CSS3, которые мы добавляем в этом примере, никак не затрагивают браузеры, которые пока что не поддерживают эти свойства.В итоге самое важное, что каждый из этих элементов –
Пример обмена сообщениями с помощью менеджера ресурсов
Пример обмена сообщениями с помощью менеджера ресурсов Код файла заголовков #define NET_OPER "/net/904-3"#define NET_REG "/net/Bed-Test"// Максимальная длина обычного стандартного сообщения.#define MESSIZE_MAX 100// Максимальная длина инвентаризационного имени процесса#define PROC_NAME_MAX 100struct IdLabel_t { // Структура,
Упрощение sip.conf
Упрощение sip.conf Файл sip.conf (который был скопирован в папку /etc/asterisk с помощью команды make samples в предыдущей главе) содержит большое количество опций и документации, но сам файл на самом деле очень небольшой, если убрать из него все закомментированные параметры. Стандартный
Упрощение
Упрощение При упрощении трехмерного тела команду редактирования SOLIDEDIT следует вызывать из падающего меню Modify ? Solid Editing ? Clean либо щелчком на пиктограмме Clean на плавающей панели инструментов Solid Editing. В команде используются ключи Body, Clean.При использовании команды SOLIDEDIT с
Упрощение
Упрощение При упрощении трехмерного тела команду редактирования SOLIDEDIT следует вызывать из падающего меню Modify ? Solid Editing ? Clean либо щелчком на пиктограмме Clean на плавающей панели инструментов Solid Editing. В команде используются ключи Body, Clean.При использовании команды SOLIDEDIT с
Упрощение
Упрощение При упрощении трехмерного тела команду редактирования SOLIDEDIT следует вызывать из падающего меню Modify ? Solid Editing ? Clean либо щелчком на пиктограмме Clean плавающей панели инструментов Solid Editing. В команде используются ключи Body, Clean.При использовании команды SOLIDEDIT с
Пример 9-25. Имитация бросания кубика с помощью RANDOM
Пример 9-25. Имитация бросания кубика с помощью RANDOM #!/bin/bash# Случайные ли числа возвращает RANDOM?RANDOM=$$ # Инициализация генератора случайных чисел числом PID процесса-сценария.PIPS=6 # Кубик имеет 6 граней.MAXTHROWS=600 # Можете увеличить, если не знаете куда девать свое время.throw=0
Пример 10-25. Создание меню с помощью case
Пример 10-25. Создание меню с помощью case #!/bin/bash# Грубый пример базы данныхclear # Очистка экранаecho " Список"echo " ------"echo "Выберите интересующую Вас персону:"echoecho "[E]vans, Roland"echo "[J]ones, Mildred"echo "[S]mith, Julie"echo "[Z]ane, Morris"echoread personcase "$person" in# Обратите внимание: переменная взята в кавычки.
Пример 11-4. Ввод многострочного текста с помощью read
Пример 11-4. Ввод многострочного текста с помощью read #!/bin/bashechoecho "Введите строку, завершающуюся символом , и нажмите ENTER."echo "Затем введите вторую строку, и снова нажмите ENTER."read var1 # При чтении, символ "" экранирует перевод строки. # первая строка # вторая
Пример 16-2. Перенаправление stdout с помощью exec
Пример 16-2. Перенаправление stdout с помощью exec #!/bin/bash# reassign-stdout.shLOGFILE=logfile.txtexec 6>&1 # Связать дескр. #6 со stdout. # Сохраняя stdout.exec > $LOGFILE # stdout замещается файлом "logfile.txt".# ----------------------------------------------------------- ## Весь вывод от команд, в данном блоке, записывается в файл
Пример 24-1. Проверка аргументов командной строки с помощью "И-списка"
Пример 24-1. Проверка аргументов командной строки с помощью "И-списка" #!/bin/bash# "И-список"if [ ! -z "$1" ] && echo "Аргумент #1 = $1" && [ ! -z "$2" ] && echo "Аргумент #2 = $2"then echo "Сценарию передано не менее 2 аргументов." # Все команды в цепочке возвращают true.else echo "Сценарию передано менее 2
Пример 24-2. Еще один пример проверки аргументов с помощью "И-списков"
Пример 24-2. Еще один пример проверки аргументов с помощью "И-списков" #!/bin/bashARGS=1 # Ожидаемое число аргументов.E_BADARGS=65 # Код завершения, если число аргументов меньше ожидаемого.test $# -ne $ARGS && echo "Порядок использования: `basename $0` $ARGS аргумент(а)(ов)" && exit $E_BADARGS# Если
Пример 28-2. Создание файла подкачки (swapfile), с помощью /dev/zero
Пример 28-2. Создание файла подкачки (swapfile), с помощью /dev/zero #!/bin/bash# Создание файла подкачки.# Этот сценарий должен запускаться с правами root.ROOT_UID=0 # Для root -- $UID 0.E_WRONG_USER=65 # Не root?FILE=/swapBLOCKSIZE=1024MINBLOCKS=40SUCCESS=0if [ "$UID" -ne "$ROOT_UID" ]then echo; echo "Этот сценарий должен запускаться с правами