# 機能設計書 64-パイプ接続

## 概要

本ドキュメントは、libuvのパイプハンドルを使用して非同期でパイプサーバーに接続する機能（`uv_pipe_connect()`/`uv_pipe_connect2()`）の設計を記述する。

### 本機能の処理概要

パイプクライアントから指定した名前のパイプサーバーへの非同期接続を開始する機能である。

**業務上の目的・背景**：プロセス間通信のクライアント側として、既にバインド・リスン中のパイプサーバーへの接続を確立する。接続完了は非同期コールバックで通知され、イベントループのノンブロッキング特性を維持する。

**機能の利用シーン**：パイプサーバーへの接続確立、子プロセスとの通信チャネル構築、マイクロサービス間のUnixドメインソケット通信など。

**主要な処理内容**：
1. パラメータのバリデーション
2. ソケット/パイプの作成（未作成の場合）
3. connect()システムコール（Unix）またはCreateFileW()（Windows）の実行
4. 接続結果の非同期コールバック通知

**関連システム・外部連携**：Unix connect()システムコール、Windows CreateFileW()/WaitNamedPipeW() API。

**権限による制御**：接続先のパイプファイル/Named Pipeへの読み書き権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | パイプ | 主機能 | uv_pipe_connect()/uv_pipe_connect2()による非同期パイプ接続のAPI定義 |

## 機能種別

非同期接続処理

## 入力仕様

### 入力パラメータ

#### uv_pipe_connect()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| req | uv_connect_t* | Yes | 接続リクエスト構造体 | - |
| handle | uv_pipe_t* | Yes | 接続に使用するパイプハンドル | - |
| name | const char* | Yes | 接続先のパイプ名 | NULLでないこと |
| cb | uv_connect_cb | Yes | 接続完了時のコールバック | - |

#### uv_pipe_connect2()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| req | uv_connect_t* | Yes | 接続リクエスト構造体 | - |
| handle | uv_pipe_t* | Yes | 接続に使用するパイプハンドル | - |
| name | const char* | Yes | 接続先のパイプ名 | NULLでないこと |
| namelen | size_t | Yes | パイプ名の長さ | 0でないこと |
| flags | unsigned int | Yes | オプションフラグ | UV_PIPE_NO_TRUNCATEのみ有効 |
| cb | uv_connect_cb | Yes | 接続完了時のコールバック | - |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値（connect2） | int | エラー発生時は負のエラーコード。ただしコールバックは必ず呼ばれる |
| コールバック引数status | int | 接続成功時は0、失敗時は負のエラーコード |

### 出力先

コールバック関数経由で呼び出し元に通知される。

## 処理フロー

### 処理シーケンス

