# 機能設計書 161-作業ディレクトリ制御

## 概要

本ドキュメントは、libuv の `uv_cwd()` および `uv_chdir()` APIによるカレントワーキングディレクトリ（CWD）の取得・変更機能について記述する。

### 本機能の処理概要

本機能はプロセスの作業ディレクトリ（カレントディレクトリ）を取得および変更するためのクロスプラットフォームAPIを提供する。

**業務上の目的・背景**：アプリケーションがファイルシステム上の相対パスを解決する際、カレントディレクトリは基準点となる。libuvを使用するアプリケーション（Node.js等）では、プロセスの作業ディレクトリを動的に取得・変更する必要があるため、OSのAPIの差異を吸収するラッパーが必要となる。

**機能の利用シーン**：アプリケーション起動時の作業ディレクトリ確認、ユーザー指定のディレクトリへの変更、相対パスの解決に必要なベースディレクトリの取得、CLIツールにおけるカレントディレクトリベースのファイル操作などに利用される。

**主要な処理内容**：
1. `uv_cwd()`: POSIXの`getcwd()`を呼び出し、カレントディレクトリのパスを取得する
2. `uv_chdir()`: POSIXの`chdir()`を呼び出し、カレントディレクトリを指定パスに変更する
3. バッファサイズ不足時はスクラッチバッファを使って必要サイズを算出し`UV_ENOBUFS`を返す
4. 末尾スラッシュの除去（ルートディレクトリを除く）

**関連システム・外部連携**：OS標準ライブラリ（POSIX `getcwd()`/`chdir()`、Windows `GetCurrentDirectoryW()`/`SetCurrentDirectoryW()`）を使用する。

**権限による制御**：特に権限による制御はない。ただし、`uv_chdir()`で指定するディレクトリに対するアクセス権がない場合はエラーとなる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_cwd()/chdir()によるカレントディレクトリ制御のAPI定義 |

## 機能種別

システム情報取得・設定

## 入力仕様

### 入力パラメータ

#### uv_cwd()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| buffer | char* | Yes | 取得したパスを格納するバッファ | NULLでないこと |
| size | size_t* | Yes | バッファサイズ（入出力パラメータ） | NULLでないこと、*size > 0 |

#### uv_chdir()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dir | const char* | Yes | 変更先ディレクトリパス | 有効なディレクトリパスであること |

### 入力データソース

OS（POSIXシステムコール）

## 出力仕様

### 出力データ

#### uv_cwd()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時0、エラー時負のエラーコード |
| buffer | char* | カレントディレクトリのパス文字列（末尾スラッシュなし） |
| *size | size_t | パス文字列の長さ（NULL終端を含まない） |

#### uv_chdir()

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

### 出力先

呼び出し元に直接返却

## 処理フロー

### 処理シーケンス

