# 帳票設計書 25-環境変数一覧

## 概要

プロセスの全環境変数を`uv_env_item_t`構造体の配列として出力する帳票（API出力）の設計書である。`uv_os_environ()`関数により、現在のプロセスに設定されているすべての環境変数の名前と値のペアを取得する。

### 本帳票の処理概要

本帳票は、プロセスの実行環境に存在するすべての環境変数を一覧として取得し、`uv_env_item_t`構造体の動的配列に格納して出力する機能を提供する。Unix系では`environ`グローバル変数、Windowsでは`GetEnvironmentStringsW()`を使用して環境変数を列挙する。

**業務上の目的・背景**：アプリケーションの実行環境の把握、デバッグ情報の収集、環境設定の検証、コンテナ環境での設定情報確認などの場面で環境変数の一覧取得が必要となる。個別の環境変数取得（uv_os_getenv）とは異なり、一括ですべての環境変数を取得できるため、環境のスナップショットを得る用途に適している。

**帳票の利用シーン**：アプリケーション起動時の環境ダンプ、デバッグ情報の収集ログ出力、環境変数ベースの設定システムでの一括読み込み、CI/CDパイプラインでの環境検証、コンテナ起動時の設定確認などに利用される。

**主要な出力内容**：
1. 環境変数名（name）
2. 環境変数値（value）
3. 環境変数の件数（count）

**帳票の出力タイミング**：任意のタイミングで`uv_os_environ()`関数を呼び出すことにより出力される。同期関数であり、即座に結果が返却される。

**帳票の利用者**：libuvを利用するアプリケーション開発者、Node.jsランタイム（process.env の初期化）、デバッグツール開発者、運用監視ツール開発者。

## 帳票種別

一覧表（環境変数一覧出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | CLIまたはAPI呼び出し | N/A（C言語API） | `uv_os_environ()` 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | メモリ上の構造体配列（uv_env_item_t[]） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（ポインタ経由で返却） |
| 出力方法 | 引数ポインタへの配列先頭アドレスと件数の書き込み |
| 文字コード | UTF-8 |

### uv_env_item_t 構造体定義

```c
struct uv_env_item_s {
  char* name;   /* 環境変数名 */
  char* value;  /* 環境変数値 */
};
```

## 帳票レイアウト

### レイアウト概要

本帳票は可変長のuv_env_item_t配列として出力される。

```
┌─────────────────────────────────────┐
│  uv_env_item_t 配列                  │
├─────────────────────────────────────┤
│  [0] name: "PATH"                   │
│      value: "/usr/bin:/usr/local/..."│
│  [1] name: "HOME"                   │
│      value: "/home/user"            │
│  [2] name: "LANG"                   │
│      value: "en_US.UTF-8"           │
│  ...                                │
│  [N-1] name: "TERM"                 │
│        value: "xterm-256color"      │
└─────────────────────────────────────┘
│  count = N                          │
```

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | name | 環境変数名 | environ配列の"="の左側 / GetEnvironmentStringsW の"="の左側 | 文字列（char*） | 可変 |
| 2 | value | 環境変数値 | environ配列の"="の右側 / GetEnvironmentStringsW の"="の右側 | 文字列（char*） | 可変 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| envitems | uv_env_item_t** ポインタ。出力配列の先頭アドレスが格納される | Yes |
| count | int* ポインタ。出力された環境変数の件数が格納される | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| N/A | OS が提供する順序（未ソート） | 順序保証なし |

### 改ページ条件

N/A

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを参照しない。プロセスの環境変数テーブルから取得する。

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A | N/A | N/A |

### プラットフォーム別データ取得元