```
1. パラメータバリデーション
   └─ name, namelen, flags, 埋め込みNUL文字チェック
2. ソケット/パイプの作成（新規の場合）
   └─ Unix: uv__socket(AF_UNIX, SOCK_STREAM, 0)
   └─ Windows: CreateFileW() + WaitNamedPipeW()
3. 接続試行
   └─ Unix: connect(fd, &saddr, addrlen)
   └─ Windows: open_named_pipe()
4. 接続結果の処理
   └─ 即時成功: ストリームオープン + I/O開始
   └─ EINPROGRESS: I/Oウォッチャー登録（POLLOUT待ち）
   └─ エラー: delayed_errorに設定
5. コールバック登録
   └─ req->cb = cb として次のイテレーションで呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始: uv_pipe_connect2] --> B{バリデーション}
    B -->|不正| C[エラー設定]
    B -->|OK| D{既存ソケットあり?}
    D -->|No| E[ソケット作成]
    D -->|Yes| F[connect 実行]
    E --> F
    F --> G{接続結果}
    G -->|成功/EINPROGRESS| H[ストリームオープン<br/>POLLOUT監視開始]
    G -->|エラー| I[delayed_error設定]
    H --> J[コールバック登録]
    I --> J
    C --> J
    J --> K[return 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 非同期接続 | 接続結果は必ずコールバックで通知される。uv_pipe_connect()のエラーもコールバック経由 | 常に適用 |
| BR-02 | uv_pipe_connect2の戻り値 | connect2はバリデーションエラーを戻り値で返すが、それ以外のエラーはコールバック経由 | connect2使用時 |
| BR-03 | Windows PIPE_BUSY待ち | Windowsでパイプが一時的にビジーな場合、スレッドプールでWaitNamedPipeW()を最大30秒待機する | Windows環境 |
| BR-04 | Cygwin互換性 | CygwinではEBADFをENOTSOCKに変換する | Cygwin環境 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | パラメータ不正 | name==NULL、namelen==0、不正なflags | パラメータ修正 |
| UV_ENOENT | パス不在 | 指定パスのパイプが存在しない | サーバーが起動していることを確認 |
| UV_ECONNREFUSED | 接続拒否 | サーバーがリスン状態でない | サーバーの状態を確認 |
| UV_EACCES | アクセス拒否 | パイプへのアクセス権がない | 権限を確認 |

### リトライ仕様

接続失敗時のリトライはアプリケーション側で実装する。

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

該当なし。

## パフォーマンス要件

ローカル通信のため通常はミリ秒単位で接続完了する。WindowsのPIPE_BUSYの場合は最大30秒のタイムアウトが設定される。

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

接続先のパイプ名が外部入力に基づく場合、パス走査攻撃に注意が必要。

## 備考

- uv_pipe_connect()はuv_pipe_connect2(req, handle, name, strlen(name), 0, cb)のラッパー
- Unix版では接続エラー時もuv__io_feed()で次のイテレーションでコールバックが呼ばれることを保証
- Windows版ではERROR_PIPE_BUSY時にスレッドプールでWaitNamedPipeW()を使用して再接続を試みる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | L882-891: uv_pipe_connect()/uv_pipe_connect2()の関数宣言 |

#### Step 2: Unix実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pipe.c (Unix) | `src/unix/pipe.c` | L231-251: uv_pipe_connect()。エラー時のコールバック保証処理 |
| 2-2 | pipe.c (Unix) | `src/unix/pipe.c` | L254-346: uv_pipe_connect2()。バリデーション、ソケット作成、connect()実行 |

**主要処理フロー（Unix版 uv_pipe_connect2 L254-346）**:
1. **266-280行目**: バリデーション
2. **286-293行目**: 新規ソケット作成
3. **295-307行目**: sockaddr_un構造体設定とconnect()実行
4. **309-320行目**: EINPROGRESSとCygwin互換処理
5. **323-327行目**: ストリームオープン（新規ソケットの場合）
6. **329-330行目**: POLLOUT監視開始
7. **336-345行目**: リクエスト初期化とエラー時のio_feed

#### Step 3: Windows実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | pipe.c (Win) | `src/win/pipe.c` | L856-873: uv_pipe_connect()のWindows版 |
| 3-2 | pipe.c (Win) | `src/win/pipe.c` | L876-997: uv_pipe_connect2()のWindows版 |
| 3-3 | pipe.c (Win) | `src/win/pipe.c` | L814-853: pipe_connect_thread_proc()。PIPE_BUSY時のスレッドプール待機処理 |

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

```
uv_pipe_connect(req, handle, name, cb)
    |
    +-- uv_pipe_connect2(req, handle, name, strlen(name), 0, cb)
            |
            +-- [バリデーション]
            +-- uv__socket(AF_UNIX, SOCK_STREAM, 0)         [Unix: 新規ソケット]
            +-- connect(fd, &saddr, addrlen)                  [Unix]
            |   +-- EINPROGRESS → I/Oウォッチャー登録
            +-- open_named_pipe(name, &duplex_flags)          [Windows]
            |   +-- ERROR_PIPE_BUSY → pipe_connect_thread_proc
            |       +-- WaitNamedPipeW(name, 30000)
            +-- uv__stream_open() [新規ソケット時]
            +-- uv__io_start(POLLOUT)
```

### データフロー図

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

uv_connect_t* req ---------> uv_pipe_connect2() -------> コールバック通知
uv_pipe_t* handle             |                           (status: 0 or エラー)
const char* name              +-- connect() / CreateFileW()
uv_connect_cb cb              +-- 非同期完了待ち
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（L882-891） |
| pipe.c (Unix) | `src/unix/pipe.c` | ソース | Unix版実装（L231-346） |
| pipe.c (Win) | `src/win/pipe.c` | ソース | Windows版実装（L856-997） |
| stream.c | `src/unix/stream.c` | ソース | uv__stream_open()実装 |
