# 機能設計書 63-パイプバインド

## 概要

本ドキュメントは、libuvのパイプハンドルを名前（パス）にバインドする機能（`uv_pipe_bind()`/`uv_pipe_bind2()`）の設計を記述する。

### 本機能の処理概要

パイプハンドルをファイルシステムパス（Unix）またはNamed Pipeパス（Windows）にバインドし、サーバーとして接続を待ち受ける準備を行う。

**業務上の目的・背景**：パイプサーバーを構築するためには、クライアントが接続先を特定できるよう名前付きのエンドポイントを作成する必要がある。本機能はその名前付けを行い、後続のuv_listen()による接続待受の前提条件を整える。

**機能の利用シーン**：プロセス間通信サーバーの構築時に使用される。Unixドメインソケットサーバー、Windows Named Pipeサーバーの作成時に、指定パスへのバインドを行う。

**主要な処理内容**：
1. 入力パラメータのバリデーション（名前、フラグ、状態チェック）
2. Unix: AF_UNIXソケットの作成とbind()システムコールの実行
3. Windows: CreateNamedPipeW()によるNamed Pipeインスタンスの作成
4. バインド成功時にUV_HANDLE_BOUNDフラグを設定

**関連システム・外部連携**：Unix bind()システムコール、Windows CreateNamedPipeW() API。

**権限による制御**：ファイルシステムパスへのバインドにはディレクトリの書き込み権限が必要。Windowsでは名前空間の権限によりEADDRINUSEが返る場合がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | パイプ | 主機能 | uv_pipe_bind()/uv_pipe_bind2()によるパイプバインドのAPI定義 |

## 機能種別

リソース割り当て（OSソケット/パイプの作成とバインド）

## 入力仕様

### 入力パラメータ

#### uv_pipe_bind()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_pipe_t* | Yes | バインドするパイプハンドル | 既にバインド済み/クローズ中でないこと |
| name | const char* | Yes | バインド先のパス名 | NULLでないこと |

#### uv_pipe_bind2()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_pipe_t* | Yes | バインドするパイプハンドル | 既にバインド済み/クローズ中でないこと |
| name | const char* | Yes | バインド先のパス名 | NULLでないこと |
| namelen | size_t | Yes | パス名の長さ | Linuxの抽象名前空間以外では0不可 |
| flags | unsigned int | Yes | オプションフラグ | UV_PIPE_NO_TRUNCATEのみ有効 |

### 入力データソース

呼び出し元アプリケーションから直接提供される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時は0、失敗時は負のエラーコード |

### 出力先

パイプハンドルの状態更新（UV_HANDLE_BOUNDフラグ設定、ソケットFD設定）。

## 処理フロー

### 処理シーケンス

```
1. パラメータバリデーション
   └─ flags, name, namelen, 埋め込みNUL文字、パス長、バインド済み判定、クローズ中判定
2. パス名のコピー（必要に応じて）
   └─ Unix: 抽象ソケット以外はmalloc + memcpy
   └─ Windows: UTF-8 → UTF-16変換
3. ソケット/パイプの作成
   └─ Unix: uv__socket(AF_UNIX, SOCK_STREAM, 0)
   └─ Windows: CreateNamedPipeW()
4. バインド実行
   └─ Unix: bind(sockfd, &saddr, addrlen)
   └─ Windows: pipe_alloc_accept()で最初のインスタンスを作成
5. 成功時の状態更新
   └─ UV_HANDLE_BOUNDフラグ設定、FD/ハンドル保存
```

### フローチャート

