Обновление 1/9/2014: TL; версия DR:. Внизу этого сообщения можно получить доступ к Cygwin для вызовов программ, не связанных с Cygwin.
Потратив время на то, чтобы сделать несколько сценариев bash, которые имеют значительный размер, новые версии Cygwin нарушили их. Эти скрипты вызывают в собственные приложения Win32, которые не связаны с Cygwin, который, по-видимому, официально не поддерживается Cygwin.
Это стало для меня неожиданностью, поскольку в течение многих лет у меня создалось впечатление, что Cygwin можно использовать в более смешанной среде, которая сочетает в себе как родные приложения, не связанные с Cygwin Win32, так и программы POSIX с использованием уровня совместимости Cygwin. Но, по-видимому, поддерживается только уровень совместимости POSIX, и если работающие приложения Win32 не Cygwin работают, то это считается счастливым совпадением.
Я нашел это из несовместимости, с которой я столкнулся, с запущенными программами, скомпилированными с .NET Framework, из Cygwin. Это работало нормально, но было разбито несколько месяцев назад. В частности, стандартный вывод из .NET-программы, которая передается по каналу любому другому стандарту Win32, обычно приводит к тому, что получающая программа Win32 получает сигнал о преждевременном конце файла, поскольку Cygwin недавно переключился на каналы сообщений из байт-труб несколько месяцев назад - и каналы сообщений кажутся несовместимыми с любым приложением-получателем с использованием Visual С++ или .NET Framework. Это связано с тем, что .NET выдает нулевую запись на стандартный вывод, который передается только принимающему приложению, если используется канал сообщений. Получающее приложение успешно считывает нулевые байты, поэтому считает, что это конец файла. Похоже, что проект не считает это реальной проблемой, поскольку они, по-видимому, действительно не поддерживают запуск не Cygwin-программ из Cygwin (сюрприз!).
Чтобы процитировать проект, возглавляющий Кристофера Фейлора из нескольких электронных писем в списке рассылки:
То, что вы видите, может быть связано с тем, что Cygwin был изменен на использование в сообщениях-типах несколько раз назад. Это не собирается изменение. Это изменение было принято для решения проблемы с программами Cygwin и это, очевидно, наш приоритет №1.
Независимо от того, сколько людей используют Visual С++ или .NET, они действительно не наша целевая аудитория. Это хорошо, когда все работает для людей, которые не хотят использовать инструменты UNIX, но они не являются нашей основной задачей. Устранение проблем для людей, которые хотят использовать материалы, не связанные с Cygwin, не то, что я считаю высоким приоритетом.
От pipe.cc: Обратите внимание, что сторона записи канала открывается как PIPE_TYPE_MESSAGE. Это, похоже, более точно имитирует поведение Linux-труб и определенно требуется для обработки pty, поскольку fhandler_pty_master пишет к трубе в кусках, завершенной символом новой строки, когда режим CANON указано.
В приведенном выше комментарии показано отношение "и" здесь. Тип сообщения трубы более тесно имитируют поведение труб Linux (UNIX) И, безусловно, требуется для ptys.
Я согласен с Джеймсом в том, что время работы, вероятно, багги, но я также согласитесь, что cygwin должен иметь возможность справиться с этими сценариями.
Ваше полное согласие друг с другом не будет иметь многого эффект. Исходный код Cygwin не изменяется путем голосования.
Даже если эта проблема в конечном итоге исправлена - кто знает - они могут сломать что-то еще через 3 месяца и не хотят исправлять регресс. Они могли бы рассмотреть патч, но мне потребовалось некоторое время, чтобы понять, что работает. Я думаю, что мое время лучше проводить в другом месте, потому что ясно, что они вполне готовы нарушить совместимость с родными приложениями Win32 и не хотят тратить больше времени на то, чтобы работать с Win32. Поэтому я думаю, что Cygwin не следует рассматривать как стабильную платформу для смешанных сред Win32/Cygwin - каковы мои альтернативы? С чего начать, чтобы избежать полной перезаписи в нечто иное, чем bash? Я не использую больше, чем базовая установка Cygwin + некоторые базовые скрипты perl.
ОБНОВЛЕНИЕ:. После публикации этого исходного вопроса они в конце концов добавили новый флаг pipe_byte
в переменную среды CYGWIN
: посмотрите документацию. Если этот флаг установлен, он исправит проблему, описанную выше. При вызове программы, не связанной с Cygwin Win32, всегда убедитесь, что установлен флаг pipe_byte
.
Однако с тех пор я обнаружил несовместимость с .NET Framework 4.0 и Cygwin. Предыдущие версии .NET Framework не имеют этой проблемы. Я впервые упомянул о проблеме в списке рассылки Cygwin:
Синхронизация труб и несовместимость между Cygwin и .NET Framework 4.0
Не получив плодотворных ответов, я исследовал дальше и обнаружил, что Cygwin создает перекрывающиеся каналы, что вызывает проблему. Обратите внимание, что попытка использовать неперекрывающиеся вызовы API Win32 с перекрывающимся каналом - это undefined, а большинство (все?) Win32 не-Cygwin-программ не используют перекрывающиеся ввода-вывода с их стандартными файловыми дескрипторами. Я представил патч, который создает флаг pipe_nooverlap
в переменной среды CYGWIN
, которая предотвращает это:
Патч для необязательного отключения перекрывающихся каналов
К сожалению, они отклонили патч, поэтому вы никогда не увидите это в главной библиотеке Cygwin:
Re: Патч для необязательного отключения перекрывающихся каналов
Причины отказа от патча:
- Предполагалось, что я нарушил реализацию сигнала в Cygwin; Я не нашел, что это так, поскольку сигналы все еще используют перекрывающиеся каналы.
- Им не хочется добавлять флаг переменной среды, хотя это, по-видимому, проблемы с фиксацией.
- Они не хотят поддерживать код, который даже имеет возможность иметь неперекрывающиеся каналы.
С такими рассуждениями и отношениями я боюсь, что не могу придумать, как изменить патч в соответствии с их требованиями... они, похоже, решили запретить использование неперекрывающихся труб из когда-либо используемых. Я уже давно использую патч, и у меня не было никаких проблем с ним. Кроме того, я не могу думать о каких-либо ситуациях, когда флаг pipe_nooverlap
будет разорваться (см. Мой последующий адрес электронной почты в своем списке рассылки), но я оставил его как флаг только в случае возникновения проблем.
Итак, если вы хотите вызывать программы Cygwin Win32 или .NET Framework от Cygwin, вам необходимо сделать следующее:
- Примените мой патч к источнику любой версии Cygwin, которую вы используете. Не ожидайте, что этот патч появится в будущих версиях Cygwin.
- Установите флаги
pipe_byte
иpipe_nooverlap
в переменной средыCYGWIN
.
Это работает... на данный момент!!! Я публикую это на случай, если это поможет кому-то еще, кто все еще хочет использовать Cygwin для некоторых вещей.