intro - システムコールの説明 - Linux コマンド集 一覧表
名前
intro, _syscall - システムコールの説明
説明
この章は Linux のシステムコールを記述している。 Linux 2.0 では 164 個のシステムコールが存在する。 syscall(2) を参照のこと。
直接呼び出す
ほとんどの場合、直接システムコールを呼び出す必要はないが、 場合によっては標準 C ライブラリに適切な関数が実装されていないこともある。 このような場合は、プログラマーは、_syscall マクロか syscall ()のいずれかを使って、自分でシステムコールを呼び出さなければならない。 syscall ()を使う方法については syscall (2) で説明されている。 このページでは _syscall マクロについて説明する。 また、いつどちらの仕組みを使うべきかについても述べる。
書式
#include <linux/unistd.h>
A _syscall macro
desired system call
設定
システムコールに関してそのプロトタイプを知ることが重要で
ある。引き数の個数、それらの型、そして返り値の型を知らなければならない。
実際の使用にあたっては、より容易にシステムを呼び出すために次の 6 個の
マクロが用意されている。その形式は以下の通りである:
_syscall
X
(
type
,
name
,
type1
,
arg1
,
type2
,
arg2
,...)
X
は 0\(en5 の値で、システムコールが必要とする引き数の数である。
type
はシステムコールの返り値の型である。
name
はシステムコールの名前である。
typeN
は N 番目の引き数の型である。
argN
は N 番目の引き数の名前である。
これらのマクロは、指定した引き数を持つ name
という名前の関数を生成する。
一度ソースファイル中でこの _syscall() マクロを呼んでおくと、
name
でこのシステムコールを呼ぶことができる。
例
#include <stdio.h> #include <errno.h> #include <linux/unistd.h> /* for _syscallX macros/related stuff */ #include <linux/kernel.h> /* for struct sysinfo */
_syscall1(int, sysinfo, struct sysinfo *, info);
/* 注意: nroff のソースファイルから直接コピーするときは printf 文に含まれている余分なバックスラッシュを除去する ことを忘れないように */
int main(void) { struct sysinfo s_info; int error;
error = sysinfo(&s_info); printf("code error = %d\n", error); printf("Uptime = %lds\nLoad: 1 min %lu / 5 min %lu / 15 min %lu\n" "RAM: total %lu / free %lu / shared %lu\n" "Memory in buffers = %lu\nSwap: total %lu / free %lu\n" "Number of processes = %d\n", s_info.uptime, s_info.loads[0], s_info.loads[1], s_info.loads[2], s_info.totalram, s_info.freeram, s_info.sharedram, s_info.bufferram, s_info.totalswap, s_info.freeswap, s_info.procs); return(0); }
出力例
code error = 0 uptime = 502034s Load: 1 min 13376 / 5 min 5504 / 15 min 1152 RAM: total 15343616 / free 827392 / shared 8237056 Memory in buffers = 5066752 Swap: total 27881472 / free 24698880 Number of processes = 40
注意
_syscall() マクロはプロトタイプを生成しない。ユーザーは自分で
プロトタイプを書かなければならないかもしれない。
C++ ユーザーの場合は特に重要である。
システムコールは正のエラーコードのみまたは負のエラーコードのみを
返すことが定められているわけではない。
そのシステムコールがどのようなエラーコードを返すかについて確認する
ためにはそのソースコードを読む必要がある。
たいていの場合、標準のエラーコードの負の値 (例えば -EPERM
のような)
を返す。
_syscall() マクロは、そのシステムコールの返り値 r
が負でない場合、
その値をそのまま返す。負の場合には変数
errno
に -r
を設定して -1 を返す。
各エラーコードに関しては
errno
(3) を参照。
(
mmap
()などの) いくつかのシステムコールは 5個より多くの引き数を要求する。
こういったシステムコールはスタックに引き数をプッシュし、
その引き数のかたまりへのポインタを渡して処理される。
システムコールを定義する場合、その引き数の型は値渡し (by-value) か、
(構造体のような集合的なデータの場合は) ポインタ渡し (by-pointer)
でなければならない。
glibc がまだ知らないシステムコールを起動するのに好ましい方法は
syscall
(2) を使うことである。しかしながら、この仕組みを利用できるのは、
syscall
(2) に対応した libc (glibc など) を使っており、
ヘッダファイル
<sys/syscall.h>
に必要な SYS_foo の定義が含まれている場合だけである。
そうでない場合は、_syscall マクロを使用する必要がある。
いくつかのアーキテクチャ、特に ia64、では _syscall マクロは
提供されていない。このようなアーキテクチャでは
syscall
(2) を使わなければならない。
準拠
このセクションのシステムコールが準拠する Unix の種別や標準規格を 表すために、以下の略号を使用する。 standards (7)を参照。
ファイル
/usr/include/linux/unistd.h