# 機能設計書 164-環境変数一覧取得

## 概要

本ドキュメントは、libuv の `uv_os_environ()` および `uv_os_free_environ()` APIにより、すべての環境変数を取得・解放する機能について記述する。

### 本機能の処理概要

本機能は、プロセスの全環境変数をname=valueペアの配列として取得し、使用後にメモリを解放するためのクロスプラットフォームAPIを提供する。

**業務上の目的・背景**：環境変数はアプリケーションの設定や実行環境の情報を伝達する重要な手段である。libuvを使用するアプリケーション（Node.jsの`process.env`等）では、全環境変数を一括で取得する必要がある。Unixの`environ`グローバル変数とWindowsの`GetEnvironmentStringsW()`の差異を吸収し、統一的なインターフェースを提供する。

**機能の利用シーン**：アプリケーション起動時の環境変数一括読み込み、環境変数のダンプ・デバッグ出力、子プロセスへの環境変数引き継ぎ時の参照に利用される。

**主要な処理内容**：
1. `uv_os_environ()`: POSIXの`environ`外部変数を走査し、全環境変数を`uv_env_item_t`配列にコピーする
2. `uv_os_free_environ()`: `uv_os_environ()`で確保されたメモリを解放する
3. 各環境変数はname=value形式の文字列を'='で分割して格納する

**関連システム・外部連携**：POSIX `environ` 外部変数（Unix）、`GetEnvironmentStringsW()` / `FreeEnvironmentStringsW()`（Windows）を使用する。

**権限による制御**：特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_os_environ()/free_environ()による全環境変数取得・解放のAPI定義 |

## 機能種別

データ取得・メモリ管理

## 入力仕様

### 入力パラメータ

#### uv_os_environ()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| envitems | uv_env_item_t** | Yes | 環境変数配列のポインタ（出力） | - |
| count | int* | Yes | 環境変数数のポインタ（出力） | - |

#### uv_os_free_environ()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| envitems | uv_env_item_t* | Yes | 解放する環境変数配列 | - |
| count | int | Yes | 環境変数の数 | - |

### 入力データソース

OS環境変数（POSIX `environ` 外部変数）

## 出力仕様

### 出力データ

#### uv_os_environ()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、エラー時負のエラーコード |
| *envitems | uv_env_item_t* | 環境変数の配列 |
| *count | int | 環境変数の数 |

#### uv_env_item_t 構造体

| フィールド | 型 | 説明 |
|-----------|-----|------|
| name | char* | 環境変数名 |
| value | char* | 環境変数値 |

### 出力先

呼び出し元に直接返却（動的メモリ確保）

## 処理フロー

### 処理シーケンス

```
uv_os_environ():
1. 出力パラメータを初期化（*envitems = NULL, *count = 0）
2. environ配列を走査して環境変数の数をカウント
3. uv__calloc()で環境変数配列のメモリを確保
4. 各environ[j]に対してループ処理
   a. uv__strdup()で文字列を複製
   b. strchr()で'='を検索
   c. '='がない場合はスキップ（continue）
   d. '='をNULL終端に置き換え、nameとvalueを分離
5. countを設定して返却

uv_os_free_environ():
1. 各envitems[i].nameのメモリを解放（nameとvalueは同一アロケーション）
2. envitems配列全体を解放
```

### フローチャート

