# 機能設計書 80-ファイル操作

## 概要

本ドキュメントは、FreeBSDの基本ファイル操作コマンド群（cp, mv, rm, ln, mkdir, rmdir, ls）の機能設計について記述する。これらのコマンドはファイルシステム上のファイルやディレクトリの作成・コピー・移動・削除・一覧表示といった基本操作を提供する。

### 本機能の処理概要

**業務上の目的・背景**：ファイル操作はUNIXシステムの最も基本的な機能であり、ユーザの日常作業からスクリプトによる自動処理まで、あらゆる場面で使用される。POSIX準拠の標準的なファイル操作コマンドとして、移植性と信頼性が求められる。

**機能の利用シーン**：ファイルのコピー（cp）、移動・名前変更（mv）、削除（rm）、リンク作成（ln）、ディレクトリ作成（mkdir）、ディレクトリ削除（rmdir）、ファイル一覧表示（ls）。

**主要な処理内容**：
1. cp(8): ファイル/ディレクトリのコピー。再帰コピー、メタデータ保持、ハードリンク/シンボリックリンクコピー対応
2. mv(1): ファイル/ディレクトリの移動・名前変更。同一FS内はrename(2)、異なるFS間はコピー+削除
3. rm(1): ファイル/ディレクトリの削除。再帰削除、確認プロンプト対応
4. ln(1): ハードリンク/シンボリックリンクの作成
5. mkdir(1): ディレクトリの作成。-pによる中間ディレクトリ自動作成
6. rmdir(1): 空ディレクトリの削除
7. ls(1): ファイル/ディレクトリ一覧の表示。ソート、カラー出力、詳細表示対応

**関連システム・外部連携**：stat(2)/lstat(2)によるファイル情報取得、rename(2)によるファイル移動、unlink(2)/rmdir(2)によるファイル削除、fts(3)によるディレクトリトラバーサル、copy_file_range(2)による効率的なファイルコピー。

**権限による制御**：各操作はファイル/ディレクトリのパーミッションに従う。root権限では追加の保護（immutableフラグ等）が適用される場合がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （画面なし） | - | コマンドラインツールであり直接的な画面UIを持たない |

## 機能種別

ファイルシステム操作 / CRUD操作

## 入力仕様

### 入力パラメータ（cp）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -a | フラグ | No | アーカイブモード（-RpP相当） | なし |
| -f | フラグ | No | 強制上書き（-iと排他） | なし |
| -i | フラグ | No | 上書き前に確認（-fと排他） | なし |
| -L | フラグ | No | シンボリックリンクをたどる | なし |
| -l | フラグ | No | コピーの代わりにハードリンク作成 | なし |
| -n | フラグ | No | 既存ファイルを上書きしない | なし |
| -P | フラグ | No | シンボリックリンクをたどらない | なし |
| -p | フラグ | No | メタデータ（所有者、パーミッション、タイムスタンプ）を保持 | なし |
| -R/-r | フラグ | No | 再帰コピー | なし |
| -s | フラグ | No | コピーの代わりにシンボリックリンク作成 | なし |
| -v | フラグ | No | 詳細表示 | なし |
| -x | フラグ | No | ファイルシステム境界をまたがない | なし |
| source | パス | Yes | コピー元ファイル/ディレクトリ | 存在すること |
| target | パス | Yes | コピー先 | なし |

### 入力パラメータ（ls）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -a | フラグ | No | ドットファイル含む全エントリ表示 | なし |
| -l | フラグ | No | 詳細表示（パーミッション、所有者、サイズ等） | なし |
| -R | フラグ | No | 再帰的にサブディレクトリも表示 | なし |
| -t | フラグ | No | 更新時刻順ソート | なし |
| -r | フラグ | No | ソート順を逆順にする | なし |
| -h | フラグ | No | サイズを人間可読形式で表示 | なし |
| -S | フラグ | No | サイズ順ソート | なし |
| --color | 文字列 | No | カラー出力（auto/always/never） | なし |
| file | パス | No | 表示対象（省略時はカレントディレクトリ） | なし |

### 入力データソース

- コマンドライン引数（ソース・ターゲットパス）
- ファイルシステム（ファイルメタデータ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| コピー先ファイル | ファイル | cp: コピーされたファイル |
| 移動先ファイル | ファイル | mv: 移動されたファイル |
| ファイル一覧 | テキスト | ls: ファイル/ディレクトリの一覧 |

### 出力先

- ファイルシステム（cp, mv, ln, mkdir）
- 標準出力（ls）

## 処理フロー

### 処理シーケンス