| プラットフォーム | ファイル | 取得方法 | 備考 |
|---------------|---------|---------|------|
| Unix系 | `src/unix/core.c` | `environ` グローバル変数を走査 | macOS では `_NSGetEnviron()` 経由 |
| Windows | `src/win/util.c` | `GetEnvironmentStringsW()` API | UTF-16からUTF-8への変換が必要 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 配列サイズ | environ配列のNULLまでの要素数 | N/A | uv__calloc(i, sizeof(**envitems)) で一括確保 |
| 名前/値の分割 | strchr(buf, '=') で"="の位置を検出 | N/A | "="が見つからないエントリはスキップ |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_os_environ 呼び出し] --> B[envitems=NULL, count=0 で初期化]
    B --> C{プラットフォーム判定}
    C -->|Unix| D[environ 配列の要素数をカウント]
    D --> E[uv__calloc で配列メモリ確保]
    E --> F{確保成功?}
    F -->|No| G[UV_ENOMEM を返却]
    F -->|Yes| H[各 environ エントリを処理]
    H --> I[uv__strdup でコピー]
    I --> J[strchr で = を検索]
    J --> K{= あり?}
    K -->|No| L[コピーを free してスキップ]
    K -->|Yes| M[= を NULLに置換]
    M --> N[name = buf, value = ptr+1]
    N --> O[cnt をインクリメント]
    L --> H
    O --> H
    H --> P[count = cnt を設定]
    P --> Q[0 を返却]
    C -->|Windows| R[GetEnvironmentStringsW 呼び出し]
    R --> S[wchar_t 文字列の要素数をカウント]
    S --> T[uv__calloc で配列メモリ確保]
    T --> U[各エントリを UTF-16→UTF-8 変換]
    U --> V[strchr で = を検索して分割]
    V --> W[FreeEnvironmentStringsW]
    W --> Q
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| UV_ENOMEM | 配列メモリまたは個別文字列のメモリ確保に失敗した場合 | N/A | メモリ使用量を確認 |
| UTF-16変換エラー | Windows で UTF-16→UTF-8 変換に失敗した場合 | N/A | 環境変数の文字エンコーディングを確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数十～数百件（典型的なプロセス環境変数数） |
| 目標出力時間 | ミリ秒オーダー（メモリ確保 + 文字列コピー） |
| 同時出力数上限 | 制限なし（各呼び出しで独立したメモリを確保） |

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

- 環境変数にはパスワード、APIキー、トークン等のセキュリティクリティカルな情報が含まれる可能性がある
- 取得した環境変数一覧をログに出力する場合は、センシティブな変数のフィルタリングを推奨する
- 返却されたメモリは `uv_os_free_environ()` で明示的に解放する必要がある
- 環境変数の各エントリはuv__strdupによるコピーであり、元のenviron配列への参照は保持しない

## 備考

- 返却された配列は `uv_os_free_environ(envitems, count)` で解放すること
- Unix系ではenvironの各エントリを `uv__strdup` でコピーし、"=" を NUL 文字に置換することで name と value を分割する。name と value は同一メモリブロック内に存在する
- Windows では各エントリが独立した `uv__convert_utf16_to_utf8` によるメモリ確保で作成される。同様に name と value は同一バッファ内
- "=" を含まないエントリ（通常は存在しないが異常な環境変数）はスキップされる
- Windows では先頭が "=" で始まる特殊環境変数が存在するため、`buf + 1` から "=" を検索する
- macOS では `_NSGetEnviron()` マクロにより environ にアクセスする（crt_externs.h）

---

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

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

### 推奨読解順序

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

uv_env_item_t 構造体のメンバ構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | struct uv_env_item_s の定義（行1364-1367）: name, value の2フィールド |
| 1-2 | uv.h | `include/uv.h` | uv_os_environ / uv_os_free_environ の宣言（行1369-1370） |

**読解のコツ**: name と value は同一の malloc バッファ内に存在する（"=" が NUL に置換されている）。解放時は name のみを free すればよい。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | environ のプラットフォーム別定義（行62-68）: macOS では _NSGetEnviron() 経由、その他は extern char** environ |
| 2-2 | core.c | `src/unix/core.c` | uv_os_environ() 関数（行1524-1577）: environ 配列の走査と環境変数の抽出 |