```mermaid
flowchart TD
    A[uv_os_environ呼び出し] --> B[出力パラメータ初期化]
    B --> C[environ走査で数をカウント]
    C --> D[uv__calloc で配列確保]
    D --> E{メモリ確保成功?}
    E -->|No| F[UV_ENOMEM返却]
    E -->|Yes| G[各environ要素をループ]
    G --> H[uv__strdup で文字列複製]
    H --> I{複製成功?}
    I -->|No| J[fail: 確保済みメモリ解放しUV_ENOMEM]
    I -->|Yes| K[strchr で = を検索]
    K --> L{'=' が見つかった?}
    L -->|No| M[uv__free buf, continue]
    L -->|Yes| N['='をNULL終端に置換]
    N --> O[name=buf, value=ptr+1]
    O --> P[cnt++]
    P --> G
    G -->|ループ完了| Q[*count = cnt, return 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | '='なしスキップ | '='を含まない環境変数エントリはスキップする | name=value形式でない場合 |
| BR-02 | 文字列複製 | 各環境変数文字列はuv__strdup()で独立コピーする | 全エントリ |
| BR-03 | name/value同一アロケーション | nameとvalueは同一のメモリブロック内に格納される | uv_os_free_environ()で解放時はnameのみfree |

### 計算ロジック

該当なし

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

該当なし（データベースは使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_ENOMEM | メモリ不足 | uv__calloc()またはuv__strdup()が失敗 | メモリを確保してリトライ |

### リトライ仕様

メモリ不足の場合、不要なメモリを解放した後にリトライ可能。

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

該当なし

## パフォーマンス要件

環境変数の数に比例した処理時間（通常数十~数百個程度）。各文字列のコピーにメモリアロケーションが発生する。

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

- 環境変数にはパスワードやAPI鍵などの機密情報が含まれる可能性がある
- 取得した環境変数配列は使用後に`uv_os_free_environ()`で確実に解放すべき
- マルチスレッド環境では、environ配列への並行アクセスに注意が必要

## 備考

- `uv_os_free_environ()` は `src/uv-common.c` で実装されている（Unix/Windows共通）
- environ配列の走査中にenviron[j]がNULLになる可能性を考慮したチェック（L1542）がある
- `include/uv.h` L1364-1370 で構造体およびAPI定義

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | L1364-1367: uv_env_item_s構造体定義（name, value） |
| 1-2 | uv.h | `include/uv.h` | L1369-1370: uv_os_environ()/uv_os_free_environ()のAPI宣言 |

**読解のコツ**: `uv_env_item_t` のnameとvalueは同一のメモリブロック内にある（'='をNULL終端に置換して分割）。このため解放時はnameのみfreeすればよい。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | L1524-1577: uv_os_environ()のUnix実装 |

**主要処理フロー**:
1. **1528-1529行目**: 出力パラメータ初期化
2. **1531行目**: environ配列の要素数カウント
3. **1533行目**: uv__calloc()で配列メモリ確保
4. **1538-1562行目**: 各environ要素の複製とname/value分離
5. **1549-1555行目**: '='による文字列分割処理
6. **1567-1576行目**: エラー時のクリーンアップ（fail:ラベル）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | uv-common.c | `src/uv-common.c` | L941-949: uv_os_free_environ()の実装 |

**主要処理フロー**:
- **944-945行目**: 各envitems[i].nameをuv__free()で解放
- **948行目**: envitems配列全体をuv__free()で解放

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

```
uv_os_environ() [src/unix/core.c:1524]
    |
    +-- environ[] グローバル変数走査
    +-- uv__calloc() [メモリ確保]
    +-- uv__strdup() [各文字列コピー]
    +-- strchr() [name/value分離]

uv_os_free_environ() [src/uv-common.c:941]
    |
    +-- uv__free(envitems[i].name)  [各name解放]
    +-- uv__free(envitems)          [配列解放]
```

### データフロー図

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

environ[]         ───> 文字列複製 + '='分割          ───> uv_env_item_t* (name/value配列)
(グローバル変数)        uv__calloc + uv__strdup           *count (環境変数数)
                                                          戻り値 (0 or エラー)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | 構造体定義（L1364-1367）、API宣言（L1369-1370） |
| core.c | `src/unix/core.c` | ソース | Unix実装 uv_os_environ()（L1524-1577） |
| uv-common.c | `src/uv-common.c` | ソース | 共通実装 uv_os_free_environ()（L941-949） |
| util.c | `src/win/util.c` | ソース | Windows実装 |
