Windows изначально использует файловые дескрипторы. См. Низкоуровневый ввод / вывод в MSDN. Все они сообщают об ошибках через переменную C errno
, что означает, что они отображаются в Perl $!
.
Обратите внимание, что вы можете немного сэкономить, набрав:
open(STDOUT, ">&=", $saveout) or ...;
Это работает, потому что документация для open
в perlfunc содержит:
Если вы используете форму с 3 аргументами, вы можете передать либо число, имя дескриптора файла, либо обычную «ссылку на глобус».
Наконец, всегда включает значимую диагностику, когда вы звоните die
! Приведенная ниже программа идентифицирует себя ($0
), сообщает, что она пыталась сделать (open
) и почему это не удалось ($!
). Кроме того, поскольку сообщение не заканчивается новой строкой, die
добавляет имя файла и номер строки, в которой оно было вызвано.
my $fakefd = 12345;
open(STDOUT, ">&=", $fakefd) or die("$0: open: $!");
Это производит
prog.pl: open: Bad file descriptor at foo.pl line 2.
Согласно документации для _fdopen
(поскольку вы использовали >&=
, а не >&
), он имеет два режима отказа:
Если выполнение разрешено продолжать, errno
устанавливается либо на EBADF
, что указывает на неверный дескриптор файла, либо на EINVAL
, указывая, что режим был нулевым указателем.
Вторым будет ошибка в Perl, и это маловероятно, потому что я не вижу нигде в perlio.c
, где используется вычислительный режим: все они являются статическими строками.
Что-то пошло не так с $saveout
. Может быть $saveout
были закрыты, прежде чем пытаться восстановить его? Из вашего примера неясно, включили ли вы прагму strict
. Если это не лексическое (объявлено с my
), вызываете ли вы функцию, которая также обезьяна с $saveout
?