diff --git a/reference.md b/reference.md index b052c1bf97..369c75a62f 100644 --- a/reference.md +++ b/reference.md @@ -230,7 +230,7 @@ | [``](/reference/clocale.md) | ロケール | | | [``](/reference/cmath.md) | 数学関数 | | | `` | ジャンプ処理 | | -| `` | シグナル | | +| [``](reference/csignal.md) | シグナル | | | `` | アライメント操作のマクロ | C++17で非推奨
C++20で削除 | | `` | 可変引数操作 | | | [``](/reference/stdbit.h.md.nolink) | ビット操作 | C++26 | diff --git a/reference/csignal.md b/reference/csignal.md new file mode 100644 index 0000000000..e62085edb9 --- /dev/null +++ b/reference/csignal.md @@ -0,0 +1,39 @@ +# csignal +* csignal[meta header] + +``ヘッダでは、シグナル操作のための機能を定義する。 +シグナルの集合、意味、及びデフォルトの処理は処理系定義である。 + +## 型 + +| 名前 | 説明 | 対応バージョン | +|------|------|----------------| +| [`sig_atomic_t`](csignal/sig_atomic_t.md) | 非同期シグナルハンドラからアトミックなエンティティとしてアクセス可能な整数型 | | + +## マクロ + +### `signal`関数用のハンドラ指定子 + +| 名前 | 説明 | 対応バージョン | +|------|------|----------------| +| `SIG_DFL` | デフォルト動作を指定する | | | +| `SIG_ERR` | `signal`関数が失敗したことを示す戻り値 | | +| `SIG_IGN` | シグナルを無視する | | + +### シグナル番号を表すマクロ + +| 名前 | 説明 | 対応バージョン | +|------|------|----------------| +| [`SIGINT`](csignal/sigint.md) | 割り込みを示すシグナル番号 | | +| [`SIGILL`](csignal/sigill.md) | 不正な命令を示すシグナル番号 | | +| [`SIGABRT`](csignal/sigabrt.md) | `abort`関数などによる異常終了を示すシグナル番号 | | +| [`SIGFPE`](csignal/sigfpe.md) | 算術演算エラーを示すシグナル番号 | | +| [`SIGSEGV`](csignal/sigsegv.md) | 無効なメモリアクセスを示すシグナル番号 | | +| [`SIGTERM`](csignal/sigterm.md) | 終了要求を示すシグナル番号 | | + +## 関数 + +| 名前 | 説明 | 対応バージョン | +|------|------|----------------| +| [`signal`](csignal/signal.md) | 特定のシグナルに対するシグナルハンドラを設定する | | +| [`raise`](csignal/raise.md) | プログラムにシグナルを送信する | | diff --git a/reference/csignal/raise.md b/reference/csignal/raise.md new file mode 100644 index 0000000000..7139da2c95 --- /dev/null +++ b/reference/csignal/raise.md @@ -0,0 +1,49 @@ +# raise +* csignal[meta header] +* std[meta namespace] +* function[meta id-type] + +```cpp +namespace std { + int raise(int sig); +} +``` + +## 概要 +現在のプログラムにシグナルを送信する。 + +## 引数 +- `sig`: 送信するシグナル番号 + +## 戻り値 +正常に終了した場合は0を返す。 +それ以外の場合は非ゼロの値を返す。 + +## 備考 +`signal`関数などにより、シグナルハンドラが呼び出された場合、それが終了するまでこの関数は戻らない。 + +## 例 +```cpp example +#include +#include + +volatile std::sig_atomic_t got_signal = 0; + +void signal_handler(int signum) { + got_signal = 1; +} + +int main (){ + std::signal(SIGABRT, signal_handler); + std::raise(SIGABRT); + if (got_signal) + std::cout << "SIGABRT" << std::endl; + return 0; +} +``` +* std::raise[color ff0000] + +### 出力例 +``` +SIGABRT +``` diff --git a/reference/csignal/sig_atomic_t.md b/reference/csignal/sig_atomic_t.md new file mode 100644 index 0000000000..9d73d0f839 --- /dev/null +++ b/reference/csignal/sig_atomic_t.md @@ -0,0 +1,60 @@ +# sig_atomic_t +* csignal[meta header] +* std[meta namespace] +* type-alias[meta id-type] + +```cpp +namespace std { + using sig_atomic_t = integer-type; +} +``` +* integer-type[italic] + +## 概要 +`sig_atomic_t`は、非同期シグナルハンドラと通常の実行コンテキストの間で、単純な読み書きを分断されずに行えることが保証された整数型である。 + +この型に対して保証されるのは単純な代入および読み出しのみであり、 +複合操作や算術演算は保証されない。 + +実際の使用では通常`volatile`修飾子と組み合わせて用いられる。 + +具体的な型は処理系定義である。 + +## 備考 +最大値は`SIG_ATOMIC_MAX`、最小値は`SIG_ATOMIC_MIN`に定義されている。 + +## 例 +```cpp example +#include +#include + +volatile std::sig_atomic_t flag = 0; + +void signal_handler(int signum) +{ + flag = 1; +} + +int main () +{ + std::signal(SIGINT, signal_handler); + while (!flag) { + //処理 + } + if (flag) { + std::cout << "caught SIGINT" << std::endl; + } + return 0; +} +``` +* std::sig_atomic_t[color ff0000] + +### 出力例 +``` +caught SIGINT +``` +`Ctrl + c`などで割り込みが発生した場合。 + +## 関連項目 +- [`SIG_ATOMIC_MAX`](/reference/cstdint/sig_atomic_max.md) +- [`SIG_ATOMIC_MIN`](/reference/cstdint/sig_atomic_min.md) diff --git a/reference/csignal/sigabrt.md b/reference/csignal/sigabrt.md new file mode 100644 index 0000000000..8475ca2ed7 --- /dev/null +++ b/reference/csignal/sigabrt.md @@ -0,0 +1,35 @@ +# SIGABRT +* csignal[meta header] +* macro[meta id-type] + +```cpp +#define SIGABRT see below +``` + +## 概要 +`abort`関数などによる異常終了時に送られるシグナルの、シグナル番号を表すマクロ。 + +`int`型の正の整数の定数式に展開され、実際の値は未規定。 + +## 例 +```cpp example +#include +#include + +void handler(int) { + std::_Exit(0); +} + +int main() { + std::signal(SIGABRT, handler); + std::abort(); +} +``` +* SIGABRT[color ff0000] + +### 出力 +``` +``` + +## 関連項目 +- [`abort`](/reference/cstdlib/abort.md) diff --git a/reference/csignal/sigfpe.md b/reference/csignal/sigfpe.md new file mode 100644 index 0000000000..34e24396c4 --- /dev/null +++ b/reference/csignal/sigfpe.md @@ -0,0 +1,39 @@ +# SIGFPE +* csignal[meta header] +* macro[meta id-type] + +```cpp +#define SIGFPE see below +``` + +## 概要 +算術演算エラー(浮動小数点例外など)が発生した際に送られるシグナルの、シグナル番号を表すマクロ。 + +`int`型の正の整数の定数式に展開され、実際の値は未規定。 + +## 例 +```cpp example +#include +#include + +void handler(int) +{ + std::_Exit(0); +} + +int main() +{ + std::signal(SIGFPE, handler); + + volatile double x = 1.0; + volatile double y = 0.0; + // 浮動小数点の 0 除算。 + // SIGFPE が発生することもあるが、規格上は保証されない。 + x = x / y; +} +``` +* SIGFPE[color ff0000] + +### 出力 +``` +``` diff --git a/reference/csignal/sigill.md b/reference/csignal/sigill.md new file mode 100644 index 0000000000..7907a0c820 --- /dev/null +++ b/reference/csignal/sigill.md @@ -0,0 +1,34 @@ +# SIGILL +* csignal[meta header] +* macro[meta id-type] + +```cpp +#define SIGILL see below +``` + +## 概要 +無効な命令を実行しようとした際に送られるシグナルの、シグナル番号を表すマクロ。 + +`int`型の正の整数の定数式に展開され、実際の値は未規定。 + +## 例 +```cpp example +#include +#include + +void handler(int) +{ + std::_Exit(0); +} + +int main() +{ + std::signal(SIGILL, handler); + std::raise(SIGILL); +} +``` +* SIGILL[color ff0000] + +### 出力 +``` +``` diff --git a/reference/csignal/sigint.md b/reference/csignal/sigint.md new file mode 100644 index 0000000000..7424bd03d1 --- /dev/null +++ b/reference/csignal/sigint.md @@ -0,0 +1,37 @@ +# SIGINT +* csignal[meta header] +* macro[meta id-type] + +```cpp +#define SIGINT see below +``` + +## 概要 +外部割り込みが発生した際に送られるシグナルの、シグナル番号を表すマクロ。 + +`int`型の正の整数の定数式に展開され、実際の値は未規定。 + +## 例 +```cpp example +#include +#include + +volatile std::sig_atomic_t flag = 0; + +void handler(int) +{ + std::_Exit(0); +} + +int main() +{ + std::signal(SIGINT, handler); + std::raise(SIGINT); + return 0; +} +``` +* SIGINT[color ff0000] + +### 出力 +``` +``` diff --git a/reference/csignal/signal.md b/reference/csignal/signal.md new file mode 100644 index 0000000000..09d085d7e0 --- /dev/null +++ b/reference/csignal/signal.md @@ -0,0 +1,82 @@ +# signal +* csignal[meta header] +* std[meta namespace] +* function[meta id-type] + +```cpp +namespace std { + extern "C" using signal-handler = void(int); // exposition only + signal-handler* signal(int sig, signal-handler* func); +} +``` +* signal-handler[italic] + +## 概要 + +シグナル番号`sig`の受け取り後の処理を指定する。 + +`func`の値が`SIG_DFL`の場合、そのシグナルに対するデフォルトの処理が行われる。 +`func`の値が`SIG_IGN`の場合、そのシグナルを無視する。 +それ以外の場合、関数`func`が実行される。 + +## 引数 + +- `sig`: シグナルハンドラを設定するシグナル番号 +- `func`: シグナルに対する処理。以下のいずれかを指定する。 + - `SIG_DFL`: そのシグナルに対するデフォルト処理を指定する。 + - `SIG_IGN`: そのシグナルを無視する。 + - `func`: シグナルハンドラにする関数へのポインタを示す。 + +### シグナルハンドラ関数の制約 +シグナルハンドラ関数は戻り値を持たず、`int`型の引数を持つ。 +この引数にはシグナル番号が格納される。 + +シグナルハンドラ内で以下以外の処理を行うことは未定義動作である。 +- `volatile std::sig_atomic_t`オブジェクトへの代入 +- `abort`関数 +- `_Exit`関数 +- `quick_exit`関数 +- `atomic`引数がロックフリーである場合の``内の関数 +- 任意の`atomic`引数を持つ`atomic_is_lock_free`関数 +- `signal`関数(ただし、ハンドラを起こしたシグナル番号に対する呼び出しに限る) + +## 戻り値 + +成功した場合、指定されたシグナルに対する直前のハンドラを返す。 +それ以外の場合は`SIG_ERR`を返す + +## 備考 + +マルチスレッド内でのこの関数の動作は未定義。 + +## 例 +```cpp example +#include +#include + +volatile std::sig_atomic_t flag = 0; + +void signal_handler(int sig) +{ + flag = 1; + // std::cout << "signal: " << sig << std::endl; 未定義動作 +} + +int main() +{ + std::signal(SIGINT, signal_handler); + while (!flag) { + //処理 + } + if (flag) { + std::cout << "caught SIGINT" << std::endl; + } + return 0; +} +``` +* std::signal[color ff0000] + +### 出力例 +``` +caught SIGINT +``` diff --git a/reference/csignal/sigsegv.md b/reference/csignal/sigsegv.md new file mode 100644 index 0000000000..893f40e991 --- /dev/null +++ b/reference/csignal/sigsegv.md @@ -0,0 +1,38 @@ +# SIGSEGV +* csignal[meta header] +* macro[meta id-type] + +```cpp +#define SIGSEGV see below +``` + +## 概要 +無効なメモリアクセス(不正なアドレス参照など)が発生した際に送られるシグナルの、シグナル番号を表すマクロ。 + +`int`型の正の整数の定数式に展開され、実際の値は未規定。 + +## 例 +```cpp example +#include +#include + +void signal_handler(int) +{ + std::_Exit(0); +} + +int main() +{ + std::signal(SIGSEGV, signal_handler); + + int *p = nullptr; + *p = 42; // 未定義動作。多くの処理系では SIGSEGV が発生するが、保証はない。 + + return 0; +} +``` +* SIGSEGV[color ff0000] + +### 出力 +``` +``` diff --git a/reference/csignal/sigterm.md b/reference/csignal/sigterm.md new file mode 100644 index 0000000000..01890575dd --- /dev/null +++ b/reference/csignal/sigterm.md @@ -0,0 +1,35 @@ +# SIGTERM +* csignal[meta header] +* macro[meta id-type] + +```cpp +#define SIGTERM see below +``` + +## 概要 +プロセスの終了を要求するために送られるシグナルの、シグナル番号を表すマクロ。 + +`int`型の正の整数の定数式に展開され、実際の値は未規定。 + +## 例 +```cpp example +#include +#include + +void handler(int) +{ + std::_Exit(0); +} + +int main() +{ + std::signal(SIGTERM, handler); + std::raise(SIGTERM); + return 0; +} +``` +* SIGTERM[color ff0000] + +### 出力 +``` +``` diff --git a/reference/cstdlib/abort.md b/reference/cstdlib/abort.md index 5e301f80ff..cf3d5ac90b 100644 --- a/reference/cstdlib/abort.md +++ b/reference/cstdlib/abort.md @@ -13,7 +13,7 @@ namespace std { ## 概要 プログラムを異常終了させる。 -この関数は、シグナルハンドラでシグナル[`SIGABRT`](/reference/csignal/sigabrt.md.nolink)を捕捉しない限り、プログラムを異常終了させる。 +この関数は、シグナルハンドラでシグナル[`SIGABRT`](/reference/csignal/sigabrt.md)を捕捉しない限り、プログラムを異常終了させる。 この関数を呼び出したときに生存しているオブジェクトは、破棄されない。 @@ -24,8 +24,8 @@ namespace std { ```cpp raise(SIGABRT); ``` -* raise[link /reference/csignal/raise.md.nolink] -* SIGABRT[link /reference/csignal/sigabrt.md.nolink] +* raise[link /reference/csignal/raise.md] +* SIGABRT[link /reference/csignal/sigabrt.md] ## 戻り値