🐧 Linux 総合学習プラットフォーム
システムコール ・ 上級

man 2 でシステムコールを調べる

Linuxのマニュアルはセクション番号で分かれており、セクション2がシステムコール、セクション3がライブラリ関数です。同じ名前でも別物のことがあるため、man 2 open のように番号を指定して目的のページを開きます。各ページには概要(SYNOPSIS)、必要なヘッダファイル、引数の意味、戻り値、そして失敗時に errno へ設定されるエラー一覧(ERRORS)が載っています。どんな番号があるかは man man で確認でき、apropos でキーワード検索もできます。正確な仕様の一次情報として、まず man 2 を引く習慣が大切です。

システムコール(syscall)やライブラリ関数を正しく使うには、引数の意味や戻り値、そして失敗したときの挙動を正確に知る必要がある。

ネット上の解説記事も便利だが、情報が古かったり、対象のディストリビューションやバージョンによって違ったりすることがある。

いま自分が使っているこのシステムで、その関数が実際にどう振る舞うのか。その答えを最も確実に教えてくれるのが、Linuxに標準で備わっているオンラインマニュアル、手元のmanだ。

💡
ポイントネット記事は古かったりバージョンで違ったりする。いま自分のシステムでの実際の挙動を最も確実に教えてくれるのは、手元のmanだ。

低レイヤを扱うなら、困ったらまずmanを引く習慣を身につけることが、遠回りに見えて実は最短の近道になる。仕様を推測で済ませないことが、信頼できるプログラムを書く第一歩だ。

🗂 同じ名前のページが複数あるわけ

manを使ううえで最初に理解すべきは「セクション」という区分だ。Linuxのマニュアルは内容ごとに番号で分類されている。

man のセクション(内容ごとの番号)1一般のコマンド2システムコールman 2 open3ライブラリ関数libc など5ファイル書式設定ファイル同じ名前でも内容の違うページがセクションごとに並ぶ

よく使うものを挙げると、セクション1が一般のコマンド、セクション2がシステムコール、セクション3がライブラリ関数(libcなどが提供する関数)、セクション5がファイルフォーマットや設定ファイルの書式だ。

この区別が重要なのは、同じ名前でも内容の異なるページが複数存在しうるからだ。

writeはセクション2(システムコール)とライブラリ側で別ページ。printfはコマンド(セクション1)とライブラリ関数(セクション3)が別々に存在する。

代表例がwriteだ。セクション2のwriteはカーネルが直接提供するシステムコール、それとは別にライブラリ側の説明があり、両者は属する層が違う。

printfに至っては、コマンドとしてのprintf(セクション1)と、ライブラリ関数としてのprintf(セクション3)が別々に存在する。

つまずき番号を指定せずman writeと打つと、一番若いセクションのページが優先表示され、見たいものと違うページが出ることがある。

ここで困ったことが起きる。番号を指定せずにman writeと打つと、一番若いセクションのページが優先して表示されるため、自分が見たかったものと違うページが出てしまうことがあるのだ。

この食い違いを避けるために、セクション番号の存在を意識することが大切になる。

🧭 man 2 を開くと、何がどう並んでいるか

目的のシステムコールを確実に開くには、セクション番号を明示してman 2 openやman 2 readのように引く。

man 2 open ……セクション番号を明示すると、目的のシステムコールのページを確実に開ける。

開いたページには、どの関数でも決まった構成で情報が並んでいる。NAME(名前と一行の説明)、SYNOPSIS(必要なヘッダファイルと、関数の正確な宣言)、DESCRIPTION(動作の詳しい説明)、RETURN VALUE(戻り値が何を意味するか)、そしてERRORS(失敗したときにerrno(errno)へ設定されうるエラーの一覧)だ。

man 2 open のページ構成(上から順に)NAME(名前と一行の説明)SYNOPSIS(ヘッダと関数の正確な宣言)DESCRIPTION(動作の詳しい説明)RETURN VALUE(戻り値の意味)ERRORS(errno へ設定されうる一覧)

この構成が頭に入っていると、長いページでも知りたい部分へ直行できる。

たとえばman 2 openを引けば、冒頭のSYNOPSISに #include <fcntl.h> というインクルードすべきヘッダと、int open(const char *pathname, int flags, ...); という関数の形が示される。

