# 機能設計書 59-Bun.spawn

## 概要

本ドキュメントは、Bunの子プロセス生成API（Bun.spawn/Bun.spawnSync）の設計仕様を記述する。

### 本機能の処理概要

Bun.spawnは、子プロセスを非同期で生成する機能を提供する。Bun.spawnSyncは同期版である。Node.jsのchild_processモジュールと互換性のあるAPIを提供しつつ、より高性能な実装を実現している。

**業務上の目的・背景**：外部コマンドの実行、シェルスクリプトの呼び出し、他のプログラムとの連携などに必要な子プロセス管理機能を提供する。

**機能の利用シーン**：ビルドツールからの外部コマンド実行、シェルスクリプト呼び出し、テストランナーからのプロセス起動、パイプライン処理。

**主要な処理内容**：
1. Bun.spawn()でSubprocessオブジェクト生成
2. stdin/stdout/stderrのパイプ設定
3. 環境変数・作業ディレクトリの設定
4. プロセス起動と監視
5. プロセス終了とリソースクリーンアップ

**関連システム・外部連携**：OSのプロセス管理API（fork/exec、posix_spawn、libuv）。

**権限による制御**：実行ファイルの実行権限に従う。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | プログラマティックなプロセス生成 |

## 機能種別

プロセス管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cmd | string[] | Yes | 実行するコマンドと引数 | 最低1要素 |
| options.cwd | string | No | 作業ディレクトリ | 有効なパス |
| options.env | object | No | 環境変数 | - |
| options.stdin | string/Blob/number | No | 標準入力（"pipe", "inherit", "ignore"等） | - |
| options.stdout | string/Blob/number | No | 標準出力 | - |
| options.stderr | string/Blob/number | No | 標準エラー | - |
| options.onExit | function | No | 終了時コールバック | - |
| options.signal | AbortSignal | No | キャンセル用シグナル | - |
| options.timeout | number | No | タイムアウト（ミリ秒） | 正の数 |

### stdio設定オプション

```typescript
type StdioOption =
  | "pipe"      // パイプで接続
  | "inherit"   // 親プロセスから継承
  | "ignore"    // /dev/null
  | number      // ファイルディスクリプタ
  | Blob/BunFile // ファイルから読み込み/書き込み
```

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Subprocess | object | 子プロセスオブジェクト |

### Subprocessプロパティ・メソッド

```typescript
interface Subprocess {
  pid: number;
  stdin: WritableStream | null;
  stdout: ReadableStream | null;
  stderr: ReadableStream | null;
  exited: Promise<number>;
  exitCode: number | null;
  signalCode: string | null;
  killed: boolean;

  kill(signal?: number | string): boolean;
  ref(): void;
  unref(): void;
  send(message: any): void;  // IPC時
  disconnect(): void;        // IPC時
  resourceUsage(): object;
}
```

## 処理フロー

### 処理シーケンス

```
1. Bun.spawn()呼び出し
   └─ Subprocess.spawn関数
2. 引数とオプションの解析
   └─ cmd、env、cwd等のパース
3. stdio設定
   └─ stdin/stdout/stderrのパイプ作成
4. プロセス生成
   └─ posix_spawn / CreateProcess
5. Subprocess オブジェクト返却
   └─ プロパティとメソッドを持つオブジェクト
6. プロセス監視
   └─ exitedプロミスで終了を待機
7. リソースクリーンアップ
   └─ パイプクローズ、メモリ解放
```

### フローチャート

```mermaid
flowchart TD
    A[Bun.spawn呼び出し] --> B[引数解析]
    B --> C[stdioパイプ設定]
    C --> D{プロセス生成}
    D -->|成功| E[Subprocess返却]
    D -->|失敗| F[エラーthrow]
    E --> G[プロセス実行]
    G --> H{終了イベント}
    H -->|正常終了| I[exitCode設定]
    H -->|シグナル終了| J[signalCode設定]
    H -->|タイムアウト| K[kill実行]
    I --> L[リソースクリーンアップ]
    J --> L
    K --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-59-1 | デフォルトstdin | stdinのデフォルトは"pipe" | spawnSync以外 |
| BR-59-2 | デフォルトstdout/stderr | stdout/stderrのデフォルトは"pipe" | 常時 |
| BR-59-3 | タイムアウト処理 | タイムアウト時はkillSignalで終了 | timeout指定時 |
| BR-59-4 | AbortSignal対応 | AbortSignalでプロセスをキャンセル可能 | signal指定時 |
| BR-59-5 | IPC通信 | 'ipc'オプションでプロセス間通信 | stdio配列にipc指定時 |

### SignalCode

```
SIGTERM = 15 (デフォルト)
SIGKILL = 9
SIGINT = 2
SIGHUP = 1
等
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ENOENT | FileNotFound | 実行ファイルが存在しない | パスを確認 |
| EACCES | PermissionDenied | 実行権限なし | 権限を確認 |
| EMFILE | TooManyFiles | ファイルディスクリプタ上限 | リソース解放 |

