diff --git a/ja_JP.eucJP/man/man2/getuid.2 b/ja_JP.eucJP/man/man2/getuid.2 index f2ac246cd0..ffbc1531eb 100644 --- a/ja_JP.eucJP/man/man2/getuid.2 +++ b/ja_JP.eucJP/man/man2/getuid.2 @@ -1,88 +1,88 @@ .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)getuid.2 8.1 (Berkeley) 6/4/93 -.\" %FreeBSD: src/lib/libc/sys/getuid.2,v 1.11 2001/10/01 16:09:01 ru Exp % +.\" %FreeBSD: src/lib/libc/sys/getuid.2,v 1.12 2002/12/18 09:22:30 ru Exp % .\" .\" $FreeBSD$ .Dd June 4, 1993 .Dt GETUID 2 .Os .Sh 名称 .Nm getuid , .Nm geteuid .Nd ユーザ識別子を得る .Sh ライブラリ .Lb libc .Sh 書式 .In unistd.h .In sys/types.h .Ft uid_t .Fn getuid void .Ft uid_t .Fn geteuid void .Sh 解説 .Fn getuid システムコールは、呼び出しプロセスの実ユーザ ID を返します。 .Fn geteuid システムコールは、呼び出しプロセスの実効ユーザ ID を返します。 .Pp 実ユーザ ID は、プログラムを起動したユーザの ID です。 実効ユーザ ID は、 .Dq Em ユーザ ID 設定 モードプロセスの実行中にプロセスに追加のパーミッションを与えるので、 .Fn getuid を使用して呼び出しプロセスの実ユーザ ID を把握します。 .Sh エラー .Fn getuid システムコールと .Fn geteuid システムコールは必ず正常に完了するので、エラーを示すための戻り値はありません。 .Sh 関連項目 .Xr getgid 2 , .Xr issetugid 2 , .Xr setgid 2 , .Xr setreuid 2 , .Xr setuid 2 .Sh 規格 .Fn geteuid システムコールと .Fn getuid システムコールは .St -p1003.1-90 に適合しています。 .Sh 歴史 .Fn getuid 関数と .Fn geteuid 関数は .At v7 ではじめて登場しました。 diff --git a/ja_JP.eucJP/man/man2/rfork.2 b/ja_JP.eucJP/man/man2/rfork.2 index 17d42be35b..959b064fd3 100644 --- a/ja_JP.eucJP/man/man2/rfork.2 +++ b/ja_JP.eucJP/man/man2/rfork.2 @@ -1,169 +1,169 @@ .\" .\" This manual page is taken directly from Plan9, and modified to .\" describe the actual BSD implementation. Permission for .\" use of this page comes from Rob Pike . .\" -.\" %FreeBSD: src/lib/libc/sys/rfork.2,v 1.30 2003/02/23 01:47:48 ru Exp % +.\" %FreeBSD: src/lib/libc/sys/rfork.2,v 1.31 2003/04/27 21:01:34 robert Exp % .\" .\" $FreeBSD$ .Dd January 31, 2003 .Dt RFORK 2 .Os .Sh 名称 .Nm rfork .Nd プロセスリソースの操作 .Sh ライブラリ .Lb libc .Sh 書式 .In unistd.h -.Ft int +.Ft pid_t .Fn rfork "int flags" .Sh 解説 fork, vfork, rfork は、新しいプロセスが作成される唯一の方法です。 .Fn rfork への引数 .Fa flags は、起動しているプロセス (親) のどのリソースが新しいプロセス (子) に よって共有されるか、またはそれらのデフォルト値に初期化されるかを選択します。 リソースにはオープンファイル記述子テーブル (これは、共有される場合、 プロセスが他のプロセスについてファイルを開閉することを 許容します) およびオープンファイルが含まれます。 .Fa flags 引数は次の項目の論理和 (OR) です: .Bl -tag -width ".Dv RFLINUXTHPN" .It Dv RFPROC 設定されている場合、新しいプロセスが作成されます。 そうでない場合、変更が現在のプロセスに影響を及ぼします。 .It Dv RFNOWAIT 設定されている場合、子プロセスは親プロセスから分離されます。 終了時に、子プロセスは、親プロセスが集めるステータスを残しません。 .Xr wait 2 を参照してください。 .It Dv RFFDG 設定されている場合、起動側のファイル記述子テーブル .Xr ( intro 2 を参照) がコピーされます。 そうでない場合、2 つのプロセスが 1 つのテーブルを共有します。 .It Dv RFCFDG 設定されている場合、新しいプロセスは新しいファイル記述子テーブルを持って 開始します。 .Dv RFFDG とは互いに排他的です。 .It Dv RFMEM 設定されている場合、 通常、ハードウェアのページテーブルを直接共有することで、 カーネルはアドレス空間全体を強制的に共有します。 子は、このような方法で、親プロセスが所有しているすべてのセグメントを、 それが普段共有可能であるか否かに関係なく、継承し共有します。 スタックセグメントは分割されない (親と子の両方が同じスタック上に復帰する) ので、RFMEM フラグを指定した .Fn rfork は一般に、C 言語を含む高級言語から直接呼び出すことはできません。 共に設定可能なフラグは .Dv RFPROC だけです。 この問題を解決し、提供されたスタック上で新しいプロセスを 走らせるために補助関数が提供されています。 詳しくは .Xr rfork_thread 3 を参照してください。 .It Dv RFSIGSHARE 設定されている場合、カーネルは、親子間で sigacts 構造体を強制的に共有します。 .It Dv RFLINUXTHPN 設定されている場合、カーネルは、子についてのスレッド終了時に、 SIGCHILD の代わりに SIGUSR1 を返します。 これは特定の Linux クローン動作を模倣するためです。 .El .Pp 共有ファイル記述子テーブル内のファイル記述子は、 明示的に閉じられるか、またはテーブルを 共有しているすべてのプロセスが終了するまで開いたままに保たれます。 .Pp .Dv RFPROC が設定されている場合、 親プロセス内で返される値は子プロセスのプロセス ID です。 子プロセス内で返される値は 0 です。 .Dv RFPROC がない場合、戻り値は 0 です。 プロセス ID の範囲は 1 から最大整数値 .Ft ( int ) です。 必要であれば、要求されたプロセスリソースが利用できるようになるまで .Fn rfork システムコールは待機します。 .Pp .Fn fork システムコールは、 .Fn rfork "RFFDG | RFPROC" への呼び出しとして実装可能ですが、後方互換性のために そのようには実装されていません。 .Sh 戻り値 正常に完了した場合、 .Fn rfork は、子プロセスに値 0 を返し、子プロセスのプロセス ID を親プロセスに 返します。 そうでない場合、子プロセスは作成されずに、値 -1 が親プロセスに返され、 エラーを示すためにグローバル変数 .Va errno が設定されます。 .Sh エラー .Fn rfork システムコールは、次の場合に処理を失敗し、子プロセスは作成されません: .Bl -tag -width Er .It Bq Er EAGAIN 実行中のプロセスの合計数がシステムの課す制限を超過してしまいます。 制限は .Xr sysctl 3 MIB 変数 .Dv KERN_MAXPROC によって指定されます (スーパユーザを除いて、制限は実際には これより 10 個少なくなります)。 .It Bq Er EAGAIN ユーザがスーパユーザではなく、1 人のユーザによる実行中の プロセスの合計数がシステムの課した制限を超過してしまいます。 制限は、 .Xr sysctl 3 MIB 変数 .Dv KERN_MAXPROCPERUID によって指定されます。 .It Bq Er EAGAIN ユーザがスーパユーザではなく、 .Fa resource 引数 .Dv RLIMIT_NOFILE に対応するソフトリソースの制限を超過してしまいます .Pf ( Xr getrlimit 2 を参照)。 .It Bq Er EINVAL RFFDG フラグと RFCFDG フラグの両方が指定されました。 .It Bq Er EINVAL これまでに列挙されていないフラグが指定されました。 .It Bq Er ENOMEM 新しいプロセス用に十分なスワップ空間が不足しました。 .El .Sh 関連項目 .Xr fork 2 , .Xr intro 2 , .Xr minherit 2 , .Xr vfork 2 , .Xr rfork_thread 3 .Sh バグ .Fx では、ネイティブな .Fn clone ライブラリコールは未だに実装されていませんし、 現在の pthreads 実装は RFMEM を指定した .Fn rfork を利用していません。 linux スレッドライブラリのネイティブポートである、 .Pa /usr/ports/devel/linuxthreads は RFMEM を利用して動作する .Fn clone 呼び出しを含んでいます。 .Xr rfork_thread 3 関数は .Fn clone の代わりとして利用することができます。 .Sh 歴史 .Fn rfork 関数は Plan9 ではじめて登場しました。 diff --git a/ja_JP.eucJP/man/man2/vfork.2 b/ja_JP.eucJP/man/man2/vfork.2 index 768b410251..5e26852a6e 100644 --- a/ja_JP.eucJP/man/man2/vfork.2 +++ b/ja_JP.eucJP/man/man2/vfork.2 @@ -1,131 +1,131 @@ .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)vfork.2 8.1 (Berkeley) 6/4/93 -.\" %FreeBSD: src/lib/libc/sys/vfork.2,v 1.21 2002/12/27 12:15:29 schweikh Exp % +.\" %FreeBSD: src/lib/libc/sys/vfork.2,v 1.22 2003/04/27 21:01:34 robert Exp % .\" .\" $FreeBSD$ .Dd June 4, 1993 .Dt VFORK 2 .Os .Sh 名称 .Nm vfork .Nd 効率的な方法で仮想メモリに新しいプロセスを生成 .Sh ライブラリ .Lb libc .Sh 書式 .In unistd.h -.Ft int +.Ft pid_t .Fn vfork void .Sh 解説 .Fn vfork システムコールは、古いプロセスのアドレス空間を完全にコピーせずに、 新しいプロセスを作成できます。 ページングする環境では、古いプロセスのアドレス空間を完全にコピーすることは、 非常に非効率的です。 .Xr fork 2 する目的が、 .Xr execve 2 のための新しいシステムコンテキストの作成である場合に有効です。 .Fn vfork システムコールは、 .Xr execve 2 を呼び出すか、終了する ( .Xr _exit 2 を呼び出すか異常終了する) まで子が親のメモリと制御スレッドを借りるという点で、 .Xr fork 2 と異なります。 親プロセスは、子がリソースを使用している間停止されます。 .Pp .Fn vfork システムコールは、0 を子のコンテキストに、そして (後に) 子の pid を 親のコンテキストに戻します。 .Pp 通常の場合、 .Fn vfork システムコールは .Xr fork 2 のように使用できます。 しかし、 .Fn vfork を呼び出したプロシージャから子のコンテキストで動作している間に 動作して戻ることはありません。 最終的に .Fn vfork から戻ると、存在しないスタックフレームに戻るからです。 .Xr execve 2 を実行できない場合は、 .Xr exit 3 ではなく、 .Xr _exit 2 を呼び出してください。 .Xr exit 3 は標準入出力チャネルをフラッシュして閉じるため、 親プロセスの標準入出力データ構造体を壊してしまいます ( .Xr fork 2 でも、バッファに入っているデータが 2 回フラッシュされるので、 .Xr exit 3 を呼び出さないでください)。 .Sh 関連項目 .Xr execve 2 , .Xr fork 2 , .Xr rfork 2 , .Xr sigvec 2 , .Xr wait 2 , .Xr _exit 2 , .Xr exit 3 .Sh 戻り値 .Xr fork 2 と同じです。 .Sh バグ このシステムコールは、適切なシステム共有メカニズムが実現したときに 削除されます。 削除された場合は、 .Xr fork 2 と同義になるので、 .Xr vfork 2 のメモリ共有の現実装には依存しないでください。 .Pp デッドロックを避けるため、 .Fn vfork の途中で子になるプロセスには、 .Dv SIGTTOU シグナルや .Dv SIGTTIN シグナルが送信されません。 その代わりに出力、または、 .Xr ioctl 2 呼び出しが許可され、入力しようとすると EOF となります。 .Sh 歴史 .Fn vfork システムコールは、 .Bx 2.9 で登場しました。 diff --git a/ja_JP.eucJP/man/man9/sleep.9 b/ja_JP.eucJP/man/man9/sleep.9 index a2e4ac5b88..68cd8de79d 100644 --- a/ja_JP.eucJP/man/man9/sleep.9 +++ b/ja_JP.eucJP/man/man9/sleep.9 @@ -1,157 +1,157 @@ .\" .\" Copyright (c) 1996 Joerg Wunsch .\" .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" %FreeBSD: src/share/man/man9/sleep.9,v 1.38 2003/02/04 08:53:45 guido Exp % +.\" %FreeBSD: src/share/man/man9/sleep.9,v 1.39 2003/02/24 22:53:24 ru Exp % .\" $FreeBSD$ .\" " .Dd December 17, 1998 .Os .Dt SLEEP 9 .Sh 名称 .Nm sleep , .Nm msleep , .Nm tsleep , .Nm wakeup .Nd イベントのウェイト .Sh 書式 .In sys/param.h .In sys/systm.h .In sys/proc.h .Ft int .Fn tsleep "void *ident" "int priority" "const char *wmesg" "int timo" .Ft int .Fn msleep "void *ident" "struct mtx *mtx" "int priority" "const char *wmesg" "int timo" .Ft void .Fn wakeup "void *ident" .Ft void .Fn wakeup_one "void *ident" .Sh 解説 関数 .Fn tsleep および .Fn wakeup はイベントに基づいたプロセスのブロックを取り扱います。 プロセスが外部イベントを待たなければならない場合には、そのプロセスは .Fn tsleep によってスリープ状態に置かれます。 パラメータ .Ar ident は、プロセスがどのイベント上でスリープしているかを識別する一意的な 任意のアドレスです。 単一の .Ar ident 上でスリープしている全てのプロセスは後で、 .Fn wakeup によって起こされます。これは、しばしば割り込みルーチンの中から呼び出され、 プロセスがブロックしているリソースが現在利用可能になったことを示します。 .Pp パラメータ .Ar wmesg は .Xr ps 1 のようなツールのためのスリープ状態を解説する文字列です。 これらのプログラムの任意の文字列を表示するための領域の制限のため、 このメッセージは 6 文字を超えるべきではありません。 .Pp .Fn wakeup_one 関数はパラメータ .Fa ident 上でスリープしているキューの中の最初のプロセスを実行可能に するために使用されます。 これは、多数のプロセスが同じアドレス上でスリープしているが、 実行可能となったときその中の 1 つのみが実際には役に立つ作業ができるときに、 システムが飽和することを防ぐことが可能です。 .Pp .Fn tsleep 関数は一般的なスリープの呼び出しです。 明示された識別子上の wakeup が実行されるまでの間、 現在のプロセスを一時停止させます。 それからそのプロセスは明示された優先度 .Ar priority で実行可能にされます。 長くて .Ar timo \&/ hz 秒間 (0 はタイムアウトなしを意味します) スリープします。 .Ar pri が .Dv PCATCH フラグを含む場合には、スリープの前後でシグナルがチェックされます。 そうでない場合には、シグナルはチェックされません。 起こされた場合には 0 を返し、タイムアウトが経過した場合には .Er EWOULDBLOCK を返します。 .Dv PCATCH が設定されていてシグナルが配信される必要がある場合で、 可能であれば現在のシステムコールが再開始されるべきである場合には .Er ERESTART が返され、 .Er ( EINTR を返す) シグナルによってそのシステムコールが中断されるべき場合には .Er EINTR が返されます。 .Pp .Fn msleep 関数は tsleep の変種です。パラメータ .Ar mtx は、スリープの前に抜け、 .Fn msleep が戻る前に入る mutex です。 .Ar pri が .Dv PDROP フラグを含む場合には、戻る前に .Ar mtx 引数へ入りません。 ある状態を不可分にチェックできることを保証し、 その状態の変更も対応する wakeup も失うことなく 現在のプロセスを中断できることを保証するために、 この mutex は使用されます。 .Sh 戻り値 上記を参照してください。 .Sh 関連項目 .Xr ps 1 , .Xr malloc 9 , .Xr mi_switch 9 .Sh 歴史 sleep/wakeup プロセス同期機構はとても古いです。 これはとても早期のバージョンの .Ux で登場しました。 .Pp .Fn tsleep 関数は .Bx 4.4 で登場しました。 .Pp .Fn sleep 関数は伝統的な形式のために使用されます。 これはタイムアウトまたは .Ar wmesg を明示させないため、中止されています。 .Sh 作者 .An -nosplit このマニュアルページは .An J\(:org Wunsch Aq joerg@FreeBSD.org が書きました。 diff --git a/ja_JP.eucJP/man/man9/style.9 b/ja_JP.eucJP/man/man9/style.9 index 2004bd8470..9fa448a6ca 100644 --- a/ja_JP.eucJP/man/man9/style.9 +++ b/ja_JP.eucJP/man/man9/style.9 @@ -1,787 +1,787 @@ .\" Copyright (c) 1995-2001 FreeBSD Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL [your name] OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" %FreeBSD: src/share/man/man9/style.9,v 1.98 2002/12/27 12:15:34 schweikh Exp % +.\" %FreeBSD: src/share/man/man9/style.9,v 1.100 2003/03/25 19:46:55 jhb Exp % .\" $FreeBSD$ .\" .Dd December 7, 2001 .Dt STYLE 9 .Os .Sh 名称 .Nm style .Nd カーネルソースファイルのスタイルガイド .Sh 解説 このファイルは .Fx ソースツリーのカーネルソースに好ましいスタイルを明記しています。 これはユーザランドのコードスタイルの手引きでもあります。 例において、スタイル規則の多くを暗黙的に使用しています。 .Nm がこれらの事例について言及していないと決め付ける前に、 注意して例を確認してください。 .Nm はそのような事柄については記述していません。 .\" $ と FreeBSD を続けるとキーワード置換されるので、\& を挿入 .\" 2001/05/23 horikawa@jp.FreeBSD.org .Bd -literal /* * FreeBSD のためのスタイルガイドです。 * CSRG の KNF (Kernel Normal Form, カーネル標準書式) に基づいています。 * * @(#)style 1.14 (Berkeley) 4/28/95 * $\&FreeBSD: src/share/man/man9/style.9,v 1.100 2003/03/25 19:46:55 jhb Exp $ */ /* * とても重要な 1 行のコメントはこのようにします。 */ /* 殆どの 1 行のコメントはこのようにします。 */ /* * 複数行にわたるコメントはこのようにします。実際の文章を書きます。実際の * 段落に見えるように埋めていきます。 */ .Ed .Pp 著作権ヘッダの後には空行を 1 行入れ、ソースファイルには .Va rcsid を付けます。 バージョン管理システムの ID タグは、ファイル中に 1 個のみあるべきです (このファイルでは違いますが)。 C/C++ ソースファイル以外はこの例に従いますが、 C/C++ ソースファイルは以降の例に従います。 外部から入手したファイルの すべての VCS (バージョン管理システム) リビジョン識別子は、 存在すれば維持します。 これには、ファイルの来歴を示す複数の ID も含みます。 一般的に、外来の ID またはその下部構造は編集しません。 さもなければ .Dq Li ( "#if defined(LIBC_SCCS)" のように) 囲まれていない場合には、全ての互換性のない小片を隠すため、および その ID をオブジェクトファイルから追い出しておくために、両方を .Dq Li "#if 0 ... #endif" の中に囲みます。 ファイルの名前が変更された場合には、外来の VCS ID の前に .Dq Li "From: " のみを追加します。 .Bd -literal #if 0 #ifndef lint static char sccsid[] = "@(#)style 1.14 (Berkeley) 4/28/95"; #endif /* not lint */ #endif #include __FBSDID("$\&FreeBSD: src/share/man/man9/style.9,v 1.98 2002/12/27 12:15:34 schweikh Exp $"); .Ed .Pp ヘッダファイルの前に、空行を 1 行付けます。 .Pp カーネルのインクルードファイル (すなわち、 .Pa sys/*.h ) が初めに来ます。 通常、 .Aq Pa sys/types.h または .Aq Pa sys/param.h のどちらかが必要ですが、 両方は必要ないでしょう。 .Aq Pa sys/types.h は .Aq Pa sys/cdefs.h をインクルードしており、 依存関係は問題ありません。 .Bd -literal #include /* 山括弧による非ローカルインクルード */ .Ed .Pp ネットワークプログラムである場合は、 次にネットワークインクルードファイルを置きます。 .Bd -literal #include #include #include #include #include .Ed .Pp カーネル用のファイルには、 .Pa /usr/include 中のファイルを使用しないでください。 .Pp それから空行を置き、 .Pa /usr インクルードファイルを続けます。 .Pa /usr インクルードファイルはアルファベット順にソートされているべきです。 .Bd -literal #include .Ed .Pp グローバルなパス名は .Pa /usr/include/paths.h で定義されています。 プログラムにローカルなパス名はローカルディレクトリの .Qq Pa pathnames.h に入れます。 .Bd -literal #include .Ed .Pp それから、空行があって、ユーザインクルードファイルが来ます。 .Bd -literal #include "pathnames.h" /* " " によるローカルインクルード */ .Ed .Pp アプリケーションインタフェースを実装している場合を除き、 実装の名前空間で .Ic #define したり名前を定義したりしてはいけません。 .Pp .Dq Li 安全でない マクロ (副作用を持っているもの) の名前と、 明らかな定数のマクロの名前はすべて大文字です。 式のように展開されるマクロは、単一のトークンにするか外側に括弧をつけます。 .Ic #define とマクロ名の間にタブ文字を 1 個入れます。 マクロがある関数のインライン展開である場合は、 関数名は全て小文字で、マクロはすべて大文字の同じ名前を持ちます。 .\" XXX 上記は名前が同じマクロを #undef すれば関数を使える .\" という ANSI のスタイルと衝突します。 .\" これは MALLOC() については言えないし、インライン関数を使う時の .\" 一般的なやりかたではありません。 バックスラッシュは右揃えします。こうすると読みやすくなります。 マクロが複合文をカプセル化する場合には、それを .Ic do ループで囲みます。 これにより、 .Ic if 文で安全に使用できます。 最後の文の終端のセミコロンは、 マクロではなくマクロの実施時に付けられるべきです。 これにより、清書器やエディタで文法解析しやすくなります。 .Bd -literal #define MACRO(x, y) do { \e variable = (x) + (y); \e (y) += 2; \e } while (0) .Ed .Pp コードが .Ic #ifdef または .Ic #if を使用して条件付きでコンパイルされるときには、 どこで条件付きでコンパイルされるコードが終了するのかを 読む人が容易に識別することが可能にするために、それに続く適合する .Ic #endif または .Ic #else にコメントを追加しても構いません。 このコメントは (主観的に) 長い部分、20 行以上の部分、またはネストされた .Ic #ifdef の連続が読む人を混乱させるかもしれないとき、にのみ使用されるべきです。 たとえコンパイルされない領域が小さくなるかもしれないでも、 .Xr lint 1 の目的のために条件付きでコンパイルされない個所のために、 例外が作られても構いません。 そのコメントは .Ic #endif または .Ic #else から 1 つの空白によって分離されるべきです。 短い条件付きでコンパイルされる部分のために、 終わりのコメントを使用するべきではありません。 .Pp .Ic #endif のためのコメントは対応する .Ic #iF または .Ic #ifdef で使用されている表現に合わせるべきです。 .Ic #else および .Ic #elif のためのコメントは先行する .Ic #if および/または .Ic #elif 文に使用されている表現の反対に合わせるべきです。 コメントの中では、補助表現 .Dq Li defined(FOO) は .Dq Li FOO と省略されます。 コメントの目的のためには、 .Dq Ic #ifndef Li FOO は .Dq Ic #if Li !defined(FOO) とみなされます。 .Bd -literal #ifdef KTRACE #include #endif #ifdef COMPAT_43 /* 大きな部分が、または他の条件付きのコードがここに */ #else /* !COMPAT_43 */ /* またはここに */ #endif /* COMPAT_43 */ #ifndef COMPAT_43 /* 更に別の大きな部分が、または他の条件付きのコードがここに */ #else /* COMPAT_43 */ /* またはここに */ #endif /* !COMPAT_43*/ .Ed .Pp 列挙値は全て大文字を使用します。 .Bd -literal enum enumtype { ONE, TWO } et; .Ed .Pp 宣言の中では、型に関係付けられたトークンを除いて、 アスタリスクと隣接したトークンの間には空白文字を置きません。 (これらの識別子は基本の型の名前、型の修飾語句、および今宣言されようとしている もの以外の .Ic typedef 名です。) これらの識別子はアスタリスクから 1 つの空白で分離します。 .Pp 構造体の中で変数を宣言する時には、 使用順、サイズ順、アルファベット順にソートして宣言します。 最初の区分は通常適用しませんが、例外があります。 各宣言は、それぞれ独立した行にて行います。 構造体の名前の位置を、あなたの判断で読み易いように、 タブ 1 個または 2 個を使用して揃えてください。 少なくとも 90% のメンバの名前を揃えるのに十分な場合には、 1 つだけのタブを使用するべきです。 非常に長い型の後の名前は、単一の空白で区切られるべきです。 .Pp 重要な構造体は、それが使用されるファイルの先頭で宣言されるか、 複数のソースファイルで使用される場合は別のヘッダファイルで宣言されるべきです。 構造体がヘッダファイルで宣言されている場合には、 それら構造体の使用は、宣言とは分けられるべきで、かつ .Ic "extern であるべきです。 .Bd -literal struct foo { struct foo *next; /* 使用中の foo のリスト */ struct mumble amumble; /* mumble のコメント */ int bar; /* コメントを揃えようとしています */ struct verylongtypename *baz; /* タブ 2 個には収まりません */ }; struct foo *foohead; /* グローバルな foo リストの先頭 */ .Ed .Pp 可能な時には必ず、あなた自身でリストを操作するのではなく、 .Xr queue 3 マクロを使用してください。 従って、前の例をより良く書くと次のようになります。 .Bd -literal #include struct foo { LIST_ENTRY(foo) link; /* foo リストにキューマクロを使用 */ struct mumble amumble; /* mumble のコメント */ int bar; /* コメントを揃えようとしています */ struct verylongtypename *baz; /* タブ 2 個には収まりません */ }; LIST_HEAD(, foo) foohead; /* グローバルな foo リストの先頭 */ .Ed .Pp 構造体の型に typedef を使用する事は避けてください。 使用してしまうと、 構造体へのポインタを不透明 (opaque) に使用することが、 アプリケーションにとって不可能となります。 通常の struct タグを使用すると、これが可能となり、かつ有益です。 規約が .Ic typedef を要求する場合には、その名前を構造体タグに一致させます。 標準 C または .Tn POSIX によって明示されたものを除いては、 .Dq Li _t で終る typedef を避けてください。 .Bd -literal /* 構造体名と typedef を一致させます */ typedef struct bar { int level; } BAR; typedef int foo; /* これは foo です */ typedef const long baz; /* これは baz です */ .Ed .Pp 全ての関数はどこかでプロトタイプされます。 .Pp 私的な関数 (すなわち、他のどこでも使用されない関数など) の関数プロトタイプは、 最初のソースモジュールの先頭に置かれます。 単一のソースモジュールにローカルな関数は、 .Ic static で宣言されるべきです。 .Pp カーネルの別の部分から使用される関数は、 関連のあるインクルードファイルの中でプロトタイプされます。 関数プロトタイプは、異なる順序の使用を強制する理由がない場合には、 なるべくアルファベット順の論理的な順序で整列されるべきです。 .Pp 複数のモジュールでローカルに使用される関数は、 .Qq Pa extern.h 等の分離したヘッダファイルの中に置かれます。 .Pp .Dv __P マクロは使用しません。 .Pp ファイルの 50% かそれ以上を巻き込んだ修正の場合は、 一般にコードは .Dq 新しいコード とみなすことができます。 これは既存のコードの慣例を破り、 現在の .Nm ガイドラインを使用するのに十分です。 .Pp カーネルはパラメータの型に関連付けられた名前を持ちます。 例えば、カーネル内でこのように使用します。 .Bd -literal void function(int fd); .Ed .Pp ユーザランドのアプリケーションに対して見えるヘッダファイルの中では、 可視のプロトタイプは、 型を伴った .Dq 保護された (アンダスコアで開始する) 名前を使用するか、 型だけで名前を使用しないかのどちらかが必要です。 保護された名前の使用がより望ましいです。 例えば、このように使用します。 .Bd -literal void function(int); .Ed .Pp または .Bd -literal void function(int _fd); .Ed .Pp プロトタイプは関数名の行揃えを行なうために、タブの後に追加のスペース文字を 置いても構いません。 .Bd -literal static char *function(int _arg, const char *_arg2, struct foo *_arg3, struct bar *_arg4); static void usage(void); /* * 全ての主要なルーチンはそれが何をするのかを簡潔に記述した * コメントを持つべきです。"main" ルーチンの前のコメントは * そのプログラムが何をするのかを記述するべきです。 */ int main(int argc, char *argv[]) { char *ep; long num; int ch; .Ed .Pp 一貫性のために、オプションの解析には .Xr getopt 3 が使用されるべきです。 .Xr getopt 3 呼び出しと .Ic switch 文では、オプションをソートすべきですが、 .Ic switch 文のカスケードの一部の場合は例外です。 .Ic switch 文のカスケード要素は .Li FALLTHROUGH コメントを持つべきです。 数値の引数は精度をチェックされるべきです。 到達できないコードは .Li NOTREACHED コメントを持つべきです。 .Bd -literal while ((ch = getopt(argc, argv, "abn:")) != -1) switch (ch) { /* switch をインデント */ case 'a': /* case はインデントしない */ aflag = 1; /* FALLTHROUGH */ case 'b': bflag = 1; break; case 'n': num = strtol(optarg, &ep, 10); if (num <= 0 || *ep != '\e0') { warnx("illegal number, -n argument -- %s", optarg); usage(); } break; case '?': default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; .Ed .Pp 予約語 .Pq Ic if , while , for , return , switch の後にスペースを入れます。 何も伴わないかただ 1 つの文を伴う制御文は、ブレース .Ql ( \&{ および .Ql \&} ) を使用しません。 1 つの文が 複数行である文の場合には、これは許されます。 無限ループは .Ic while ではなく .Ic for で行ないます。 .Bd -literal for (p = buf; *p != '\e0'; ++p) ; /* 何もなし */ for (;;) stmt; for (;;) { z = a + really + long + statement + that + needs + two + lines + gets + indented + four + spaces + on + the + second + and + subsequent + lines; } for (;;) { if (cond) stmt; } if (val != NULL) val = realloc(val, newsize); .Ed .Pp .Ic for ループの各部は空のまま残しても構いません。 異常に複雑なルーチンでない限りは、ブロックの中に宣言を置いてはなりません。 .Bd -literal for (; cnt < 15; cnt++) { stmt1; stmt2; } .Ed .Pp インデントは 8 文字のタブです。 第 2 レベルのインデントは 4 文字のスペースです。 長い分を折り返す必要がある場合、オペレータを行末に置きます。 .Bd -literal while (cnt < 20 && this_variable_name_is_too_long && ep != NULL) z = a + really + long + statement + that + needs + two + lines + gets + indented + four + spaces + on + the + second + and + subsequent + lines; .Ed .Pp 空白文字を行末に追加してはいけません。 また、インデントを形成するためには、タブとその後にスペースのみを使用します。 タブが生み出す以上のスペースや、タブの前のスペースは使用しません。 .Pp ブレースの終了と開始は .Ic else と同じ行に置かれます。 必要でないブレースは省いても構いません。 .Bd -literal if (test) stmt; else if (bar) { stmt; stmt; } else stmt; .Ed .Pp 関数名の後はスペースを空けません。 コンマの後にはスペースを持ちます。 .Ql \&( または .Ql \&[ の後ろまたは .Ql \&] または .Ql \&) の前にはスペースを空けません。 .Bd -literal error = function(a1, a2); if (error != 0) exit(error); .Ed .Pp 単項演算子はスペースを要求しませんが、二項演算子は要求します。 優先順位が要求する場合または文が括弧なしでは混乱する場合以外は、 括弧は使用しません。 他人はあなたよりも混乱しやすいかもしれないということを覚えておいてください。 あなたは以下を理解できますか? .Bd -literal a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1; k = !(l & FLAGS); .Ed .Pp 成功時には 0 で、または .Xr sysexits 3 にあらかじめ定義してある値で exit するべきです。 .Bd -literal exit(EX_OK); /* * "Exit 0 on success." (成功時は 0 で終了) * の様に明白なコメントは避けてください */ } .Ed .Pp 関数の型は、関数自身に先行する行にあるべきです。 関数の本体の開始のブレースは、単独で 1 行であるべきです。 .Bd -literal static char * function(int a1, int a2, float fl, int a4) { .Ed .Pp 関数の中で変数を宣言する時には、サイズ順に、次にアルファベット順に ソートして宣言します。 1 行に複数の宣言は可能です。 行が溢れる場合は、型の予約語を再度使用します。 .Pp 宣言時に変数を初期化することによってコードを 不明瞭にしない様に注意してください。 この機能は良く考えて使用してください。 初期化に関数呼び出しを使用しないでください。 .Bd -literal struct foo one, *two; double three; int *four, five; char *six, seven, eight, nine, ten, eleven, twelve; four = myfunction(); .Ed .Pp 他の関数の内部で関数を宣言しないでください。 ANSI C によると、このような宣言は、宣言のネスティングによらず、 ファイルスコープになります。 ローカルスコープに見えるものの中にファイルの宣言を隠すことは好ましくなく、 良いコンパイラは苦情を言います。 .Pp キャストと .Ic sizeof 演算子の後にはスペースを続けません。 この規則は .Xr indent 1 が理解しないことに注意してください。 .Ic sizeof は常に括弧をつけて書かれます。 冗長な括弧の規則は .Fn sizeof var の事例には適用されません。 .Pp .Dv NULL は、好まれるヌルポインタ定数です。 コンパイラが型を知っている文脈、例えば代入では、 .Vt ( "type *" ) Ns 0 または .Vt ( "type *" ) Ns Dv NULL の代わりに、 .Dv NULL を使用します。 他の文脈では、特に全ての関数の引数では、 .Vt ( "type *" ) Ns Dv NULL を使用します。 (関数のプロトタイプがスコープ外かもしれない場合に、 キャストはいろいろな引数にとって必須で、その他の引数にとっても必要です。) ポインタは .Dv NULL と比較します。例えば、 .Bd -literal !(p = f()) .Ed .Pp ではなく、このように使います。 .Bd -literal (p = f()) == NULL .Ed .Pp 真理値ではない場合、テストには .Ic \&! を使用しないでください。 例えば、下記のように使います。 .Bd -literal if (*p == '\e0') .Ed .Pp 下記のようには使いません。 .Bd -literal if (!*p) .Ed .Pp .Vt "void *" を返すルーチンでは、 戻り値をどのポインタ型にもキャストしてはなりません。 .Pp .Ic return 文の値は括弧で囲まれているべきです。 .Pp .Xr err 3 または .Xr warn 3 を使用し、勝手に作らないでください。 .Bd -literal if ((four = malloc(sizeof(struct foo))) == NULL) err(1, (char *)NULL); if ((six = (int *)overflow()) == NULL) errx(1, "number overflowed"); return (eight); } .Ed .Pp 古いスタイルの関数宣言はこのようになっています。 .Bd -literal static char * function(a1, a2, fl, a4) int a1, a2; /* int 型も宣言します、デフォルトにしないこと */ float fl; /* double と float の違いに気を付けてください */ int a4; /* 出てきた順に宣言します */ { .Ed .Pp あなたが明確に K&R との互換性を必要とする場合以外は、 ANSI の関数宣言を使用してください。 長いパラメータリストの折り返しには、 4 個の空白による通常のインデントを付けます。 .Pp 可変個数の引数はこのようにします。 .Bd -literal #include void vaf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); STUFF; va_end(ap); /* void 型の関数に return は不要です */ } static void usage() { /* 関数がローカル変数を持たない場合、空行をいれます */ .Ed .Pp .Xr fputs 3 , .Xr puts 3 , .Xr putchar 3 等ではなく、 .Xr printf 3 を使用してください。 これは速くて大抵はきれいで、言うまでもなくつまらないバグを避けます。 .Pp 使用法 (usage) の文はマニュアルページの .Sx SYNOPSIS (書式) の様であるべきです。 使用法の文は、次の構造であるべきです: .Bl -enum .It オペランドの無いオプションが、最初にアルファベット順に、 1 組の大括弧 .Ql ( \&[ と .Ql \&] ) でくくられます。 .It オプションとそのオペランドがこれもアルファベット順に続き、 それぞれのオプションとその引数を 1 組の大括弧でくくります。 .It 必須の引数 (もしあれば) が続き、 コマンドラインで指定されるべき順で一覧されます。 .It 最後に、 すべての任意の引数が指定されるべき順で、 すべて大括弧の中に一覧されます。 .El .Pp 縦棒 .Pq Ql \&| は、 .Dq 二者択一 のオプションまたは引数を分割し、 同時に使用するオプションと引数は、単一の大括弧でくくります。 .Bd -literal -offset 4n "usage: f [-aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\en" "usage: f [-a | -b] [-c [-dEe] [-n number]]\en" .Ed .Bd -literal (void)fprintf(stderr, "usage: f [-ab]\en"); exit(EX_USAGE); } .Ed .Pp マニュアルページのオプション記述は、 純粋なアルファベット順であるべきであることに注意してください。 つまり、オプションが引数を取るか否かに関わらないということです。 アルファベット順は、前述の大文字小文字の順序を考慮に入れるべきです。 .Pp 新しい中心的なカーネルのコードは、適度に .Nm ガイドに従うべきです。 サードパーティが保守するモジュールやデバイスドライバのためのガイドラインは より緩やかですが、最低限内部的には彼らの一貫したスタイルであるべきです。 .Pp ソースリポジトリの文体の変更 (空白文字の変更を含む) は困難で、 正当な理由なしには避けるべきです。 リポジトリの中のおおよそ KNF .Nm に適合しているコードは、この適合から離れてはなりません。 .Pp 可能な時にはいつでも、 コードはコードチェッカ (例えば、 .Xr lint 1 または .Nm gcc Fl Wall ) を 通過し、発生する警告は最小限となるべきです。 .Sh 関連項目 .Xr indent 1 , .Xr lint 1 , .Xr err 3 , .Xr sysexits 3 , .Xr warn 3 .Sh 歴史 このページは .Bx 4.4 Lite2 リリースの .Pa src/admin/style/style ファイルに大きく基づいていて、 現在の実装と .Fx プロジェクトの要望を反映して、頻繁に更新しています。