```
cp:
1. オプション解析
   └─ -a/-f/-i/-l/-n/-p/-R/-s/-v/-x等
2. 操作モード判定
   └─ FILE_TO_FILE / FILE_TO_DIR / DIR_TO_DNE
3. fts(3)によるソースファイルトラバーサル
   └─ ディレクトリ構造を走査
4. 各ファイルのコピー
   └─ copy_file_range(2)またはread/write、メタデータ設定

ls:
1. オプション解析
   └─ -a/-l/-R/-t/-r/-h等
2. fts(3)によるディレクトリトラバーサル
   └─ ソート順に従ったファイル一覧取得
3. 表示処理
   └─ カラム整形、詳細情報、カラー表示
```

### フローチャート

```mermaid
flowchart TD
    A[cpコマンド起動] --> B[オプション解析]
    B --> C{操作モード判定}
    C -->|FILE_TO_FILE| D[単一ファイルコピー]
    C -->|FILE_TO_DIR| E[複数ファイルをディレクトリにコピー]
    C -->|DIR_TO_DNE| F[ディレクトリ構造のコピー]
    D --> G[copy関数]
    E --> G
    F --> G
    G --> H[ftsによるトラバーサル]
    H --> I{エントリ種別}
    I -->|通常ファイル| J[copy_file_range/read-write]
    I -->|ディレクトリ| K[mkdirで作成]
    I -->|シンボリックリンク| L[symlink/readlink]
    I -->|ハードリンク| M[link]
    J --> N{-p指定?}
    N -->|Yes| O[メタデータ設定]
    N -->|No| P[完了]
    O --> P
    K --> H
    L --> P
    M --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-80-01 | 上書き保護 | -n指定時は既存ファイルを上書きしない | cp -n, mv -n |
| BR-80-02 | 確認プロンプト | -i指定時は上書き前にユーザに確認 | cp -i, rm -i, mv -i |
| BR-80-03 | 再帰処理 | -R指定時はfts(3)でディレクトリ構造を再帰的に処理 | cp -R, rm -r |
| BR-80-04 | FS境界 | -x指定時はファイルシステム境界をまたがない | cp -x |
| BR-80-05 | rename最適化 | mv時、同一FS内ではrename(2)で高速移動、異なるFS間はコピー+削除 | mvコマンド |
| BR-80-06 | lsソート | デフォルトはファイル名辞書順、-tで時刻順、-Sでサイズ順 | lsコマンド |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベースは使用しない |

### テーブル別操作詳細

該当なし。ファイルシステムに直接操作する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | ファイル未検出 | ソースファイルが存在しない | エラーメッセージ出力 |
| 1 | 権限エラー | パーミッション不足 | エラーメッセージ出力 |
| 1 | ディスク容量不足 | コピー先の容量不足 | エラーメッセージ出力 |
| 1 | 同一ファイル | ソースとターゲットが同一 | エラーメッセージ出力 |
| 1 | ディレクトリ非空 | rmdir対象が空でない | エラーメッセージ出力 |

### リトライ仕様

リトライは行わない。

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

ファイル操作はアトミックではない。特にcp -Rやrm -rの再帰操作中に中断した場合、部分的な状態が残る。mvのrename(2)は同一FS内ではアトミック。

## パフォーマンス要件

- copy_file_range(2)によるカーネル空間でのファイルコピー最適化（ユーザ空間バッファを経由しない）
- fts(3)による効率的なディレクトリトラバーサル
- lsのカラム表示は端末幅に基づく自動レイアウト

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

- rm -rfの誤用によるデータ消失リスク（root権限での "/" 削除は特に危険）
- シンボリックリンクのたどり方（-L/-P）によるセキュリティリスク（symlink attack）
- cpの-pオプションによるsetuid/setgidビットのコピーに注意
- SIGINFOシグナル（Ctrl+T）によるコピー進捗表示をサポート

## 備考

- cpはlong optionsをサポート（--archive, --force, --interactive等）
- lsはCOLORLS定義時にtermcapベースのカラー出力をサポート
- cpのsort オプション（--sort）によるコピー順序制御が可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | extern.h | `bin/cp/extern.h` | PATH_T構造体（コピー先パス管理）、フラグ変数（Nflag, fflag等）を理解する |
| 1-2 | ls.h | `bin/ls/ls.h` | ls固有のデータ構造を理解する |

**読解のコツ**: cpはPATH_T構造体でコピー先パスを管理し、fts(3)でソースファイルを走査する。enum op（FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE）が操作モードを定義する。フラグ変数はグローバルに宣言されている（cp.c 73行目）。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cp.c | `bin/cp/cp.c` | main関数のオプション解析、操作モード判定（FILE_TO_FILE/FILE_TO_DIR/DIR_TO_DNE）、copy関数の呼び出しを理解する |
| 2-2 | utils.c | `bin/cp/utils.c` | copy_file関数（実際のファイルコピー処理）を理解する |

**主要処理フロー**:
1. **69-72行目**: PATH_T to構造体（コピー先パス管理）
2. **73行目**: グローバルフラグ変数（Nflag, fflag, iflag等）
3. **77行目**: enum op（FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE）
4. **86-100行目**: long_opts配列（--archive, --force等のlong options定義）

#### Step 3: lsのエントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ls.c | `bin/ls/ls.c` | main関数のオプション解析、traverse/display/mastercmp関数を理解する |
| 3-2 | print.c | `bin/ls/print.c` | ファイル情報の表示処理を理解する |
| 3-3 | util.c | `bin/ls/util.c` | ユーティリティ関数群を理解する |
| 3-4 | cmp.c | `bin/ls/cmp.c` | ソート比較関数群を理解する |

**主要処理フロー**:
1. **69行目**: STRBUF_SIZEOF(t)マクロ（数値表示用バッファサイズ計算）
2. **86-88行目**: display/mastercmp/traverse関数プロトタイプ
3. **90-100行目**: GRP_NONE/GRP_DIR_FIRST/GRP_DIR_LAST列挙型、BIN_OPT/COLOR_OPT/GROUP_OPT列挙型

#### Step 4: mv/rm/ln/mkdir/rmdirを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mv.c | `bin/mv/mv.c` | rename(2)優先、失敗時のコピー+削除フォールバックを理解する |
| 4-2 | rm.c | `bin/rm/rm.c` | fts(3)による再帰削除、確認プロンプト処理を理解する |

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

```
cp (bin/cp/cp.c)
    |
    +-- main()
          +-- copy()                    # メインコピー処理
                +-- fts_open/read       # ディレクトリトラバーサル
                +-- copy_file()         # ファイルコピー [utils.c]
                      +-- copy_file_range(2) # カーネルコピー
                      +-- chown/chmod   # メタデータ設定 (-p時)