コツSYNOPSISは、コードを書くときにどのヘッダを取り込み、引数をどの順で渡せばよいかを確認する第一の手がかりになる。

SYNOPSISは、コードを書くときにどのヘッダを取り込み、引数をどの順で渡せばよいかを確認する第一の手がかりだ。

続いて、フラグにO_RDONLYやO_CREATが使えること、成功するとファイルディスクリプタ(fd)を返し、失敗すると-1を返すこと、そしてERRORSの節に、ENOENTやEACCESがそれぞれどんなときに設定されるかが、根拠とともに列挙されている。

💡
ポイントstraceで見つけた失敗(例:ENOENT)の意味を裏取りしたいとき、ERRORSの節が決定的な手がかりになる。

straceで見つけた失敗の意味を裏取りしたいとき、このERRORSの節が決定的な手がかりになる。

なお、システムコールの中には、man 2のページの末尾に「実際にはglibcのラッパー関数を経由して呼ばれる」といった注記が書かれているものもあり、ライブラリとシステムコールの関係を理解する助けにもなる。

🚶 長いマニュアルの中を歩き回る

manのページはlessというページャ(画面送りツール)で表示されるため、その操作を覚えておくと閲覧が格段に快適になる。

スペースで一画面進む、bで一画面戻る、/語 で前方検索、nで次の一致、gで先頭、Gで末尾、qで終了。

スペースキーで一画面進み、bキーで一画面戻り、スラッシュに続けて語を打てばページ内を前方検索でき、nキーで次の一致へ移動する。gで先頭、Gで末尾へ一気に飛び、qで終了する。

コツERRORSの節だけ読みたいときは /ERRORS と検索すれば一足飛びにそこへ到達できる。straceの出力をlessに流して読むときも同じ操作感だ。

マニュアルは長いものが多い。たとえばERRORSの節だけを読みたいときは、/ERRORS と検索すれば一足飛びにそこへ到達できる。

この検索を覚えるだけで、目当ての情報にたどり着く速さがまるで変わる。同じ操作感は、前章で見たstraceの出力をlessに流して読むときにもそのまま通用する。

どんなセクションが存在するのか、manそのものの使い方を知りたいときは、man manを引けば一覧と説明が読める。

英語のページが基本だが、SYNOPSISやERRORSといった項目の構成は世界共通なので、まずは見出しの場所を覚えて拾い読みするところから慣れていくとよい。

🧶 名前がうろ覚えのときの手繰り方

「ファイルの権限を変える関数があったはずだが、肝心の名前が思い出せない」。そんなときに使うのがaproposだ。

apropos directory ……ディレクトリに関係する関数やコマンドが、セクション番号付きでずらりと並ぶ。当たりを付けてman 2やman 3で詳細を読む。

aproposは、キーワードでマニュアルの見出しを横断検索し、関連しそうなページの一覧を返してくれる。

たとえばapropos directoryと打てば、ディレクトリに関係する関数やコマンドが、それぞれのセクション番号付きでずらりと並ぶ。その中から目当てのものに当たりを付け、改めてman 2やman 3で詳細を読む、という流れで使う。

手繰る糸はもう一本ある。各manページの末尾にはSEE ALSOという節があり、関連するほかのページが示されている。

コツSEE ALSOにはopen(2)やclose(2)のように関数名のうしろにセクション番号が括弧付きで記される。何番を引けばよいかが一目で分かる。

そこではopen(2)やclose(2)のように、関数名のうしろにセクション番号が括弧付きで記されている。この表記を見れば、その関数を調べるには何番のセクションを引けばよいかが一目で分かる。

正確な仕様は推測で済ませず、システムコールならman 2、ライブラリ関数ならman 3で必ず一次情報を確かめる。この地道な姿勢が、信頼できる低レイヤプログラムを書くための確かな基礎になる。

この項目に出てくる用語

システムコールしすてむこーる
アプリがカーネルに処理を依頼する公式の窓口。
errnoえらーなんばー
直近のシステムコール失敗の原因を表す番号。

関連コマンド

man 2 openman 3 printfapropos

▶ 学習アプリでこの続きを学ぶ・演習する