# 機能設計書: 55-osproc（プロセス起動・管理）

## 1. 概要

### 1.1 業務上の目的・背景

osprocモジュールは、外部プロセスの起動・管理機能を提供する。シェルコマンドの実行、子プロセスとの入出力ストリーム通信、並列プロセス実行など、システム開発における外部プログラム連携の基盤となる機能を提供する。

### 1.2 機能の利用シーン

- シェルコマンドやシステムツールの実行
- 外部プログラムとのパイプを介した双方向通信
- 複数コマンドの並列実行によるビルド高速化
- デーモンプロセスの起動・管理
- プロセスの一時停止・再開・終了制御

### 1.3 主要な処理内容

1. プロセス起動: `startProcess`, `execProcess`, `execCmd`
2. プロセス制御: `suspend`, `resume`, `terminate`, `kill`
3. 状態監視: `running`, `waitForExit`, `peekExitCode`
4. ストリーム通信: `inputStream`, `outputStream`, `errorStream`
5. 並列実行: `execProcesses`

### 1.4 関連するデータ/ファイル

- 実行可能ファイル（コマンド）
- 標準入出力/エラーストリーム
- 環境変数（StringTableRef）
- 作業ディレクトリ

### 1.5 バッチ/オンライン区分

オンライン（リアルタイム/非同期プロセス制御）

## 2. 関連画面

- CLIアプリケーション
- ビルドシステム
- タスクランナー
- サービス監視ツール

## 3. 機能種別

- [x] データ操作
- [ ] 帳票出力
- [ ] 外部連携
- [x] バッチ処理
- [x] リアルタイム処理

## 4. 入力仕様

### 4.1 プロセス起動パラメータ

| 項目名 | 型 | 説明 | 必須 |
|--------|-----|------|------|
| command | string | 実行するコマンド | Yes |
| workingDir | string | 作業ディレクトリ | No |
| args | openArray[string] | コマンド引数 | No |
| env | StringTableRef | 環境変数 | No |
| options | set[ProcessOption] | プロセスオプション | No |

### 4.2 ProcessOption

| オプション | 説明 |
|------------|------|
| poEchoCmd | コマンドをエコー出力 |
| poUsePath | PATH環境変数を使用 |
| poEvalCommand | シェル経由でコマンド実行 |
| poStdErrToStdOut | 標準エラーを標準出力にマージ |
| poParentStreams | 親プロセスのストリームを使用 |
| poInteractive | 対話モード（Windows） |
| poDaemon | デーモンとして起動 |

### 4.3 入力チェック仕様

| チェック項目 | 内容 | エラー処理 |
|-------------|------|-----------|
| コマンド存在 | 実行ファイルが存在すること | OSError発生 |
| ストリームアクセス | poParentStreams未設定時のみストリーム取得可能 | assert失敗 |
| poEvalCommand | args.len == 0であること | assert失敗 |

## 5. 出力仕様

### 5.1 Process型

| フィールド | 型 | 説明 |
|-----------|-----|------|
| id | int | プロセスID |
| exitFlag | bool | 終了フラグ |
| exitStatus | int | 終了ステータス |
| inHandle | FileHandle | 標準入力ハンドル |
| outHandle | FileHandle | 標準出力ハンドル |
| errHandle | FileHandle | 標準エラーハンドル |
| inStream | Stream | 入力ストリーム |
| outStream | Stream | 出力ストリーム |
| errStream | Stream | エラーストリーム |
| options | set[ProcessOption] | オプション |

### 5.2 出力メッセージ

| メッセージ種別 | 内容 |
|---------------|------|
| 正常終了 | 終了コード0 |
| 異常終了 | 終了コード非0 |
| タイムアウト | プロセス強制終了後の終了コード |

## 6. 処理フロー

### 6.1 プロセス起動フロー

```mermaid
flowchart TD
    A[startProcess呼び出し] --> B{poParentStreams?}
    B -->|Yes| C[親ストリーム使用]
    B -->|No| D[パイプ作成]
    D --> E{poInteractive?}
    E -->|Yes| F[名前付きパイプ作成]
    E -->|No| G[匿名パイプ作成]
    F --> H{Windows?}
    G --> H
    C --> H
    H -->|Yes| I[CreateProcessW]
    H -->|No| J{useProcessAuxSpawn?}
    J -->|Yes| K[posix_spawn]
    J -->|No| L[fork + exec]
    I --> M[Process返却]
    K --> M
    L --> M
```