**主要処理フロー**:
1. **行1528-1529**: 出力変数を初期化（*envitems=NULL, *count=0）
2. **行1531**: environ 配列の要素数をカウント
3. **行1533**: uv__calloc で配列メモリを一括確保
4. **行1538-1562**: 各 environ エントリを処理
   - **行1545**: uv__strdup で環境変数文字列をコピー
   - **行1549**: strchr(buf, '=') で "=" の位置を検索
   - **行1550-1553**: "=" が見つからない場合はスキップ
   - **行1555**: "=" を '\0' に置換
   - **行1558-1559**: name=buf, value=ptr+1 として設定
5. **行1564**: *count = cnt で最終件数を設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | util.c | `src/win/util.c` | uv_os_environ() 関数（行1218-1286）: GetEnvironmentStringsW による環境変数取得 |

**主要処理フロー（Windows）**:
1. **行1227**: GetEnvironmentStringsW() で環境変数のワイド文字列ブロックを取得
2. **行1231**: ダブルNULLまでの要素数をカウント
3. **行1233**: uv__calloc で配列メモリ確保
4. **行1242-1267**: 各エントリを処理
   - **行1246**: uv__convert_utf16_to_utf8 で UTF-8 変換
   - **行1251**: `strchr(buf + 1, '=')` で分割（先頭の "=" をスキップ）
   - **行1257-1261**: name と value を設定
5. **行1269**: FreeEnvironmentStringsW(env) で Windows リソースを解放

#### Step 4: メモリ解放を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | uv-common.c | `src/uv-common.c` | uv_os_free_environ() 関数（行941-949）: 各エントリの name を解放し、配列自体も解放 |

**主要処理フロー**:
1. **行944-946**: 各 envitems[i].name を uv__free で解放（value は同一バッファのため不要）
2. **行948**: envitems 配列自体を uv__free で解放

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

```
uv_os_environ(uv_env_item_t** envitems, int* count)  [src/unix/core.c:1524]
    |
    +-- environ グローバル変数の走査
    +-- uv__calloc(i, sizeof(*envitems))     [src/uv-common.c:92]
    +-- [各エントリ] uv__strdup(environ[j])  [src/uv-common.c:55]
    +-- strchr(buf, '=')                     [libc]

uv_os_environ(uv_env_item_t** envitems, int* count)  [src/win/util.c:1218]
    |
    +-- GetEnvironmentStringsW()              [Win32 API]
    +-- uv__calloc(i, sizeof(*envitems))      [src/uv-common.c:92]
    +-- [各エントリ] uv__convert_utf16_to_utf8()
    +-- strchr(buf + 1, '=')                  [libc]
    +-- FreeEnvironmentStringsW(env)           [Win32 API]

uv_os_free_environ(uv_env_item_t* envitems, int count)  [src/uv-common.c:941]
    |
    +-- [各エントリ] uv__free(envitems[i].name)
    +-- uv__free(envitems)
```

### データフロー図

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

（なし）       ───> 環境変数テーブル走査     ───> uv_env_item_t[]
                    environ (Unix)               [0] name="PATH", value="..."
                    GetEnvironmentStringsW        [1] name="HOME", value="..."
                    (Windows)                     ...
                    + "=" で分割                  int count = N
                                                 戻り値: 0 または負値
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_env_item_t 構造体定義、API宣言 |
| core.c | `src/unix/core.c` | ソース | Unix向け uv_os_environ() 実装、environ定義 |
| util.c | `src/win/util.c` | ソース | Windows向け uv_os_environ() 実装 |
| uv-common.c | `src/uv-common.c` | ソース | uv_os_free_environ() メモリ解放関数 |
| test-env-vars.c | `test/test-env-vars.c` | テスト | uv_os_environ のテスト |
