# 機能設計書 91-プロセスキル

## 概要

本ドキュメントは、libuvにおけるプロセスキル機能（uv_process_kill() / uv_kill()）の設計を記述する。これらのAPIは、実行中のプロセスに対してシグナルを送信し、プロセスの終了や制御を行うための機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：非同期I/Oライブラリであるlibuvにおいて、子プロセスのライフサイクル管理は重要な機能である。uv_spawn()で生成した子プロセスの正常終了や強制終了を制御するために、プロセスへのシグナル送信機能が必要となる。Unix系OSのkill()システムコールをクロスプラットフォームで抽象化し、一貫したAPIを提供する。

**機能の利用シーン**：子プロセスの強制終了（SIGKILLの送信）、子プロセスへの割り込み（SIGINTの送信）、子プロセスへのカスタムシグナル送信、プロセスの存在確認（シグナル0の送信）などの場面で利用される。

**主要な処理内容**：
1. uv_process_kill()はuv_process_tハンドルを通じて、そのプロセスにシグナルを送信する
2. uv_kill()はPIDを直接指定して任意のプロセスにシグナルを送信する
3. いずれもPOSIXのkill()システムコールをラップし、エラーをlibuvエラーコードに変換する
4. z/OS環境ではゾンビプロセスに対するEPERMを成功として扱う特殊処理がある

**関連システム・外部連携**：POSIXのkill()システムコール、WindowsのTerminateProcess() API、z/OSではwaitid()を用いたゾンビプロセスの特殊処理がある。

**権限による制御**：シグナル送信先のプロセスに対する適切なOS権限が必要。権限不足の場合はEPERMエラーが返される。Unix系では同一ユーザーまたはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | プロセス | 主機能 | uv_process_kill()/uv_kill()によるプロセスへのシグナル送信のAPI定義 |

## 機能種別

プロセス制御操作 / システムコール呼び出し

## 入力仕様

### 入力パラメータ

#### uv_process_kill()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| process | uv_process_t* | Yes | シグナル送信先のプロセスハンドル | NULLでないこと |
| signum | int | Yes | 送信するシグナル番号 | 有効なシグナル番号 |

#### uv_kill()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pid | int | Yes | シグナル送信先のプロセスID | 有効なPID |
| signum | int | Yes | 送信するシグナル番号 | 有効なシグナル番号 |

### 入力データソース

uv_process_kill()の場合、uv_spawn()で生成されたuv_process_tハンドルから内部的にPIDを取得する。uv_kill()の場合、呼び出し元が直接PIDを指定する。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、失敗時負のlibuvエラーコード |

### 出力先

呼び出し元への戻り値として返却。OSカーネルへのシグナル送信。

## 処理フロー

### 処理シーケンス

```
1. uv_process_kill(process, signum) が呼ばれる
   └─ 内部でuv_kill(process->pid, signum)を呼び出す
2. uv_kill(pid, signum) が呼ばれる
   └─ POSIXのkill(pid, signum)を実行する
3. kill()の結果を判定する
   ├─ 成功(0): 0を返す
   └─ 失敗(-1):
       ├─ z/OS環境でEPERMかつゾンビプロセスの場合: 0を返す（特殊処理）
       └─ その他: UV__ERR(errno)を返す
```

### フローチャート