ls (bin/ls/ls.c)
    |
    +-- main()
          +-- traverse()               # ディレクトリ走査
          |     +-- fts_open/read      # ftsトラバーサル
          +-- display()                # エントリ表示
          |     +-- printlong()        # 詳細表示 [print.c]
          |     +-- printcol()         # カラム表示 [print.c]
          +-- mastercmp()              # ソート比較 [cmp.c]

mv (bin/mv/mv.c)
    +-- rename(2)                      # 同一FS内の高速移動
    +-- (失敗時) cp + rm              # 異なるFS間のフォールバック

rm (bin/rm/rm.c)
    +-- fts_open/read                  # 再帰走査
    +-- unlink(2) / rmdir(2)          # ファイル/ディレクトリ削除
```

### データフロー図

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

ソースファイル          cp:                            コピー先ファイル
(パス指定) ----------> fts走査 --> copy_file_range --> (ファイルシステム)

ソースファイル          mv:                            移動先ファイル
(パス指定) ----------> rename(2) or cp+rm -----------> (ファイルシステム)

ターゲットファイル      rm:                            (ファイル削除)
(パス指定) ----------> fts走査 --> unlink/rmdir -----> (ファイルシステム)

ディレクトリパス        ls:                            ファイル一覧
(パス指定) ----------> fts走査 --> display -----------> (標準出力)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cp.c | `bin/cp/cp.c` | ソース | cpコマンドのメイン処理 |
| utils.c | `bin/cp/utils.c` | ソース | cpのファイルコピー実装 |
| extern.h | `bin/cp/extern.h` | ヘッダ | cpの外部定義（PATH_T等） |
| mv.c | `bin/mv/mv.c` | ソース | mvコマンドのメイン処理 |
| rm.c | `bin/rm/rm.c` | ソース | rmコマンドのメイン処理 |
| ls.c | `bin/ls/ls.c` | ソース | lsコマンドのメイン処理 |
| print.c | `bin/ls/print.c` | ソース | lsの表示処理 |
| util.c | `bin/ls/util.c` | ソース | lsのユーティリティ関数 |
| cmp.c | `bin/ls/cmp.c` | ソース | lsのソート比較関数 |
| ls.h | `bin/ls/ls.h` | ヘッダ | lsのデータ構造定義 |
| cp.1 | `bin/cp/cp.1` | マニュアル | cpコマンドのmanページ |
| mv.1 | `bin/mv/mv.1` | マニュアル | mvコマンドのmanページ |
| rm.1 | `bin/rm/rm.1` | マニュアル | rmコマンドのmanページ |
| ls.1 | `bin/ls/ls.1` | マニュアル | lsコマンドのmanページ |