### 6.2 プロセス待機フロー

```mermaid
flowchart TD
    A[waitForExit呼び出し] --> B{exitFlag?}
    B -->|Yes| C[キャッシュ済みステータス返却]
    B -->|No| D{timeout指定?}
    D -->|Yes| E[タイムアウト付き待機]
    D -->|No| F[無限待機]
    E --> G{タイムアウト?}
    G -->|Yes| H[SIGKILL送信]
    G -->|No| I[終了ステータス取得]
    F --> I
    H --> I
    I --> J[exitFlag=true設定]
    J --> K[exitStatusLikeShell変換]
    K --> L[終了コード返却]
```

### 6.3 並列実行フロー

```mermaid
flowchart TD
    A[execProcesses呼び出し] --> B{n > 1?}
    B -->|No| C[順次実行]
    B -->|Yes| D[プロセスキュー初期化]
    D --> E[最大n個のプロセス起動]
    E --> F{Windows?}
    F -->|Yes| G[WaitForMultipleObjects]
    F -->|No| H[waitpid -1]
    G --> I[終了プロセス検出]
    H --> I
    I --> J[afterRunEventコールバック]
    J --> K{残コマンドあり?}
    K -->|Yes| L[新プロセス起動]
    K -->|No| M{全終了?}
    L --> E
    M -->|No| E
    M -->|Yes| N[最大終了コード返却]
    C --> N
```

## 7. ビジネスルール

### 7.1 プロセスオプション組み合わせ

| 条件 | ルール |
|------|--------|
| poEvalCommand使用時 | args配列は空であること |
| poParentStreams使用時 | inputStream/outputStream/errorStreamの呼び出し不可 |
| poStdErrToStdOut使用時 | errHandleはoutHandleと同じ |

### 7.2 終了コード変換

| プラットフォーム | 変換方式 |
|-----------------|---------|
| Windows | そのまま返却 |
| POSIX | WEXITSTATUS/WTERMSIGマクロで変換 |

### 7.3 タイムアウト処理

| プラットフォーム | 実装方式 |
|-----------------|---------|
| macOS/BSD | kqueue + EVFILT_PROC |
| Haiku | wait_for_objects_etc |
| Linux | ポーリング + clock_nanosleep |
| Windows | WaitForSingleObject |

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

該当なし（ファイルシステム・プロセス操作のみ）

## 9. エラー処理

### 9.1 エラー一覧

| エラー条件 | 発生関数 | 処理 |
|-----------|---------|------|
| コマンド未検出 | startProcess | OSError発生 |
| パイプ作成失敗 | startProcess | OSError発生 |
| fork/spawn失敗 | startProcess | OSError発生 |
| waitpid失敗 | waitForExit | OSError発生 |
| kill失敗 | terminate/kill | OSError発生 |

### 9.2 エラーコード

| コード | 意味 |
|--------|------|
| errFileNotFound (2) | コマンドが見つからない（Windows） |
| errInvalidParameter (87) | 無効なパラメータ（Windows） |
| ECHILD | 子プロセスなし（POSIX） |
| EINTR | シグナル割り込み（POSIX） |

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

該当なし（プロセス管理はトランザクション対象外）

## 11. パフォーマンス要件

| 項目 | 要件 |
|------|------|
| プロセス起動 | fork/spawnのオーバーヘッド |
| 並列実行数 | countProcessors()で自動決定 |
| タイムアウト精度 | プラットフォーム依存（50ms〜1ms） |
| waitpidポーリング | 50μs〜50msの指数バックオフ |

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

### 12.1 コマンドインジェクション

| リスク | 対策 |
|--------|------|
| シェルインジェクション | poEvalCommand未使用時は引数が個別にエスケープされる |
| 環境変数汚染 | env引数で明示的に環境を制御 |
| 作業ディレクトリ操作 | workingDirで安全なディレクトリを指定 |