```mermaid
flowchart TD
    A[uv_process_kill / uv_kill 呼び出し] --> B[kill システムコール実行]
    B --> C{kill 成功?}
    C -->|Yes| D[0 を返す]
    C -->|No| E{z/OS かつ EPERM?}
    E -->|Yes| F[waitid でゾンビ確認]
    F --> G{ゾンビプロセス?}
    G -->|Yes| H[0 を返す]
    G -->|No| I[UV__ERR errno を返す]
    E -->|No| I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-91-1 | PID委譲 | uv_process_kill()はハンドルからPIDを取得してuv_kill()に委譲する | uv_process_kill()呼び出し時 |
| BR-91-2 | z/OSゾンビ特殊処理 | z/OSではEPERMでもゾンビプロセスの場合は成功として扱う | z/OS環境でkill()がEPERMを返した場合 |
| BR-91-3 | シグナル0 | signum=0はプロセスの存在確認に使用可能（シグナルは送信されない） | signum=0指定時 |

### 計算ロジック

特になし。

## データベース操作仕様

### 操作別データベース影響一覧

該当なし（データベース操作は行わない）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_ESRCH | プロセス不在 | 指定PIDのプロセスが存在しない | プロセスの存在を確認する |
| UV_EPERM | 権限不足 | シグナル送信権限がない | 適切な権限でプロセスを実行する |
| UV_EINVAL | 無効シグナル | 無効なシグナル番号を指定 | 有効なシグナル番号を使用する |

### リトライ仕様

リトライは不要。シグナル送信は即座に完了する同期操作である。

## トランザクション仕様

該当なし。

## パフォーマンス要件

kill()システムコールは即座に完了するため、特別なパフォーマンス要件はない。通常マイクロ秒オーダーで完了する。

## セキュリティ考慮事項

- プロセスへのシグナル送信にはOS権限が必要
- 他ユーザーのプロセスへのシグナル送信は通常root権限が必要
- PIDの再利用による意図しないプロセスへのシグナル送信のリスクがある
- 任意のPIDへのシグナル送信が可能なため、pid引数の検証が重要

## 備考

- uv_process_kill()はuv_kill()の薄いラッパーであり、ハンドルのpidフィールドを取り出してuv_kill()に渡すだけの実装である（Unix版）
- Windows版ではTerminateProcess() APIを使用する異なる実装がある
- シグナル番号0を送信するとプロセスの存在確認として使用できる

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | **1170-1174行目**: uv_process_s構造体のpidフィールドとexit_cbフィールドを確認する |

**読解のコツ**: UV_HANDLE_FIELDSマクロにより共通ハンドルフィールドが展開される。pidフィールドがプロセスIDを保持する重要なメンバーである。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | **1179-1180行目**: uv_process_kill()とuv_kill()の2つの公開APIの宣言を確認する |

**主要処理フロー**:
1. **1179行目**: `uv_process_kill(uv_process_t*, int signum)` - ハンドルベースのシグナル送信
2. **1180行目**: `uv_kill(int pid, int signum)` - PIDベースのシグナル送信

#### Step 3: Unix実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | process.c | `src/unix/process.c` | **1097-1099行目**: uv_process_kill()の実装。uv_kill()への委譲パターンを確認する |
| 3-2 | process.c | `src/unix/process.c` | **1102-1114行目**: uv_kill()の実装。kill()システムコール呼び出しとエラー処理 |

**主要処理フロー**:
- **1097-1098行目**: uv_process_kill()はprocess->pidを取り出してuv_kill()に渡すのみ
- **1103行目**: POSIX kill()システムコールの直接呼び出し
- **1104-1109行目**: z/OS固有のゾンビプロセス処理（EPERMの場合にwaitidで確認）
- **1111行目**: エラー時はUV__ERR(errno)でlibuvエラーコードに変換

### プログラム呼び出し階層図

```
uv_process_kill(process, signum)
    |
    +-- uv_kill(process->pid, signum)
            |
            +-- kill(pid, signum)  [POSIX syscall]
            |
            +-- [z/OS] waitid(P_PID, pid, ..., WNOHANG|WNOWAIT|WEXITED)
```

### データフロー図

```
[入力]                    [処理]                        [出力]

uv_process_t*    ---> process->pid取得 --->
                                            kill(pid, signum) ---> int (0 or error)
int signum       ---> シグナル番号     --->
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | API宣言とuv_process_t構造体定義 |
| process.c | `src/unix/process.c` | ソース | Unix系プラットフォームのuv_process_kill()/uv_kill()実装 |
| process.c | `src/win/process.c` | ソース | Windowsプラットフォームの実装 |
| uv-data-getter-setters.c | `src/uv-data-getter-setters.c` | ソース | uv_process_get_pid()のアクセサ実装 |
