# 画面設計書 34-ファイルシステム

## 概要

libuvユーザーガイドのファイルシステムページ（guide/filesystem.rst）に関する画面設計書。ファイル読み書き操作、バッファとストリーム、ファイル変更イベントの使い方をサンプルコード付きで解説するページの構造と仕様を定義する。

### 本画面の処理概要

本ページはlibuvのファイルシステム操作（uv_fs_*関数群）、ストリームI/O（uv_stream_t）、およびファイル変更通知（uv_fs_event_t）の実践的な使い方を、複数のサンプルプログラムを通じて解説するガイドページである。

**業務上の目的・背景**：ファイルI/Oは多くのシステムプログラムの基本的な要素であり、libuvがスレッドプールを使ってブロッキングファイル操作を非同期化する仕組みを理解することが重要である。本ページではcatコマンドの実装（uvcat）、teeコマンドの実装（uvtee）、ファイル変更監視（onchange）の3つの実践的なサンプルを通じて、非同期ファイルI/OとストリームI/Oの両方のパターンを学習できる。全ファイルシステム関数の一覧も提供される。

**画面へのアクセス方法**：ユーザーガイド一覧（No.31）のtoctreeリンク、または基本事項（No.33）からのNextナビゲーションでアクセスする。URLパスは `/guide/filesystem.html` となる。

**主要な操作・処理内容**：
1. ファイルシステム操作の同期/非同期モードの説明
2. uvcat（catコマンド実装）サンプルの表示と解説 -- uv_fs_open/read/write/close
3. 全ファイルシステム操作関数の一覧表示
4. バッファとストリーム（uv_stream_t）の概念説明
5. uvtee（teeコマンド実装）サンプルの表示と解説 -- uv_pipe_t使用
6. ファイル変更イベント監視の説明とonchangeサンプルの表示

**画面遷移**：
- 遷移元：ユーザーガイド一覧（No.31）、基本事項（No.33）
- 遷移先：ネットワーク（No.35）、プロセス（No.37、パイプの説明から参照）
- 外部リンク：man7.org（open(2)）、libuv公式APIリファレンス

**権限による表示制御**：なし。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 96 | ファイルオープン・クローズ | 主機能 | ファイルオープン・クローズのサンプルコードを使った解説 |
| 97 | ファイル読み書き | 主機能 | catコマンド実装サンプルによるファイル読み書きの解説 |
| 113 | FSリクエストクリーンアップ | 補助機能 | uv_fs_req_cleanup()の使用パターンの説明 |
| 104 | ディレクトリ走査 | 補助機能 | ディレクトリ走査のサンプルコードによる解説 |

## 画面種別

チュートリアル（サンプルコード付き解説）

## URL/ルーティング

- ソースファイル：`docs/src/guide/filesystem.rst`
- 生成先URL：`/guide/filesystem.html`
- Sphinxルーティング：guide.rstのtoctreeから参照

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|-----|------|
| FS操作説明 | 出力 | テキスト | ファイルシステム操作の概要・注意事項 |
| uvcat/main.cコード | 出力 | Cソースコード | catコマンド実装（行番号・ハイライト付き、部分表示） |
| FS操作関数一覧 | 出力 | Cコードブロック | 全uv_fs_*関数のプロトタイプ一覧 |
| ストリーム説明 | 出力 | テキスト/コードブロック | uv_stream_t関連の概念と関数 |
| uvtee/main.cコード | 出力 | Cソースコード | teeコマンド実装（行番号付き、部分表示） |
| onchange/main.cコード | 出力 | Cソースコード | ファイル変更監視サンプル（行番号付き、部分表示） |
| uv_fs_event_flags | 出力 | Cコードブロック | FS_EVENT_WATCH_ENTRY/STAT/RECURSIVEの定義 |

