Для защиты от одновременного запуска нескольких процессов, можно сделать так:my $cfg_glob_lock="/var/run/test.pid";
# Проверяем лок.
if (-f $cfg_glob_lock){
# Лок присутствует. Проверяем не дохлый ли процесс.
my $lock_pid = 0;
open(LOCK,"<$cfg_glob_lock");
# Если удалось заблокировать, значит процесс мертв.
my $zombie_lock_flag = flock(LOCK, 2|4);
$lock_pid = <LOCK>;
close (LOCK);
chomp ($lock_pid);
if ($lock_pid > 0 && $zombie_lock_flag == 0){
# Реакция на зависший процесс.
die "Proccess locked (pid=$lock_pid)";
} else {
# Лок от мертвого процесса.
unlink("$cfg_glob_lock");
warn("DeadLock detected ($lock_pid)");
}
}
# Записываем pid в новый лок файл.
open(LOCK,">$cfg_glob_lock");
print LOCK "$$\n";
close(LOCK);
# Открываем лок.
open(GLOB_LOCK,"<$cfg_glob_lock");
flock(GLOB_LOCK, 2);.... рабочий код скрипта
# Закрываем и удаляем лок
flock(GLOB_LOCK, 8);
close(GLOB_LOCK);
unlink("$cfg_glob_lock");
URL:
Обсуждается: https://www.opennet.ru/tips/info/778.shtml
А если чужой файл появился в промежутке между
if (-f $cfg_glob_lock){
и
open(LOCK,">$cfg_glob_lock"); ?man 2 open
/EXВсе другие варианты, к сожалению, нерабочие ;(
>А если чужой файл появился в промежутке между
>if (-f $cfg_glob_lock){
>open(LOCK,">$cfg_glob_lock"); ?Полностью согласен, поправил в контексте использования sysopen(LOCK,$cfg_glob_lock, O_CREAT|O_EXCL|O_WRONLY), можно также вариант блокировки хардлинками привести.
Для борьбы с использованием Race Condition в плане безопасности еще хорошо помогает монтирование world writable разделов с nosymfollow и создание локов/временных файлов в недоступных для посторонних местах.
Ещё (я не зануда ;-):лучше всё-таки использовать символьные константы O_CREAT и прочие, они от юникса к юниксу отличаются, а мы же боремся за переносимость ;)
И по поводу хардлинков не всё так просто: на монтированных файловых системах, типа той же самбы, их не будет, что приведёт к очевидным проблемам.
Впрочем, вариант с open тоже имеет трудности на некоторых реализациях NFS, но этим, пожалуй, уж точно можно пренебречь.
>лучше всё-таки использовать символьные константы O_CREAT и прочие, они от юникса к
>юниксу отличаются, а мы же боремся за переносимость ;)Поправил.
>И по поводу хардлинков не всё так просто: на монтированных файловых системах,
>типа той же самбы, их не будет, что приведёт к очевидным
>проблемам.
>Впрочем, вариант с open тоже имеет трудности на некоторых реализациях NFS, но
>этим, пожалуй, уж точно можно пренебречь.А для samba разделов open лок точно без проблем работает ? Просто на них тот же File::Find без рукоприкладства ($File::Find::dont_use_nlink=1) неработоспособен.
Впринципе, для локов хардлинками на CPAM есть готовый модуль File::NFSLock.
Да, open точно работает, по крайней мере на C я проверял. Perl тоже должен, обвязка же в итоге сводится к вызову open(2) AFAIK.
Не работает для платформ DOS-OS2-Win, там только через rename, потому что очень сильно зависит от реализации библиотеки, да и в случае хорошей библиотеки нельзя закладываться на это ;-(
Мака под рукой нету, VMS тоже, на них не проверял ;-)
Пародон, а чем use Proc::Lock::File; уже устарел???