```mermaid
flowchart TD
    A[開始: uv_pipe_bind2] --> B{パラメータ<br/>バリデーション}
    B -->|不正| C[return UV_EINVAL]
    B -->|OK| D[パス名のコピー]
    D --> E{ソケット/パイプ作成}
    E -->|失敗| F[リソース解放<br/>return エラー]
    E -->|成功| G[bind/CreateNamedPipe]
    G -->|失敗| F
    G -->|成功| H[UV_HANDLE_BOUND設定<br/>return 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | パス長の切り詰め | UV_PIPE_NO_TRUNCATEフラグなしの場合、sun_pathの最大長を超えるパスは自動的に切り詰められる | namelenがsun_pathサイズを超える場合 |
| BR-02 | 切り詰め禁止 | UV_PIPE_NO_TRUNCATEフラグありの場合、パスが長すぎるとUV_EINVALを返す | UV_PIPE_NO_TRUNCATEフラグ指定時 |
| BR-03 | Linuxの抽象ソケット | Linux上でnameの先頭がNUL文字（'\0'）の場合、抽象ソケット名前空間が使用される。namelen==0でautobindとなる | Linux環境でのバインド時 |
| BR-04 | ENOENTからEACCESへの変換 | Unixでbind()がENOENTを返した場合、Windows互換性のためEACCESに変換する | Unix環境でのバインド失敗時 |
| BR-05 | デフォルト保留インスタンス数 | Windowsでpending_instancesが未設定の場合、デフォルト値4が使用される | Windows環境でのバインド時 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | パラメータ不正 | name==NULL、不正なflags、既にバインド済み、クローズ中、パス長超過（NO_TRUNCATE時） | パラメータを修正 |
| UV_ENOMEM | メモリ不足 | パス名コピーやaccept_reqsの割り当てに失敗 | メモリを解放してリトライ |
| UV_EACCES | アクセス拒否 | パスのディレクトリに書き込み権限がない、またはENOENTからの変換 | 権限を確認 |
| UV_EADDRINUSE | アドレス使用中 | 同名のパイプが既に存在（Windows） | 別のパス名を使用 |

### リトライ仕様

UV_ENOMEMの場合のみリトライが有効。それ以外はパラメータ修正が必要。

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

該当なし。失敗時はソケット/メモリを解放して元の状態に戻る。

## パフォーマンス要件

OSのbind()システムコールを含むため、ファイルシステムI/Oが発生する。通常は数ミリ秒以内に完了する。

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

- ファイルシステム上のソケットファイルの権限に注意。デフォルトではumask適用。必要に応じてuv_pipe_chmod()で権限を調整する。
- Linuxの抽象ソケット名前空間はファイルシステム権限による保護がないため、同一ホスト上の全プロセスからアクセス可能。

## 備考

- uv_pipe_bind()はuv_pipe_bind2(handle, name, strlen(name), 0)のラッパーである
- Unix版ではバインド時にソケットファイルのパスをpipe_fnameに保存し、クローズ時にunlink()で削除する
- 抽象ソケット（'\0'で始まるパス）の場合はpipe_fnameをNULLのままにする（ファイルが存在しないため）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | L858-860: UV_PIPE_NO_TRUNCATEフラグの定義 |
| 1-2 | uv.h | `include/uv.h` | L868-873: uv_pipe_s構造体 |

**読解のコツ**: UV_PIPE_NO_TRUNCATEはbit 0のフラグ（値: 1）。これにより長いパスの切り詰め動作を制御する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pipe.c (Unix) | `src/unix/pipe.c` | L58-60: uv_pipe_bind()。uv_pipe_bind2()の単純なラッパー |
| 2-2 | pipe.c (Unix) | `src/unix/pipe.c` | L63-150: uv_pipe_bind2()のUnix版実装。バリデーション、ソケット作成、bind()実行 |
| 2-3 | pipe.c (Win) | `src/win/pipe.c` | L704-706: uv_pipe_bind()。同様にuv_pipe_bind2()のラッパー |
| 2-4 | pipe.c (Win) | `src/win/pipe.c` | L709-811: uv_pipe_bind2()のWindows版実装 |

**主要処理フロー（Unix版 L63-150）**:
1. **75-76行目**: フラグのバリデーション
2. **78-79行目**: name==NULLチェック
3. **84-87行目**: Linux以外でnamelen==0はEINVAL
4. **89-90行目**: 埋め込みNUL文字チェック
5. **92-94行目**: UV_PIPE_NO_TRUNCATEでパス長超過チェック
6. **97-98行目**: パス長の切り詰め
7. **101-105行目**: 既にバインド済み/クローズ中チェック
8. **111-120行目**: 抽象ソケット判定とパス名コピー
9. **122-125行目**: AF_UNIXソケット作成
10. **127-139行目**: bind()実行とエラー処理（ENOENTをEACCESに変換）
11. **142-145行目**: 成功時のフラグ・FD設定

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

```
uv_pipe_bind(handle, name)
    |
    +-- uv_pipe_bind2(handle, name, strlen(name), 0)
            |
            +-- [バリデーション]
            +-- uv__socket(AF_UNIX, SOCK_STREAM, 0)    [Unix]
            |       +-- socket() + cloexec設定
            +-- bind(sockfd, &saddr, addrlen)           [Unix]
            +-- CreateNamedPipeW()                      [Windows]
            +-- UV_HANDLE_BOUND設定
```

### データフロー図

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

uv_pipe_t* handle ---------> uv_pipe_bind2() -------> handle->flags |= UV_HANDLE_BOUND
const char* name              |                        handle->io_watcher.fd = sockfd (Unix)
size_t namelen                +-- バリデーション       handle->pipe_fname = コピー (Unix)
unsigned int flags            +-- ソケット作成         handle->name = UTF-16名前 (Win)
                              +-- bind/CreateNP
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（L877-881）とフラグ定義（L858-860） |
| pipe.c (Unix) | `src/unix/pipe.c` | ソース | Unix版実装（L58-150） |
| pipe.c (Win) | `src/win/pipe.c` | ソース | Windows版実装（L704-811） |
| uv-common.h | `src/uv-common.h` | 内部ヘッダー | UV_HANDLE_BOUNDフラグ定義 |