## 表示項目

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| セクションタイトル | "Filesystem" | ページ見出し（h1） |
| NOTEボックス | ファイルシステム操作とソケット操作の違い | スレッドプール使用の注記 |
| Reading/Writing files (h2) | uv_fs_open/close/read/writeの使い方 | uvcat/main.c参照 |
| Filesystem operations (h2) | 全uv_fs_*関数一覧 | 約30関数のプロトタイプ |
| Buffers and Streams (h2) | uv_stream_tとuv_buf_tの概念 | uvtee/main.c参照 |
| File change events (h2) | uv_fs_event_tの使い方 | onchange/main.c参照 |
| WARNINGボックス | ディスク書き込みの保証に関する注意 | 書き込み成功≠ディスクコミット |
| WARNINGボックス | uv_fs_req_cleanup()が必須である旨 | メモリリーク防止 |
| WARNINGボックス | SIGPIPEへの対処に関する注意 | signal(SIGPIPE, SIG_IGN) |
| ERRORボックス | uvteeプログラムの動作不良に関する注記 | 改善が必要な旨の記載 |
| NOTEボックス | onchangeの動作制限に関する注記 | OSX/Windowsのみ動作 |

## イベント仕様

### 1-サンプルコードの部分表示

literalincludeディレクティブの `:lines:` オプションにより、ソースファイルの特定行範囲のみが表示される。`:emphasize-lines:` により重要な行がハイライトされる。

### 2-内部クロスリファレンス

`:doc:networking` によりネットワークページ（No.35）へ、`:doc:processes` によりプロセスページ（No.37）へのクロスリファレンスリンクが生成される。`_buffers-and-streams` ラベルにより他ページからの参照も可能。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 静的HTMLページのため該当なし |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| N-34-01 | 注記 | "The libuv filesystem operations are different from socket operations..." | ページ冒頭 |
| W-34-01 | 警告 | "Due to the way filesystems and disk drives are configured..." | Reading/Writingセクション |
| W-34-02 | 警告 | "The uv_fs_req_cleanup() function must always be called..." | Reading/Writingセクション |
| W-34-03 | 警告 | "If your program is meant to be used with other programs..." | Buffers and Streamsセクション |
| E-34-01 | エラー | "THIS PROGRAM DOES NOT ALWAYS WORK, NEED SOMETHING BETTER" | Buffers and Streamsセクション |
| N-34-02 | 注記 | "Currently this example only works on OSX and Windows." | File change eventsセクション |

## 例外処理

静的HTMLページのため、アプリケーションレベルの例外処理は発生しない。

## 備考

- uvcatサンプルは非同期ファイルI/Oの代表的なパターン（open→read→write→readのループ）を示す。
- uvteeサンプルにはERRORディレクティブで「常に動作するわけではない」旨が記載されており、改善が必要とされている。
- ファイルシステム操作は内部的にブロッキング関数を使用し、スレッドプールで実行される点がソケット操作との重要な違いである。
- `_buffers-and-streams` ラベルはネットワークガイド（No.35）から参照される。
- 脚注として、inotify (Linux)、FSEvents (Darwin)、kqueue (BSDs)、ReadDirectoryChangesW (Windows)、event ports (Solaris) のプラットフォーム別通知機構が記載されている。

---

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

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

### 推奨読解順序

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

uv_fs_t構造体とuv_buf_tバッファの役割を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | filesystem.rst | `docs/src/guide/filesystem.rst` | 行1-24: ファイルシステム操作の基本概念（同期/非同期、スレッドプール） |
| 1-2 | uvcat/main.c | `docs/code/uvcat/main.c` | 行1-14: グローバル変数（uv_fs_t, char buffer[], uv_buf_t）の定義 |

**読解のコツ**: uv_fs_t構造体はFS操作の全てで使用され、resultフィールドに操作結果（FD、読み取りバイト数等）が格納される。同期モードはコールバックにNULLを渡すことで実現される。

#### Step 2: uvcat（catコマンド）の処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uvcat/main.c | `docs/code/uvcat/main.c` | 行54-62: main関数 -- uv_fs_openでファイルオープン |
| 2-2 | uvcat/main.c | `docs/code/uvcat/main.c` | 行40-52: on_openコールバック -- result >= 0で読み取り開始 |
| 2-3 | uvcat/main.c | `docs/code/uvcat/main.c` | 行25-38: on_readコールバック -- result判定で書き込みorクローズ |
| 2-4 | uvcat/main.c | `docs/code/uvcat/main.c` | 行16-23: on_writeコールバック -- 次の読み取りへ |

