# 帳票設計書 16-ファイル統計情報

## 概要

本ドキュメントは、libuvライブラリが提供するファイル統計情報取得機能（uv_fs_stat / uv_fs_lstat / uv_fs_fstat）の帳票設計書である。

### 本帳票の処理概要

uv_fs_stat()、uv_fs_lstat()、uv_fs_fstat() APIは、ファイルのメタデータ（サイズ、パーミッション、タイムスタンプ、リンク数等）をuv_stat_t構造体に出力する関数群である。

**業務上の目的・背景**：ファイル操作を行うアプリケーションにおいて、ファイルの存在確認、サイズの取得、更新日時の確認、パーミッションチェックは基本的な要件である。libuvはPOSIX stat/lstat/fstatに相当する機能をクロスプラットフォームで提供し、非同期実行にも対応している。Node.jsのfs.stat()、fs.lstat()、fs.fstat()はこれらのAPIを通じて実装される。

**帳票の利用シーン**：ファイル存在確認、ファイルサイズ取得、ファイル更新日時の確認、パーミッションチェック、シンボリックリンクの解決、ファイルタイプの判定（通常ファイル/ディレクトリ/シンボリックリンク等）。

**主要な出力内容**：
1. デバイスID（st_dev）
2. ファイルモード/パーミッション（st_mode）
3. ハードリンク数（st_nlink）
4. UID/GID（st_uid, st_gid）
5. ファイルサイズ（st_size）
6. アクセス/更新/変更/作成タイムスタンプ（st_atim, st_mtim, st_ctim, st_birthtim）
7. inode番号（st_ino）
8. ブロックサイズ/ブロック数（st_blksize, st_blocks）

**帳票の出力タイミング**：コールバック（cb）がNULLの場合は同期実行、非NULLの場合はスレッドプール上で非同期実行され、コールバック経由で結果が通知される。

**帳票の利用者**：Node.jsランタイム内部（fs.stat等）、ファイル操作ライブラリ開発者、アプリケーション開発者

## 帳票種別

構造体レポート（uv_stat_t構造体出力型）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | C API呼び出し | N/A | uv_fs_stat() / uv_fs_lstat() / uv_fs_fstat() 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | メモリ上の構造体（uv_stat_t） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（uv_fs_t.statbufに格納） |
| 出力方法 | uv_fs_tリクエスト構造体のstatbufフィールド |
| 文字コード | N/A |

## 帳票レイアウト

### レイアウト概要

uv_stat_t構造体は16個のフィールドで構成される。