### リトライ仕様

リトライは行わない。

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

該当なし。

## パフォーマンス要件

- プロセス起動オーバーヘッド：最小化
- メモリ効率：パイプバッファの適切な管理
- イベントループ：非同期でブロックしない

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

- コマンドインジェクション対策（シェル経由を避ける）
- 環境変数の適切なフィルタリング
- 権限昇格の防止

## 備考

- Bun.spawnSyncは同期版
- terminal オプションでPTY対応
- maxBuffer でstdout/stderrのバッファ制限

---

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

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

### 推奨読解順序

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

まず、Subprocess構造体を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | subprocess.zig | `src/bun.js/api/bun/subprocess.zig` | Subprocess構造体、Flags |

**読解のコツ**: Subprocessは参照カウント（RefCount）で管理される。stdin/stdout/stderrはReadable/Writableで抽象化されている。

**主要処理フロー**:
- **1-9行目**: コメント。SubprocessはBun.spawnで返されるオブジェクト
- **15-52行目**: Subprocess構造体フィールド
- **54-62行目**: Flags packed struct

#### Step 2: プロセス管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | subprocess.zig | `src/bun.js/api/bun/subprocess.zig` | kill、hasExited、tryKill |

**主要処理フロー**:
- **364-400行目**: kill関数。シグナル送信とエラーハンドリング
- **391-400行目**: tryKill関数。終了済みチェック後にkill実行

#### Step 3: stdio処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | subprocess.zig | `src/bun.js/api/bun/subprocess.zig` | Writable、Readable |
| 3-2 | Readable.zig | `src/bun.js/api/bun/subprocess/Readable.zig` | 読み取り処理 |

**主要処理フロー**:
- **271行目**: PipeReader import
- **272行目**: Readable import

#### Step 4: IPC通信を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | subprocess.zig | `src/bun.js/api/bun/subprocess.zig` | doSend、disconnectIPC |

**主要処理フロー**:
- **437-441行目**: doSend関数。IPC経由でメッセージ送信
- **442-445行目**: disconnectIPC関数。IPC接続切断

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

```
Bun.spawn(cmd, options) (BunObject.zig)
    │
    └─ api.Subprocess.spawn
           │
           ├─ 引数解析
           │      ├─ cmd配列
           │      ├─ env環境変数
           │      └─ cwd作業ディレクトリ
           │
           ├─ stdio設定
           │      ├─ stdin (Writable)
           │      ├─ stdout (Readable)
           │      └─ stderr (Readable)
           │
           ├─ Process生成
           │      └─ posix_spawn / CreateProcess
           │
           └─ Subprocess返却
                  ├─ pid
                  ├─ exited (Promise)
                  ├─ kill()
                  └─ IPC (doSend/disconnect)
```

### データフロー図

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

cmd配列 ─────────────▶ コマンド解析 ─────────▶ 実行パス特定
options.env ─────────▶ 環境変数設定 ─────────▶ 子プロセス環境
options.cwd ─────────▶ 作業ディレクトリ設定 ─▶ 起動ディレクトリ
                              │
                              ▼
                        posix_spawn
                              │
                              ▼
stdin (親→子) ────────▶ パイプ ──────────────▶ 子プロセスstdin
stdout (子→親) ◀──────── パイプ ◀──────────── 子プロセスstdout
stderr (子→親) ◀──────── パイプ ◀──────────── 子プロセスstderr
                              │
                              ▼
                        exited Promise
                              │
                              ▼
                        exitCode / signalCode
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| subprocess.zig | `src/bun.js/api/bun/subprocess.zig` | ソース | Subprocess実装 |
| Readable.zig | `src/bun.js/api/bun/subprocess/Readable.zig` | ソース | stdout/stderr読み取り |
| SubprocessPipeReader.zig | `src/bun.js/api/bun/subprocess/SubprocessPipeReader.zig` | ソース | パイプ読み取り |
| ResourceUsage.zig | `src/bun.js/api/bun/subprocess/ResourceUsage.zig` | ソース | リソース使用量 |
| BunObject.zig | `src/bun.js/api/BunObject.zig` | ソース | Bun.spawn/spawnSync登録 |
