
Cygwinのerrno変換が強化された変更点まとめ:WindowsエラーとPOSIX errnoの対応追加・構造体のconst化まで解説
CygwinはWindows上でUNIX互換環境を提供するため、Windows固有の失敗理由(Win32エラーコード)を、アプリが期待するPOSIXのerrnoへ変換する仕組みを持っています。今回の差分は、その中核のひとつであるwinsup/cygwin/errno.ccに手が入り、エラー対応表の拡充と、実装の安全性・最適化に寄与する調整が入っています。地味に見えて、ネットワークやストレージ周りの不具合解析が楽になる重要アップデートです。
- Cygwinのerrno変換が強化された変更点まとめ:WindowsエラーとPOSIX errnoの対応追加・構造体のconst化まで解説
- 変更対象はwinsup/cygwin/errno.cc:Cygwinの「失敗理由の翻訳機」
- まず押さえたい2つの主変更:年号更新と構造体の扱い変更
- いちばん重要:Windowsエラー→POSIX errnoの対応が増えた
- CANCELLED → EINTR:キャンセルは「割り込み」として扱う
- CONNECTION_REFUSED → ECONNREFUSED:ネットワーク失敗原因が明確に
- DEV_NOT_EXIST → ENOENT:デバイスが無いを「存在しない」に統一
- DS_GENERIC_ERROR → EIO:抽象的な失敗はI/Oエラーへ寄せる
- NOT_ENOUGH_QUOTA → EIO:クォータ不足を捕捉
- SERVICE_REQUEST_TIMEOUT / TIMEOUT → EBUSY:タイムアウト系を「忙しい」に分類
- UNEXP_NET_ERR → (差分が途中)ネットワークの想定外エラーも整理中
- この変更で何が良くなる?開発・運用の「地味に効く」改善点
- 注意点:errnoの意味は「方言」が出やすい
- まとめ:Cygwinの信頼性を底上げする、実務向けの改善
変更対象はwinsup/cygwin/errno.cc:Cygwinの「失敗理由の翻訳機」
errno.ccは、Windows APIが返すDWORDのエラー(例:ERROR_ACCESS_DENIEDなど)を、UNIX系プログラムが理解するerrno(例:EACCES)へ置き換えるためのロジックが集約されたファイルです。
多くのUNIX系ツールやライブラリは「失敗したらerrnoを見る」という前提で作られています。Windows上でそれを成立させるには、Cygwinが「Windowsの失敗理由」を「UNIXの失敗理由」に寄せて表現する必要があります。ここが弱いと、アプリは同じ失敗でも別の原因として扱ってしまい、リトライや例外処理の分岐が崩れます。
まず押さえたい2つの主変更:年号更新と構造体の扱い変更
差分の冒頭で目につくのは次の2点です。
1) 著作権表記の年号が2014まで更新
細部ですが、メンテナンスが継続していることを示す典型的な更新です。機能面への影響はありません。
2) 変換テーブルが「書き換え不可」寄りに:NO_COPY → const
差分では、エラー変換テーブル定義が
-
static NO_COPY struct { ... }
から -
static const struct { ... }
へ変更されています。
const化は「実行中にテーブルが変更されない」ことをコンパイラに明確に伝える意図が強く、結果として以下のメリットが期待できます。
-
意図しない書き換え防止(安全性)
-
最適化の余地(読み取り専用領域に置ける可能性、参照の最適化など)
-
スレッド環境での安心感(データが不変である前提が作りやすい)
Cygwinのように多くのプロセス・スレッドから参照されやすい基盤コードでは、「不変データにする」だけで事故率が下がります。
いちばん重要:Windowsエラー→POSIX errnoの対応が増えた
今回の差分の本丸は、X(WindowsError, errno)形式で列挙される対応表の拡充です。追加されたものの中から、実務上効きが大きいものを解説します。
CANCELLED → EINTR:キャンセルは「割り込み」として扱う
ERROR_CANCELLEDがEINTRに対応付けられました。EINTRは「システムコールが割り込まれた」を表すため、次のような動作が取りやすくなります。
-
I/O待ちがキャンセルされた場合に、アプリ側が正しくリトライ判断できる
-
タイムアウトやユーザーキャンセルを「中断」として統一的に処理しやすい
特に、端末・パイプ・ソケット周りで「中断」をどう扱うかはアプリ品質に直結します。
CONNECTION_REFUSED → ECONNREFUSED:ネットワーク失敗原因が明確に
ERROR_CONNECTION_REFUSEDがECONNREFUSEDへ。これはネットワーク系で非常にありがたい変更です。
-
接続先ポートが閉じている、サービスが起動していない等のケースを、
EIOやEINVALのような曖昧なエラーにしない -
アプリ側で「接続拒否ならバックオフ」「別ホストに切替」などの戦略が取りやすい
ログを見たときに原因が一発でわかるようになります。
DEV_NOT_EXIST → ENOENT:デバイスが無いを「存在しない」に統一
ERROR_DEV_NOT_EXISTがENOENTに対応。ENOENTはファイル/パスが無いときにも使われますが、UNIX世界では「指定対象が存在しない」を広く表現します。
-
/dev相当の扱いや、特殊デバイスを参照するツールの挙動が自然になる -
「存在しないなら作る」「別経路を探す」などの分岐が素直になる
DS_GENERIC_ERROR → EIO:抽象的な失敗はI/Oエラーへ寄せる
ERROR_DS_GENERIC_ERRORがEIOに。ディレクトリサービス(DS)絡みの包括的失敗を、POSIX側では汎用のI/Oエラーとして扱う方針です。アプリ側からすると「対象は正しいが操作が成立しなかった」系として扱いやすくなります。
NOT_ENOUGH_QUOTA → EIO:クォータ不足を捕捉
ERROR_NOT_ENOUGH_QUOTAがEIOに追加されました。POSIX側にもEDQUOT(ディスククォータ超過)がありますが、状況や互換性の判断でEIOに寄せた可能性があります。
実務上は、以下のようなトラブルシュートがしやすくなります。
-
「空き容量はあるのに書けない」ケースで、Windows側のクォータ制限が疑える
-
ストレージ系の障害を、より一貫した分類でログに残せる
SERVICE_REQUEST_TIMEOUT / TIMEOUT → EBUSY:タイムアウト系を「忙しい」に分類
ERROR_SERVICE_REQUEST_TIMEOUTとERROR_TIMEOUTがEBUSYに追加されています。EBUSYは「リソースが使用中/要求を受け付けられない」寄りの意味で、タイムアウトをそこに寄せるのは少し意外に見えるかもしれません。
ただ、Cygwinの世界では「一時的に成功しない」失敗をEBUSYとして扱うと、アプリが次を取りやすい場合があります。
-
リトライ設計があるコードで「致命傷扱い」になりにくい
-
一時的失敗としてログ分類できる
とはいえ、アプリがETIMEDOUTを強く期待している場合は注意点にもなります(後述)。
UNEXP_NET_ERR → (差分が途中)ネットワークの想定外エラーも整理中
末尾が途中で切れていますが、UNEXP_NET_ERR(予期しないネットワークエラー)も追加対象として見えており、ネットワーク周辺のエラー整理を強化している流れが読み取れます。
この変更で何が良くなる?開発・運用の「地味に効く」改善点
今回の追加は、単に「対応表が増えた」以上の価値があります。
-
原因分析が速くなる:
ECONNREFUSEDのように意味が明確なerrnoが増えると、ログの解像度が上がる -
アプリの分岐が正しくなる:中断=
EINTR、存在しない=ENOENTなど、定番の分岐が成立しやすい -
再現性が上がる:Windows側の状態が同じなら、Cygwin側の
errnoも一貫しやすくなる
特にネットワーク(拒否・タイムアウト)とI/O(キャンセル・クォータ・デバイス不在)は、現場で遭遇頻度が高い領域です。
注意点:errnoの意味は「方言」が出やすい
Cygwinは互換層なので、どうしても「Windowsの出来事」を「POSIXの言葉」に翻訳します。その際、完全一致の概念がないこともあります。
-
タイムアウトが
EBUSYに寄ると、ETIMEDOUT前提の実装では意図とズレる可能性がある -
クォータ不足が
EIOに寄ると、EDQUOTで拾う設計は効かない場合がある
ただしこれは、Cygwinが「互換性と実用性の落としどころ」を選んだ結果でもあります。重要なのは、今回の変更で「曖昧な分類が減り、より使える分類が増えた」ことです。
まとめ:Cygwinの信頼性を底上げする、実務向けの改善
winsup/cygwin/errno.ccの差分は、CygwinがWindowsのエラーをより正確にPOSIXのerrnoへ落とし込むためのアップデートでした。const化で基盤コードの安全性が上がり、さらにキャンセル・接続拒否・デバイス不在・クォータ不足・タイムアウトなど、よく遭遇する失敗原因がより扱いやすいerrnoへマッピングされています。
Cygwin上で動くツールの挙動が「UNIXらしく」なり、ログの読みやすさと復旧ロジックの精度が上がる。目立たないけれど、使い込むほど効いてくるタイプの改善です。