Cygwin ユーザーズガイド


目次

1. Cygwin の概要
1.1. これは何ですか?
1.2. Cygwin ツールはフリーソフトウェアですか?
1.3. Cygwin プロジェクトの簡単な歴史
1.4. Windows により慣れている方のためのクイックスタートガイド
1.5. UNIX により慣れている方のためのクイックスタートガイド
1.6. Cygwin の機能のハイライト
1.6.1. イントロダクション
1.6.2. Windows NT と 9x の両方のサポート
1.6.3. パーミッションとセキュリティ
1.6.4. ファイルアクセス
1.6.5. テキストモード対バイナリモード
1.6.6. ANSI C ライブラリ
1.6.7. プロセスの生成
1.6.8. シグナル
1.6.9. ソケット
1.6.10. Select
2. Cygwin をセットアップする
2.1. インターネットセットアップ
2.1.1. ダウンロード元
2.1.2. インストールディレクトリの選択
2.1.3. ローカルパッケージディレクトリ
2.1.4. 接続方法
2.1.5. ミラーサイトの選択
2.1.6. パッケージの選択
2.1.7. ダウンロードとインストールの進捗状況
2.1.8. アイコン
2.1.9. インストール後処理スクリプト
2.2. 環境変数
2.3. NT セキュリティと ntsec の使用方法
2.3.1. NT セキュリティ
2.3.2. プロセスの特権
2.3.3. ファイルパーミッション
2.3.4. Cygwin での NT SID
2.3.5. マッピングの漏れ
2.3.6. ACL API
2.3.7. 新しい setuid のコンセプト
2.3.8. ユーザコンテキストの切り替え
2.3.9. 特別な値を持つユーザ ID 及びグループ ID
2.4. Cygwin の最大メモリを変更する
2.5. bash のカスタマイズ
3. Cygwin を使う
3.1. パス名のマッピング
3.1.1. イントロダクション
3.1.2. Cygwin マウントテーブル
3.1.3. パスに関連する追加情報
3.2. テキストモードとバイナリモード
3.2.1. 論点
3.2.2. デフォルトでの Cygwin の動作
3.2.3. 例
3.2.4. バイナリ? それともテキスト?
3.2.5. プログラミング
3.3. ファイルパーミッション
3.4. 特殊なファイル名
3.4.1. DOS デバイス
3.4.2. POSIX デバイス
3.4.3. 拡張子 .exe
3.4.4. /proc ファイルシステム
3.4.5. @パス名
3.5. CYGWIN 環境変数
3.6. Cygserver
3.6.1. Cygserver とは何ですか?
3.6.2. Cygserver のコマンドラインオプション
3.6.3. Cygserver の起動方法
3.6.4. Cygserver サービスの利用方法
3.6.5. Cygserver の設定ファイル
3.7. Cygwin ユーティリティ
3.7.1. cygcheck
3.7.2. cygpath
3.7.3. dumper
3.7.4. getfacl
3.7.5. kill
3.7.6. mkgroup
3.7.7. mkpasswd
3.7.8. mount
3.7.8.1. mount を使う
3.7.8.2. Cygdrive マウントポイント
3.7.8.3. 制限
3.7.9. passwd
3.7.10. ps
3.7.11. regtool
3.7.12. setfacl
3.7.13. ssp
3.7.14. strace
3.7.15. umount
3.8. Cygwin を Windows と共に効果的に使う
3.8.1. パス名
3.8.2. コンソールプログラム
3.8.3. Cygwin と Windows のネットワーク接続
3.8.4. cygutils パッケージ
3.8.5. cygutils を利用してショートカットを作成する
3.8.6. cygutils を利用した印刷
4. Cygwin におけるプログラミング
4.1. Cygwin 上で GCC を使用する
4.1.1. コンソールモードアプリケーション
4.1.2. GUI モードアプリケーション
4.2. Cygwin プログラムのデバッグ
4.3. DLL のビルドと利用
4.3.1. DLL のビルド
4.3.2. DLL に対するリンク
4.4. Windows リソースの定義
5. 日本語訳への注

Cygwin とは Windows 上における Linux 的な環境です。 Cygwin は基本的な POSIX (Portable Operating System Interface) システムコールを提供するエミュレーション層である DLL(cygwin1.dll)と、 Linux 的なルック & フィールを提供する様々なツールの集合から構成されています。 Cygwin DLL は Windows 95 以降の x86 版 Windows 上で動作します。

Cygwin をインストールすれば、ユーザは数多くの標準的な UNIX ユーティリティを利用することが出来ます。これらのツールは bash のような Cygwin が提供するシェル上で利用することも、 Windows のコマンドプロンプト上で利用することも出来ます。 加えて、プログラマは 標準的な Microsoft の Win32 API 及び Cygwin API を利用して、Win32 のコンソールアプリケーション又は GUI アプリケーションを作成することが出来ます。結果として、数多くの重要な UNIX プログラムを大規模なソースコードの修正なしに容易に移植することが出来ます。 (Cygwin の配布物中に含まれる開発ツールに入っているパッケージを含んだ)殆どの GNU ソフトウエアの configure とビルドもこの対象となります。

はい。幾つかは GNU のソフトウェア(gcc、gas、ld、など)であり、幾つかは標準的な X11 ライセンス によって保護されています。パブリックドメインなものもあれば、Red Hat が書いて GNU 一般公有使用許諾契約書 (GPL)の元に置いたものもあります。シェアウェアはありません。 これを使用するために誰かにお金を支払う必要はありませんが、これらのツールを使用する上で GNU GPLがどのような影響を与えるかについての詳細な情報を、FAQ の著作権の章を読んで確認しなければなりません。もし Cygwin を使って商用(GPL でない)アプリケーションを移植しようと考えているのであれば、Cygwin の商用ライセンスが必要になるかもしれません。 商用ライセンスについての詳細な情報については、 http://www.redhat.com/software/tools/cygwin/. を参照して下さい。 ネイティブ Win32 版 の GNUPro の顧客は、 通常の窓口を通じてバグレポートを送ったり質問したりすることが出来ます。 その他の質問は全て、このプロジェクトのメーリングリストである に送ってください。

Cygwin の開発は Cygnus Solutions(現在は Red Hat Software の一部門となっています) によって 1995 年から始められました。まず、開発ツール(gccgdbgas など)の強化が行われました。 これによって Win32 ネイティブオブジェクトファイルの生成と解釈が出来るようになりました。 次の仕事はツールを Windows NT/95 に移植することでした。ソースの大部分を Win32 API の文脈で動作するように書き換えることでも出来たでしょうが、 その方法では個々のツール全てに対して膨大な時間を費やすことになります。 その代わりに我々は、共有ライブラリ(Cygwin DLL)を書くという全く異なったアプローチを取ることにしました。 このライブラリは UNIX 風の環境に必要な機能 (forkspawnsignalsselectsocketsなど)のうち、 Win32 API に欠けているものを追加します。 我々はこの新しいインタフェースを Cygwin API と呼んでいます。 このライブラリが作成された後は、 UNIX 上のクロスコンパイラを使ってこのライブラリをリンクし、 動作する Win32 ツールをビルドすることが可能になりました。

この時点で我々は、Windows 95/NT 上で自分自身を再構築可能なネイティブツールを作成する、という目標を達成しました(これはよく「セルフホスティング」と呼ばれます)。 95 にも NT にも UNIX 上の標準的なユーザツール(fileutils、textutils、 bash などなど)は付属していないので、私たちは Cygwin API と共に動作する同様の GNU ツールを手に入れる必要がありました。 それまで、これらのツールの殆どは Windows 専用にビルドされていたため、 configure スクリプトをクロスコンパイルできるように修正する必要がありました。 その変更以外にも、ごく僅かですがソースレベルの変更が必要でした。 bash が開発ツールやユーザツールと共に正しく動作すれば、 Windows 95 も NT も、GNU configure のメカニズムから見れば UNIX の一種のように見えます。セルフホスティングは 1996 年 10 月にリリースされた beta 17.1 以降で達成されました。

完全な Cygwin ツールセットは、単一の巨大な存在としてのみインストール可能でした。 2000 年 4 月に、プロジェクトは 新しい Cygwin Net Release をアナウンスしました。 Net Release では、パッケージを個々にインストール及びアップデートするためのネイティブ Win32 プログラムである setup.exe が提供されています。 Cygwin DLL と setup.exe は、今も継続して開発されています。

もし UNIX の世界に初めて足を踏み入れたのであれば、 この世界を理解することは困難であるということにまず気付くでしょう。 このガイドは包括的なものではありませんから、インターネット上で利用可能な各種のリソースを利用して UNIX の基本について理解することをお勧めします(「UNIX 基本」或いは「UNIX 入門」などで検索してみて下さい)。

基本的な Cygwin 環境をインストールするには setup.exe プログラムを実行し、各ページで Next をクリックします。 デフォルトの設定は多くのユーザにとって適切なものです。 各オプションが何を意味するのかについてより深く知りたければ、 項2.1. 「インターネットセットアップ」 を参照して下さい。 Cygwin のパッケージをインストール、或いはアップデートしたいときは、常に setup.exe を利用して下さい。 Cygwin を特別な目的でインストールするのであれば、setup.exe を利用して必要なツールをインストールします。 例えば、C++ のプログラムをコンパイルしたければ gcc-g++ パッケージと、恐らくは nano のようなテキストエディタが必要でしょう。 setup.exe を実行し、パッケージインストール画面でカテゴリとパッケージをクリックすれば、 インストール或いはアップデートの対象とするものを選択出来ます。

もう一つの選択肢は、All カテゴリの Default フィールドをクリックして Install へと変更し、全てのパッケージをインストールするというものです。しかし、この方法では何百 MB ものソフトウェアがあなたのコンピュータにダウンロード及びインストールされるということに注意して下さい。 最良のプランはおそらく、個別のカテゴリをクリックしてカテゴリ全体、或いはカテゴリ中の必要なパッケージを選んでインストールすることでしょう。

Windows 上での経験を持つ開発者は、Microsoft の Win32 API を利用するコンソール実行形式、或いは GUI の実行形式を作成するためのツールが揃っていることに気がつくでしょう。 dlltool ユーティリティは Windows のダイナミックリンクライブラリ (DLL)を作成するために使われます。リソースコンパイラとして windres も提供されています。全てのツールは Microsoft のコマンドプロンプトから利用可能です。この場合、通常の Windows パス名も完全にサポートされます。

強力なコマンドライン環境に飢えている経験豊富な UNIX の利用者は、 Cygwin を存分に楽しむことが出来るでしょう。幾つかのワークアラウンドが含まれているため、 Cygwin の動作は大部分の UNIX 系オペレーティングシステムとは異なっていることに注意して下さい。 更なる詳細については、項3.8. 「Cygwin を Windows と共に効果的に使う」 に記述されています。

グラフィカルな setup.exe プログラムを利用することによって、 いつでも Cygwin のパッケージをアップデート、或いはインストールすることが可能です。 デフォルトでは setup.exe は最小限のパッケージしかインストールしませんので、 好みのユーティリティをパッケージ選択画面から選んで下さい。 特定のツールを探すには、Cygwin の Web サイトにある Setup Package Search が利用出来ます。 setup.exe の各オプションが何を意味するかについての更なる詳細については、 項2.1. 「インターネットセットアップ」 を参照して下さい。

もう一つの選択肢は、All カテゴリの Default フィールドをクリックして Install へと変更し、全てのパッケージをインストールするというものです。しかし、この方法では何百 MB ものソフトウェアがあなたのコンピュータにダウンロード及びインストールされるということに注意して下さい。 最良のプランはおそらく、個別のカテゴリをクリックしてカテゴリ全体、或いはカテゴリ中の必要なパッケージを選んでインストールすることでしょう。

UNIX での経験を持つ開発者は、今まで慣れ親しんできたユーティリティ群(UNIX シェルを含む)を見つけることが出来るでしょう。 コンパイラツールは、多くの人々が既に UNIX 上で使ったであろうと思われる、Windows ホスト上に唯一移植された標準の GNU コンパイラです。UNIX ソフトウェアを Windows NT または 9x に移植したいと考えているプログラマには、Cygwin ライブラリが ソースコードに対する最小の変更だけで UNIX パッケージを移植出来る簡単な方法を提供しているということことが分かるでしょう。

Cygwin DLL をリンクしたバイナリが実行されると、Cygwin DLL はアプリケーションのテキストセグメントをロードします。 Cygwin DLL の元で動作する全てのプロセスがアクセスすることになる UNIX カーネルをエミュレートするために、Cygwin DLL はまず、 DLL の個々のインスタンスを使用するプロセスがアクセス可能な共有メモリ領域を作成します。 特に、オープンされたファイルのディスクリプタの保持と、 fork 及び exec の補助のために使われます。 全てのプロセスは、追加された共有メモリ領域中にプロセス ID、ユーザ ID、 シグナルマスク、そして他のプロセス独自の情報を格納するための per_process 構造をも保持します。

Cygwin DLL は Win32 API を使用して実装されており、 全ての Win32 ホスト上で動作します。 プロセスは標準 Win32 サブシステムの元で動作するので、 これらのプロセスは Win32 API 呼び出しと同様に Cygwin が提供する UNIX 互換の呼び出しを扱うことが出来ます。 これはプログラマに対し、Win32 API を使用して作られたプログラム構造のデザインに完全なる柔軟性を与えます。 例えば、彼らは Cygwin を使用することによって UNIX バックエンド上に、 Win32 API 呼び出しを使用した Win32 特有の GUI を書くことが出来るのです。

開発工程の初期に、我々はそれが不可能な場合、又は Win32 プラットフォーム上でのツールの使い勝手を極めて悪くしてしまう場合、 POSIX.1 のような既存の UNIX 標準の存在に対して厳格に忠実である必要はないのではないかという、重要な設計の議論を行いました。 多くの場合は、ある環境変数によってデフォルトの振る舞いを上書きしたり、 標準への準拠を強制出来るようにしました。

Windows NT はアクセス制御リスト(ACL)をベースにした、 洗練されたセキュリティモデルを備えています。 デフォルトでは、Cygwin は Win32 ファイルの所有権とパーミッションを、 より標準的な古い UNIX のモデルに対応付けます。 Cygwin バージョン 1.1 は、新しいバージョンの Solaris が使用しているシステムコールによって ACL のサポートを取り入れています。 「ntsec」機能と共に使用されるこの機能については別章で説明されています。 chmod 呼び出しは、Win32 の同等な機能から UNIX スタイルのパーミッションを割り当てます。 多くのプログラムは /etc/passwd と /etc/group ファイルの存在を仮定しているため、 オペレーティングシステムによって提供されるユーザとグループの情報からこれらのファイルを構築するユーティリティが提供されています。

Windows NT 環境下では、administrator はファイルの chown が出来ます。 Cygwin バージョン 1.1.2 以来、setuid のコンセプト又は API 呼び出しのメカニズムはありません。 バージョン 1.1.3 では、Cygwin は Windows NT/2000 環境下での実 UID 及び実効 UID の設定メカニズムを取り入れました。 これについては ntsec の章で説明されています。

Windows 9x 環境下では、この状況は相当に異なるものとなります。 セキュリティモデルが準備されていないため、Cygwin は ファイルがデフォルトのユーザ ID とグループ ID によって所有されているように見せかけることで、 ファイルの所有権を偽装します。 NT 環境下では、ファイルパーミッションはファイルの読み / 書き / 実行状態を調べることによって決定することが出来ます。 Windows 9x 環境下での chown 呼び出しは、 実装されていないというエラーを返すのではなく、 何らの処理をも行わずに直ちに成功を返します。 ファイルの所有権という概念が全く存在しない場合、 全てのユーザはファイルを一緒に所有していることになるので、 これは本質的に適切です。

Cygwin プロセスに関する情報を蓄えた共有メモリを使用する「カーネル」 の密接な関係に関する議論は重要です。 それらの領域にはまだ何らの保護もなされていないため、 Cygwin プロセスが予期しない動作を起こすように、 悪意のあるユーザがそれを書き換えることが原則的に可能です。 (オペレーティングシステムによるセキュリティが欠けているがための) Windows 9x 環境下での新しい問題ではなく、 Windows NT 環境下でもセキュリティホールとなり得るものです。 なぜなら、あるユーザによって実行された Cygwin プログラムに対し、 他のユーザが通常の Windows NT のプログラムでは不可能な方法によって共有メモリ情報を変更することにより、 そのプログラムに影響を与えることが出来るからです。 このため、高いセキュリティが要求されるアプリケーションにおいて Cygwin を使用することは適切ではありません。 実際のところ、これはライブラリの大部分の用途に対しては大きな問題とはなりませんが。

Cygwin は、 ディレクトリの区切りとしてスラッシュあるいはバックスラッシュを使用する、 Win32 と POSIX の両方のパス形式をサポートしています。 DLL が受け取ったパスは必要に応じて Win32 パスから POSIX パスへと変換されます。結果として、ライブラリはファイルシステムが POSIX 準拠のものであると考え、Win32 API 関数を呼び出すときは常にパスを Win32 パスへと変換します。UNC パス名(二つのスラッシュから始まる) もサポートされています。

Windows ファイルシステム空間にあるこの POSIX ビューのレイアウトは、Windows レジストリ中に蓄えられます。 デフォルトでは、スラッシュ(「/」)ディレクトリはシステムパーティションを示しますが、 これは Cygwin の mount ユーティリティによって簡単に変更出来ます。 スラッシュパーティションの選択に加えて、このユーティリティは任意の Win32 パスを POSIX ファイルシステム空間へとマウントします。多くの人々は、各ドライブ文字をスラッシュパーティションへと割り当てる(例えば、C:\ を /c に、D:\ を /d に、など)ためにこのユーティリティを使用しています。

Cygwin DLL は、 Win32 のパス又はパスのリストから POSIX パスへの変換あるいはその逆を行う外部プログラムによって使用される、 様々な Cygwin 独自の関数をエクスポートしています。 シェルスクリプトや Makefile はこれらの関数を直接呼び出すことは出来ません。 代わりに、それらの中では Cygwin に付属する cygpath ユーティリティを実行することによって、同様のパス変換が行えます。

Win32 のファイルシステムは大文字小文字の区別を保存しますが、 大文字小文字の区別は行いません。 Cygwin は現在のところ、大文字小文字の区別はサポートしていません。 なぜなら、実際には大文字小文字の区別に頼っている UNIX プログラムはごく僅かだからです。 大文字小文字の区別のサポートによってファイル名を押し延ばすことが出来ますが、 これはライブラリに対して不要なオーバーヘッドを発生させ、 それらのファイルに対する非 Cygwin アプリケーションのアクセスをより難しいものにしてしまうでしょう。

シンボリックリンクは、リンク位置を示すパスに続くマジッククッキーを含んだファイルによってエミュレートされます。 それらのファイルにはシステム属性が付与されます。 システム属性を持つファイルだけが、 そのファイルがシンボリックリンクであるか、 そうでないかの判定のために用いられるからです。 ハードリンクは Windows NT 環境上の NTFS ファイルシステムでは完全にサポートされています。FAT ファイルシステムでは、 link 呼び出しは単純にファイルのコピーを行いますが、 この方針は多くの場合問題なく動きます。

ファイルに対する i ノード番号は、完全な Win32 パスをハッシュして計算されます。stat 呼び出しによって生成される i ノード番号は、dirent 構造体中の d_ino に格納される値と常に合致します。 この方法で生成される番号はユニークである保証はない、ということに注意して下さい。 しかし重複した i ノード番号が生成される可能性は低いため、 このことが重大な問題となったことはありません。