```
┌─────────────────────────────────────┐
│  uv_stat_t                          │
├─────────────────────────────────────┤
│  st_dev    : デバイスID             │
│  st_mode   : ファイルモード          │
│  st_nlink  : ハードリンク数          │
│  st_uid    : ユーザーID             │
│  st_gid    : グループID             │
│  st_rdev   : 特殊ファイルデバイスID  │
│  st_ino    : inode番号              │
│  st_size   : ファイルサイズ          │
│  st_blksize: ブロックサイズ          │
│  st_blocks : ブロック数              │
│  st_flags  : フラグ                 │
│  st_gen    : 生成番号               │
│  st_atim   : 最終アクセス時刻       │
│  st_mtim   : 最終更新時刻           │
│  st_ctim   : 最終状態変更時刻       │
│  st_birthtim: 作成時刻              │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | N/A | ヘッダー部は存在しない | N/A | N/A |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | st_dev | デバイスID | stat/statx | uint64_t | 8バイト |
| 2 | st_mode | ファイルモード/パーミッション | stat/statx | uint64_t | 8バイト |
| 3 | st_nlink | ハードリンク数 | stat/statx | uint64_t | 8バイト |
| 4 | st_uid | ファイル所有者UID | stat/statx | uint64_t | 8バイト |
| 5 | st_gid | ファイル所有者GID | stat/statx | uint64_t | 8バイト |
| 6 | st_rdev | 特殊ファイルのデバイスID | stat/statx | uint64_t | 8バイト |
| 7 | st_ino | inode番号 | stat/statx | uint64_t | 8バイト |
| 8 | st_size | ファイルサイズ（バイト） | stat/statx | uint64_t | 8バイト |
| 9 | st_blksize | 推奨I/Oブロックサイズ | stat/statx | uint64_t | 8バイト |
| 10 | st_blocks | 割当済みブロック数（512byte単位） | stat/statx | uint64_t | 8バイト |
| 11 | st_flags | フラグ（BSD系） | stat | uint64_t | 8バイト |
| 12 | st_gen | 生成番号（BSD系） | stat | uint64_t | 8バイト |
| 13 | st_atim | 最終アクセス時刻 | stat/statx | uv_timespec_t | 16バイト |
| 14 | st_mtim | 最終更新時刻 | stat/statx | uv_timespec_t | 16バイト |
| 15 | st_ctim | 最終状態変更時刻 | stat/statx | uv_timespec_t | 16バイト |
| 16 | st_birthtim | 作成時刻 | statx（Linux）/ stat（macOS） | uv_timespec_t | 16バイト |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | N/A | フッター部は存在しない | N/A | N/A |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| path（stat/lstat） | 対象ファイルパス | Yes（stat/lstat時） |
| file（fstat） | 対象ファイルディスクリプタ | Yes（fstat時） |
| loop | イベントループ | Yes |
| cb | コールバック関数（NULLで同期実行） | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| N/A | N/A | 単一ファイルの情報 |

### 改ページ条件

改ページは発生しない（単一構造体の返却）。

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A | ファイルシステムを直接参照 | N/A |

### テーブル別参照項目詳細

#### API別の動作差異

| API | 対象 | シンボリックリンクの扱い | 備考 |
|-----|------|----------------------|------|
| uv_fs_stat | パスで指定されたファイル | リンク先をたどる | stat()相当 |
| uv_fs_lstat | パスで指定されたファイル | リンク自体の情報を返す | lstat()相当 |
| uv_fs_fstat | FDで指定されたファイル | N/A（FD経由） | fstat()相当 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| st_atim等のtv_sec | statの該当フィールドをそのまま変換 | なし | uv__to_stat()で変換 |
| st_atim等のtv_nsec | statの該当フィールドをそのまま変換 | なし | ナノ秒精度 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_fs_stat/lstat/fstat 呼び出し] --> B{cbがNULL?}
    B -->|Yes 同期| C[uv__fs_stat/lstat/fstat 直接呼び出し]
    B -->|No 非同期| D[スレッドプールにタスク投入]
    D --> E[ワーカースレッドでuv__fs_work実行]
    E --> C
    C --> F{Linux?}
    F -->|Yes| G[statxシステムコール試行]
    G --> H{statx成功?}
    H -->|Yes| I[statx結果をuv_stat_tに変換]
    H -->|No ENOSYS| J[stat/lstatにフォールバック]
    J --> K[uv__to_stat で変換]
    F -->|No| L[stat/lstat/fstat呼び出し]
    L --> K
    I --> M[結果をuv_fs_t.statbufに格納]
    K --> M
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| UV_ENOENT | ファイルが存在しない | なし | req->resultに負のエラーコード |
| UV_EACCES | パーミッション不足 | なし | req->resultに負のエラーコード |
| UV_EINVAL | 不正な引数 | なし | req->resultに負のエラーコード |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1件（単一ファイルの情報） |
| 目標出力時間 | ミリ秒オーダー（ファイルシステムI/O依存） |
| 同時出力数上限 | スレッドプールサイズに依存（デフォルト4スレッド） |

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

ファイルパスに対するアクセス権限はOS側で制御される。ファイルのパーミッション情報（st_mode）が返却されるため、セキュリティ監査での利用も可能。

## 備考

- Linux環境ではstatxシステムコールを優先的に使用する。statxが利用できない場合（ENOSYS）はstat/lstatにフォールバックする。
- uv_stat_tの全フィールドはuint64_t型に統一されており、プラットフォーム間の型の差異を吸収している。
- 結果はuv_fs_t.statbufフィールドに格納され、uv_fs_get_statbuf()でポインタを取得できる。
- 非同期実行後はuv_fs_req_cleanup()で必ずリクエストをクリーンアップする必要がある。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | 363-401行目: uv_timespec_t構造体とuv_stat_t構造体の定義。16フィールドの構造 |
| 1-2 | uv.h | `include/uv.h` | 1458行目: uv_fs_t内のstatbufフィールド |

**読解のコツ**: uv_stat_tのフィールドはすべてuint64_t型であり、POSIX stat構造体の型差異を吸収している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | 1558行目: uv_fs_stat()宣言 |
| 2-2 | uv.h | `include/uv.h` | 1562行目: uv_fs_fstat()宣言 |
| 2-3 | uv.h | `include/uv.h` | 1621行目: uv_fs_lstat()宣言 |
| 2-4 | fs.c (unix) | `src/unix/fs.c` | 2157行目: uv_fs_stat()のUnix実装 |
| 2-5 | fs.c (unix) | `src/unix/fs.c` | 1938行目: uv_fs_lstat()のUnix実装 |
| 2-6 | fs.c (unix) | `src/unix/fs.c` | 1876行目: uv_fs_fstat()のUnix実装 |

**主要処理フロー（uv_fs_stat）**:
1. **2157行目**: INIT(STAT)マクロで初期化
2. **2158行目**: PATHマクロでパスをコピー
3. **2160-2162行目**: cb非NULLならio_uringでstatx試行
4. **2163行目**: POSTマクロで同期/非同期分岐

#### Step 3: 内部実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fs.c (unix) | `src/unix/fs.c` | 1574行目: uv__fs_stat内部関数。statxを試行し、フォールバックでstat()を使用 |
| 3-2 | fs.c (unix) | `src/unix/fs.c` | 1590行目: uv__fs_lstat内部関数 |
| 3-3 | fs.c (unix) | `src/unix/fs.c` | 1606行目: uv__fs_fstat内部関数 |

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

```
uv_fs_stat(loop, req, path, cb)
    │
    ├─ INIT(STAT) → req初期化
    ├─ PATH → パスコピー
    ├─ (非同期) uv__iou_fs_statx() → io_uringでstatx
    └─ POST → uv__fs_work()
           │
           └─ uv__fs_stat(path, &req->statbuf)
                  ├─ uv__fs_statx() → statxシステムコール
                  └─ (フォールバック) stat() → uv__to_stat()
```

### データフロー図

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

path/fd      ───▶  stat/statx/fstat        ───▶  uv_stat_t (16フィールド)
uv_loop_t*          ├─ statx (Linux優先)          └─ req->statbuf
uv_fs_cb            ├─ stat (フォールバック)
                    └─ uv__to_stat (変換)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | uv_stat_t構造体定義（384-401行目）、API宣言 |
| fs.c (unix) | `src/unix/fs.c` | ソース | Unix系実装（stat: 2157行目、lstat: 1938行目、fstat: 1876行目） |
| fs.c (win) | `src/win/fs.c` | ソース | Windows実装 |
