# 機能設計書 105-ファイル権限変更

## 概要

本ドキュメントは、libuvが提供するファイル権限変更機能（uv_fs_chmod / uv_fs_fchmod）の設計仕様を記載する。

### 本機能の処理概要

ファイルまたはディレクトリのパーミッション（アクセス権限）を非同期で変更する機能を提供する。パス指定（chmod）とファイルディスクリプタ指定（fchmod）の2種類のAPIを備える。

**業務上の目的・背景**：ファイルのアクセス制御はセキュリティの基本的な要素である。新規作成したファイルの権限を適切に設定したり、既存ファイルの権限を変更して機密性を確保したりする場面で使用される。サーバーアプリケーションではログファイルや設定ファイルの権限管理が特に重要である。

**機能の利用シーン**：ファイル作成後のパーミッション設定、設定ファイルの読み取り専用化、実行権限の付与・削除、セキュリティポリシーに基づくアクセス制御の適用など。

**主要な処理内容**：
1. リクエスト構造体を初期化し、対象パスまたはFDとモードを設定する
2. 同期/非同期モードに応じてchmod()またはfchmod()を呼び出す
3. 結果をreq->resultに設定する

**関連システム・外部連携**：POSIXのchmod()/fchmod()システムコール。

**権限による制御**：ファイル所有者またはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | ファイルシステム操作 | 主機能 | uv_fs_chmod()/fchmod()によるパーミッション変更のAPI定義 |

## 機能種別

データ更新処理（ファイルメタデータの変更）

## 入力仕様

### 入力パラメータ

**uv_fs_chmod:**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | イベントループ | - |
| req | uv_fs_t* | Yes | FSリクエスト | NULLでUV_EINVAL |
| path | const char* | Yes | 対象パス | assert(path != NULL) |
| mode | int | Yes | パーミッション（0755等） | POSIXモードビット |
| cb | uv_fs_cb | No | コールバック | NULLで同期実行 |

**uv_fs_fchmod:**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | イベントループ | - |
| req | uv_fs_t* | Yes | FSリクエスト | NULLでUV_EINVAL |
| file | uv_file | Yes | ファイルディスクリプタ | 有効なFD |
| mode | int | Yes | パーミッション | POSIXモードビット |
| cb | uv_fs_cb | No | コールバック | NULLで同期実行 |

### 入力データソース

ユーザーがAPI呼び出し時に指定するパスまたはFDとモード値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | ssize_t | 成功時0、失敗時は負のエラーコード |

### 出力先

uv_fs_t構造体のresultフィールド。

## 処理フロー

### 処理シーケンス

```
1. INITマクロによるリクエスト初期化
   └─ chmod: fs_type = UV_FS_CHMOD
   └─ fchmod: fs_type = UV_FS_FCHMOD
2. パラメータ設定
   └─ chmod: PATHマクロ + req->mode
   └─ fchmod: req->file + req->mode
3. POSTマクロによる実行
4. uv__fs_work内で実行
   └─ CHMOD: chmod(req->path, req->mode)
   └─ FCHMOD: fchmod(req->file, req->mode)
```

### フローチャート

```mermaid
flowchart TD
    A[API呼び出し] --> B{chmod/fchmod}
    B -->|chmod| C[INIT + PATH + mode設定]
    B -->|fchmod| D[INIT + file + mode設定]
    C --> E[POST: 実行]
    D --> E
    E --> F{cb != NULL?}
    F -->|Yes| G[スレッドプール投入]
    F -->|No| H[同期実行]
    G --> I[chmod/fchmod呼び出し]
    H --> I
    I --> J[result設定]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-501 | 直接システムコール呼び出し | chmodとfchmodはPOSIXシステムコールを直接呼び出す（内部ラッパーなし） | Unix系 |
| BR-502 | 同期・非同期モード | cbがNULLなら同期、非NULLなら非同期 | 常時 |

### 計算ロジック

特になし。

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

### 操作別データベース影響一覧

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | パラメータエラー | reqがNULL | 有効なリクエスト構造体を渡す |
| UV_ENOENT | ファイル不在 | 指定パスが存在しない | パスの正当性を確認する |
| UV_EACCES | 権限エラー | ファイル所有者でなくroot権限もない | 権限を確認する |
| UV_EPERM | 操作不許可 | 操作が許可されていない | 権限を確認する |
| UV_EBADF | 不正FD | fchmodに無効なFDが渡された | 有効なFDを確認する |

### リトライ仕様

EINTRで中断された場合、自動リトライされる。

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

該当なし（アトミック操作）

## パフォーマンス要件

システムコール1回で完了するため、特にパフォーマンス上の懸念はない。

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

- 権限変更は所有者またはroot（CAP_FOWNER）のみ実行可能
- 不適切なパーミッション設定はセキュリティホールとなりうるため、アプリケーション側で適切なモード値を検証すべき
- setuid/setgidビットの不正設定に注意

## 備考

- Windowsでは権限モデルが異なるため、chmodの動作が制限される
- シンボリックリンクの権限変更にはlchmodが必要だが、libuvでは未提供

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_fs_t構造体（1450-1460行目）。mode、file、pathフィールド |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | uv_fs_chmod()宣言（1596-1600行目） |
| 2-2 | uv.h | `include/uv.h` | uv_fs_fchmod()宣言（1657-1661行目） |
| 2-3 | fs.c | `src/unix/fs.c` | uv_fs_chmod()実装（1790-1799行目）。INIT(CHMOD)/PATH/mode/POST |
| 2-4 | fs.c | `src/unix/fs.c` | uv_fs_fchmod()実装（1826-1835行目）。INIT(FCHMOD)/file/mode/POST |

**主要処理フロー**:
- **1795-1798行目**: chmod -- INIT、PATH、req->mode設定、POST
- **1831-1834行目**: fchmod -- INIT、req->file、req->mode設定、POST

#### Step 3: ディスパッチャを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fs.c | `src/unix/fs.c` | uv__fs_work()内（1700行目）: CHMOD -> chmod(req->path, req->mode) |
| 3-2 | fs.c | `src/unix/fs.c` | uv__fs_work()内（1704行目）: FCHMOD -> fchmod(req->file, req->mode) |

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

```
uv_fs_chmod()
    +-- INIT(CHMOD) + PATH + req->mode
    +-- POST -> uv__fs_work -> chmod(req->path, req->mode)

uv_fs_fchmod()
    +-- INIT(FCHMOD) + req->file + req->mode
    +-- POST -> uv__fs_work -> fchmod(req->file, req->mode)
```

### データフロー図

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

path + mode  -------> chmod()  -------->  result (0 or error)
file + mode  -------> fchmod() -------->  result (0 or error)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言 |
| fs.c | `src/unix/fs.c` | ソース | Unix系のchmod/fchmod実装 |
| fs.c | `src/win/fs.c` | ソース | Windows版実装 |