**主要処理フロー**:
1. **行55**: `uv_fs_open(uv_default_loop(), &open_req, argv[1], O_RDONLY, 0, on_open)` -- ファイルオープン
2. **行44-47**: `on_open` -- resultがFDの場合、uv_buf_initでバッファ初期化しuv_fs_readを呼び出し
3. **行34-36**: `on_read` -- result > 0 の場合、uv_fs_writeでstdoutへ書き込み
4. **行29-32**: `on_read` -- result == 0 (EOF) の場合、uv_fs_closeで同期クローズ
5. **行21**: `on_write` -- 書き込み成功後、uv_fs_readで次のブロックを読み取り
6. **行58-60**: main末尾 -- uv_fs_req_cleanup()で全リクエストをクリーンアップ

#### Step 3: uvtee（ストリームI/O）の処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | uvtee/main.c | `docs/code/uvtee/main.c` | 行62-80: main関数 -- パイプ初期化とstdin読み取り開始 |
| 3-2 | uvtee/main.c | `docs/code/uvtee/main.c` | 行44-60: read_stdinコールバック -- nread判定と2つのwrite_data呼び出し |
| 3-3 | uvtee/main.c | `docs/code/uvtee/main.c` | 行23-42: write_data関数 -- バッファコピーと非同期書き込み |

#### Step 4: onchange（ファイル変更イベント）の処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | onchange/main.c | `docs/code/onchange/main.c` | 行26-44: main関数 -- uv_fs_event_init/start でファイル監視設定 |
| 4-2 | onchange/main.c | `docs/code/onchange/main.c` | 行9-24: run_commandコールバック -- UV_RENAME/UV_CHANGEの判定とコマンド実行 |

**主要処理フロー**:
1. **行37-38**: `uv_fs_event_init(loop, fs_event_req)` -- FSイベントハンドル初期化
2. **行40**: `uv_fs_event_start(fs_event_req, run_command, argv[argc], UV_FS_EVENT_RECURSIVE)` -- 監視開始
3. **行13**: `uv_fs_event_getpath(handle, path, &size)` -- 監視対象パス取得
4. **行17-20**: UV_RENAME / UV_CHANGE のイベント種別判定
5. **行23**: `system(command)` -- 指定コマンドの実行

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

```
uvcat/main.c
    |
    +-- uv_fs_open() --> on_open()
    |                       |
    |                       +-- uv_buf_init()
    |                       +-- uv_fs_read() --> on_read()
    |                                              |
    |                                              +-- [result > 0] uv_fs_write() --> on_write()
    |                                              |                                     |
    |                                              |                                     +-- uv_fs_read() [ループ]
    |                                              +-- [result == 0] uv_fs_close() [同期]
    +-- uv_run()
    +-- uv_fs_req_cleanup() x3

onchange/main.c
    |
    +-- uv_fs_event_init()
    +-- uv_fs_event_start(run_command, file, UV_FS_EVENT_RECURSIVE)
    |       +-- run_command() [コールバック]
    |               +-- uv_fs_event_getpath()
    |               +-- system(command)
    +-- uv_run()
```

### データフロー図

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

ファイル (argv[1])       --> uv_fs_open()                --> FD取得
FD + バッファ            --> uv_fs_read()                --> 読み取りデータ
読み取りデータ           --> uv_fs_write(stdout)         --> 標準出力
EOF                      --> uv_fs_close()               --> FDクローズ

ファイルパス(監視対象)   --> uv_fs_event_start()         --> イベント通知
イベント通知             --> run_command()                --> system()実行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| filesystem.rst | `docs/src/guide/filesystem.rst` | テンプレート | ファイルシステムガイドページ本体 |
| guide.rst | `docs/src/guide.rst` | テンプレート | 親ページ（toctreeで参照） |
| uvcat/main.c | `docs/code/uvcat/main.c` | ソース | catコマンド実装サンプル |
| uvtee/main.c | `docs/code/uvtee/main.c` | ソース | teeコマンド実装サンプル |
| onchange/main.c | `docs/code/onchange/main.c` | ソース | ファイル変更監視サンプル |
| conf.py | `docs/src/conf.py` | 設定 | Sphinxビルド設定 |
