%20%E3%81%8A%E3%82%88%E3%81%B3%20sigsuspens(set)%20%E9%96%A2%E6%95%B0%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AF%E3%81%A9%E3%81%93%E3%81%AB%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F.png)
glibc-2.14.1パッケージでPauseとsigsuspensionのソースファイルを見つけたいと思います。パッケージをgrepし、関数一時停止の定義を含むsysdeps/posix/pause.cファイルを見つけました。コードは次のとおりです。
int
__libc_pause (void)
{
sigset_t set;
__sigemptyset (&set);
__sigprocmask (SIG_BLOCK, NULL, &set);
/* pause is a cancellation point, but so is sigsuspend.
So no need for anything special here. */
return __sigsuspend (&set);
}
weak_alias (__libc_pause, pause)
また、sigsuspens関数が定義されているパッケージをgrepし、sysdeps/posix/sigsuspens.cやsysdeps/unix/sysv/linux/sigsuspens.cなどのいくつかのファイルに定義があります。
sysdeps/posix/sigsuspens.c にある sigsuspens の定義は次のとおりです。
int
__sigsuspend (set)
const sigset_t *set;
{
sigset_t oset;
int save;
if (set == NULL)
{
__set_errno (EINVAL);
return -1;
}
if (sigprocmask (SIG_SETMASK, set, &oset) < 0)
return -1;
(void) pause();
save = errno;
if (sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL) < 0)
return -1;
__set_errno (save);
return -1;
}
libc_hidden_def (__sigsuspend)
weak_alias (__sigsuspend, sigsuspend)
問題を発見しました。 sysdeps/posix/pause.c は sigsuspension 関数を呼び出して一時停止し、sysdeps/posix/sigsuspens.c は一時停止関数を呼び出して sigsuspension を一時停止します。周期のようです。そのため、一時停止とsigsuspensionの正しいソースファイルが見つからなかったようです。誰でもこの機能のソースファイルがどこにあるのか教えてもらえますか?よろしくお願いします。
答え1
glibcツリーには、Pause()とsigsuspens()のいくつかの定義があります。使用される実際の定義は、glibcが構築されるシステムとアーキテクチャによって異なります。以前のUnixシステムでは、Pause()はシステムコールで、sigsuspens()はPause()を呼び出して実装されていました。 sigsuspens() がシステムコールであるシステムでは、 Pause() は sigsuspens() を呼び出して実装されます。システムコール自体はアセンブリ言語で実装され、割り込みをトリガしたり特殊なコマンドを実行してカーネルが引き継がれるようにします。 glibcビルドプロセスは、Cとアセンブリ言語ソースファイルの正しい組み合わせが最終ライブラリのビルドに使用されることを保証します。
独自のソースファイルを持たないシステムコールには、make-syscalls.shというシェルスクリプトを使用してビルドプロセスによって生成された定義があり、その操作はsyscalls.listによって駆動されます。システムコール用のコードは、このスクリプトによって生成されます。スクリプトのコード生成部分はシェルコードほど理解しにくく、最初に「ここで何が起こっているのかを理解する最良の方法はBUILDDIR / sysd-syscallsの出力を調べることです」と言います。 glibcをビルドして、システムコールによって生成されたソースファイルの直接コード化バージョンがないことを確認します。