```
uv_cwd():
1. 入力バリデーション
   └─ buffer, size, *size が無効な場合 UV_EINVAL を返却
2. getcwd()でユーザーバッファに直接読み込み
   └─ 成功した場合はfixupへ
3. ERANGE（バッファ不足）の場合、スクラッチバッファ（UV__PATH_MAX+1）で再取得
   └─ 失敗した場合はシステムエラーを返却
4. fixup: パスの長さを計算
   └─ 末尾スラッシュがある場合は除去（ルートディレクトリ"/"を除く）
5. スクラッチバッファ使用時は必要サイズを返却しUV_ENOBUFS

uv_chdir():
1. chdir()を呼び出し
   └─ 失敗時はerrnoベースのエラーコードを返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_cwd呼び出し] --> B{buffer/size有効?}
    B -->|No| C[UV_EINVAL返却]
    B -->|Yes| D[getcwd buffer, *size]
    D -->|成功| E[fixup処理]
    D -->|失敗| F{errno == ERANGE?}
    F -->|No| G[UV__ERR errno 返却]
    F -->|Yes| H[getcwd scratch, sizeof scratch]
    H -->|成功| I[buffer = scratch]
    H -->|失敗| G
    I --> E
    E --> J[末尾スラッシュ除去]
    J --> K{スクラッチバッファ使用?}
    K -->|Yes| L[*size = len+1, UV_ENOBUFS返却]
    K -->|No| M[return 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 末尾スラッシュ除去 | パスの長さが1より大きく末尾がスラッシュの場合、スラッシュを除去する | uv_cwd()成功時 |
| BR-02 | バッファ不足処理 | ユーザーバッファが不足している場合、必要サイズを返してUV_ENOBUFSを返す | getcwd()がERANGEを返した場合 |

### 計算ロジック

該当なし

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | バリデーションエラー | buffer/sizeがNULL、または*sizeが0 | 有効なパラメータを指定する |
| UV_ENOBUFS | バッファ不足 | バッファサイズが不足 | *sizeに返却された必要サイズ以上のバッファを確保して再呼び出し |
| UV_EACCES | 権限エラー | ディレクトリへのアクセス権がない | 適切な権限で実行する |
| UV_ENOENT | 存在しない | 指定ディレクトリが存在しない（chdir時） | 存在するディレクトリを指定する |

### リトライ仕様

UV_ENOBUFS の場合、返却された*sizeに基づきバッファを再確保して再呼び出しする。

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

該当なし

## パフォーマンス要件

OSシステムコールの直接ラッパーであり、特段のパフォーマンス要件はない。

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

- `uv_chdir()` はプロセス全体に影響するため、マルチスレッド環境では注意が必要
- ディレクトリアクセス権のチェックはOS側で行われる

## 備考

- Unix環境では `uv_cwd()` 内部でスクラッチバッファとして `UV__PATH_MAX + 1` バイトのスタック変数を使用する
- 末尾スラッシュの除去は、ルートディレクトリ "/" の場合は行わない（長さが1の場合はスキップ）

---

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

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

### 推奨読解順序

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

本機能で使用する固有のデータ構造は特にない。標準Cの `char*` バッファと `size_t` でやり取りする。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | L1827-1829: uv_cwd()/uv_chdir()のAPI宣言を確認 |

**読解のコツ**: `size_t* size` は入出力パラメータであり、入力時はバッファサイズ、出力時は実際のパス長（またはUV_ENOBUFS時は必要サイズ）を返す点に注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | L753-789: uv_cwd()のUnix実装 |
| 2-2 | core.c | `src/unix/core.c` | L792-797: uv_chdir()のUnix実装 |

**主要処理フロー**:
1. **753-757行目**: 入力パラメータのバリデーション
2. **760-761行目**: ユーザーバッファへの直接getcwd()呼び出し
3. **763-764行目**: ERANGE以外のエラー処理
4. **769-770行目**: スクラッチバッファ(UV__PATH_MAX+1)でのgetcwd()再試行
5. **776-786行目**: fixup処理（末尾スラッシュ除去、バッファ不足時のサイズ返却）
6. **792-797行目**: uv_chdir()はchdir()の単純ラッパー

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | util.c | `src/win/util.c` | Windows固有の実装（GetCurrentDirectoryW/SetCurrentDirectoryW使用） |

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

```
uv_cwd() [src/unix/core.c:753]
    |
    +-- getcwd() [POSIX]
    |      +-- (成功) -> fixup処理
    |      +-- (ERANGE) -> getcwd() with scratch buffer
    |                         +-- (成功) -> fixup処理 -> UV_ENOBUFS
    |                         +-- (失敗) -> UV__ERR(errno)
    +-- strlen() -> 末尾スラッシュ除去

uv_chdir() [src/unix/core.c:792]
    |
    +-- chdir() [POSIX]
           +-- (成功) -> return 0
           +-- (失敗) -> UV__ERR(errno)
```

### データフロー図

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

buffer (char*)     ───> getcwd() でCWDを取得       ───> buffer にパスを格納
size (size_t*)     ───> 末尾スラッシュ除去           ───> *size にパス長を格納
                        バッファ不足判定              ───> 戻り値 (0 or エラー)

dir (const char*)  ───> chdir() でCWD変更           ───> 戻り値 (0 or エラー)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（L1827-1829） |
| core.c | `src/unix/core.c` | ソース | Unix実装（L753-797） |
| util.c | `src/win/util.c` | ソース | Windows実装 |
