Программист победил race condition в модуле MkDir из предыдущей задачи:
package MkDir5;
use strict;
use warnings;
=head1 NAME
MkDir5 -- рекурсивное создание каталогов
=head1 SYNOPSIS
use MkDir5;
MkDir5::mkdir_recursive("test/a");
MkDir5::mkdir_recursive("/tmp/test/b");
=head1 DESCRIPTION
Модуль предоставляет функцию mkdir_recursive для рекурсивного создания каталогов.
Модуль предназначен для Unix-подобных систем с разделителем в именах каталогов "/" и корневым каталогом /.
=cut
sub _mkdir
{
my ($dir) = @_;
unless(-d $dir){
unless(mkdir $dir){
unless(-d $dir){
die "Can't create dir $dir: $!";
}
}
}
}
sub mkdir_recursive
{
my $path = shift or die;
my @parts = split "/", $path;
my $dir = shift @parts;
_mkdir $dir unless $dir eq '';
for my $d (@parts){
$dir .= "/$d";
_mkdir $dir;
}
}
1;
Файл можно скачать: MkDir5.pm .
Неужели здесь еще остались ошибки?
Увы, когда скрипту все-таки не удается создать каталог, он выводит какие-то странные сообщения…
Можно скачать пример использования и убедиться своими глазами.
Например, если обычным пользователем
попытаться создать каталог /roooot
,
ожидаемо было бы увидеть ошибку Permission denied
,
но вместо этого выдается
No such file or directory
.
perldoc -v '$!'
Если оператор -d
не находит
указанный каталог, он заполняет переменную
$!
, и к моменту
выполнения die "Can't create dir $dir: $!";
эта переменная уже не содержит
информации о том, почему не прошел mkdir
.
Чтобы всегда видеть правильные сообщения, стоило бы сохранять сообщение об ошибке в обыкновенной пользовательской переменной:
unless(-d $dir){
unless(mkdir $dir){
my $mkdir_err = $!;
unless(-d $dir){
die "Can't create dir: $mkdir_err";
}
}
}
На этом заканчивается эпопея нашего программиста с рекурсивным созданием каталогов.
Впрочем, кто знает: возможно, через полгода ему придется исправлять даже этот “хороший” код.