chroot はリリース 1.1.3 からサポートされました。chroot は本来、Windows ではサポートされていないという点に注意して下さい。これは幾つかの制限が存在することを意味します。第一に、chroot 呼び出しは特権呼び出しではなく、個々のユーザが呼び出すことが可能です。 第二に、chroot 環境はネイティブの Windows プロセスに対して安全ではありません。 chroot 環境をサポートしたいのであれば、例えば、制限付きのアクセスを備えた匿名 FTP をサポートしたいのであれば、ネイティブの Cygwin アプリケーションだけが chroot 環境の内部にアクセス出来るように注意する必要があります。 アプリケーションがファイルシステムに対するアクセスに Cygwin の POSIX API だけを使用するのであれば、そのアプリケーションは意図した通りに制限されます。 これは POSIX パスだけでなく、Win32 パス(ドライブ文字とバックスラッシュを含む)と CIFS パス(//server/share 又は \\server\share)もまた含まれます。

Cygwin での fork 呼び出しは、 Win32 API の最上位に対してうまく割り当てることが出来ないという点で、 特に興味深いものです。 そのため、この呼び出しを正しく実装することはたいへん難しい作業です。 現在、Cygwin の fork は初期の UNIX でよく使用されたような、 non-copy-on-write 実装を用いています。

親プロセスが子プロセスを fork する際に最初に発生する作業は、 親プロセスが子プロセスのために Cygwin のプロセステーブル内の領域を初期化するすることです。 それから、Win32 の CreateProcess 呼び出しを使用して、 サスペンド状態の子プロセスを作成します。 次に、親プロセスは自分自身のコンテキストを保持するために setjmp を呼び出し、Cygwin の共有メモリ領域 (Cygwin の全てのタスクの間で共有される) にこのコンテキストへのポインタを設定します。 そして、親プロセス自身のアドレス領域からサスペンド状態の子プロセスのアドレス 領域へとコピーすることで、 子プロセスの .data セクション及び .bss セクションを埋めます。 子プロセスのアドレス領域が初期化された後、 子プロセスが実行され、その間親プロセスはミューテックスを使用して待機します。 子プロセスは自分自身が fork されたことを知ると、保存されたジャンプバッファを使用して longjump します。 子プロセスは親プロセスが待機しているミューテックスをセットし、 もう一つのミューテックスをブロックします。 これは親プロセスに対して、 子プロセスが親プロセスのスタックとヒープをコピーし終わったことを知らせるシグナルとなり、 その後、親プロセスは子プロセスが待機していたミューテックスをリリースして fork 呼び出しから復帰します。 最後に、子プロセスは最後のミューテックスのブロックから復帰し、 共有領域を使用して渡されたメモリマップ済み領域を再生成して、 自分自身の fork から復帰します。

親プロセスと子プロセスの間で発生するコンテキストスイッチの数を減らすことで、 いかにして fork の実装を高速化するかということに対する幾つかのアイデアを得たとしても、 その後 fork はほぼ間違いなく常に Win32 の元では役に立たないものとなりました。 幸運なことに、多くの状況下では Cygwin が提供する spawn ファミリの呼び出しが、多少の作業だけで fork/exec の代わりを務めることが出来ます。これらの呼び出しは Win32 API の最上位に対して正しくマップされています。この結果として、 それらはより効果的なものとなりました。 fork の代わりに spawn 呼び出しを使うようにコンパイラのドライバプログラムを変更するという作業は些細な変更であり、 我々のテストではコンパイル速度が 20% から 30% も上昇しました。

しかしながら、spawn と exec にはそれぞれ独自の問題があります。 Win32 の元では実際の exec を行う方法が存在しないため、 Cygwin は独自のプロセス ID(PID)を考案しました。 この結果として、プロセスが複数の exec 呼び出しを実行した場合、 それらは一つの Cygwin PID に対して割り当てられた複数の Windows PID となります。幾つかの場合、これらの Win32 プロセスの個々のスタブが残ってしまい、 それらを呼び出した Cygwin プロセスの終了を待つことになります。

Cygwin のプロセスの開始時に、Cygwin DLL はシグナルハンドリング用に第二のスレッドを生成します。 このスレッドはシグナルをプロセスに渡すために使用される Windows イベントを待ち受けています。 プロセスに対してシグナルが送られた時点で、 このスレッドは自分自身が持つシグナルのビットマスクを調べ、 適切な方法でシグナル処理を行います。

実装における様々な複雑化は、 シグナルハンドラは実行プログラムとして同じアドレス空間で処理を行うという事実からきています。 直接の結論は、Cygwin システム関数は、 それを避けるための特別な処理がなければ中断され得るということです。 シグナルを送信する sig_send 関数が中断されるという事態を避けるため、 幾らかの長さに行きます(原文: We go to some lengths to prevent the sig_send function that sends signals from being interrupted.)。 プロセスが別のプロセスに対してシグナルを送る場合、 sig_send がシグナルの送信を完全に完了する前に中断されぬよう、 sig_send の周りにミューテックスが置かれます。

プロセスが自分自身に対してシグナルを送る場合、 ミューテックスの代わりにセマフォ及びイベントのペアを使用します。 sig_send はイベントによって開始され、 そのシグナルを処理するシグナルハンドラに立てられたセマフォをインクリメントします。 シグナルが処理されると、シグナルハンドラによっては既に実行されたイベントをシグナル状態にします。 このプロセスは POSIX によって要求されているプロセス間 (intraprocess)シグナル同期を管理します。

多くの標準的な UNIX のシグナルが提供されています。 ジョブコントロールは、シェルがサポートしていれば動作します。

UNIX の select 関数は、 Win32 API の最上位に正しくマップ出来ないもう一つの呼び出しです。 たいへんがっかりさせられたことに、Winsock 中の Win32 の select はソケットハンドルに対してしか動作しません。 我々の実装では、select は異なるタイプのファイルディスクリプタ (ソケット、パイプ、ハンドル、そして独自の Windows メッセージ仮想デバイスである /dev/windows) に対しても通常は機能します。

select 関数に入る時点で最初に行われる処理は、 ファイル記述子を異なるタイプごとに整列することです。 ここで、二つの場合が考えられます。 最も単純なのは、最低一つのファイル記述子が、 可能状態にあることを常に知ることが出来るタイプ (ディスク上のファイルのような)である場合です。 この場合、select は可能状態にあるかどうかを確認するために他のタイプのファイル記述子をポーリングするやいなや、速やかに復帰します。より複雑なのは、 ソケット又はパイプへのファイル記述子が可能状態かどうかを待っている場合です。 これはメインスレッドが自分自身をサスペンドさせ、その後、 ファイル記述子のタイプごとに一つのスレッドを開始することによって実現されています。 個々のスレッドは自分が担当しているタイプのファイルディスクリプタを、 それに対応する Win32 API を呼び出すことによってポーリングします。 スレッドが可能状態になったファイルディスクリプタを発見するやいなや、 そのスレッドはメインスレッドに復帰するよう通知します。 全てのファイル記述子を一度にポーリングした後、select がリターンします。

Cygwin ネットリリースをインストールするには、 http://cygwin.com/ にアクセスして "Install Cygwin Now!" をクリックします。これによって、インターネット経由で完全な Cygwin インストレーションのダウンロードを行う GUI インストーラ(setup.exe と呼ばれています)をダウンロード出来ます。 Cygwin をインストールするには、個々の画面に表示される指示に従って下さい。

setup.exe インストーラは初心者にも使い易くデザインされていますが、 一方で経験豊富なユーザのために柔軟性も残してあります。 ボランティアの開発者チームは絶えず setup.exe に対する作業を続けています。新しい機能を要求する前に、 CVS README にある「やるべきことリスト(wishlist)」をチェックして下さい。 CVS 内のバージョンでは、その機能は既に存在していることでしょう!

全てのオプションのデフォルトの値は一般的なインストール用に合うように選ばれていますので、各ページにある Next ボタンを単にクリックしていくだけで、最小の Cygwin 環境が手に入ります。 この唯一の例外は Cygwin のミラーサイトの選択であり、 http://cygwin.com/mirrors.html にあるリストから試しに選択してみることが出来ます。 setup.exe によるインストールの各ページについての更なる説明が必要なら、 これ以降を続けて読んで下さい。 このガイドは読者が既に UNIX(或いは UNIX 系の OS) に関する基礎的な知識を持っていることを前提としています。読者が UNIX の初心者であれば、 他の情報源 にも当たったほうがよいでしょう。

Cygwin は様々なソフトウェアを管理するためにパッケージを利用しています。 デフォルトである Install from Internet オプションが選択されると、setup.exe はパッケージの内容を実際にインストールする前に、パッケージをローカルディレクトリに保存します。 Download from Internet は最初の部分 (パッケージをローカルへと保存する)だけを、そして Install from Local Directory は次の部分 (パッケージの内容物のインストール)だけを行います。

The Download from Internet オプションは主として基本となる Cygwin パッケージツリーを特定のコンピュータに作成するためのものです。 ディレクトリ構造をそのままに、完全なローカルのパッケージツリーを別のマシンへとコピーすれば、 Install from Local Directory によって他の様々なマシンへのインストールが可能となります。 例えば、C:\cache\ ディレクトリを作成し、 そこに setup.exe を置いておきます。 setup.exe によって Install from InternetDownload from Internet を実行してから、C:\cache\ 全体を各マシンにコピーし、Install from Local Directory を選択します。 不幸にして、setup.exe はまだ無人インストールをサポートしていません。

基本的なミラー用の機能は用意されていますが、 Cygwin のインストールを幅広く管理するのであれば、 内容を最新に保つために wget のようなミラー用のツールを利用することをお勧めします。 Cygwin メーリングリストのある有能なユーザが、この作業を実現するための簡単なデモスクリプトを作成しました。mkcygwget でメーリングリストのアーカイブを探してみて下さい。

貴方にはどこから Cygwin をダウンロードするかについてを知る方法はないため、最低でも一つのミラーサイトを選択する必要があります。 Cygwin のミラーサイトは地理的にも世界中の様々な場所に分散されています。 http://cygwin.com/mirrors.html にあるリストを参照し、近い場所を選択して下さい。 Ctrl キーを押しながら一つ一つクリックしていけば、複数のミラーサイトを選択することが出来ます。 ミラーサイトの一覧に上がっていない URL を利用する場合(例えば、貴方の組織が内部的に Cygwin をミラーしている場合など)、その URL を追加することも出来ます。

選択されたミラーサイト毎に、setup.exesetup.bz2 という小さなテキストファイルをダウンロードします。 このファイルには各ミラーサイトから取得可能なパッケージのリストに加えて、 setup.exe が解釈して選択ウィンドウに表示するために利用する、 パッケージ単位の基本的な情報が含まれています。このファイルの形式に関する詳細については、 setup.exe のホームページ を参照して下さい。

選択ウィンドウは setup.exe の中でも最も込み入った部分です。 パッケージ群はカテゴリでグループ化されており、更に一つのパッケージは複数のカテゴリ (ボランティアのパッケージ開発者によって割り当てられています)に所属していることがあります。 個々のパッケージは、階層化された選択ウィンドウ内にあるこれらのカテゴリ内に置かれています。 デフォルトでは setup.exeBase カテゴリ内のパッケージ、及びそれらのパッケージが依存しているパッケージのみをインストールするので、結果として最小の Cygwin インストレーションが出来上がります。しかし、これには gcc(Devel カテゴリの中にあります)のように、一般的に使われる数多くのツールは含まれていません。 setup.exe は自動的に依存関係にあるパッケージを選択しますので、要求されるパッケージを選択対象から外さないように注意して下さい。 特に、Base カテゴリに含まれているものは全て必要です。

setup.exe の表示方法は変更することが可能です。 インストールしたいパッケージの名前は知っているが、 そのパッケージがどのカテゴリに所属しているか分からない場合などに役立つでしょう。 View ボタンをクリックすると、Category(デフォルト)、 Full(全てのパッケージ)、そして Partial(アップグレード対象のパッケージのみ)が切り替えられます。 もし UNIX に慣れ親しんでいるのであれば、おそらくはお気に入りのツールを探すために 少なくとも Full の表示を一目見たくなることでしょう。

既に一度でも Cygwin をインストールしたことがあれば、 setup.exe の選択ウィンドウを現在の Cygwin 環境の管理にも利用することが出来ます。 インストールされたパッケージの情報は Cygwin 環境中の /etc/setup/ に保持されています。 setup.exe がこのディレクトリを探し出すことが出来なければ、 setup.exe は Cygwin 環境がインストールされていないものとして動作します。 インストールされているパッケージよりも新しいバージョンのパッケージが利用可能である場合、 setup.exe は自動的にパッケージをアップグレード対象とします。 既存のパッケージのアンインストール、再インストール、或いはソースの取得を行うには、 Keep をクリックして UninstallReinstall 或いは Source へとトグルさせます。 また、アップグレード後の再起動を避けるためには、setup.exe を利用してアップグレードパッケージをインストールする前に、全ての Cygwin アプリケーションのウィンドウを閉じ、全ての Cygwin プロセスを終了させておきます。

setup.exe 選択ウィンドウの最後の機能は、Previous 及び Experimental パッケージに対するものです。 デフォルトでは選択ウィンドウには各パッケージの現在のバージョンのみが表示されますが、 ミラーサイトは以前のバージョンを少なくとも一つは保持していますし、時としてテストバージョン或いはベータバージョンのパッケージが利用可能となっていることもあります。 これらのパッケージを参照するには、Prev 又は Exp ラジオボタンをクリックして下さい。 しかしながら注意して下さい。次回 setup.exe を実行した際、setup.exe は古いバージョン、或いは実験(experimental)バージョンを現在の安定版で置き換えようとするでしょう。

最後に、setup.exe はインストールされたパッケージの設定を正しく完了させるべく、 幾つかの post-install スクリプトを実行します。各スクリプトは個別に実行されるため、 様々なウィンドウがポップアップします。何が行われているのかについて興味があるのであれば、 http://cygwin.com/setup.html にある Cygwin Package Contributor's Guide を参照して下さい。 最後の post-install スクリプトの処理が完了すると、setup.exe は完了を告げるダイアログを表示します。 OpenSSH サーバのような幾つかのパッケージでは、手動でのサイト特有の設定が必要となります。 関連するドキュメントは /usr/doc/Cygwin/ 或いは /usr/share/doc/Cygwin/ ディレクトリの中に格納されているでしょう。

bash を実行する前に、幾つかの環境変数を設定しておく必要があります。 bash が起動する前に非常に重要な環境変数を設定するためのバッチファイルが提供されます。 これは最初に bash を起動するための、最も安全な方法です。 デフォルトでは、このバッチファイルはセットアップ中に指定したルートディレクトリにインストールされ、スタートメニューの「Cygwin」中にも配置されます。 このファイルは、好みに合うように編集出来ます。

CYGWIN 環境変数は Cygwin 実行環境における共通の設定を行うために使用されます。 bash を実行させる前に CYGWIN 環境変数に何も設定せずにおくことも出来ますし、DOS シェルで設定するときの方法に似た方法で tty を設定しておく(^Z を使ったジョブコントロールをサポートする、など)ことも出来ます。

C:\> set CYGWIN=tty notitle glob

PATH 環境変数は Cygwin アプリケーションが実行ファイルを検索するディレクトリのリストとして扱われます。 この環境変数は Cygwin プロセスが最初に開始された時点で、 Windows フォーマット(C:\WinNT\system32;C:\WinNT のようなもの)から UNIX フォーマット (/WinNT/system32:/WinNT)へと変換されます。 bash の外側で Cygwin のツールを利用するつもりであれば、 少なくとも x:\cygwin\bin ディレクトリ (「x:\cygwin」が Cygwin インストレーションの「ルート」である場合)が含まれるように設定しておかなければなりません。

HOME 環境変数は、 多くのプログラムがあなたのホームディレクトリの位置を決定するために使用しますので、設定しておくことをお薦めします。 この環境変数もまた、Cygwin プロセスが最初に開始された時点で Windows フォーマットから変換されます。 bash を実行する前にあなたのホームディレクトリを設定しておいて下さい。

TERM 環境変数は端末タイプを設定します。 この変数に値が設定されていない場合は、 cygwin が自動的に設定されます。

LD_LIBRARY_PATH 環境変数には、 Cygwin の関数 dlopen() がロードする DLL ファイルを検索するディレクトリのリストを指定します。 この環境変数は Cygwin プロセスが最初に開始されたときに、Windows フォーマットから UNIX フォーマットへと変換されます。 多くの Cygwin アプリケーションは dlopen() を使用しませんので、この変数を指定する必要はありません。

UNIX 的なオブジェクトパーミッションの設定は、 CYGWIN 環境変数(no)ntsec を設定することによって行われます。 デフォルトでは ntsec が設定されています。

ntsec のデザイン上のゴールは、Windows NT のセキュリティ機能を使ってより UNIX 的なパーミッション構造を実現することにあります。 この変更について説明するため、項2.3.1. 「NT セキュリティ」 では NT セキュリティについての概略を示します。

プロセスの特権 では、プロセスの特権(privileges)に関する ntsec での変更点について議論します。

ファイルパーミッション では UNIX 的なファイルパーミッションの設定について示します。

Cygwin での NT SID では、/etc/passwd 及び /etc/group 内での SID の利用方法について説明します。

マッピングの漏れ では Windows NT のパーミッションマッピングの漏れを例証します。

ACL API リリース 1.1 で導入された新しいアクセス制御リスト(ACL) API について簡単に記述します。

新しい setuid のコンセプト ではリリース 1.1.3 で導入された setuid のコンセプトに対する新たなサポートについて記述します。

ユーザコンテキストの切り替え では、SYSTEM ユーザを利用したユーザコンテキストの切り替えを行う方法に関する基本について説明します。

特別な値を持つユーザ ID 及びグループ ID では、/etc/passwd 或いは /etc/group に存在しないユーザ及びグループを Cygwin が表現する方法について説明します。

NT セキュリティでは、異なる種類の「オブジェクト」に対するアクセスの許可と拒否を規定することが出来ます。 「オブジェクト」とはファイル、プロセス、スレッド、セマフォなどです。

NT セキュリティの主要なデータ構造は「セキュリティ記述子(security descriptor; SD)」構造です。 この構造はオブジェクトが許可(又は拒否)されるパーミッションを明示し、「セキュリティ識別子(security identifiers; SID)」に関連付けられる情報を含んでいます。

SID はユーザ、グループ、ドメインに対するユニークな識別子です。SID は UNIX の UID 及び GID に相当しますが、SID はネットワークを越えてユニークとなるため、より複雑なものとなっています。 以下に例を挙げます。

システム「foo」の SID:

  S-1-5-21-165875785-1005667432-441284377

システム「foo」におけるユーザ「johndoe」の SID:

  S-1-5-21-165875785-1005667432-441284377-1023

上記の例は SID の表示方法に関する慣習を示しています。 最初の「S」はこれが SID であることを示しています。 次の数値はバージョン番号であり、常に 1 です。 次の番号は「トップレベル権限(top-level authority)」と呼ばれる、 SID の発行元を示す識別子です。

NT ネットワークに所属する個々のシステムは独自の SID を持っていますが、この状況は NT ドメインでは異なり、ドメインコントローラの SID が個々のドメインユーザのベース SID となります。 もしある NT ユーザがドメインユーザとして一つのアカウントを持っており、 それとは別に彼のローカルマシン上のアカウントを持っていた場合、 同じユーザ名とパスワードを使用していたとしても、これらのアカウントはあらゆる状況下で異なるものとなります!

ドメイン「bar」の SID:

  S-1-5-21-186985262-1144665072-740312968

ドメイン「bar」におけるユーザ「johndoe」の SID:

  S-1-5-21-186985262-1144665072-740312968-1207

SID の最後のパートは「相対識別子(relative identifier; RID)」 と呼ばれ、Cygwin ではデフォルトで UID 及び GID として扱われます。 その名称と上記の例が暗示するように、 この ID は一つのシステム又はドメイン中でのみユニークです。

一人のユーザが 2 つの異なったシステムの間で同じ RID を持つことが可能であるという点に注意して下さい。 それにも関わらず、結果として生成される SID は異なったものとなります。 二つの SID は、NT ネットワーク内での異なるユーザを示しているのです。

UNIX ID と NT SID の間には、「既知グループ(well known groups)」 の存在という非常に大きな違いがあります。 例えば、UNIX には「全てのユーザ」のグループに対する GID はありませんが、 NT ではそれに相当する「Everyone(英語版での名称)」と呼ばれる SID があります。 既知グループの SID は NT ネットワーク内でユニークではありませんが、 それらの意義は間違いようがありません。 既知グループの例としては、以下のようなものがあります。

everyone                                S-1-1-0
creator/owner                           S-1-3-0
batch process (「at」コマンドによる)    S-1-5-3
authenticated users                     S-1-5-11
system                                  S-1-5-18

SID の最後の重要なグループは「事前定義グループ(predefined groups)」です。 このグループはドメインの外部にあるシステムにおいて、 主にユーザパーミッションの管理を簡単にするために使われます。 対応する SID はネットワークを越えてユニークではないので、 これらはローカルでのみ解釈されます。

administrators                  S-1-5-32-544
users                           S-1-5-32-545
guests                          S-1-5-32-546
...

それでは、 パーミッションはどのようにしてオブジェクトに対して与えられるのでしょう? プロセスは SD をオブジェクトに与えます。オブジェクトの SD は 3 つのパートから構成されています。

UNIX は 3 つの異なるパーミッション、即ち、所有者、 グループ、全員に対するパーミッションを作り出すことが出来ます。 それに対して ACL は、潜在的には無限のメンバに対して存在し得ます。 各メンバはアクセス制御エントリ(access control element: ACE)と呼ばれます。 ACE は 3 つの部分から構成されています。

ACE の 2 つの重要なタイプは「アクセス許可 ACE」と「アクセス拒否 ACE」です。 Cygwin バージョン 1.1.0 まで、ntsec の機能は「アクセス許可 ACE」しか使用していませんでした。 それ以降のバージョンでは、UNIX パーミッションを可能な限り反映するように「アクセス拒否 ACE」をも使用します。

オブジェクトに対して設定可能なパーミッションは UNIX に比べてより複雑です。 例えば、オブジェクトの削除パーミッションは書き込みパーミッションとは異なったものです。

前述の方法と共に、NT はオブジェクトへのパーミッションを更なる特別な方法で有効にしたり無効にすることが出来ます。 しかし Cygwin ではどうでしょう? POSIX 環境には POSIX システムのセキュリティ仕様がありますが、 NT セキュリティモデルは POSIX のモデルの殆どを再現することができます。 ntsec の手法はこれを Cygwin で実現しようとするものです。

「殆ど? どうして殆どなの???」そう質問されるかもしれませんが、 何故なら NT モデルには漏れがあるからです。詳細については第 5 章で説明します。

系統だったオブジェクトセキュリティの生成は少々分かりにくいものですが、 一般的には 2 つの単純なヴァリエーションだけが使われます。

安全なオブジェクトの作成やオープンに利用される関数の引数には、 「セキュリティ属性(security attributes; SA)」 と呼ばれる別のデータ構造体が使われます。この構造体は SD と、 作成またはオープンされるオブジェクトに対して返されるハンドルが子プロセスに継承されるか否かを示すフラグから構成されます。 このプロパティは ntsec では重要ではないので、この文書では SD と SA の違いは無視されます。

Cygwin の制御の元で開始される全てのプロセスには、シグナルを送信する目的で使われるセマフォがアタッチされています。 このセマフォの生成は cigproc.cc の「getsem」関数内で行われています。 この関数に対する最初の引数「CreateSemaphore」は SA です。 ntsec が適用されていない場合、この SA はセマフォに対してデフォルトのセキュリティを割り当てます。 ここで単純な不都合が発生します。 プロセスの所有者だけしかそのプロセスに対してシグナルを送信できないのです。 言い換えれば、そのプロセスの所有者が Administrators グループに属していなければ、Administrator は決してそのプロセスを殺すことが出来ません! プロセスがサービスマネージャから起動されていた場合、これは特に問題となります。

現在の ntsec はプロセス制御セマフォに対し、プロセスのユーザ、Administrators グループ、そしてオペレーティングシステム自身を示す用語「SYSTEM」に対する個々のパーミッションを持った SA を割り当てます。 この SA の生成は「shared.cc」内の「sec_user」関数で行われています。 Administrators グループのメンバはプロセスの所有者に関わらず、Cygwin 上で生成された全プロセスに対してシグナルを送信することができます。

更に、今や「CreateProcess」 によって開始された個々のプロセスは適切なセキュリティ設定を持ちます。 これは「spawn.cc」の「spawn_guts」関数中で定義されています。 他のユーザコンテキストにおいて開始されたプロセスに対するセキュリティ設定も、 新しいユーザの SID を追加する必要があります。 「CreateProcessAsUser」呼び出しによってプロセスが開始された場合、 sec_user 関数は新しいユーザの SID に対する追加のエントリを含んだ SA を生成します。

ntsec が有効であれば、ファイルパーミッションは UNIX と同様に設定されます。 所有者とグループ、そして所有者、グループ、「Everyone」に対する ACE を含んだファイルに対しては SD が割り当てられます。

完全な UNIX 的なパーミッションの設定はファイル security.cc 中で行われます。2 つの関数「get_nt_attribute」と「set_nt_attribute」 がその主要なコードです。SD の読み取りと書き込みは関数「read_sd」と 「write_sd」にて行われます。 「write_sd」はより簡単な関数「SetFileSecurity」の代わりに関数 「BackupRead」を使用します。 なぜなら、「SetFileSecurity」では呼び出し元とは異なる所有者を設定出来ないからです。

Cygwin の外側でファイル「foo」を生成した場合、ls -ln の結果は次のようになるでしょう。

Administrators グループのメンバとしてログインした場合:

  rwxrwxrwx 1  544  513  ... foo

そうでない場合:

  rwxrwxrwx 1  1000  513  ... foo

ユーザ ID とグループ ID に注目して下さい。544 は Administrators グループの UID です。これは Windows NT の「仕様」:-P です。仮にあなたが Administrators のメンバであったとした場合、あなたが作成した全てのファイルはあなたではなく、Administrators グループの所有物となります。

第 2 の例は NT のユーザ管理ツールによって作成された最初のユーザの UID を示しています。ユーザとグループには 1000 から始まる連続した番号が振られます。 ユーザとグループは同じ番号体系を使用するので、ユーザとグループの間で同じ ID を共有することは出来ません。

両方の例において、GID 513 には特別な点があります。 この GID はローカルシステムとドメインにおいて異なる名称を持つ既知グループです。 ドメインの外ではこのグループは 「なし」(英語では「None」、ドイツ語では「Kein」、フランス語では「Aucun」などとなります) と呼ばれ、ドメイン内では「Domain Users」と呼ばれます。 不幸にして、グループ「なし」はドメインの外側ではユーザ管理ツール上に表示されません! これは大きな混乱を生じさせますが、マイナスの影響は与えないとは思われます。

ntsec を正しく動かすためには /etc/passwd/etc/group が必要です。Cygwin リリース 1.0 では、 名前と ID は対応する NT の ID と一致していなければなりません! 既に述べたように、Cygwin での ID は NT SID の RID です。 私の NT ワークステーションのユーザ「corinna」の SID は以下の通りです。

  S-1-5-21-165875785-1005667432-441284377-1000

最後の番号を覚えておいて下さい。RID は 1000 であり、 これが Cygwin 上での UID となります。

不幸なことに、ドメインに属していないワークステーションとサーバでは、プライマリグループを設定することが出来ません! この場合、ユーザとプライマリグループの間には何らの関連もありません。 NT はプライマリグループとして 513(なし)を返し、既存のローカルグループへのメンバシップについては関与しません。

このようなシステムにおいて、mkpasswd -l -g を使用した際に「なし」をプライマリグループとして使用したくないのであれば(恐らくしたくないですよね)、手作業でプライマリグループを変更する必要があります。

以下の例を見て下さい。これらは私の /etc/passwd 及び /etc/group の一部分であり、SID を格納する前の状態です(詳細については次の章で説明します)。 私の個人ユーザのエントリ以外、全てのエントリは既知のエントリです。

私が自分のプライマリグループを 513(none)から 547(powerusers)へと変更したことがわかるでしょう。 これによって、Cygwin の内部で私が作成した全てのファイルの所有グループは、none ではなく powerusers となります。これこそが私が望んでいたことです。

passwd ファイル中にはグループも記述されています。これには二つの長所があります。

前述した通り、グループ「SYSTEM」はオペレーティングシステム自身の同義語であり、通常はサービスマネージャによって起動されたプロセスの所有者となります。 サービスマネージャによって起動されたプロセスによって作成されたファイルについても同様です。

Cygwin リリース 1.1 では、 /etc/passwd/etc/group の利用についての新しいテクニックが導入されました。

現在、両ファイルはユーザとグループの SID を含んでいます。 SID は /etc/passwd の pw_gecos フィールドの最後に、 そして /etc/group の gr_passwd フィールドの最後に格納されています。

これには以下の利点があります:

mkpasswdmkgroup の両ツールは、必要となるエントリをデフォルトで作成します。 そうしたくなければ、オプション -s 又は --no-sids を使用することが出来ますが、これはお奨め出来ません。 ntsec は SID を利用することによって、より正しく動作するからです。

/etc/passwd の pw_gecos フィールドは、コンマ区切りのリストとして定義されていることに注意して下さい。 SID は最後のフィールドでなければなりません!

既に述べた通り、Cygwin でのアカウント名は NT でのアカウント名とは異なるものとすることが出来ます。 もし「telnet」又はそれ以外の方法でログインする場合、特別な login を使用しなければなりません。 そして pw_gecos フィールドには、ドメインを含めた NT 上のユーザ名を定義するために、もう一つのフィールドを追加することが出来ます。 そう、それぞれのドメインのユーザとしてログインすることが出来るのです。 このシンタックスは簡単です。pw_gecos フィールドに U-ntdomain\ntusername の形式でエントリを追加するだけです。 SID はまだ pw_gecos の最後のフィールドとして残しておかねばならないことを覚えておいて下さい!

the_king::1:1:Elvis Presley,U-STILLHERE\elvis,S-1-5-21-1234-5678-9012-1000:/bin/sh

ローカルユーザに対しては、ドメインを落すだけです。

the_king::1:1:Elvis Presley,U-elvis,S-1-5-21-1234-5678-9012-1000:/bin/sh

どちらの場合でも、ユーザのパスワードは NT のユーザデータベースから取得されます。 passwd ファイルからではありません!

前章と同様、例として私個人の/etc/passwd/etc/group を提示します。 これらのファイルはかなり変更されている点に注意して下さい! 変更しなければならない理由はありませんが、 これはテストのためであり、そして…楽しみのためでもあります。

同様の変更を行うのは、このコンセプトを理解している場合にのみにして下さい。 そうでない場合は、何かが正しく動作しなくなっても驚かないで下さい。 破滅を迎えてしまった場合、mkpasswd 及び mkgroup でファイルを作り直すことが出来ます。 特に、ユーザ SYSTEM の UID と名前は変更しないで下さい。 大部分は動作するでしょうが、SYSTEM アカウントの元でローカルサービスとして動作する幾つかの Cygwin アプリケーションは、突如として奇妙な振る舞いを示すかもしれません。

今こそ NT パーミッションにおける漏れについて説明するときです。 公式の文書では、以下のように簡単に説明されています。

最後のルールは推奨事項であり、決まりではありません。NT は順番とは無関係に ACL を正しく扱います。 希望する順番で ACE を取得するよう、第 2 のルールを修正することは出来ません。

不幸なことに、NT4 のエクスプローラのセキュリティタブでは、 完全にアクセス拒否 ACE を取り扱うことが出来ません。 Windows 2000 のエクスプローラは、ACE を読み込む前にその順番を再整理します。 困ったことに、この整列結果はキャンセルボタンをクリックしても戻りません。

まだ「どこに漏れがあるの?」と尋ねられることでしょう。NT の ACL は POSIX パーミッションの個々の可能な組み合わせを反映することが出来ません。 例えば、

rw-r-xrw-

1 回目の挑戦:

UserAllow:   110
GroupAllow:  101
OthersAllow: 110

ふーむ、許可の蓄積によって、group が実行可能であれば user も実行可能となります。

2 回目の挑戦:

UserDeny:    001
GroupAllow:  101
OthersAllow: 110

今度は user は読み書き可能ですが実行は出来ません。これでいいのでしょうか? いいえ! 不幸にも others が書き込み可能であるため、group も書き込み可能になってしまいます。

3 回目の挑戦:

UserDeny:    001
GroupDeny:   010
GroupAllow:  001
OthersAllow: 110

今度は group は意図した通り書き込み不可になりましたが、しかし不幸なことに、user もまたどこにも書き込み出来ません。どのようにすればこの問題が解決出来るのでしょう? 公式なルールによると、UserAllow は GroupDeny に従わねばなりませんが、しかしこの方法では解決することが出来ないのは明らかです。

唯一の方法:

UserDeny:    001
UserAllow:   010
GroupDeny:   010
GroupAllow:  001
OthersAllow: 110

繰り返します: これは NT4 と Windows 2000 の両方で動作します。GUI だけがこの順番を設定出来ないのです。

ユーザコンテキストを変更する必要がある UNIX アプリケーションは、Windows API には存在しない setuid 及び seteuid 呼び出しを使用します。 それにも関わらず、これらの呼び出しは Cygwin 1.1.3 以降、Windows NT/2000 の元ではサポートされています。 しかしながら NT セキュリティの性質により、この機能が必要なアプリケーションに対しては修正が必要となります。

NT はユーザとパーミッションを識別するために「アクセストークン」と呼ばれるものを使用します。 ユーザコンテキストを変更するためには、アプリケーションは「アクセストークン」を要求する必要があります。 これは通常、NT の API 関数 LogonUser を呼び出すことによって実行されます。アクセストークンが返されると、アクセストークンは ImpersonateLoggedOnUser によってユーザコンテキストを変更するために、 又は CreateProcessAsUser によって生成された子プロセスのユーザコンテキストを変換するために使用されます。 但し、LogonUser を使用するアプリケーションは、以下の特殊なユーザ権利を持っていなければならないという重大な制限があります。

「オペレーティングシステムの一部として機能(Act as part of the operating system)」
「プロセスレベルトークンの置き換え(Replace process level token)」
「クォータの増加(Increase quotas)」

デフォルトで設定されているユーザ権利では、Administrators にもこの全ての権利が設定されていないということに注意して下さい。

setuid を使用するアプリケーションが最小の変更で移植出来るように、二つの新しい Cygwin の呼び出しが導入されました。Cygwin に対して正しいアクセストークンを与えれば、POSIX アプリケーションで利用するのと同様、普通に seteuid 又は setuid を呼び出すことが出来ます。 sexec 呼び出しは何も必要としません。 setuid を使用するアプリケーションの移植は、以下の簡単な例で示すように行えます。

/* まず、全ての必要な Cygwin 関連ファイルをインクルードする */
#ifdef __CYGWIN__
#include <windows.h>
#include <sys/cygwin.h>
/* Windows のバージョンを決定するために以下の定義を使用する */
#define is_winnt        (GetVersion() < 0x80000000)
#endif

[...]

  struct passwd *user_pwd_entry = getpwnam (username);
  char *cleartext_password = getpass ("Password:");

[...]

#ifdef __CYGWIN__
  /* 典型的なパスワードのテストに対するパッチ */
  if (is_winnt)
    {
      HANDLE token;

      /* NT のアクセストークンを得ることが出来るかどうか */
      token = cygwin_logon_user (user_pwd_entry, cleartext_password);
      if (token == INVALID_HANDLE_VALUE)
         error_exit;
      /* 新しい偽装トークンを Cygwin に通知。
         今や Cygwin は、setuid 又は seteuid 呼び出しを使用することに
         よってユーザコンテキストを変更出来る。*/
      cygwin_set_impersonation_token (token);
    }
  else
#endif /* CYGWIN */
    /* Windows 9x でうまく動作させるための標準的な方法 */
    hashed_password = crypt (cleartext_password, salt);
    if (!user_pwd_entry ||
        strcmp (hashed_password, user_pwd_entry->pw_password))
      error_exit;

[...]

  /* 後は全て同じです! */

  setegid (user_pwd_entry->pw_gid);
  seteuid (user_pwd_entry->pw_uid);
  execl ("/bin/sh", ...);  

アクセストークンを取得するための新しい Cygwin の呼び出しは、以下のように定義されています。

#include <windows.h>
#include <sys/cygwin.h>

HANDLE
cygwin_logon_user (struct passwd *pw, const char *cleartext_password)

異なったユーザでのログオンを行う際には、常にこの関数を呼び出すことが出来ます。 また、更なる呼び出しに備えてアクセストークンを保持しておくためには、第二の関数を使用することが出来ます。

#include <windows.h>
#include <sys/cygwin.h>

void
cygwin_set_impersonation_token (HANDLE hToken);

この呼び出しは、更なる setuid/seteuid の呼び出しによって変更されるユーザコンテキストを Cygwin に対して通知します。 他のユーザコンテキストへ setuid/seteuid するための正しいアクセストークンが必要になった場合は、パラメータに自身の UID を指定して setuid/seteuid を使用することで、自身のユーザコンテキストへ復帰することが出来ます。

cygwin_logon_user 呼び出しによって返される様々なアクセストークンを覚えていれば、 以下の順序に注意深く従うことにより、ユーザコンテキストを異なるものへと変更することが出来ます。

  cygwin_set_impersonation_token (user1_token);
  seteuid (user1_uid);

[...]

  seteuid (own_uid);
  cygwin_set_impersonation_token (user2_token);
  seteuid (user2_uid);

[...]

  seteuid (own_uid);
  cygwin_set_impersonation_token (user1_token);
  seteuid (user1_uid);

など。

現在のユーザのユーザ ID が 400 という特別な値に設定されている場合、そのユーザは /etc/passwd には含まれませんが、ユーザ名は常に正しく表示されます。 他のユーザ(或いは、ユーザとして扱われる Windows グループ)で /etc/passwd に含まれないものは、 そのユーザ ID が -1 という特別な値(ls の出力では 65535 となります)となります。 このような場合、そのユーザのユーザ名は「????????」と表示されます。

現在のユーザのログイングループ ID が 401 という特別な値に設定されている場合、そのユーザは /etc/passwd には含まれません。 他のユーザで /etc/passwd に含まれないものは、 そのユーザのログイングループ ID が -1 という特別な値になっています。 /etc/passwd に含まれているユーザだが、そのユーザのグループが /etc/group に含まれておらず、かつそのグループはそのユーザのログイングループではないという場合、そのグループのグループ ID は特別な値 -1 に設定されています。 このグループ(ID が -1 のグループ)のグループ名は、「????????」と表示されます。 Cygwin 1.3.20 以前のリリースでは、グループ ID 401 にはグループ名「なし」が与えられていました。Cygwin リリース 1.3.20 以降、グループ ID 401 には、この状況を少しでも解決するために実行するべきであるコマンド名である「mkpasswd」が表示されるようになりました。

また、Cygwin リリース 1.3.20 以降では、もし現在のユーザが /etc/passwd に含まれているにも関わらず、ユーザのログイングループが /etc/group に含まれていない場合、グループ名として同様に「mkgroup」を表示します。

要約すれば、次のようになります:

特別なユーザとグループの名称は表示に利用されるだけであり、 「mkpasswd」という名前を持つユーザが実際に /etc/passwd に含まれる(或いは、「mkgroup」というユーザが /etc/group に含まれる)ということを回避させるものではありません。 そのようなことをした場合は、混乱が発生するであろうことには注意して下さい。

デフォルトでは、Cygwin プログラムには 384MB 以上のメモリ(プログラム + データ)を割り当てることは出来ません。 一般的な状況では、この値を変更する必要はないでしょう。 しかし、より多くの実メモリ或いは仮想メモリを必要とする場合は、レジストリの HKEY_LOCAL_MACHINE (全てのユーザの制限を変更する)又は HKEY_CURRENT_USER(現在のユーザの制限だけを変更する)セクションに、あるエントリを追加します。

DWORDheap_chunk_in_mb を追加し、必要となるメモリの上限値を 10 進数表現の MB 単位で設定します。 Cygwin から行うのであれば、Cygwin パッケージに含まれている regtool プログラムを利用するほうがよいでしょう (regtool 及び他の Cygwin ユーティリティに関する更なる情報については 項3.7. 「Cygwin ユーティリティ」 を参照するか、各ユーティリティに --help オプションを付けて実行して下さい)。 システムのレジストリに損傷を与えると、結果としてシステムが使用不能になり得ます。 regtool を利用する場合は常に十分な注意を払って下さい。 この例はメモリの上限を 1024 MB に設定しています。

regtool -i set /HKLM/Software/Cygnus\ Solutions/Cygwin/heap_chunk_in_mb 1024
regtool -v list /HKLM/Software/Cygnus\ Solutions/Cygwin

全ての実行中の Cygwin プロセスを終了させ、再度起動して下さい。 メモリはシステムのスワップスペースのサイズから、実行中のプロセスの全合計サイズを引いた量まで割り当てることが出来ます。 システムスワップは少なくとも物理メモリよりは大きくなければなりません。 スワップ量はコントロールパネルの「システム」を利用して変更することが出来ます。

これは DJ Delorie による簡単なプログラムで、 システムのメモリ割り当ての上限値をテストします。

main()
{
  unsigned int bit=0x40000000, sum=0;
  char *x;

  while (bit > 4096)
  {
    x = malloc(bit);
    if (x)
    sum += bit;
    bit >>= 1;
  }
  printf("%08x bytes (%.1fMb)\n", sum, sum/1024.0/1024.0);
  return 0;
}

このプログラムは次のようにしてコンパイル出来ます。

gcc max_memory.c -o max_memory.exe

プログラムを実行すると、割り当て可能なメモリの最大量が出力されます。

bash で適切にカット & ペーストが出来るように設定するには、 ウィンドウの「プロパティ」ボタンをクリックし、 「その他」タブを開きます。「範囲指定に使う(簡易編集モード)(原文:Quick Edit)」 をチェックし、「高速に貼り付け」からチェックを外します。 これらの設定は、次回にショートカットから bash を起動したときにも引き継がれます。 同様に、「プログラム」タブ中にある作業ディレクトリも設定出来ます。 「%HOME%」と入力しましょう。

ホームディレクトリには bash の動作をコントロールするための 3 つの初期化ファイルを置いておくべきです。.profile.bashrc そして .inputrc です。 これらの初期化ファイルは、bash の開始前に HOME が設定されていた場合にのみ読み込まれます。

.profile(他の名称も使用出来ます。bash の man ページを参照して下さい)は bash コマンドを含んでいます。 これは、bash がログインシェルとして開始された場合、例えば bash --login として開始されたときに実行されます。 このファイルは環境変数を定義してエクスポートしたり、bash 自身、又は bash から起動されるプログラムが使用する bash 関数を定義するのに便利です。 必要であれば PATH を再定義するためにも使えます。 現在の作業ディレクトリ(DOS とは違い、デフォルトではローカルディレクトリは検索されません) もまたコマンド探索対象とするためには、 PATH の最後に「:.」を追加しておくことをお薦めします。 動作が遅くなるのを防ぐために、unset MAILCHECK を設定するか、既存のメールの inbox を MAILPATH に指定しておくべきでしょう。

.bashrc.profile と似ていますが、bash が対話的に実行される度に実行されるものです。 これは環境を通じて継承されない要素、 例えばエイリアスのようなものを定義するために使われます。 もしログインシェルを使用しないのなら、 先に検討した .profile の内容を、 代わりにこのファイルに記述したいと考えるかもしれません。

shopt -s nocaseglob

は bash にファイル名を大文字小文字の区別を無視する形で認識させることが出来ます。 .bashrc はログインシェルでは自動的に読み込まれないことに注意して下さい。 .profile 中で読み込ませることは出来ます。

.inputrc は、 プログラムがどのように readline ライブラリ (bash に含まれています)を扱うかをコントロールします。 このファイルは自動的に読み込まれます。 完全な詳細については readline のマニュアル中の Function and Variable Index を参照して下さい。 以下のような設定について考えてみましょう。

# 補完時に大文字小文字の違いを無視する
set completion-ignore-case on
# bash を 8 ビットクリーンにする
set meta-flag on
set convert-meta off
set output-meta on

最後のコマンドは、ファイル名補完において大文字小文字の区別を無視させます。 Windows 環境では便利です。次の 3 つのコマンドは bash が 8 ビット文字を表示出来るようにするものであり、アクセント付きの文字を使用する言語では有効でしょう。 lessls のように readline を表示に利用しないツールでは、更なる設定が必要です。 .bashrc に以下の内容を記述して下さい。

alias less='/bin/less -r'
alias ls='/bin/ls -F --color=tty --show-control-chars'

訳注: 上に記述された .inputrc.bashrc におけるは、日本語を利用する際にも有用です。 なお、一部で流布している「.inputrcset kanji-code sjis を記述する」という設定方法は、日本語化パッチを適用していない bash では意味を持ちません。

本章では Cygwin 環境と伝統的な UNIX システムの間にある、 幾つかの重要な違いについて記述します。 標準的な UNIX コマンドの知識があることを仮定しています。

mount ユーティリティプログラムは、Win32 ドライブとネットワーク共有を Cygwin の内部的 POSIX ディレクトリツリーにマップするために使用されます。 これは典型的な UNIX のマウントプログラムのコンセプトと同様です。 Windows での経験が豊富であれば、mount ユーティリティはかつての DOS に存在した join と非常に似ており、ドライブ文字を任意のサブディレクトリとして扱うことを可能にするといえば分かりやすいかもしれません。

このマッピングは現在のユーザの Cygwin マウントテーブル(Windows レジストリ中に格納されています)に保存され、次回のログインの際にも取り出されることになります。 時として、ユーザ単位でのマウントと同様に、システム全体でのマウント情報を持つことが望ましいので、Cygwin の全利用者が継承するシステム全体のマウントテーブルもまた存在します。 システム全体のテーブルは、適切な権限を持ったユーザだけが修正可能です(Windows NT では Administrator 権限)。

現在のユーザのテーブルは 「"HKEY_CURRENT_USER/Software/Cygnus Solutions/Cygwin/mounts v<version>」以下に保存されています。ここで <version> とは Cygwin ライブラリによって割り当てられる最新のレジストリバージョンです(このバージョンはリリース番号と同一ではありません)。 システム全体のテーブルは HKEY_LOCAL_SYSTEM 以下にある同様のサブキーの下にあります。

デフォルトでは、POSIX ルート / はシステムパーティションに位置づけられていますが、mount コマンドを使用することによって Windows ファイルシステム中の任意のディレクトリで再定義することが出来ます。 Cygwin が Win32 パスから POSIX パスを生成したかどうかに関わらず、 最も長くマッチしたプレフィックスがマウントテーブル中で使われます。 すなわち、C:/c として、更に / としてマウントされている場合、 Cygwin は C:/foo/bar/c/foo/bar として変換することになります。

引数なしで mount を起動した場合、Cygwin の現在のマウントポイントを表示します。 以下の例では、C ドライブは POSIX ルートとして、D ドライブは /d としてマップされています。この例では、ルートマウントは Cygwin プログラムを使用する全てのユーザが使用出来るシステム全体のマウントポイントですが、一方で /d は現在のユーザだけが使用できます。

mount コマンドは新しいマウントポイントを追加するために、umount コマンドはマウントポイントを削除するために使用できます。Cygwin の POSIX ファイルシステムを設定するこれらのユーティリティの使用方法についての更なる情報が得るには、項3.7.8. 「mount」項3.7.15. 「umount」 を参照して下さい。

特定の Win32 パスを 既存のマウントによって POSIX パスへと変換することが出来なかった場合、Cygwin は常に自動的に POSIX パス /cygdrive の下にある仮想上のマウントポイントを使用します。例えば、Cygwin が Z:\foo にアクセスしたが、Z ドライブは現在のマウントテーブルには存在しなかった場合、 Z:\ は自動的に /cygdrive/Z へと変換されます。デフォルトのプレフィックス /cygdrive は変更可能です(更なる情報については 項3.7.8. 「mount」 を参照して下さい)。

個々のマウントポイントに対して、ある特定の属性を割り当てることが可能です。 自動的にマウントされるパーティションは「auto」として表示されます。 マウントには同様に、「textmode」又は「binmode」 ― デフォルトでテキストファイルがバイナリファイルと同様の方法で読まれるか否か ― を指定出来ます(テキストモードとバイナリモードに関する更なる情報については、項3.2. 「テキストモードとバイナリモード」を参照して下さい)。

cygpath プログラムを使うことにより、シェルスクリプト中で Win32 のパス名と POSIX のパス名を変換することが出来ます。詳細については 項3.7.2. 「cygpath」 を参照して下さい。

環境変数 HOMEPATH そして LD_LIBRARY_PATH は、Cygwin プロセスが最初に開始された時点で自動的に Win32 フォーマットから POSIX フォーマットへと変換されます (c:\cygwin\bin から /bin のように。但し、この Win32 パスがこのように POSIX パスとしてマウントされていた場合)。

シンボリックリンクもまた、Win32 パス名から POSIX パス名へとマップされます。 例えば、コマンド ln -s //pollux/home/joe/data /dataは、シンボリックリンクがデフォルトのファイルアクセスモードをセット出来なかった場合を除き、mount によって //pollux/home/joe/data/data へのマウントポイントとして作成されていた場合と同様の結果をもたらします。 異なるのは、シンボリックリンクによるマッピングはファイルシステム全体に渡って分布するといことと、カーネルテーブル中でマッチする最長のプレフィックスを使用する代わりに、ディレクトリツリー中を繰り返し移動することによって処理されるという点です。 なお、シンボリックリンクは「system」ファイル属性を正しくサポートするように構成されたネットワークドライブでのみ動作するということに気をつけて下さい。 多くのものは、デフォルトでは「system」ファイル属性を正しくサポートしません(例えば、UNIX の Samba サーバは、デフォルトではそのように動作しません)。

UNIX システムでは、アプリケーションがファイルを読み込む際、ディスク上にあるファイルの内容をきっちり正確に読み取り、書き込む際もそれと同様に動作します。 DOS/Windows の世界ではこの状況は異なり、ファイルはバイナリ又はテキストという二つのモードのどちらかで読み込まれます。 バイナリモードでは、システムは UNIX と同様にきっちり正確に動作します。 しかしテキストモードにおける書き込みでは、NL(\n、^J)は CR (\r, ^M) NL の連続へと変換されます。

アプリケーションから見たバイト数が実際のものとは異なってくるため、seek/fseek を呼び出したときには大混乱が発生することでしょう。

以下のプログラミングの章に記述されているように、このモードは明示的に指定することが出来ます。 理想的な DOS/Windows の世界では、行をレコードとみなして動作するプログラム (bashmakesed ... など)はファイルをテキストモードでオープンします (そして標準入出力を使用するときはモードを変更します)。それ以外の全てのプログラム (catcmptr ... など)はバイナリモードを使用します。Cygwin の習慣では、 明示的にオブジェクトファイルを扱うプログラムではバイナリモードを指定します(CR 問題を診断する際に有用である od コマンドがこれに該当します)。 その他の多くのプログラム(catcmptrなど)はデフォルトのモードを使用します。

Cygwin システムには、明示的にモードを指定しなかった場合、どのようにファイルをオープンするかを決定するための柔軟性が備わっています。 このルールは発展中であり、本章ではデザインゴールを示します。

  1. ファイルがマウントされたファイルシステム中に存在するのであれば(パス名が mount によって表示されるディレクトリから始まっていれば)、デフォルトはマウントフラグによって指定されます。 もしファイルがシンボリックリンクであるなら、ターゲットファイルシステムのモードが適用されます。

  2. ファイルがマウントされていないファイルシステム中に存在するのであれば(パスがドライブ文字を含んでいるような場合)、デフォルトはバイナリモードとなります。

  3. CYGWIN 環境変数が nobinmode を含んでいる場合を除き、パイプと非ファイルデバイスはバイナリモードでオープンされます。

  4. Cygwin プログラムがシェルから起動された場合、パイプされるかリダイレクトされる場合を除き、 標準入力、標準出力、標準エラー出力は CYGWIN 環境変数が tty を含んでいればバイナリモードとなり、そうでなければテキストモードとなります。

    リダイレクト時、Cygwin シェルはルール(a-c)を使用します。 これらのシェルが使用する CYGWIN の値はシェルが起動した時点での値であり、プログラムが実行された時点の値ではありません。 非 Cygwin シェルは常にパイプとリダイレクトをバイナリモードで行います。 非 Cygwin シェルでは、テキストマウントされたパーティションに存在する filename に対しては、コマンド cat filename | program program < filename は、異なるものとなります。

最大限の移植性を考慮して書かれた UNIX プログラムはテキストとバイナリのファイルの違いを知っており、Cygwin の元でも適切に動作します。 これらのプログラムにおいては、デフォルトがテキストモードであるのは有用な選択です。公式な Cygwin の配布物中に含まれるプログラムはデフォルトのモードで正しく動作します。

Windows プログラムは通常 CRLF フォーマットを使用するので、テキストモードは Cygwin と Windows プログラムの間でのファイルの混在をより簡単なものにします。 あいにく、テキストモードにはまだ幾つかの問題があります。 まず、Cygwin に含まれる幾つかのユーティリティは、必要なときにもまだバイナリモードを指定しません。 次に、作成するテキストファイルに CR を持ち込むと、それらを UNIX システムに持ち帰った時点で問題が発生することになるでしょう。

UNIX マシンのリモートファイルシステムをマウントするなら、又はファイルを UNIX マシンへ持ち帰るか、持ってくるのであれば、ファイルへのアクセスをバイナリモードで行いたいと考えるでしょう。 テキストファイルは UNIX の NL フォーマットとして通常通り作成され、Cygwin プログラムは UNIX 上で理解可能なフォーマットで全てのファイルを保存することを期待するでしょう。 Makefile とシェルスクリプトからは必ず CR を取り除き、ファイルを編集する場合は NL で終了する行を正しく編集 / 保存することが可能な DOS/Windows のエディタだけを使わなければなりません。

モードはディスク単位で決定することが出来ます(例えば、ローカルディスクはテキストモードでマウントし、ネットワークディスクはバイナリモードでマウントすることが出来ます)。 ディスクのパーティションについても同様です。 例えば、c: をテキストモードで、c:\home をバイナリモードでマウント出来ます。

Windows 9x 上ではファイルは常に読み込み可能であり、Cygwin はファイルが書き込み可能かどうかを判断するために独自のリードオンリーモードを使用します。 ファイル名が .bat、.com または .exe で終了しているか、或いはファイルの内容が #! で始まっているのなら、 そのファイルは実行可能だと判断されます。 その結果、chmod は「w」モードに対してのみ影響を与え、その他のモードは無言で無視されます。 つまり、ls -l はファイルを開いて読み込まなければなりません。 この処理は比較的遅くなりがちです。

NT 環境でも、ファイルパーミッションは基本的に Windows 9x と同様の動作によって決定されます。しかし、Cygwin にはファイルシステムの動作をより UNIX システム的に出来るような機能が備えられています。 これは、環境変数 CYGWIN に「ntea」オプションを追加することによって有効になります。

「ntea」機能が有効になると、Cygwin は先に決定したような基本パーミッションでスタートしますが、POSIX ファイルパーミッションを NT 拡張属性へと保存することが出来ます。この機能は、NTFS ファイルシステム構造でしか完全に動作しません。 しかしながら、FAT パーティション上では、NT は拡張属性をそのパーティションのルートにある EA DATA. SFという名称のフラットファイルに保存します。 パーティション中に多数のファイルが存在する場合、このファイルは極端に大きなサイズになる可能性があり、システムの動作を遅くしていきます。 更に、EA DATA. SF ファイルは「使用中」であるため、Windows の外からでしか削除することが出来ません。 これらの理由により、Cygwin のデフォルトでは NT 拡張属性はオフにされています。 最後に、Windows 9x では CYGWIN 環境変数に「ntea」を指定しても、何の意味もないということを覚えておいて下さい。

NT 環境では、「[ -w ファイル名]」は chmod +w filename などを使用して、ファイル名が書き込み可能とされたときにのみ真となります。

POSIX の /dev ディレクトリを作成する必要はありません。 Cygwin が自動的に内部でシミュレートします。 これらのデバイスは、ls /dev/tty のようにしない限り、コマンド ls /dev では表示されません。 /dev/ 以下の全てのデバイスを見えるようにしたければ、Igor Pechtchanski による create_devices.sh を利用することが出来ます。

Cygwin は POSIX システムで通常利用される、以下のデバイスをサポートしています: /dev/dsp/dev/null/dev/zero/dev/console/dev/tty/dev/ttym/dev/ttyX/dev/ttySX/dev/pipe/dev/port/dev/ptmx/dev/mem/dev/random 及び /dev/urandom/dev/kmem のような他の POSIX デバイスの開発も予定されています。 Cygwin は様々な Windows 特有のデバイスもサポートしています: /dev/comX(シリアルポートで、COM1 から始まります。ttyS0 と同じです)、 /dev/conin(Windows の CONIN$)、 /dev/conout(Windows の CONOUT$)、 /dev/clipboard(Windows のクリップボードですが、現在はテキストのみサポートしています)、 及び /dev/windows(Windows のメッセージキュー)。

加えて、Windows NT/W2K/XP ではフロッピー、ディスク、パーティションやテープのような raw デバイスをサポートしています。 二つの異なった方法によってサポートされる POSIX デバイス名を利用して、Cygwin アプリケーションからこれらのデバイスにアクセス出来ます。

Cygwin 1.3.3 まで、これらのデバイスにアクセスする唯一の方法は Win32 デバイス名を POSIX デバイス名へとマウントすることでした。 この利用方法は Cygwin 1.3.4 以降は推奨されておらず、後方互換性のためにのみ残されています。

Cygwin 1.3.4 からは、固定の POSIX デバイス名を利用することによって Cygwin のプロセスから raw デバイスへとアクセスすることが可能となりました。 これら固定の POSIX デバイス名は、NT の内部名前空間から POSIX の名前空間への直接変換によって生成されています。 例えば、最初のハードディスクは NT 内部デバイス \device\harddisk0\partition0 であり、三番目のハードディスクにある最初のパーティションは \device\harddisk2\partition1 です。 システムの最初のフロッピーは \device\floppy0、最初の CD-ROM は \device\cdrom0、最初のテープドライブは \device\tape0 です。

新しい固定 POSIX 名は、NT 内部デバイスと以下のように対応付けられています。

/dev/st0    \device\tape0、巻き戻しあり
/dev/nst0   \device\tape0、巻き戻しなし
/dev/st1    \device\tape1
...

/dev/fd0    \device\floppy0
/dev/fd1    \device\floppy1
...

/dev/scd0   \device\cdrom0
/dev/scd1   \device\cdrom1
...
/dev/sr0	\device\cdrom0
/dev/sr1	\device\cdrom1
...
/dev/sda    \device\harddisk0\partition0	(ディスク全体)
/dev/sda1   \device\harddisk0\partition1	(最初のパーティション)
...
/dev/sda15  \device\harddisk0\partition15	(15 番目のパーティション)

/dev/sdb    \device\harddisk1\partition0
/dev/sdb1   \device\harddisk1\partition1

[up to]

/dev/sdl    \device\harddisk11\partition0
/dev/sdl1   \device\harddisk11\partition1
...
/dev/sdl15  \device\harddisk11\partition15

もしこれらのデバイス名が気に入らなければ、使いやすくするために、 Linux システム上で作られているように自由にシンボリックリンクを作成します。

ln -s /dev/scd0 /dev/cdrom
ln -s /dev/nst0 /dev/tape
...

警告

内部 NT デバイス名や固定デバイス名を自分用のデバイス名へと対応付ける際、マウントテーブルを利用しないように注意して下さい。 同様に、内部 NT デバイス名から自分用のデバイス名へのシンボリックリンクを作成しても、それは望むような動作はしません。 以下に挙げた二つの例は、期待通りには動作しないでしょう。

mount -f -b /dev/nst0 /dev/tape     # 動作しません
mount -f -b /device/tape0 /dev/tape # 動作しません
ln -s /device/tape0 /dev/tape       # 動作しません

実行可能プログラムファイル名は .exe で終わりますが、.exe がコマンド名中に含まれている必要はありません。 すなわち、伝統的な UNIX コマンド名が使用できます。 しかし、.bat及び .com で終わるプログラムについては、拡張子を省略することはできません。

副作用として、filename.exe は存在するが filename は存在しないという場合でも、 ls filenamefilename.exe に関する情報を出力します。 同様の現象として、stat("filename",..) 関数呼び出しは filename.exe に関する情報を返します。 このような二つのファイルは、以下に示すように i ノードを調べれば区別出来ます。

C:\> ls * 
a      a.exe     b.exe
C:\> ls -i a a.exe
445885548 a       435996602 a.exe
C:\> ls -i a a.exe
432961010 b       432961010 b.exe

シェルスクリプト myprog とプログラム myprog.exe があるディレクトリ中に共存していた場合、myprog の実行に際してはプログラムが優先して選択されます。

gcc コンパイラは filename を生成するように指示された場合、filename.exe という名前で実行ファイルを生成します。これによって、UNIX システム用に書かれた多くの Makefile は Cygwin 上でも同様に動作します。

不幸なことに、install 及び strip コマンドは filenamefilename.exe を区別することが出来ません。この二つのプログラムは filename.exe が存在して filename が存在しない場合は失敗してしまうため、一部の Makefile による make は中断してしまうことになるでしょう。 この問題は、必要に応じて「.exe」の存在を想定する install 及び strip の二つのシェルスクリプトを作成することによって解決出来ます。

CYGWIN 環境変数は Cygwin 実行環境に対する共通の設定を行うために使用されます。 この環境変数には以下に記述するオプションが含まれ、個々のオプションは空白文字で区切られます。 多くのオプションは前置詞「no」を置くことによってその機能をオフにすることが出来ます。

Cygserver のオプションでは、通常の UNIX で採用されている「-X」というスタイル、 或いは「--longoption」形式の両方が利用出来ます。 コマンドラインからの設定が不要な場合、殆ど全てのオプションの機能は設定ファイル(下記参照) 中の設定項目によって設定することも出来ます。コマンドラインオプションは Cygserver 設定ファイルでの設定内容よりも優先されます。

一文字のオプションは単一のダッシュに続きます。また、長いオプションは二つのダッシュに続きます。 以下では、オプションの引数は不等号記号(「<」及び「>」)で括って示します。 これらの不等号記号は実際の文法の一部ではなく、引数を示すためだけに利用されています。 全ての引数は必須であるという点に注意して下さい。Cygserver には、引数を指定してもしなくてもよいようなオプションはありません。

認識可能なオプションは以下の通りです。

Cygwin アプリケーションが Cygserver が提供するサービスを利用するには、環境変数 CYGWIN に文字列「server」が含まれていなければなりません。 この設定は、アプリケーションを起動する前に行う必要があります。

通常、他のオプションは必要ありません。従って、環境変数 CYGWIN にはただ単に「server」のみを設定すれば大丈夫です。Cygserver プロセスが開始する前に環境変数 CYGWIN を設定する必要はありませんが、設定せずにおく理由はないでしょう。

最も簡単な方法は、環境変数 CYGWIN を Windows のシステム環境変数として設定し、マシンをリブートすることです。 一旦設定してしまえば、後はそのことを忘れてしまっても構わないという意味で、この方法はお勧めです。 また、この方法であれば、サービスとデスクトップアプリケーションとで確実に同じ設定が使われることになります。

システム環境変数として設定したくない理由があるのなら、 デスクトップから Cygwin の bash を起動するために使われる /cygwin.bat ファイルで環境変数を設定することが出来ます。 このファイル中では、Windows のコマンドプロンプトが利用する構文で 環境変数 CYGWIN を設定出来ます。 例えば、次のようになります。

set CYGWIN=server

環境変数 CYGWIN をシステム環境変数として設定せずに他の Cygwin サービスを実行させている場合、 これらのサービスはインストール時に cygrunsrv のオプション「-e」によって設定された環境変数 CYGWIN から設定値を得なければなりません。サービス「foo」をインストールする場合の例を示します。

cygrunsrv -I foo -p /usr/sbin/foo -e "CYGWIN=server"

Cygserver には必要に応じてサーバをカスタマイズするための、様々なオプションが備わっています。 カスタマイズは設定ファイル(デフォルトでは /etc/cygserver.conf です)を編集することによって行われます。このファイルは cygserver の起動時に一回だけ読み込まれます。実行時にファイルを再度読み込ませるためのオプションはありません。 必要があれば、cygserver にシグナルを送って下さい。

設定ファイルは cygserver の動作を決定するためのものです。 並行動作するスレッドの数、どこへどのようにログを出力するか、IPC サービスにおける様々な最大値などを設定するためのオプションがあります。

cygserver と共に配布されるデフォルトの設定ファイルは /etc/defaults/etc にインストールされます。 /usr/bin/cygserver-config スクリプトはデフォルトの設定ファイルを /etc にコピーします(既存のファイルを上書きするか、それとも残しておくかを選択することも出来ます)。 これ以降にパッケージをアップデートしたとしても /etc に置かれたファイルは上書きされませんから、 貴方が設定ファイルに施した変更は安全に守られることになります。

デフォルトの設定ファイルには大量のコメントが含まれていますが、そこには設定内容を理解するために必要な事項が記述されています。 ファイルの先頭に記述されたコメントには、このファイルの構文規則が記述されています。 デフォルトのオプションはファイル中に記述されていますが、全てコメントアウトされています。

このファイル中では、デフォルトの値から変更したいオプションのコメントだけを外すべきです。 cygserver の起動時におけるオプションの読み込みには大した時間はかからないものの、ファイル中の他の全てのコメントは手を付けずにおくほうがよいでしょう。 他の場所から、問題の手がかりを探し出さなくともよくなります。

Cygwin には Cygwin 環境の UNIX エミュレーション部分を管理するために使われる、様々なコマンドラインユーティリティが存在します。 UNIX 上での対応するユーティリティの機能の大部分を反映するために、 これらはそれぞれ Cygwin に特化した形で書かれています。 オプション名は長い形式又は短い形式が共に利用可能です。 例えば、--help-h の機能は同等です。全ての Cygwin コマンドラインユーティリティは --help--version オプションをサポートしています。

Usage: cygcheck [OPTIONS] [PROGRAM...]
Check system information or PROGRAM library dependencies

 -c, --check-setup   check packages installed via setup.exe
 -d, --dump-only     no integrity checking of package contents (requires -c)
 -s, --sysinfo       system information (not with -k)
 -v, --verbose       verbose output (indented) (for -[cfls] or programs)
 -r, --registry      registry search (requires -s)
 -k, --keycheck      perform a keyboard check session (not with -[scfl])
 -f, --find-package  find installed packages containing files (not with -[cl])
 -l, --list-package  list the contents of installed packages (not with -[cf])
 -h, --help          give help about the info (not with -[cfl])
 -V, --version       output version information and exit

cygcheck プログラムは Cygwin プログラムの診断を行うユーティリティです。 もし dpkgrpm を使い慣れていれば、cygcheck も同じようにに利用出来ます(一番の違いは、インストールやアンインストールは setup.exe が行うという点です。詳細については 項2.1. 「インターネットセットアップ」 を参照して下さい)。

-c オプションはインストール済みの Cygwin パッケージのバージョンと状態をチェックします。 引数が指定されなかった場合は全てのパッケージの情報が出力されますが、 一つ以上のパッケージを指定した場合、cygcheck は指定されたパッケージの情報だけを出力します。 「Incomplete」が出力されたパッケージは、 元々インストールされていたはずのファイルが失われてしまっていることを示しています。 このような場合は、setup.exe を利用してパッケージを再インストールして下さい。 失われたファイルを確認するには -v オプションを利用します。 もし個々のパッケージの状態を調べる必要はなく、cygcheck をより高速に実行させたければ、オプション -d を指定して下さい。この場合、cygcheck は各パッケージの名前とバージョンだけを出力します。

一つ以上のプログラムをコマンドラインから指定した場合、cygcheck はそれらのプログラムが依存している DLL の名前を示すことによって、プログラムの実行時環境を診断します。 -s オプションを指定した場合、cygcheck は一般的なシステム情報を出力します。-s に加えて一つ以上のプログラムをコマンドラインに指定した場合、cygcheck は両方の情報を出力します。

-f オプションはあるファイルがどのパッケージに所属しているかを調査し、-l オプションはパッケージに含まれる全てのファイルの一覧を表示します。 例えば、/usr/bin/less とそのパッケージについて調べるならば、次のようにします。

-h オプションは、レポート中の各セクションの先頭に追加の補助情報を出力します。 テーブルの行ヘッダも追加されます。 これは有用な情報ですが、レポートのサイズは若干大きくなります。 コンパクトなレポートを必要とする場合、あるいは全てについて既に知っている場合は、単にこれを取り除いて下さい。

-v オプションは出力をより詳細なものにします。 通常は必要とされない追加の情報、例えば DLL の内部バージョン番号や再帰的な DLL の使用に関する追加情報、そして PATH 中に含まれるディレクトリ中のあるファイルが、PATH 中に含まれる他のディレクトリ中にも存在しているかどうかなどが出力されます。

-r オプションは、Cygwin プログラムに関連した情報を含むレジストリを cygcheck に検索させます。 これらのレジストリエントリはその名称中に「Cygwin」を含むものです。 もしプライバシーにこだわるのであればこのレポートから情報を削除しても構いませんが、問題を解決する作業がより困難になるであろうということを覚えておいて下さい。

cygcheck プログラムは、トラブルシューティング用にあなたのシステムの情報が必要になった場合に、それを送るために利用されます。 このコマンドを実行するように要求された場合、電子メールで送信出来るように出力を保存して下さい。以下に例を示します。

C:\cygwin> cygcheck -s -v -r -h > cygcheck_output.txt
Usage: cygpath (-d|-m|-u|-w|-t TYPE) [-c HANDLE] [-f FILE] [options] NAME
       cygpath [-ADHPSW] 
Convert Unix and Windows format paths, or output system path information

Output type options:
  -d, --dos             print DOS (short) form of NAME (C:\PROGRA~1\)
  -m, --mixed           like --windows, but with regular slashes (C:/WINNT)
  -M, --mode            report on mode of file (currently binmode or textmode)
  -u, --unix            (default) print Unix form of NAME (/cygdrive/c/winnt)
  -w, --windows         print Windows form of NAME (C:\WINNT)
  -t, --type TYPE       print TYPE form: 'dos', 'mixed', 'unix', or 'windows'
Path conversion options:
  -a, --absolute        output absolute path
  -l, --long-name       print Windows long form of NAME (with -w, -m only)
  -p, --path            NAME is a PATH list (i.e., '/bin:/usr/bin')
  -s, --short-name      print DOS (short) form of NAME (with -w, -m only)
System information:
  -A, --allusers        use `All Users' instead of current user for -D, -P
  -D, --desktop         output `Desktop' directory and exit
  -H, --homeroot        output `Profiles' directory (home root) and exit
  -P, --smprograms      output Start Menu `Programs' directory and exit
  -S, --sysdir          output system directory and exit
  -W, --windir          output `Windows' directory and exit

cygpath プログラムは、 ネイティブの Windows ファイル名から Cygwin の POSIX スタイルのパス名への変換、 またはその逆の変換を行うためのユーティリティです。 Cygwin プログラムがネイティブの Windows プログラムへとファイル名を渡す必要がある場合、又はネイティブの Windows プログラムが Cygwin プログラムへとファイル名を渡すことが想定される場合に使用します。 また、cygpath は重要なシステムディレクトリの位置を、Windows 又は UNIX の形式の何れかで出力することも出来ます。

-u-w は、 Windows 形式から UNIX(POSIX) 形式へと変換するのか (-u)、或いは UNIX(POSIX) 形式から Windows 形式へと変換するのか (-w)を指示します。 DOS 形式(8.3 形式)のファイル名又はパス名を得るためには、-d を利用して下さい。 -m オプションは Windows 形式で出力しますが、バックスラッシュの代わりにスラッシュを利用します。 このオプションは、バックスラッシュをエスケープ文字として利用するシェルスクリプト内で特に有用でしょう。

-w オプションに組み合わせるオプションとして、 通常形式(長い形式)を出力するための -l と、DOS 形式(短い形式)を出力するための -s オプションが利用出来ます。-d オプションは -w-s の両方を指定した結果と同等です。

注意: 環境変数 CYGWINcheck_case パラメータに strict が設定されている場合、-l オプションは動作しません。なぜなら、このモードでは Cygwin は Windows の短いパスにマッチさせることが出来ないからです。

-p オプションは、 単独のファイル名ではなくパス形式の文字列へと変換することを意味します。 例えば、PATH 環境変数は Windows ではセミコロンで区切られていますが、 UNIX ではコロンで区切られています。 -p を使用することによって、 これらの形式の間の変換を行うように cygpath に指示出来ます。

-p オプションは単純なファイル名ではなく、パス形式の文字列を変換するために利用します。 例えば、PATH 環境変数は Windows ではセミコロンで区切られていますが、UNIX ではコロンで区切られています。 -p オプションを利用すれば、cygpath を利用して両方のフォーマットの変換を行うことが出来ます。

-i オプションは、引数としてファイル名が与えられなかった場合に、使用方法が出力されることを抑制します。 適切な形式に省略されうる変数を変換する Makefile のルール内で利用することが出来ます。 cygpath の出力にはスペースが含まれる可能性があるので(例: C:\Program Files)、クォートで括る必要があります。

大文字のオプション -D-H-P-S そして -W は、Windows によって利用されるディレクトリを出力します。 これらのディレクトリは、全てのシステムに対して同一ではありません。 例えば、-S は C:\WINNT\SYSTEM32 か C:\WINDOWS\SYSTEM を出力し得ます。 -H は、ホームのルートとして利用される Windows のプロファイルディレクトリを出力します。 -A オプションは、-D-P オプションが出力する現在のユーザ用のディレクトリの代わりに、「All Users」ディレクトリを出力させるために利用します。 シングルユーザでしか利用されない Windows 9x システムでは、-A は何らの意味も持ちません。-D-AD は同じ出力になります。 デフォルトでは、出力は UNIX(POSIX)形式となります。 他の形式で出力するには、-w 又は -d オプションを利用して下さい。

Usage: dumper [OPTION] FILENAME WIN32PID
Dump core from WIN32PID to FILENAME.core

-d, --verbose  be verbose while dumping
-h, --help     output help information and exit
-q, --quiet    be quiet while dumping (default)
-v, --version  output version information and exit

dumper ユーティリティは実行中の Windows プロセスのコアダンプを作成するために利用します。 このコアダンプは後から gdb で読み込み、分析するために利用出来ます。 一般的な dumper の利用方法は、Cygwin のジャストインタイムデバッグ機能として組み込むことです。 そのためにはCYGWIN 環境変数に

error_start=x:\path\to\dumper.exe

を追加します。x:\path\to\dumper.exe は Cygwin 上でのパスではなく、Windows 形式で記述する必要があるという点に注意して下さい。 error_start がこのように設定されたなら、プログラムに致命的なエラーが発生した時点で dumper が起動されます。

dumper は実行中のプロセスのコアダンプを作るために、コマンドラインから開始させることも出来ます。 残念ながら Windows API の制限により、コアダンプが作成され dumper が終了した時点で、対象となったプロセスもまた終了させられてしまいます。

コアダンプのスペースを小さくするため、dumper はプロセスのメモリ空間のうち、実行ファイルからロードされた部分、DLL ファイル、そして不変部分(例えばプログラムコードやデバッグ情報)については書き出しを行いません。 代わりに、dumper はそれらのデータを含んでいるファイルへのパスを保存します。 コアダンプが gdb によってロードされると、 これらのパスは適切なファイルをロードするために利用されます。 このことはつまり、あるマシンで作成されたコアダンプを別のマシンでデバッグするのであれば、コアダンプが作成されたマシンと同じ位置に実行形式や DLL のコピーを配置しておく必要があるということを意味します。

Usage: getfacl [-adn] FILE [FILE2...]
Display file and directory access control lists (ACLs).

  -a, --all      display the filename, the owner, the group, and
                 the ACL of the file
  -d, --dir      display the filename, the owner, the group, and
                 the default ACL of the directory, if it exists
  -h, --help     output usage information and exit
  -n, --noname   display user and group IDs instead of names
  -v, --version  output version information and exit

When multiple files are specified on the command line, a blank
line separates the ACLs for each file.

getfacl は引数として与えられた個々の通常のファイル、特殊ファイル又はディレクトリについて、所有者、グループそして ACL を出力します。 ディレクトリに対しては、getfacl は更にデフォルトの ACL をも表示します。 オプションが指定されなかった場合、 getfacl はファイル名、所有者、グループ、ACL と(もし存在するのなら)デフォルトの ACL の両方を表示します。 Cygwin 及び Windows の ACL に関する更なる情報については、 Cygwin ユーザーズガイドの 項2.3. 「NT セキュリティと ntsec の使用方法」 を参照して下さい。ACL の出力形式は以下のようになります。

     # file: filename
     # owner: name or uid
     # group: name or uid
     user::perm
     user:name or uid:perm
     group::perm
     group:name or gid:perm
     mask:perm
     other:perm
     default:user::perm
     default:user:name or uid:perm
     default:group::perm
     default:group:name or gid:perm
     default:mask:perm
     default:other:perm

Usage: kill [-f] [-signal] [-s signal] pid1 [pid2 ...]
       kill -l [signal]
Send signals to processes

 -f, --force     force, using win32 interface if necessary
 -l, --list      print a list of signal names
 -s, --signal    send signal (use kill --list for a list)
 -h, --help      output usage information and exit
 -v, --version   output version information and exit

kill プログラムは他の Cygwin プログラムに対して任意のシグナルを送信するためのものです。 通常、 ^C が動作しない場合に他のウィンドウから実行中のプログラムを停止させるために利用しますが、 SIGUSR1 のようなプログラム指定のシグナルをプログラム中でのトリガ、 例えばデバッグ用途やログファイルの再オープンなどのために送信することも出来ます。 個々のプログラムは、プログラム自身が理解するシグナルを定義します。

Cygwin のデフォルトのシェルである bash を含む幾つかのシェルから kill を実行する場合、フルパスで指定する必要があります。なぜなら、bash は組み込みコマンドとして kill を定義しているからです。更なる情報については、bash のマニュアルページの BUILTIN COMMANDS を参照して下さい。Cygwin 版の kill を利用していることを確かめるには、

$ /bin/kill --version

を実行して、Cygwin の kill のバージョン番号と著作権情報が出力されることを確認します。

-f オプションを指定しない限り、kill が利用する「pid」値は Cygwin の PID であり、Windows の PID ではないことに注意して下さい。実行中のプログラムとそれらの Cygwin での PID のリストを取得するには、Cygwin の ps を使用します。ps -W は、全ての Windows PID を表示します。

kill -l オプションは指定されたシグナルの名前を表示します。 シグナルが指定されなかった場合は、全てのシグナルの名前を表示します。

特定のシグナルを送信するためには、 次に示す例のようにシグナル番号又はシグナル名 (「SIG」部分を省いたもの)と共に -signN オプションを使用します。

利用可能なシグナルとシグナル番号、そしてそれらに対するコメントをここに挙げます。 これらの情報は、この情報に関する公式な情報源であると考えられる <sys/signal.h> から引用したものです。

SIGHUP       1    ハングアップ
SIGINT       2    中断
SIGQUIT      3    終了
SIGILL       4    不正な命令 (受信時にリセットされない)
SIGTRAP      5    トレーストラップ (受信時にリセットされない)
SIGABRT      6    abort の使用
SIGEMT       7    EMT 命令
SIGFPE       8    浮動小数点例外
SIGKILL      9    kill (受信あるいは無視は出来ない)
SIGBUS      10    バスエラー
SIGSEGV     11    セグメント違反
SIGSYS      12    システムコールに対する不正な引数
SIGPIPE     13    誰も読まないパイプに対する書き込み
SIGALRM     14    アラームクロック
SIGTERM     15    kill からのソフトウェア終了命令
SIGURG      16    入出力チャネルにおける緊急事態
SIGSTOP     17    tty からではない、送信可能な中止
SIGTSTP     18    tty からの中止
SIGCONT     19    停止したプロセスの再開
SIGCHLD     20    親プロセスに対する、子プロセスの中止又は終了
SIGCLD      20    System V における SIGCHLD の名称
SIGTTIN     21    to readers pgrp upon background tty read
SIGTTOU     22    like TTIN for output if (tp->t_local&LTOSTOP)
SIGIO       23    入出力可能なシグナル
SIGPOLL     23    System V における SIGIO の名称
SIGXCPU     24    CPU 時間の制限の超過
SIGXFSZ     25    ファイルサイズの制限の超過
SIGVTALRM   26    仮想タイムアラーム
SIGPROF     27    プロファイリングタイムアラーム
SIGWINCH    28    ウィンドウの変更
SIGLOST     29    リソースの消失 (例えば、レコードロックの消失)
SIGUSR1     30    ユーザ定義シグナル 1
SIGUSR2     31    ユーザ定義シグナル 2
Usage: mkgroup [OPTION]... [domain]...
Prints /etc/group file to stdout

Options:
   -l,--local             print local group information
   -c,--current           print current group, if a domain account
   -d,--domain            print global group information (from current
                          domain if no domains specified).
   -o,--id-offset offset  change the default offset (10000) added to gids
                          in domain accounts.
   -s,--no-sids           don't print SIDs in pwd field
                          (this affects ntsec)
   -u,--users             print user list in gr_mem field
   -g,--group groupname   only return information for the specified group\n");
   -h,--help              print this message

   -v,--version           print version information and exit

One of `-l' or `-d' must be given on NT/W2K.

mkgroup プログラムは、システム情報から最初の /etc/group の代用品(幾つかのコマンドはこのファイルを必要とします)を作成することによって、Windows システムの構成の手助けを行います。このプログラムは NT 系システム(Windows NT、2000 及び XP)でのみ動作します。 mkgroup は Windows 9x 系システム(Windows 95、98 及び Me)では動作しません。なぜなら、それらの OS にはセキュリティモデルのサポートが欠けているからです。マシンの最初のセットアップのためには、以下のようにします。

mkgroup プログラムは最初の /etc/group を作成することによって、 Windows システムをより UNIX 的に構成するための手助けを行います。 mkgroup の用途は Windows のセキュリティ情報を取り込むことにあり、 NT 系列(WindowsNT、2000 及び XP)では不可欠です。 mkgroup は Windows 9x 系列(Windows 95、98 及び Me)ででも、 正しい形式でファイルを作成するために利用されます。 貴方がローカルユーザであれば、マシンの最初の設定のために以下のようにコマンドを実行して下さい。

この情報は静的なものであることに注意して下さい。 もしシステム内のグループ情報を変更したときは、 新しい情報を反映するために group ファイルを再作成する必要があります。

-d-l オプションは、「ローカルマシンから」「(デフォルト、又は指定した)ドメインから」或いは「その両方から」のどの方法で情報を取り出すかを指定するためのものです。 現在のドメインのユーザに対するエントリは、オプション -c と共に -l を与えた場合に生成されますが、-c-d と共に使われた場合、何の効果も持ちません。 -o オプションは、(複数のドメインのような)特別なケースにおいて、GID が違うものにマッチする場合に利用します。 -s オプションは NT セキュリティ識別子(SID)を省略します。 SID に関する更なる情報については、Cygwin ユーザーズガイドの 項2.3. 「NT セキュリティと ntsec の使用方法」 を参照して下さい。 -u オプションは個々のグループごとにユーザを調べ、gr_mem フィールド(最後のフィールド)にグループのメンバを格納するよう mkgroup に通知します。 大きなドメインに対して mkgroup を実行すると、実行時間が非常に大きくなるという点には注意して下さい。 ローカルマシンがドメインコントローラから切断されていても、gr_mem フィールドを設定しておけばリモートからのドメインユーザでのログイン時に役立ちます。 -g は一つのグループに関する情報のみを出力します。

Usage: mkpasswd [OPTION]... [domain]...
Prints /etc/passwd file to stdout

Options:
   -l,--local              print local user accounts
   -c,--current            print current account, if a domain account
   -d,--domain             print domain accounts (from current domain
                           if no domains specified)
   -o,--id-offset offset   change the default offset (10000) added to uids
                           in domain accounts.
   -g,--local-groups       print local group information too
                           if no domains specified
   -m,--no-mount           don't use mount points for home dir
   -s,--no-sids            don't print SIDs in GCOS field
                           (this affects ntsec)
   -p,--path-to-home path  use specified path and not user account home dir or /home
   -u,--username username  only return information for the specified user
   -h,--help               displays this message
   -v,--version            version information and exit

One of `-l', `-d' or `-g' must be given on NT/W2K.

mkpasswd プログラムはシステム情報から最初の /etc/passwd を作成します。 mkpasswd の用途は Windows のセキュリティ情報を取り込むことにあり、 NT 系列(WindowsNT、2000 及び XP)では不可欠ですが、 実際のパスワードは /etc/passwd の内容からではなく、 Windows によって決定されます。 Windows 9x 系列(Windows 95、98 及び Me)でリモートアクセスが必要な場合、 password フィールドは crypt your_password の出力によって置き換えられていなければなりません。 貴方がローカルユーザであれば、マシンの最初の設定のために以下のようにコマンドを実行して下さい。

この情報は静的なものであることに注意して下さい。 もしシステム内のユーザ情報を変更したときは、 新しい情報を反映するために passwd ファイルを再度作成し直す必要があります。

-d-l オプションは、 「ローカルマシンから」「(デフォルト、又は指定した)ドメインから」或いは「その両方から」のどの方法で情報を取り出すかを指定するためのものです。 -d オプションを指定した場合、mkpasswd プログラムはドメインコントローラに接続します。 現在のドメインのユーザに対するエントリは、 オプション -c と共に -l を与えた場合に生成されますが、 -c-d と共に使われた場合、何の効果も持ちません。 -o オプションは、(複数のドメインのような)特別なケースにおいて、UID が違うものにマッチする場合に利用します。 -g オプションは各ローカルグループに対応するローカルユーザを生成します。 これは、NT がグループにもファイル所有権を与えるからです。 -m オプションは現在のマウントテーブルをバイパスします。 なぜなら、仮に二人のユーザが Windows ホームディレクトリを H: に構えているとしても、それぞれに異なった方法でマウント出来るからです。 -s オプションは NT セキュリティ識別子(SID)を省略します。 SID に関する更なる情報については、Cygwin ユーザーズガイドの 項2.3. 「NT セキュリティと ntsec の使用方法」 を参照して下さい。 -p オプションはアカウントのホームディレクトリや /home/ ではなく、指定した接頭辞を付けるように mkpasswd に指示するためのものです。例えば、以下のコマンド

は、ローカルのユーザのホームディレクトリを Windows の「Profiles」ディレクトリに配置します。 Windows 9x マシンでは、-u は指定したユーザのエントリを生成します。 NT 系列では -u オプションは指定したユーザだけを出力対象とするので、大きなドメインでの実行時間を大幅に短縮させます。

Usage: mount [OPTION] [<win32path> <posixpath>]
Display information about mounted filesystems, or mount a filesystem

  -b, --binary     (default)    text files are equivalent to binary files
                                (newline = \n)
  -c, --change-cygdrive-prefix  change the cygdrive path prefix to <posixpath>
  -f, --force                   force mount, don't warn about missing mount
                                point directories
  -h, --help                    output usage information and exit
  -m, --mount-commands          write mount commands to replace user and
                                system mount points and cygdrive prefixes
  -o, --options X[,X...]        specify mount options
  -p, --show-cygdrive-prefix    show user and/or system cygdrive path prefix
  -s, --system     (default)    add system-wide mount point
  -t, --text                    text files get \r\n line endings
  -u, --user                    add user-only mount point
  -v, --version                 output version information and exit
  -x, --executable              treat all files under mount point as executables
  -E, --no-executable           treat all files under mount point as 
                                non-executables
  -X, --cygwin-executable       treat all files under mount point as cygwin
                                executables

mount プログラムは、一般的な UNIX システム上の mount コマンドが行うように、ドライブ及び共有を Cygwin がシミュレートする POSIX ディレクトリツリーにマップします。 Cygwin の POSIX ファイルシステムの背後にあるコンセプト及びマウントの戦略についての更なる情報については 項3.1.2. 「Cygwin マウントテーブル」 を参照して下さい。 マウントを解除するには、umount コマンドを利用します。

パラメータを指定せずただ単に mount とタイプした場合、 現在のマウントテーブルが表示されます。

この例では、C:\cygwin は POSIX ディレクトリツリーのルートディレクトリに、D ドライブは /d にマップされています。この場合、ルートのマウントは Cygwin プログラムを実行する全ユーザが利用可能なシステム全体のマウントポイントですが、 対して /d のマウントは現在のユーザにだけのものであるということを覚えておいて下さい。

mount ユーティリティはマウントテーブルに新しいマウントを追加する仕組みでもあります。 以下の例は、ディレクトリ \\pollux\home\joe\data/data へとマウントするというものです。

先の例の mount は Windows コマンドシェルから起動されたということに注意して下さい。 bash を含む多くのUNIX シェルでは「\」がシェルのエスケープ文字であるため、Win32 パス名中でも「/」を使用することが出来ますし、またそのほうが便利です。

mount-s フラグは、ユーザ独自のマウントテーブルではなく、そのシステムにおける全ての Cygwin ユーザによって使用されるシステム全体のマウントテーブルにマウントを追加するために使われます。 システム全体でのマウントは、先の例での / パーティションのように、 mount コマンド使用時に「system」タイプとして表示されます。 Windows NT では、Administrator 権限を持ったユーザだけがシステム全体のマウントテーブルを修正することが出来ます。

指定された POSIX パスはユーザテーブルとシステム全体のテーブルのいずれかにのみ存在可能であるということに注意して下さい。 マウントを置き換えようとした場合、busy エラーが発生して失敗します。 -f (force; 強制)フラグは、既存のマウントを警告なしに新しいマウントで置き換えます。 Win32 パスとしてディレクトリが存在しない場合についても警告を発しません。

-b フラグは、デフォルトでバイナリを処理し、テキストファイルについても同様の動作をするよう Cygwin に指示するために使われます。 バイナリモードマウントは、mount の出力中の Flags 列中で「binmode」として表示されます。 デフォルトでは、マウントはテキストモードとなります(Flags 列には「textmode」として表示されます)。

通常、特定の拡張子(.exe、.com、.bat、.cmd)で終了するファイルは実行形式であると見なされます。 同様に、ファイルの先頭の 2 文字が「#!」で始まっているファイルも実行可能だと見なされます。 -x フラグは、マウントされたファイルは「実行可能」であるということを Cygwin に指示するために使われます。 もし -x フラグがディレクトリに対して使用された場合、 そのディレクトリ中の全てのファイルが実行可能となります。 このオプションを使用すればそれ以外のファイルも実行可能としてマーク出来るので、 個々のファイルの内容が「#!」で始まっているかどうかをチェックするためのオーバーヘッドを回避することが出来ます。 -X オプションは -x と非常に似ていますが、多少の高速化を図るため、通常の Windows プログラムに対するコマンドと環境変数を Cygwin が設定することを防止します。 これらのフラグと対照的なのが -E であり、全てのファイルが実行可能ではないことを意味します。

-m オプションは、ユーザ及びシステムの両方のマウントポイントを再生成するための一連のコマンド群を mount ユーティリティに出力させるというものです。 マウントテーブルの実験をする場合、この出力をバックアップとして保存しておくことが出来ます。 また、設定内容を別のマシンへとより簡単に適用するために利用することも出来るでしょう。

-o オプションはマウントポイントに関する様々なオプションをまとめるメソッドです。 以下のオプションが利用できます(オプションの大部分は他のマウントフラグと重複していることに注意して下さい)。

  user       - ユーザ独自マウント中のマウントとする。
  system     - システムテーブル中のマウントとする(デフォルト)。
  binary     - ファイルのデフォルトをバイナリモードとする(デフォルト)。
  text       - ファイルのデフォルトを CRLF テキストモード行終端とする。
  exec       - マウントポイント以下のファイルを全て実行可能とする。
  notexec    - マウントポイント以下のファイルを全て実行不能とする。
  cygexec    - マウントポイント以下のファイルを全て Cygwin の実行可能形式とする。
  nosuid     - suid されたファイルを許可しない(現在未実装)。
  managed    - Cygwin によってディレクトリが管理される。ファイル名中の
               大文字小文字の混在及び特殊文字の利用が許される。

特定の Win32 パスを POSIX パスへと変換する際に Cygwin が既存のどのマウントも利用できなかった場合は、 Cygwin は代わりにデフォルトのマウントポイントである /cygdrive を使用した POSIX パスへと変換します。 例えば、Cygwin が Z:\foo へとアクセスしたものの、 Z ドライブが現在のマウントテーブル中に存在しなかった場合、 Z:\/cygdrive/Z としてアクセス可能になります。 mount ユーティリティの「--change-cygdrive-prefix」 フラグを使えば、デフォルトの自動マウント用プレフィックスを変更することが出来ます。 以下の例では、自動マウント用のプレフィックスを / に変更しています。

この方法にで新しいプレフィックスを設定する際、-s フラグを指定すれば、新しいプレフィックスをシステム全体のデフォルトプレフィックスとすることが出来るということを覚えておいて下さい。 デフォルトでは、cygdrive プレフィックスはシステム全体の設定のみに適用されます。 ユーザ及びシステムの cygdrive プレフィックスは -p オプションで常に参照することが出来ます。 --change-cygdrive-prefix と共に -b フラグを使用すれば、 全ての新しい自動マウントされたファイルシステムのデフォルトをバイナリモードでのファイルアクセスとすることが出来ます。

制限: マウントポイントは最大 30 までに制限されており、 これはハードコーディングされています。 また、仮に「/」から始まらないパス名をマウントすることが出来たとしても、 そのようなマウントポイントを使用する方法はありません。

通常、標準的な UNIX がそうであるように、Cygwin の POSIX マウントポイントは既存の空のディレクトリとなります。 この場合、又はマウントポイントのプレースホルダ (ファイル、どこかへのシンボリックリンク、 または空でないディレクトリ)が存在する場合、 予想される動作が示されます。 現在マウントポイントとなっているファイルのマウント前の姿は、 Cygwin プログラムからは見えなくなります。

例えば、ディスクを指し示す abc といった名前がルートディレクトリに散乱するのを防ぎたいような場合、 時には存在しないディレクトリへのマウントが望ましいことがあります。 たとえ mount が警告を表示したとしても、 明示的にマウントポイントを参照した場合は全てがほぼ正確に動作します。 しかしながら、幾つかの奇妙な結果が発生するかもしれません。 例えば、現在の作業ディレクトリが /dir であり、しかも /dir/mtpt がマウントポイントである場合、mtptlsecho * コマンドでは表示されず、 find .mtpt を探し出せません。

Usage: passwd [OPTION] [USER]
Change USER's password or password attributes.

User operations:
  -l, --lock               lock USER's account.
  -u, --unlock             unlock USER's account.
  -c, --cannot-change      USER can't change password.
  -C, --can-change         USER can change password.
  -e, --never-expires      USER's password never expires.
  -E, --expires            USER's password expires according to system's
                           password aging rule.
  -p, --pwd-not-required   no password required for USER.
  -P, --pwd-required       password is required for USER.

System operations:
  -i, --inactive NUM       set NUM of days before inactive accounts are disabled
                           (inactive accounts are those with expired passwords).
  -n, --minage DAYS        set system minimum password age to DAYS days.
  -x, --maxage DAYS        set system maximum password age to DAYS days.
  -L, --length LEN         set system minimum password length to LEN.

Other options:
  -S, --status             display password status for USER (locked, expired,
                           etc.) plus global system password settings.
  -h, --help               output usage information and exit.
  -v, --version            output version information and exit.

If no option is given, change USER's password.  If no user name is given,
operate on current user.  System operations must not be mixed with user
operations.  Don't specify a USER when triggering a system operation. 

passwd はユーザアカウントのパスワードを変更します。 通常のユーザは自分自身のアカウントのパスワードだけを変更できますが、 Administrators グループに所属するユーザはどのアカウントのパスワードも変更できます。 passwd はまた、 パスワードの有効期限やパスワード変更間隔といった、 アカウントの情報を変更することが出来ます。

パスワードを変更する際、パスワードが既に定義されていれば、ユーザは最初に旧来のパスワードを入力するように促されます。 入力されたパスワードは暗号化され、保存されているパスワードと比較されます。 ユーザには正しいパスワードを入力するチャンスは一回しかありません。 パスワードを忘れてしまった場合でもパスワードを変更出来るようにするため、Administrators グループに所属するユーザはこのステップを省略することが出来ます。

続いてユーザは変更するパスワードの入力を促されます。 passwd は再度入力を促し、最初の入力と 2 回目の入力が合致しているかどうかを確認します。 パスワードを変更するためには、両方の入力が同じものである必要があります。

パスワードが入力された後、今回のパスワード変更が許可されているかどうかを確認するために、 パスワードの有効期限情報がチェックされます。もしチェックが通らなければ、passwd はパスワードの変更を拒否して終了します。

現在のパスワードの状態に関する情報を得るには、-S オプションを利用します。 Administrators は passwd を利用して、様々なアカウントの管理を行うことが可能です (ユーザは自分自身のアカウントに対しては、幾つかの管理を行うことが出来ます)。 -l フラグと共に実行すればアカウントのロックを、 -u フラグと共に実行すればアカウントのロックの解除を行うことが出来ます。 同様に、-c はユーザによるパスワードの変更を不可能にし、 -C はユーザによるパスワードの変更を可能にします。 パスワードの期限については、-e によってパスワードの期限を無制限にし、-E はシステムの通常の期限設定ルールに従ってパスワードの期限付けを行います。 -p はユーザに対してパスワードの設定を要求せず、 -P はユーザに対してパスワードの設定を要求します。

Administrators グループに所属するユーザは -i-n-x 及び -L オプションを利用することによって、システム全体のパスワードの有効期間と有効な長さも変更することが出来ます。 -i オプションはパスワードの有効期間満了後、 アカウントを無効とするための日数を指定するために利用します。 パスワードの有効期限が切れてから NUM 日が経過すると、それ以降、ユーザはもはやそのアカウントを利用してログオンすることは出来ません。 -n オプションは、パスワードの変更禁止期間を日数で設定するために使われます。 ユーザは MINDAYS 日数が経過するまで、パスワードを変更することは出来ません。 -x オプションは、パスワードの有効期限の最大日数を設定するために使われます。 MAXDAYS日数の後、パスワードは変更されなければなりません。 上記のオプションで利用可能な値の範囲は、0 から 999 までです。 -L オプションは、Administrators グループに属さないユーザに許されるパスワードの最小の長さを LEN 分の文字数で指定します。 最小のパスワード長として認められるのは 0 から 14 文字までです。 この場合、0 という値は「制限なし」を意味します。

制限: 幾つかのシステムでは、ユーザは自分のパスワードを変更することが出来ません。

Usage: ps [-aefls] [-u UID]
Report process status

 -a, --all       show processes of all users
 -e, --everyone  show processes of all users
 -f, --full      show process uids, ppids
 -h, --help      output usage information and exit
 -l, --long      show process uids, ppids, pgids, winpids
 -s, --summary   show process summary
 -u, --user      list processes owned by UID
 -v, --version   output version information and exit
 -W, --windows   show windows as well as cygwin processes
With no options, ps outputs the long format by default

ps プログラムは、システム内で動作している全ての Cygwin プロセスの情報を返します(ps とは「process status」を意味します)。 Windows 環境下における POSIX 環境のシミュレートによる制限のため、限られた情報しか出力されません。

PID 列は kill に与えるために必要なプロセス ID です。 PPID は親プロセス ID であり、PGID はプロセスグループ ID です。 WINPID 列は NT のタスクマネージャに表示されるプロセス ID です。 TTY 列はプロセスがどの仮想端末上で動作しているかを示すものであり、'?' はサービスであることを表しています。UID 列には各プロセスのオーナーが示されます。 STIME はプロセスが起動した時刻であり、COMMAND は実行しているプログラムを示しています。 0 番目のカラムには、ステータスフラグもまた表示されます。 S は停止中或いはサスペンド中(言い換えるならバックグラウンド)であることを、I は入力待ち中或いは対話処理待ち中(フォアグラウンド)であることを、O は出力待ち中であることを示しています。

デフォルトでは、ps は現在のユーザが所有しているプロセスのみを表示します。 -a-e のどちらかのオプションを使えば、全てのプロセス(システムプロセスも含む)が表示されます。 二つのオプションが同じ機能を持っているのは、UNIX の歴史的な理由によるものです。 -f は「完全(full)な」リスト表示を行うオプションであり、UID に対するユーザ名も表示されます。-l オプションはデフォルトの表示モードであり、上記の列について「長い(long)」リスト表示を行います。 他の表示オプションとしては -s があり、PID、TTY、STIME そして COMMAND だけを短く表示します。-u オプションは、指定されたユーザが所有しているプロセスだけを表示するためのものです。 -W オプションは、 Cygwin のプロセスと共に Cygwin プロセス以外の Windows プロセスをも ps に表示させるものです。 WINPID もまた PID であり、Windows プロセスは kill コマンドに -f オプションを付けることによって殺すことが出来ます。

Usage: regtool.exe [OPTION] (add | check | get | list | remove | unset) KEY
View or edit the Win32 registry

Actions:
 add KEY\SUBKEY             add new SUBKEY
 check KEY                  exit 0 if KEY exists, 1 if not
 get KEY\VALUE              prints VALUE to stdout
 list KEY                   list SUBKEYs and VALUEs
 remove KEY                 remove KEY
 set KEY\VALUE [data ...]   set VALUE
 unset KEY\VALUE            removes VALUE from KEY

Options for 'list' Action:
 -k, --keys           print only KEYs
 -l, --list           print only VALUEs
 -p, --postfix        like ls -p, appends '\' postfix to KEY names

Options for 'set' Action:
 -e, --expand-string  set type to REG_EXPAND_SZ
 -i, --integer        set type to REG_DWORD
 -m, --multi-string   set type to REG_MULTI_SZ
 -s, --string         set type to REG_SZ

Options for 'set' and 'unset' Actions:
 -K<c>, --key-separator[=]<c>  set key separator to <c> instead of '\'

Other Options:
 -h, --help     output usage information and exit
 -q, --quiet    no error output, just nonzero return if KEY/VALUE missing
 -v, --verbose  verbose output, including VALUE contents when applicable
 -V, --version  output version information and exit

KEY is in the format [host]\prefix\KEY\KEY\VALUE, where host is optional
remote host in either \\hostname or hostname: format and prefix is any of:
  root     HKCR  HKEY_CLASSES_ROOT (local only)
  config   HKCC  HKEY_CURRENT_CONFIG (local only)
  user     HKCU  HKEY_CURRENT_USER (local only)
  machine  HKLM  HKEY_LOCAL_MACHINE
  users    HKU   HKEY_USERS

You can use forward slash ('/') as a separator instead of backslash, in
that case backslash is treated as escape character
Example: regtool.exe get '\user\software\Microsoft\Clock\iFormat'

regtool プログラムを使えば、シェルスクリプトから Windows レジストリのアクセスと修正が可能になります。 Windows レジストリの修正は危険であり、不注意からシステムが使用不能になることがあります。 注意して下さい。

-v オプションは「冗長(verbose)」を意味します。 多くのコマンドでは、 これは追加の、又は長ったらしいメッセージを出力するためのものです。 逆に、-q オプションはエラーメッセージを抑制します。 キーが存在したか否かを調べるには、(例えば)プログラムの終了ステータスを使用します。

regtool には、以下に示すようなオプションを アクション として指定する必要があります。 現在のところ、アクションとなるのは addsetcheckgetlistremoveset 及び unset です。

デフォルトでは、最後の「\」又は「/」はキーと値の区切り文字として認識されます。 -K オプションを利用することによって、キーと値の区切り文字として別の文字を利用することが可能になります。

add アクションは新しいキーを追加します。 check アクションはキーが存在するかどうかを確認します (プログラムの終了コードが 0 なら存在し、非 0 ならは存在しません)。 get アクションはキーの値の値を取得し、標準出力にその値を出力します(あるいは何も出力しません)。 なお、値が存在しない場合はエラーメッセージが表示され、プログラムは非 0 の終了コードを返します。 -q が指定された場合、プログラムはメッセージを表示しませんが非 0 の終了コードを返します。

list アクションは、与えられたキーが持つサブキーと値を出力します。 list-k オプションを指定すれば、regtool はキーだけを表示します。また、-l を指定した場合は値だけが表示されます。-p は個々のキーの最後に後置詞として '/' を付けますが、値には何も付けません。 remove アクションはキーを削除します。 キーを削除する前にはキー中にある全てを削除する必要がありますが、そのことが必要以上に削除してしまうことを偶然にも止める手段になるということは期待しないで下さい。

set アクションはキー中に値を設定します。 -e は値が展開可能な文字列(REG_EXPAND_SZ)であり、埋め込みの環境変数が含まれていることを示します。 -i は値が整数(REG_DWORD) であることを示します。 -m は値が複数行文字列(REG_MULTI_SZ)であることを意味します。 -s は値が文字列(REG_SZ)であることを示します。 もしこのいずれをも指定しなかった場合、regtool は与えられた値を元に型を推測します。 もし数値に見えるのであれば、それは DWORD 値です。 もしパーセントで始まる値であれば、それは展開可能な文字列値です。 複数の値を与えたのであれば、それは複数行文字列値です。 そうでなければ、それは通常の文字列値です。 unset コマンドはキーから値を削除します。

Usage: setfacl [-r] (-f ACL_FILE | -s acl_entries) FILE...
       setfacl [-r] ([-d acl_entries] [-m acl_entries]) FILE...
Modify file and directory access control lists (ACLs)

  -d, --delete     delete one or more specified ACL entries
  -f, --file       set ACL entries for FILE to ACL entries read
                   from a ACL_FILE
  -m, --modify     modify one or more specified ACL entries
  -r, --replace    replace mask entry with maximum permissions
                   needed for the file group class
  -s, --substitute substitute specified ACL entries for the
                   ACL of FILE
  -h, --help       output usage information and exit
  -v, --version    output version information and exit

At least one of (-d, -f, -m, -s) must be specified

パラメータとして与えられた個々のファイルについて、setfacl はそれらのファイルの完全な ACL を置き換える(-s-f)か、ACL エントリの追加、修正又は削除を行います。 Cygwin と Windows ACL に関する更なる情報については、Cygwin ユーザーズガイドの 項2.3. 「NT セキュリティと ntsec の使用方法」 を参照して下さい。

acl_entries は、以下のリストに示されたような一つ又はそれ以上のカンマ区切りの ACL エントリ群です。

         u[ser]::perm
         u[ser]:uid:perm
         g[roup]::perm
         g[roup]:gid:perm
         m[ask]::perm
         o[ther]::perm

デフォルトのエントリは上記に加えて、追加の default 識別子を持っています。例えば、次のようになります。

         d[efault]:u[ser]:uid:perm

perm はそれぞれ「rwx」形式に従う 3 文字のパーミッション文字列であり、パーミッションが無い場合は 「-」文字を利用します。 また、0 (「---」と同じ) から 7 (「rwx」と同じ)までの 8 進数表現を利用してパーミッションを表すことも出来ます。 uid はユーザ名か数値表現の UID であり、gid はグループ名か数値表現の GID です。

以下のオプションがサポートされています。

-d 一つ又はそれ以上の指定されたエントリをファイルの ACL から削除します。 所有者、グループそしてその他エントリを削除してはいけません。 削除される acl_entries はパーミッションなしで指定します。 例えば、次に示すリストのようになります。

         u[ser]:uid
         g[roup]:gid
         d[efault]:u[ser]:uid
         d[efault]:g[roup]:gid
         d[efault]:m[ask]:
         d[efault]:o[ther]:

-f ACL_FILE から acl_entries を一行ずつ読み込みます。 空白文字は無視され、文字「#」はコメントの開始として扱われます。 は標準入力から読み込ませるには、特殊ファイル名「-」を利用します。 あるファイルから別のファイルへと ACL をコピーする場合は、getfaclsetfacl を利用することが出来ます。

$ getfacl source_file | setfacl -f - target_file

ファイルの所有者として一つのユーザエントリ、ファイルのグループとして一つのグループエントリ、そしてその他エントリが必要となります。

追加のユーザ及びグループエントリとして、ファイルのファイルグループクラスに対するマスクエントリ及び、同じ UID / GID を持った重複しないユーザ又はグループエントリを指定することが出来ます。

もし対象がディレクトリであれば、ファイルの所有者として一つのデフォルトのユーザエントリ、ファイルのグループとして一つのデフォルトのグループエントリ、ファイルグループクラスとして一つのデフォルトのマスクエントリ、そして一つのその他エントリが必要となります。

-m 一つ又はそれ以上の指定した ACL エントリを追加又は削除します。 acl_entries は既に示したような、カンマ区切りのエントリのリストとなります。

-r マスク入力として指定されたパーミッションを無視し、ファイルグループクラスに必要となる最大のパーミッションで置き換えます。

-s -f と似ていますが、カンマ区切りのリストとしてコマンドラインから指定された acl_entries でファイルの ACL を置き換えます。

-d 及び -m オプションは同じコマンド内で利用できますが、-f-s オプションは排他的にしか利用出来ません。

ディレクトリはデフォルトの ACL エントリを保持しています。 デフォルトの ACL エントリを含んだディレクトリ内に作成されたファイルのパーミッションは、 現在の umask 値、明示的に指定されたパーミッション要求そしてデフォルトの ACL エントリを結合して決定されます。

制限: Cygwin 環境下では、デフォルトの ACL エントリは現在のアカウントからは取得されません。

Usage: ssp [options] low_pc high_pc command...
Single-step profile COMMAND

 -c, --console-trace  trace every EIP value to the console. *Lots* slower.
 -d, --disable        disable single-stepping by default; use
                      OutputDebugString ("ssp on") to enable stepping
 -e, --enable         enable single-stepping by default; use
                      OutputDebugString ("ssp off") to disable stepping
 -h, --help           output usage information and exit
 -l, --dll            enable dll profiling.  A chart of relative DLL usage
                      is produced after the run.
 -s, --sub-threads    trace sub-threads too.  Dangerous if you have
                      race conditions.
 -t, --trace-eip      trace every EIP value to a file TRACE.SSP.  This
                      gets big *fast*.
 -v, --verbose        output verbose messages about debug events.
 -V, --version        output version information and exit

Example: ssp 0x401000 0x403000 hello.exe

SSP - シングルステッププロファイラ

オリジナルの作者: DJ Delorie

SSP は Win32 デバッグ API を利用してプログラムを実行するためのプログラムです。 SSP は個々の命令が利用された場所、命令が使用した時間、そして全ての関数呼び出しを記録します。 SSP の実行結果はプロファイル用プログラム gprof が取り扱える形式として保存されますが、gprof は値が秒であり、それらは本当は命令数だと主張するでしょう。

SSP は元々 Cygwin DLL をプロファイルするために設計されたので、統計レポートを報告するコードブロックを自動的に選択することは出来ません。 メモリアドレスの範囲を手で把握し、それを指定する必要があります、その作業は難しくはありません。 ターゲットの「.text」セクションの範囲を決定するには、「objdump」プログラムを利用します。 我々が行う cygwin1.dll のプロファイリング方法を説明しましょう。 デバッグシンボルが含まれるようにビルドを行い(そうでないと、gprof を実行することが出来ません)、そして objdump を次のように実行します。

$ objdump -h cygwin1.dll

次のようなレポートが出力されるでしょう。

cygwin1.dll:     file format pei-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0007ea00  61001000  61001000  00000400  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
  1 .data         00008000  61080000  61080000  0007ee00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  . . .

必要となる情報は .text セクションの VMA と、それに続くセクションの VMA だけです(通常、セクションは連続しています。 最終アドレスを知るためには、VMA に Size を加えても構いません)。 この場合、VMA は 0x61001000 であり、最終アドレスは 0x61080000(.data の開始アドレスから求める方法)又は 0x0x6107fa00(VMA に Size を加えて求める方法)のどちらかとなります。

SSP の基本的な使い方は二つです。 プログラム全体をプロファイリングするか、プログラム中の特定の場所をプロファイリングするかです。

プログラム全体をプロファイリングするのであれば、オプションなしでただ単に ssp を実行します。 デフォルトでは、SSP はプログラム全体をステップ実行します。 単純な例として、上記の数値を使ってみます。

$ ssp 0x61001000 0x61080000 hello.exe

これによってプログラム全体がステップ実行されます。 Pentium II / 300MHz のマシンでは最低でも 8 分が必要になります(ええ、本当ですとも)。 処理が完了すると、SSP は「gmon.out」というファイルを作成します。 gprof を利用すれば、このデータを人間にも読める形式のレポートへと変換することが出来ます。

$ gprof -b cygwin1.dll

「-b」は「ヘルプページをスキップする」ことを意味しています。 gprof が出力するレポート形式をよく知っているなら、ヘルプページを省略することが出来ます。 gprof のドキュメントにはこのレポートに関する様々な説明がありますが、ssp は幾つかを変更しています。 例えば、レポートの最初の部分は次のように、各関数が使用した時間の総量を報告しています。

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 10.02    231.22    72.43       46  1574.57  1574.57  strcspn
  7.95    288.70    57.48      130   442.15   442.15  strncasematch

「seconds」列は実際には CPU opcode であり、opcode ごとに 1/100 秒となります。 即ち、上記例の「231.22」は 23,122 opcode を示しています。 ms/call 値は 10 倍の大きさとなっており、1574.57 は呼び出し毎に 157.457 であることを意味しています。 レポートの second 部分にある「self」及び「children」についても、同様の補正が必要になります。

OK、そして今や長い時間をかけて生成されたレポートを手に入れることが、そして最適化すべきスポットを識別することが出来ました。 time() 関数を使ってみましょう。 プログラム内から SSP をコントロールするための OutputDebugString() を利用することによって、この関数に対する選択的なプロファイルを行うために SSP を利用することが出来ます。 サンプルプログラムを挙げましょう。

#include <windows.h>
main()
{
    time_t t;
    OutputDebugString("ssp on");
    time(&t);
    OutputDebugString("ssp off");
}

そして、SSP に -d オプションを与えることにより、プロファイリングの初期値を *無効* とします。プログラムは最初の OutputDebugString() までは最高速度で動作し、それから少しの間だけステップ実行します。 それから、(いつも通り)gprofを利用することによって、プログラムの実行の一部分だけのパフォーマンスプロファイルが参照出来ます。

SSP には沢山のオプションがあります。ステッププロファイリングはプログラムの実行速度を通常よりも 1,000 倍も遅くしてしまうので、プログラム中でシングルステップ実行が必要な部分を絞るためにも、全てのオプションを理解することが望ましいと言えます。

-v - 冗長(verbose)。 このオプションはスレッドの開始と停止、OutputDebugString() の呼び出し、DLL のロードなどに関するメッセージを出力します。

-t 及び -c - 追跡(tracing)。 -t を利用すると、*全ての* ステップのアドレスがファイル「trace.ssp」に書き出されます。 複数のスレッドを追跡することが可能になるので、これはデバッグ関数の補助として使われます。 必要であれば、巧妙なスクリプトを利用してアドレスをディスアセンブルされた opcode とマッチさせることが出来るでしょう。 警告: 非常に急速に、*巨大な* ファイルが作成されます。 -c は各アドレスをコンソールに書き出すので、アセンブラのキーの塊に対しては有効です。 addr2line -C -f -s -e foo.exe < trace.ssp > lines.ssp を実行し、それから perl cvttrace を実行すれば、シンボリックトレースへと変換出来ます。

-s - サブスレッド(subthreads)。 通常、トレースが必要になるのはメインスレッドだけですが、 全てのスレッドをトレースする必要がある場合は、このオプションを利用します。 サブスレッドを呼び出すだけの関数をプロファイルしたいときも、このオプションが必要になるでしょう。 しかし、OutputDebugString() を利用すると、呼び出されたメインスレッドではないスレッドは自動的にプロファイリングが有効になります。

-l - DLL のプロファイリング。 プログラムが使用した各 DLL でどの程度の時間が使用されたかを示す、簡単な表を生成します。 仮に大部分の時間が DLL 内部で使用されていたとしたら、プログラム中の関数を最適化するなどということは考えられないでしょう。 私は普段、-v-s-l オプションを使用しています。

$ ssp -v -s -l -d 0x61001000 0x61080000 hello.exe

Usage: strace.exe [OPTIONS] <command-line>
Usage: strace.exe [OPTIONS] -p <pid>
Trace system calls and signals

  -b, --buffer-size=SIZE       set size of output file buffer
  -d, --no-delta               don't display the delta-t microsecond timestamp
  -f, --trace-children         trace child processes (toggle - default true)
  -h, --help                   output usage information and exit
  -m, --mask=MASK              set message filter mask
  -n, --crack-error-numbers    output descriptive text instead of error
                               numbers for Windows errors
  -o, --output=FILENAME        set output file to FILENAME
  -p, --pid=n                  attach to executing program with cygwin pid n
  -S, --flush-period=PERIOD    flush buffered strace output every PERIOD secs
  -t, --timestamp              use an absolute hh:mm:ss timestamp insted of 
                               the default microsecond timestamp.  Implies -d
  -T, --toggle                 toggle tracing in a process already being
                               traced. Requires -p <pid>
  -v, --version                output version information and exit
  -w, --new-window             spawn program under test in a new window

    MASK can be any combination of the following mnemonics and/or hex values
    (0x is optional).  Combine masks with '+' or ',' like so:

                      --mask=wm+system,malloc+0x00800

    Mnemonic Hex     Corresponding Def  Description
    =========================================================================
    all      0x00001 (_STRACE_ALL)      All strace messages.
    flush    0x00002 (_STRACE_FLUSH)    Flush output buffer after each message.
    inherit  0x00004 (_STRACE_INHERIT)  Children inherit mask from parent.
    uhoh     0x00008 (_STRACE_UHOH)     Unusual or weird phenomenon.
    syscall  0x00010 (_STRACE_SYSCALL)  System calls.
    startup  0x00020 (_STRACE_STARTUP)  argc/envp printout at startup.
    debug    0x00040 (_STRACE_DEBUG)    Info to help debugging. 
    paranoid 0x00080 (_STRACE_PARANOID) Paranoid info.
    termios  0x00100 (_STRACE_TERMIOS)  Info for debugging termios stuff.
    select   0x00200 (_STRACE_SELECT)   Info on ugly select internals.
    wm       0x00400 (_STRACE_WM)       Trace Windows msgs (enable _strace_wm).
    sigp     0x00800 (_STRACE_SIGP)     Trace signal and process handling.
    minimal  0x01000 (_STRACE_MINIMAL)  Very minimal strace output.
    exitdump 0x04000 (_STRACE_EXITDUMP) Dump strace cache on exit.
    system   0x08000 (_STRACE_SYSTEM)   Serious error; goes to console and log.
    nomutex  0x10000 (_STRACE_NOMUTEX)  Don't use mutex for synchronization.
    malloc   0x20000 (_STRACE_MALLOC)   Trace malloc calls.
    thread   0x40000 (_STRACE_THREAD)   Thread-locking calls.

strace プログラムはプログラム、及び場合によってはそのプログラムの子プログラムも実行し、そして全ての Cygwin DLL の出力をプログラムから標準出力或いは -o オプションで指定されたファイルへと書き出します。 strace のセッションは、次のようにすれば新しいウィンドウで開始することが出来ます。

$ strace -o tracing_output -w sh -c 'while true; do echo "tracing..."; done' &

これは特に、長い時間がかかる strace セッションに有効です。

strace はスタンドアロンの Windows プログラムであり、Cygwin DLL それ自体には依存していません(このことは、cygcheck を利用して確かめることが出来ます)。そのため、strace は POSIX パス名やシンボリックリンクを解釈しません。 このプログラムは主に、Cygwin DLL それ自身のデバッグに役立ちます。

Cygwin は完全なオペレーティングシステムではありませんから、 幾つかの処理を成し遂げるために Windows に頼らざるを得ません。 例えば、Cygwin は Windows ファイルシステムに対する POSIX 的な視点を提供していますが、ファイルシステムそれ自身に対するドライバは提供していません。 そのため、Cygwin を効果的に利用することの一環として、Windows の効果的な利用方法について学ぶことになります。 多くの Windows ユーティリティが Cygwin の卓越したコマンドライン環境と強調動作するためのよい方法を提供しています。 例えば、ipconfig.exe はネットワーク構成情報を提供しますし、 net.exe はネットワークファイルやプリンタ資源の表示や構成を行います。 これらのツールの大部分は利用方法を表示するための /? スイッチをサポートしています。

不幸なことに、Windows の全バージョンに含まれる標準的なツールのセットというものはありません。 自分のシステムで利用可能なツールについて不慣れな読者のために、 ここで一般的なガイドを示しておきましょう。 Windows 95、98 そして Me には非常に限られたコマンドラインの構成ツールが含まれています。 Windows NT 4.0 はより多くのツールをカバーしており、Windows 2000 と XP でより拡張されました。Microsoft は Windows NT 4.0 (the Resource Kit Support Tools)、Windows 2000(the Resource Kit Tools)、 Windows XP(Windows Support Tools)に対して、自由にダウンロード可能なツール群も提供しています。 加えて、download.comsimtel.net、 and sysinternals.com といった多くの独立系のサイトでコマンドラインユーティリティが配布されています。 find.exesort.exe といった幾つかの Windows ツールは Cygwin に含まれるバージョンと衝突します。 このため、フルパス(/usr/bin/find)で実行するか、 Cygwin の bin ディレクトリを PATH の先頭に持ってくる必要があります。

Windows プログラムは POSIX パス名を理解することは出来ませんから、 ファイルシステムを参照する全ての引数は Windows(或いは DOS)形式であるか、 変換されなければなりません。Cygwin は Windows と POSIX のパスを相互に変換するための cygpath ユーティリティを提供しています。 任意のディレクトリから Windows の Explorer を起動するためのスクリプトなど、 このユーティリティの完全なオプションは利用方法の例に関する完全な説明については 項3.7.2. 「cygpath」 を参照して下さい。 幾つかの形式が大部分の Windows プログラムで利用可能です。以下に例を挙げます。

notepad.exe "$(cygpath -aw "Desktop/Phone Numbers.txt")"

幾つかのプログラムは Windows 形式のセミコロンで区切られたパスリストを必要としますが、cygpath-p オプションを利用すれば、このようなパスリストを POSIX のパス形式へと変換することが出来ます。 例えば、Java のコンパイルを bash から行う場合、次のようになるでしょう。

javac -cp "$(cygpath -pw "$CLASSPATH")" hello.java

クォートとサブシェルの利用が何とも不恰好ですが、 しばしばシェルスクリプト内で cygpath を使うよりも望ましいものです。

別の問題はコンソールベースの Windows プログラムからの出力を受け取ったり、 入力を与えたりする場合に発生します。 不幸なことに Windows のコンソールアプリケーションとの対話というのは、 変換用ユーティリティを使えば済むような簡単な問題ではありません。 Windows コンソールアプリケーション、及び command.com 又は cmd.exe の元で動作するように設計されているアプリケーションなどは、 他の状況に対応することが出来ません。 Windows はコンソールデバイスのバックエンドにアタッチする方法を提供してくれませんので、 Cygwin はコンソール(DOS 窓)で動作している場合に限り、コンソールからの入力を受け取ることが出来ます。 Cygwin は他の伝統的な UNIX の入出力方法である pty(仮想端末)もサポートしていますが、 Windows の制限上、それは完全ではありません。 基本的な問題とは、Cygwin の pty はパイプであり、そして幾つかの Windows アプリケーションは入出力をパイプにリダイレクトしたがらないということです。

これらの問題を取り扱う助けとすべく、Cygwin は Windows と UNIX の間の互換性を維持するための動作のレベルを調整出来るようになっています。 Windows プログラムとの最大の互換性を取るためには DOS プロンプトを使い、必要となる Cygwin コマンド或いはスクリプトだけを実行します。 次の策は、デフォルトの DOS 窓で bash を実行させることです。この場合、Cygwin をより UNIX 互換とするためには、環境変数 CYGWINtty を設定して下さい(項3.5. 「CYGWIN 環境変数」 を参照)。別の方法としては、オプションの rxvt パッケージに一般的な X11 端末エミュレータのネイティブ Windows 版が含まれています(rxvt を利用する場合、環境変数 CYGWINtty を設定する必要はありません)。rxvt.exe を利用すればより UNIX 的な環境が利用出来ることになりますが、Windows プログラムとの幾つかの互換性の問題が発生するかもしれません。

ncftplynx、そして wget のような多くの Cygwin の一般的なパッケージは、ネットワーク接続を必要とします。 Cygwin は Windows のネットワーク接続に依存していますので、 これらのツールが期待通りに動作しない場合は、Windows のツールを利用して問題解決を行うことが出来ます。 最初のテストは、URL に指定されているホストへと到達可能かどうかを調べるべく、 Windows 95 以降の全てのバージョンに含まれている数少ないユーティリティの一つである ping.exe を実行することです。inetutils パッケージをインストールしているのであれば、ftptelnet のようなユーティリティについては、Windows 版と Cygwin 版の両方が使えることでしょう。 これらのプログラムを実行した場合に問題が発生するのであれば、もう一つの版が正しく動作するかについて調べてみて下さい。

特定の状況のために、他の様々なプログラムを利用することが出来ます。 もしあなたのシステムが常時ネットワークに接続されていないのであれば、自動的なダイアルアップ接続を実現する rasdial.exe(或いは、Windows 95、98 及び Me 用の他のツール)に興味を持つことでしょう。 頻繁にネットワーク構成を変更するユーザは、netsh.exe (Windows 2000 と XP に付属しています)を利用したスクリプトによって、このような変更を行うことが出来ます。 プロクシが必要なユーザはオープンソースの NTLM Authorization Proxy Server や、無償の Hummingbird SOCKS Proxy を利用することによって、貴方の環境ででも Cygwin のネットワークプログラムを利用することが可能となるでしょう。

もう一つの問題としては、 UNIX スタイルのリンク(他のファイルを指し示すファイル)と Microsoft の .link ファイル(ファイルへのショートカットを提供する) の違いが挙げられます。ちょっと見たところ、両者はそっくりに見えますが、 現実には相当異なるものです。デフォルトでは、Cygwin はシンボリックリンクを標準的な Microsoft の .lnk ファイルと互換性があるように作成する仕組みを使います。 しかし、Cygwin のシンボリックリンクには作業ディレクトリやアイコンなどといった、 標準的な Microsoft のショートカットで利用できるような情報は含まれていません。 cygutils パッケージには、標準的な Microsoft の .lnk ファイルを作成するための mkshortcut ユーティリティが含まれています。

Cygwin がこれらネイティブのショートカットを他のシンボリックリンク同様に扱ったとすると、 tar アーカイブ内に Microsoft の .lnk ファイルをアーカイブすることは出来ませんし、その中に含まれる全ての情報を保持することも出来ません。 展開後、これらのショートカットは全ての追加情報を失い、 Cygwin の標準的なシンボリックリンクとの違いはなくなってしまいます。 従って、これら二種類のリンクは異なるように扱われます。 不幸なことに、これは通常の UNIX 的な手法でのシンボリックリンクの作成と利用は、 Windows のショートカットではうまくいかないことを意味しています。

Cygwin からの印刷は、cygutils に含まれる lpr (Windows ネイティブの lpr.exe と混同しないで下さい) を利用する方法も含めて、様々な方法が利用出来ます。 cygutils に含まれる lpr を簡単に利用するには、デフォルトのデバイス名を環境変数 PRINTER に設定します。 -d-P を利用して、コマンドラインからデバイスを指定することも出来ます。 このような指定は、環境変数の設定を上書きします。

デバイス名としては UNC パス \\server_name\printer_name)、 予約済みの DOS デバイス名(prnlpt1)、 或いはプリンタ共有にマップされたローカルポート名が利用出来ます。 シェル内で lpr を利用する際に便利なように、 UNC パスにはスラッシュを利用するという点に注意して下さい (//server_name/printer_name のようになります)。 シェルでは、バックスペースはエスケープとして利用されるのです。

lpr はプリンタに raw データを送ります。 整形は一切行われません。 全てではありませんが、多くのプリンタはプレーンテキストを入力として受け取ります。 もしあなたのプリンタが PostScript をサポートしているのであれば、 a2psenscript といったパッケージを利用して、印刷用のテキストファイルを作成することが出来ます。 ghostscript パッケージもまた、 PostScript から様々なネイティブのプリンタ言語への変換機能を提供します。 加えて、PostScript を印刷する ネイティブの Windows アプリケーション gsprint が、 Ghostscript website から手に入ります。

Cygwin を使うことで、Microsoft 又は off-the-shelf の出版物において定義されている GUI 関数を含む、標準的な Windows の 32 ビット API をフルに使用したプログラムを作成することが出来ます。 しかしながら、Microsoft のツールの代わりに GNU ツールを使用する場合、 それらのアプリケーションを作成するプロセスは少々異なったものとなります。

ほとんどの部分については、ソースコードに変更を加える必要はありません。 しかし、関数から全ての __export 属性を除去し、 以下に示すような形に置き換えなければなりません。

int foo (int) __attribute__ ((__dllexport__));

int
foo (int i)

Makefile は他の UNIX 風の Makefile に、そして他の Cygwin での Makefile に似ています。唯一の違いは、プログラムをコマンドラインアプリケーションではなく GUI アプリケーションとしてリンクするために gcc -mwindows を使用するという点だけです。 例を示します。

myapp.exe : myapp.o myapp.res
	gcc -mwindows myapp.o myapp.res -o $@

myapp.res : myapp.rc resource.h
	windres $< -O coff -o $@

windres を使えば、 Windows リソースを COFF フォーマットの .res ファイルにコンパイル出来ることを覚えておいて下さい。 これによって全てのビットマップ、アイコン、そして必要となる他のリソースが、 一つの扱いやすいオブジェクトファイルに格納されます。 通常、「-O coff」を省略した場合は Windows .res フォーマットのファイルが作成されます。 しかし我々にとってリンクが可能なのは COFF オブジェクトだけです。 そこで windres が COFF オブジェクトを作成するように指示しますが、 「リンカは Windows リソースファイルを直接扱うことが可能である」 と仮定する多くの事例に合わせるべく、 .res というファイル名の命名規則は残してあります。 windres に関する更なる情報については、 binutils のマニュアルを参照して下さい。

始めるに当たって参考となるよう、GUI モードの「Hello, World!」プログラムのサンプルを以下に示しておきます。

/*-------------------------------------------------*/
/* hellogui.c - gui hello world                    */
/* build: gcc -mwindows hellogui.c -o hellogui.exe */
/*-------------------------------------------------*/
#include <windows.h>

char glpszText[1024];

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance, 
		HINSTANCE hPrevInstance,
		LPSTR lpCmdLine,
		int nCmdShow)
{
	sprintf(glpszText, 
		"Hello World\nGetCommandLine(): [%s]\n"
		"WinMain lpCmdLine: [%s]\n",
		lpCmdLine, GetCommandLine() );

	WNDCLASSEX wcex; 
 
	wcex.cbSize = sizeof(wcex);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = "HELLO";
	wcex.hIconSm = NULL;

	if (!RegisterClassEx(&wcex))
		return FALSE; 

	HWND hWnd;
	hWnd = CreateWindow("HELLO", "Hello", WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

	if (!hWnd)
		return FALSE;

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	
	switch (message) 
	{
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			RECT rt;
			GetClientRect(hWnd, &rt);
			DrawText(hdc, glpszText, strlen(glpszText), &rt, DT_TOP | DT_LEFT);
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

プログラムが正しく動作しない場合、 通常は「バグ」がプログラム中に存在します。 それは期待しない結果を返したりクラッシュしたりするプログラム中に、 どこか悪い部分が存在することを意味しています。 デバッガと呼ばれる特別なツールは、 これらのバグを診断し修正することを容易にします。 Cygwin の場合、「GNU DeBugger」を意味する GDB がデバッガです。 このツールは、実行中やクラッシュ後のプログラムの状況を調査することを可能にする、 コントロールされた環境の元でプログラムを動作させます。 クラッシュするプログラムは時折「コア」ファイルを吐き出します。 Cygwin では、これは GDB が直接扱うことが出来ない通常のテキストファイルとなります。

プログラムをデバッグする前に、 プログラムをデバッグ用に準備する必要があります。 ソースをオブジェクトへとコンパイルする際に、 他の全てのフラグに -g を追加します。

これによって、 行番号、変数名そしてその他の有益な内容を含む追加情報がオブジェクトに対して追加されます (オブジェクトのサイズはより大きくなります)。 これらの追加のシンボルとデバッグ情報は、 デバッガがデバッギングをより簡単にするために、 元のソースコードに関する十分な情報をプログラムに対して与えます。

GNUPro の Windows バージョンでは、 GDB はフル機能のグラフィカルインタフェースを備えています。 Cygwin の Net ディストリビューションでは、 GDB はコマンドラインツールとしてのみ使用可能です。 GDB を起動するには、コマンドプロンプトから単に gdb myapp.exe とタイプします。 GDB 自身について説明するテキストが表示された後、 コマンド入力を促す (gdb) プロンプトが現れます。 このプロンプトが表示されているときは常に、 gdb が runhelp といったコマンドがタイプされるのを待っていることを意味します。 おぉ:-)help とタイプすれば入力可能なコマンドのヘルプが表示されますし、 [GDB ユーザーズマニュアル] を読めば GDB とその使い方に関する完全な説明を得ることが出来ます。

もしプログラムがクラッシュし、 なぜクラッシュしたのかを見極めたいときは、run をタイプしてプログラムを動作させることが最上の方法です。 クラッシュした後、where をタイプして どこでクラッシュしたのかを見つけ出すことが出来ますし、 info locals をタイプすることによって 全ローカル変数の値を表示することも出来ます。 個別の変数の値を調べたりポインタがどこを指しているかを知るための print もまた使えます。

もしプログラムが何か期待しない動作をするのであれば、 break コマンドを使って、 特定の関数または行番号でプログラムを停止させるよう gdb に伝えることが出来ます。

run を入力すれば、 プログラムは「ブレークポイント」で停止します。 そして他の gdb コマンドを使ってその時点でのプログラムの状態を参照したり、 変数の内容を修正したり、step でプログラムのステートメントを一つずつ進めるといったことがことが出来ます。

プログラムにコマンドライン引数を与えるため、run コマンドには追加の引数を与えることが可能であることを覚えておいて下さい。 この 2 つのケースはプログラムに対して同じ結果を及ぼします。

DLL とはダイナミックリンクライブラリのことであり、 ライブラリがビルド時ではなくプログラムの実行時にリンクされることを意味します。 DLL は 3 つの部分に分かれています。

コードとデータはあなたが記述する部分、すなわち関数、 変数などです。これらは全て、 一つの大きなオブジェクトファイルを作成するように互いにマージされ、 DLL 内部に格納されます。.exe には格納されません。

エクスポートには DLL が他のプログラムに対して提供する関数と変数のリストが含まれています。 これらは「グローバル」シンボルのリストであると考えられ、残りは隠されています。 通常、このリストはテキストエディタによって手作業で作成されますが、 しかしコード中の関数のリストから自動的に作成することも出来ます。 dlltool プログラムは、 エクスポートされたシンボルが記述されたテキストファイルから DLL のエクスポートセクションを作成します。

インポートライブラリは通常の UNIX 風の .a ライブラリですが、 プログラムがどのように DLL と互いに影響しあう(インポートする) かを OS に伝えるために必要となる、ごく小さな情報だけを含んでいます。 この情報は .exe にリンクされます。 これもまた dlltool から作成されます。

このページでは、gcc によって DLL を構築する単純な例を示すだけにしておきます。 更なる沢山の追加機能について調べてみるつもりなら、gcc のドキュメントか、現在は http://gcc.gnu.org/ にある Web サイトを参照することから始めてみて下さい。

それでは、DLL をビルドする単純な例をお見せしましょう。 この例では、プログラム(myprog.exe) に対する一つのファイル myprog.c と、 DLL(mydll.dll) の内容となる一つのファイル mydll.c を使用します。

幸運にも、最新の gcc と binutils を利用するのであれば、DLL をビルドする手順は今や非常に単純なものとなっています。 mydll.c 中の、この最小の関数をビルドするとしましょう。

#include <stdio.h>

int
hello()
{
  printf ("Hello World!\n");
}

最初に、mydll.c をオブジェクトコードへとコンパイルします。

gcc -c mydll.c

続いて、gcc に共有ライブラリをビルドさせます。

gcc -shared -o mydll.dll mydll.o

これだけです! この例を完了すべく、作成した DLL を単純なプログラムへとリンクしてみましょう。

int
main ()
{
  hello ();
}  

以下のようなコマンドを利用して、先ほどの DLL をリンクしてみます。

gcc -o myprog myprog.c -L./ -lmydll

しかし、DLL をエクスポートライブラリとしてビルドするのであれば、 恐らく次のようなコンパイル構文を利用することになるでしょう。

gcc -shared -o cyg${module}.dll \
    -Wl,--out-implib=lib${module}.dll.a \
    -Wl,--export-all-symbols \
    -Wl,--enable-auto-import \
    -Wl,--whole-archive ${old_libs} \
    -Wl,--no-whole-archive ${dependency_libs}

${module} はライブラリの名前ですが、DLL に対しては接頭辞 cyg が、インポートライブラリについては接頭辞 lib が付与されます。 ネイティブの Windows MinGW DLL との区別をつけるため、Cygwin の DLL は接頭辞として cyg を利用します。詳細については MinGW Web サイト を参照して下さい。 ${old_libs} は全てのオブジェクトファイル(組み込まれる静的ライブラリ、或いは単体のオブジェクトファイル)であり、 ${dependency_libs} はリンクに必要となるインポートライブラリ (例えば、「'-lpng -lz -L/usr/local/special -lmyspeciallib'」)です。

既存の DLL をリンクするためには、Cygwin と互換性のあるインポートライブラリを作成する必要があります。 DLL をコンパイルするために必要なソースが手元にあるのなら、 gcc を利用して DLL をビルドする方法の詳細については 項4.3.1. 「DLL のビルド」 を参照して下さい。 もしソースが手元になく、利用可能なインポートライブラリも提供されていない場合、 以下のコマンド群によって .def ファイルを作成することにより、 この作業の大部分を行うことが出来ます (クォーティングが正しく行われるように、この作業は bash を使って行う必要があります)。

echo EXPORTS > foo.def
nm foo.dll | grep ' T _' | sed 's/.* T _//' >> foo.def

これは DLL がストリップされていない場合のみ可能であることを覚えておいて下さい。 そうでなければ「No symbols in foo.dll(foo.dll にはシンボルが含まれていません)」 というエラーメッセージが発生することになるでしょう。

一旦 .def ファイルが出来上がったなら、 このようにしてこのファイルからインポートライブラリを作成出来ます。

dlltool --def foo.def --dllname foo.dll --output-lib foo.a

windres は Windows リソースファイル (*.rc) を読み込み、それを res または coff ファイルへと変換します。 入力ファイルのシンタックスとセマンティクスについては他のリソースコンパイラと同様ですので、 詳細については Windows のリソースフォーマットについて記述した他の出版物を当ってみて下さい。 windres 自身もまた、 binutils マニュアル中で完全に文書化されています。 ここではプロジェクト中での使用方法について一例を挙げます。

myapp.exe : myapp.o myapp.res
	gcc -mwindows myapp.o myapp.res -o $@

myapp.res : myapp.rc resource.h
	windres $< -O coff -o $@

以下は windres がサポートするシンタックスのクイックリファレンスです。

id ACCELERATORS サブオプション
BEG
"^C" 12
"Q" 12
65 12
65 12 , VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
65 12 , VIRTKEY, ASCII, NOINVERT, SHIFT, CONTROL, ALT
(12 はあるアクセラレータ ID)
END

SHIFT、CONTROL、ALT には VIRTKEY が必要


id BITMAP メモリフラグ "ファイル名"
メモリフラグのデフォルトは MOVEABLE


id CURSOR メモリフラグ "ファイル名"
メモリフラグのデフォルトは MOVEABLE,DISCARDABLE


id DIALOG メモリフラグ 拡張スタイル x,y,幅,高さ スタイル BEG コントロール END
id DIALOGEX メモリフラグ 拡張スタイル x,y,幅,高さ スタイル BEG コントロール END
id DIALOGEX メモリフラグ 拡張スタイル x,y,幅,高さ,ヘルプID スタイル BEG コントロール END

メモリフラグのデフォルトは MOVEABLE
拡張スタイルは EXSTYLE=number となる
スタイル:	CAPTION "文字列"
	CLASS id
	STYLE  FOO | NOT FOO | (12)
	EXSTYLE number
	FONT 数値, "名称"
	FONT 数値, "名称",ウェイト,イタリック
	MENU id
	CHARACTERISTICS 数値
	LANGUAGE 数値,数値
	VERSIONK 数値
コントロール:
	AUTO3STATE パラメータ
	AUTOCHECKBOX パラメータ
	AUTORADIOBUTTON パラメータ
	BEDIT パラメータ
	CHECKBOX パラメータ
	COMBOBOX パラメータ
	CONTROL ["名称",] id, クラス, スタイル, x,y,w,h [,拡張スタイル] [データ]
	CONTROL ["名称",] id, クラス, スタイル, x,y,w,h, 拡張スタイル, ヘルプID [データ]
	CTEXT パラメータ
	DEFPUSHBUTTON パラメータ
	EDITTEXT パラメータ
	GROUPBOX パラメータ
	HEDIT パラメータ
	ICON ["名前",] id, x,y [データ]
	ICON ["名前",] id, x,y,w,h, スタイル, 拡張スタイル [データ]
	ICON ["名前",] id, x,y,w,h, スタイル, 拡張スタイル, ヘルプID [データ]
	IEDIT パラメータ
	LISTBOX パラメータ
	LTEXT パラメータ
	PUSHBOX パラメータ
	PUSHBUTTON パラメータ
	RADIOBUTTON パラメータ
	RTEXT パラメータ
	SCROLLBAR パラメータ
	STATE3 パラメータ
	USERBUTTON "文字列", id, x,y,w,h, スタイル, 拡張スタイル
パラメータ:
	["名称",] id, x, y, w, h, [データ]
	["名称",] id, x, y, w, h, スタイル [,拡張スタイル] [データ]
	["名称",] id, x, y, w, h, スタイル, 拡張スタイル, ヘルプID [データ]

[データ] はオプションで BEG (文字列|数値) [,(文字列|数値)] (その他) END 


id FONT メモリフラグ "ファイル名"
メモリフラグのデフォルトは MOVEABLE|DISCARDABLE

id ICON メモリフラグ "ファイル名"
メモリフラグのデフォルトは MOVEABLE|DISCARDABLE

LANGUAGE 数値,数値

id MENU オプション BEG アイテム END
アイテム:
	"文字列", id, フラグ
	SEPARATOR
	POPUP "文字列" フラグ BEG メニューアイテム END
フラグ:
	CHECKED
	GRAYED
	HELP
	INACTIVE
	MENUBARBREAK
	MENUBREAK

id MENUEX サブオプション BEG アイテム END
アイテム:
	MENUITEM "文字列"
	MENUITEM "文字列", id
	MENUITEM "文字列", id, タイプ [,状態]
	POPUP "文字列" BEG アイテム END
	POPUP "文字列", id BEG アイテム END
	POPUP "文字列", id, タイプ BEG アイテム END
	POPUP "文字列", id, タイプ, 状態 [,ヘルプID] BEG アイテム END

id MESSAGETABLE メモリフラグ "ファイル名"
メモリフラグのデフォルトは MOVEABLE

id RCDATA サブオプション BEG (文字列|数値) [,(文字列|数値)] (その他) END

STRINGTABLE サブオプション BEG 文字列 END
文字列:
	id "文字列"
	id, "文字列"

(ユーザデータ)
id id サブオプション BEG (文字列|数値) [,(文字列|数値)] (その他) END

id VERSIONINFO 材料 BEG バージョンブロック END
材料:	FILEVERSION 数値,数値,数値,数値
	PRODUCTVERSION 数値,数値,数値,数値
	FILEFLAGSMASK 数値
	FILEOS 数値
	FILETYPE 数値
	FILESUBTYPE 数値
バージョンブロック:
	BLOCK "StringFileInfo" BEG BLOCK BEG バージョン値 END END
	BLOCK "VarFileInfo" BEG BLOCK BEG バージョン翻訳情報 END END
バージョン値: VALUE "foo","bar"
バージョン翻訳情報: VALUE 数値,数値



サブオプション:
	メモリフラグ
	CHARACTERISTICS 数値
	LANGUAGE 数値,数値
	VERSIONK 数値

メモリフラグは MOVEABLE/FIXED PURE/IMPURE PRELOAD/LOADONCALL DISCARDABLE