# 機能設計書 106-ファイル所有者変更

## 概要

本ドキュメントは、libuvが提供するファイル所有者変更機能（uv_fs_chown / uv_fs_fchown / uv_fs_lchown）の設計仕様を記載する。

### 本機能の処理概要

ファイルの所有者（UID）およびグループ（GID）を非同期で変更する機能を提供する。パス指定（chown）、ファイルディスクリプタ指定（fchown）、シンボリックリンク非追跡（lchown）の3種類のAPIを備える。

**業務上の目的・背景**：マルチユーザー環境でのファイル所有権管理に必要な機能である。サーバーアプリケーションが特定のユーザー/グループに所有権を変更してアクセス制御を行う場合や、デプロイメントスクリプトでファイルの所有権を適切に設定する場合に使用される。

**機能の利用シーン**：デプロイメント時のファイル所有者設定、プロセスの権限降格後のファイル作成、特定グループへのファイル共有設定、シンボリックリンク自体の所有者変更など。

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

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

**権限による制御**：通常はroot権限（CAP_CHOWN）が必要。一部OSでは所有者がグループ変更のみ可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | ファイルシステム操作 | 主機能 | uv_fs_chown()/fchown()/lchown()による所有者変更のAPI定義 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

**uv_fs_chown / uv_fs_lchown:**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | イベントループ | - |
| req | uv_fs_t* | Yes | FSリクエスト | NULLでUV_EINVAL |
| path | const char* | Yes | 対象パス | assert(path != NULL) |
| uid | uv_uid_t | Yes | ユーザーID | -1で変更しない |
| gid | uv_gid_t | Yes | グループID | -1で変更しない |
| cb | uv_fs_cb | No | コールバック | NULLで同期実行 |

**uv_fs_fchown:**

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | イベントループ | - |
| req | uv_fs_t* | Yes | FSリクエスト | NULLでUV_EINVAL |
| file | uv_file | Yes | ファイルディスクリプタ | 有効なFD |
| uid | uv_uid_t | Yes | ユーザーID | -1で変更しない |
| gid | uv_gid_t | Yes | グループID | -1で変更しない |
| cb | uv_fs_cb | No | コールバック | NULLで同期実行 |

### 入力データソース

ユーザーがAPI呼び出し時に指定するパスまたはFD、UID、GID。

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. INITマクロによるリクエスト初期化
2. パラメータ設定
   └─ chown/lchown: PATH + req->uid + req->gid
   └─ fchown: req->file + req->uid + req->gid
3. POSTマクロによる実行
4. uv__fs_work内で実行
   └─ CHOWN: chown(req->path, req->uid, req->gid)
   └─ FCHOWN: fchown(req->file, req->uid, req->gid)
   └─ LCHOWN: lchown(req->path, req->uid, req->gid)
```

### フローチャート

```mermaid
flowchart TD
    A[API呼び出し] --> B{操作種別}
    B -->|chown| C[INIT + PATH + uid/gid設定]
    B -->|fchown| D[INIT + file + uid/gid設定]
    B -->|lchown| E[INIT + PATH + uid/gid設定]
    C --> F[POST: 実行]
    D --> F
    E --> F
    F --> G[chown/fchown/lchown呼び出し]
    G --> H[result設定]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-601 | 直接システムコール呼び出し | chown/fchown/lchownはPOSIXシステムコールを直接呼び出す | Unix系 |
| BR-602 | lchownのリンク非追跡 | lchownはシンボリックリンク自体の所有者を変更する | lchown呼び出し時 |
| BR-603 | Windowsのchown | WindowsではUID/GIDの概念が異なるため、chown/fchown/lchownはno-opまたはエラー | Windows |

### 計算ロジック

特になし。

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

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

該当なし

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

該当なし

## パフォーマンス要件

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

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

- 所有者変更は通常root権限が必要
- 不適切な所有者設定はファイルへのアクセスを失う原因となりうる
- setuid/setgidファイルの所有者変更にはsetuidビットがクリアされる場合がある

## 備考

- WindowsではUID/GIDの概念が異なるため、この機能は限定的またはno-opとなる
- uid/gidに(uv_uid_t)-1を指定すると、そのフィールドは変更されない（POSIX仕様）

---

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

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

### 推奨読解順序

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | uv_fs_chown()宣言（1662-1667行目） |
| 2-2 | uv.h | `include/uv.h` | uv_fs_fchown()宣言（1668-1673行目） |
| 2-3 | uv.h | `include/uv.h` | uv_fs_lchown()宣言（1674-1679行目） |
| 2-4 | fs.c | `src/unix/fs.c` | uv_fs_chown()実装（1802-1813行目） |
| 2-5 | fs.c | `src/unix/fs.c` | uv_fs_fchown()実装（1838-1849行目） |
| 2-6 | fs.c | `src/unix/fs.c` | uv_fs_lchown()実装（1852-1863行目） |

**主要処理フロー**:
- **1808-1812行目**: chown -- INIT、PATH、uid/gid設定、POST
- **1844-1848行目**: fchown -- INIT、file、uid/gid設定、POST
- **1858-1862行目**: lchown -- INIT、PATH、uid/gid設定、POST

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fs.c | `src/unix/fs.c` | uv__fs_work()内（1701行目）: CHOWN -> chown() |
| 3-2 | fs.c | `src/unix/fs.c` | uv__fs_work()内（1705行目）: FCHOWN -> fchown() |
| 3-3 | fs.c | `src/unix/fs.c` | uv__fs_work()内（1706行目）: LCHOWN -> lchown() |

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

```
uv_fs_chown()
    +-- INIT(CHOWN) + PATH + uid/gid
    +-- POST -> uv__fs_work -> chown(req->path, req->uid, req->gid)

uv_fs_fchown()
    +-- INIT(FCHOWN) + file + uid/gid
    +-- POST -> uv__fs_work -> fchown(req->file, req->uid, req->gid)

uv_fs_lchown()
    +-- INIT(LCHOWN) + PATH + uid/gid
    +-- POST -> uv__fs_work -> lchown(req->path, req->uid, req->gid)
```

### データフロー図

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

path + uid + gid  ------> chown()  --------->  result (0 or error)
file + uid + gid  ------> fchown() --------->  result (0 or error)
path + uid + gid  ------> lchown() --------->  result (0 or error)
```

### 関連ファイル一覧

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