Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 [ 87 ] 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

что нужно. Дело в том, что они используют лишь функцию fdopen уровня С без системной функции dup2.

Если у вас установлена версия Perl 5.004 и выше, воспользуйтесь методом объекта IO::Handle:

use 10::Handle;

$fh = 10::Handle->new();

$fh->fdopen(3, "r"); # Открыть fd 3 для чтения

Закрытие числовых файловых дескрипторов встречается еще реже. Задача напрямую решается функцией POSIX::close. Если в вашей системе нет библиотеки POSIX, но зато имеется работающая функция syscall (и ваш системный администратор установил файл sys/syscall.ph, созданный транслятором h2ph), можно воспользоваться функцией syscall, хотя переносимость в этом случае оставляет желать лучшего. Вам придется добавлять О к числам и присоединять "" к строкам, чтобы обеспечить правильность типов С; кроме того, код ошибки равен -1, а не false, как в других функциях Perl. Не стоит и говорить, что syscall применяется лишь в крайнем случае.

Ниже показано, как открыть файловые дескрипторы, которые почтовая система МН передает своим дочерним процессам. Дескрипторы идентифицируются по неременной окружения MHCONTEXTFD;

$fd = $ENV{MHCONTEXTFD}:

open(MHC0NTEXT, X&Sfd") or die "couldnt fdopen $fd: $!"; # after processing

close(MHCONTEXT) or die "couldnt close context file: $!";

Чтобы закрыть дескриптор по числовому значению, достаточно сначала вызвать для него open.

1> Смотри также-

Документация но стандартным модулям POSIX и IO;;Handle; страница руководства fdopen(3) вашей системы; описание функции open вperlfunc(i).

7.20. Копирование файловых манипуляторов

npo6neNia

Требуется создать копию файлового манипулятора.

Решение

Синоним файлового манипулятора создается следующей командой: -СИНОНИМ = .ОРИГИНАЛ;

Чтобы создать независимую копию файлового дескриптора для существующего манипулятора, воспользуйтесь функцией open в режиме &:



7.20. Копирование файловых манипуляторов 279

openCOUTCOPY, >&STDOUT") or die "Couldnt dup STDOUT: $!"; open(INCOPY, "<&STDIN" ) or die "Couldnt dup STDIN : $!";

Чтобы создать синоним файлового дескриптора для существующего манипулятора, воспользуйтесь функцией open в режиме &=:

open(OUTALIAS, ">&=STDOUT") or die "Couldnt alias STDOUT: $!"; open(INALIAS, "<&=STDIN") or die "Couldnt alias STDIN : $!"; open(BYNUMBER, ">&=5") or die "Couldnt alias file descriptor 5: $!";

Комментарий

Если синоним манипулятора создан с помощью тип-глоба, программа по-прежнему работает лищь с одним объектом ввода/вывода Perl. При закрытии манипулятора-синонима закрывается и объект ввода/вывода. Все последующие попытки использования копий этого манипулятора лищь приводят к выдаче сообщений типа "print on closed filehandle ". Чередование записи через разные синонимы не вызывает проблем, поскольку при этом не создаются дублирующиеся структуры данных, способные вызвать десинхронизацию.

При копировании дескриптора командой ореп(КОПИЯ, ">&МАНИПУЛЯТОР") вызывается системная функция dup(2). Вы получаете два независимых дескриптора с общей текущей позицией, блокировкой и флагами, но разными буферами ввода/вывода. Закрытие одного дескриптора не отражается на его копии. Одновременная работа с файлом через оба дескриптора - верный путь к катастрофе. Обычно этот прием используется для сохранения и восстановления STDOUT и STDERR:

# Получить копии дескрипторов open(OLDOUT, ">&STDOUT"); open(OLDERR, ">&STDERR");

# Перенаправить stdout и stderr

open(STDOUT, "> /tmp/program.out") or die "Cant redirect stdout: open(STDERR, ">&STDOUT") or die "Cant dup stdout: $!";

# Запустить программу system($joe random program);

# Закрыть измененные манипуляторы

close(STDOUT) or die "Cant close STDOUT: $!";

close(STDERR) or die "Cant close STDERR; $!";

# Восстановить stdout и stderr

open(STDERR, ">&OLDERR") or die "Cant restore stderr: $!";

open(STDOUT, ">&OLDOUT") or die "Cant restore stdout: $!";

# Для надежности закрыть независимые копии

close(OLDOUT) or die "Cant close OLDOUT: $!";

close(OLDERR) or die "Cant close OLDERR: $!";

Если синоним дескриптора создается командой ореп(СИНОНИМ, ">&=МАНИПУЛЯ-ТОР "), в действительности вызывается системная функция ввода/вывода fdopen(3).



> Смотри также-

Страница руководства dup(2) вашей системы; описание функции open sperl-func(i).

7.21. Программа: netlock

При блокировке файлов мы рекомендуем по возможности использовать функцию flock. К сожалению, в некоторых системах блокировка через flock ненадежна. Допустим, функция flock может быть настроена на вариант блокировки без поддержки сети или вы работаете в одной из редких систем, в которой вообще не существует эмуляции flock.

Приведенная ниже программа и модуль содержат базовую реализацию механизма блокировки файлов. В отличие от обычной функции flock, данный модуль блокирует файлы по именам, а не по дескрипторам.

Следовательно, он может применяться для блокировки каталогов, сокетов и других нестандартных файлов. Более того, вы даже сможете блокировать несуществующие файлы. При этом используется каталог, созданный в иерархии на одном уровне с блокируемым файлом, поэтому вы должны иметь право записи в каталог, содержащий его. Файл в каталоге блокировки содержит сведения о владельце блокировки. Это пригодится в рецепте 7.8, поскольку блокировка сохраняется, несмотря на изменение файла, которому принадлежит данное имя.

Функция nf lock вызывается с одним или двумя аргументами. Первый определяет имя блокируемого файла; второй, необязательный - промежуток времени, в течение которого происходит ожидание. Функция возвращает true при успешном предоставлении блокировки и false при истечении времени ожидания. При возникновении различных маловероятных событий (например, при невозможности записи в каталог) инициируется исключение.

Присвойте true переменной $File:;LockDir;:Debug, чтобы модуль выдавал сообщения при неудачном ожидании. Если вы забудете снять блокировку, при выходе из программы модуль снимет ее за вас. Этого не произойдет, если ваша программа получит неперехваченный сигнал.

Вспомогательная программа из примера 7.9 демонстрирует применение модуля File;:LockDir.

Пример 7.9. drivelock

#!/usr/bm/perl -w

# drivelock - демонстрация модуля File:.LockDir

Вы получаете один файловый дескриптор с двумя буферами, доступ к которым осуществляется через два манипулятора. Закрытие одного манипулятора закрывает дескрипторы синонимов, но не манипуляторы - если вы попытаетесь вызвать print для манипулятора с закрытым синонимом, Perl не выдаст предупреждения "print on closed filehandle", даже если вызов print закончится неудачей. Короче говоря, попытки работать с файлом через оба манипулятора тоже наверняка приведут к катастрофе. Такая методика используется только для открытия файлового дескриптора по известному числовому значению (см. рецепт 7.19).



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 [ 87 ] 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242