### 12.2 リソース管理

| リスク | 対策 |
|--------|------|
| ゾンビプロセス | waitForExit/close呼び出しで回収 |
| ファイルディスクリプタリーク | close(Process)で全ハンドルをクローズ |
| デッドロック | poParentStreams使用で回避、または適切なストリーム読み書き |

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

### 13.1 関連ファイル一覧

| ファイルパス | 概要 | 行数 |
|-------------|------|------|
| lib/pure/osproc.nim | プロセス起動・管理モジュール | 約1583行 |
| lib/pure/streams.nim | ストリーム抽象（依存） | - |
| lib/std/private/ospaths2.nim | パスユーティリティ（依存） | - |
| lib/pure/strtabs.nim | 環境変数テーブル（依存） | - |

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

```
osproc.nim
├── startProcess (667-753/960-1043行)
│   ├── [Windows] createProcessW (729行)
│   │   ├── createPipeHandles (659-665行)
│   │   └── createAllPipeHandles (610-657行)
│   └── [POSIX] startProcessAuxSpawn/startProcessAuxFork (950-1016行)
│       ├── posix_spawn/posix_spawnp (1085-1088行)
│       └── fork + execve/execvp (1117-1184行)
├── execProcess (514-532行)
│   └── startProcess → outputStream → readLine
├── execProcesses (341-458行)
│   ├── [Windows] waitForMultipleObjects (382-397行)
│   └── [POSIX] waitpid (401-425行)
├── execCmd (862-885/1474-1479行)
│   ├── [Windows] createProcessW (873行)
│   └── [POSIX] csystem (1476行)
├── execCmdEx (1522-1582行)
│   └── startProcess → inputStream.write → outputStream.readLine
├── waitForExit (801-816/1242-1420行)
│   ├── [Windows] waitForSingleObject (805行)
│   ├── [macOS/BSD] kqueue + kevent (1253-1297行)
│   ├── [Haiku] wait_for_objects_etc (1335行)
│   └── [Linux] waitpid + nanosleep (1386-1418行)
├── terminate (794-796/1230-1232行)
│   ├── [Windows] terminateProcess (796行)
│   └── [POSIX] kill SIGTERM (1231行)
├── kill (798-799/1234-1236行)
│   ├── [Windows] terminateProcess (同上)
│   └── [POSIX] kill SIGKILL (1235行)
├── inputStream (832-836/1441-1445行)
├── outputStream (838-842/1447-1451行)
├── errorStream (844-848/1453-1457行)
├── lines iterator (460-487行)
└── readLines (489-511行)
```

### 13.3 データフロー図

```
[コマンド文字列]
       │
       ▼
┌─────────────────────────────────────────┐
│ startProcess                             │
│  ├─ パイプ作成                           │
│  ├─ 環境変数構築                         │
│  └─ fork/spawn/CreateProcess             │
└─────────────────────────────────────────┘
       │
       ▼
   [Process型]
       │
       ├──────────────────────────┬───────────────────────┐
       ▼                          ▼                       ▼
  inputStream              outputStream              errorStream
  (stdin書込)              (stdout読取)             (stderr読取)
       │                          │                       │
       ▼                          ▼                       ▼
  [子プロセス]  ◄───────────  waitForExit  ──────────►  [終了コード]
       │
       ▼
    close()
  (リソース解放)
```

### 13.4 読み解くべき重要なコード

1. **ProcessOption enum（79-115行）**: プロセス起動オプションの全体像
2. **startProcess Windows実装（667-753行）**: パイプ作成とCreateProcessW呼び出し
3. **startProcess POSIX実装（960-1043行）**: fork/execまたはposix_spawn
4. **waitForExit実装（1242-1420行）**: プラットフォーム別の待機ロジック
5. **execProcesses（341-458行）**: 並列プロセス実行と結果収集

### 13.5 推奨リーディング順序

1. ProcessOption enumとProcess型定義（79-150行）
2. execCmd（最もシンプルな実行関数）
3. startProcess（詳細制御可能な起動関数）
4. waitForExit（終了待機ロジック）
5. execProcesses（並列実行）
6. inputStream/outputStream/errorStream（ストリーム通信）
