# 機能設計書 163-OSファイルハンドル変換

## 概要

本ドキュメントは、libuv の `uv_get_osfhandle()` および `uv_open_osfhandle()` APIにより、libuvのファイルディスクリプタとOSネイティブハンドルを相互変換する機能について記述する。

### 本機能の処理概要

本機能は、libuvが管理するファイルディスクリプタ（int型）と、OSネイティブのファイルハンドル（Unix: int、Windows: HANDLE）を相互に変換するためのクロスプラットフォームAPIを提供する。

**業務上の目的・背景**：libuvはクロスプラットフォームの抽象化レイヤーであるが、時にはOS固有のAPIを直接呼び出す必要がある場合がある。そのような場合、libuvのファイルディスクリプタからOS固有のハンドルに変換する手段が必要となる。特にWindowsではCランタイムのファイルディスクリプタとWin32のHANDLEが異なるため、この変換が重要である。

**機能の利用シーン**：OS固有のAPIを使ったファイル操作が必要な場合（例：Windows固有のオーバーラップドI/O、Unix固有のioctl呼び出し）、サードパーティライブラリにOSネイティブのハンドルを渡す必要がある場合に利用される。

**主要な処理内容**：
1. `uv_get_osfhandle(fd)`: libuvのファイルディスクリプタからOSネイティブハンドルを取得する
2. `uv_open_osfhandle(os_fd)`: OSネイティブハンドルからlibuvのファイルディスクリプタを取得する

**関連システム・外部連携**：Unix環境ではFDとOSハンドルが同一のため単なるパススルー。Windows環境では `_get_osfhandle()` / `_open_osfhandle()` CRTランタイム関数を使用する。

**権限による制御**：特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | ファイルシステム操作 | 補助機能 | uv_get_osfhandle()/uv_open_osfhandle()によるネイティブハンドル変換のAPI定義 |
| 29 | その他ユーティリティ | 主機能 | uv_get_osfhandle()/open_osfhandle()によるネイティブハンドル変換のAPI定義 |

## 機能種別

データ変換

## 入力仕様

### 入力パラメータ

#### uv_get_osfhandle()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| fd | int | Yes | libuvのファイルディスクリプタ | 有効なFD番号であること |

#### uv_open_osfhandle()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| os_fd | uv_os_fd_t | Yes | OSネイティブファイルハンドル | 有効なOSハンドルであること |

### 入力データソース

呼び出し元から直接渡されるファイルディスクリプタ / OSハンドル

## 出力仕様

### 出力データ

#### uv_get_osfhandle()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | uv_os_fd_t | OSネイティブファイルハンドル（Unix: int、Windows: HANDLE） |

#### uv_open_osfhandle()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | libuvのファイルディスクリプタ |

### 出力先

呼び出し元に直接返却

## 処理フロー

### 処理シーケンス

```
uv_get_osfhandle() [Unix]:
1. fdをそのまま返す（Unix環境ではFD = OSハンドル）

uv_open_osfhandle() [Unix]:
1. os_fdをそのまま返す（Unix環境ではOSハンドル = FD）

uv_get_osfhandle() [Windows]:
1. _get_osfhandle(fd)を呼び出してHANDLEを取得

uv_open_osfhandle() [Windows]:
1. _open_osfhandle(os_fd, 0)を呼び出してFDを取得
```

### フローチャート

```mermaid
flowchart TD
    A[uv_get_osfhandle fd] --> B{プラットフォーム}
    B -->|Unix| C[return fd]
    B -->|Windows| D[return _get_osfhandle fd]

    E[uv_open_osfhandle os_fd] --> F{プラットフォーム}
    F -->|Unix| G[return os_fd]
    F -->|Windows| H[return _open_osfhandle os_fd, 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Unixパススルー | Unix環境ではFDとOSハンドルは同一のため変換不要 | Unix系OS |
| BR-02 | Windows変換 | Windows環境ではCRTのFDとWin32 HANDLEの相互変換が必要 | Windows |

### 計算ロジック

該当なし

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

該当なし（データベースは使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| (Windows) INVALID_HANDLE_VALUE | 無効ハンドル | 無効なFDを指定した場合 | 有効なFDを使用する |
| (Windows) -1 | 変換失敗 | 無効なOSハンドルの場合 | 有効なOSハンドルを使用する |

### リトライ仕様

リトライは不要。

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

該当なし

## パフォーマンス要件

単純な値の変換（Unix）またはCRTライブラリ呼び出し（Windows）のため、極めて高速。

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

- 返却されたOSハンドルの管理責任は呼び出し元にある
- ハンドルの二重クローズに注意が必要

## 備考

- Unix環境では `uv_os_fd_t` は `int` 型であり、FDとOSハンドルが同一
- Windows環境では `uv_os_fd_t` は `HANDLE` 型（void*）であり、CRTのFD（int）との変換が必要
- `include/uv.h` L1288-1289 で定義

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | L1288-1289: API宣言、uv_os_fd_t型の理解 |

**読解のコツ**: `uv_os_fd_t` はプラットフォームにより異なる型。Unixでは `int`、Windowsでは `HANDLE`（void*）。この違いが本機能の存在理由。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | L1658-1663: Unix実装（パススルー） |

**主要処理フロー**:
1. **1658-1660行目**: `uv_get_osfhandle()` はfdをそのまま返す
2. **1662-1663行目**: `uv_open_osfhandle()` はos_fdをそのまま返す

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | handle.c | `src/win/handle.c` | Windows実装（_get_osfhandle/_open_osfhandle使用） |

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

```
uv_get_osfhandle(fd) [src/unix/core.c:1658]
    |
    +-- [Unix] return fd  (パススルー)
    +-- [Win]  return _get_osfhandle(fd)

uv_open_osfhandle(os_fd) [src/unix/core.c:1662]
    |
    +-- [Unix] return os_fd  (パススルー)
    +-- [Win]  return _open_osfhandle(os_fd, 0)
```

### データフロー図

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

fd (int)           ───> [Unix] パススルー         ───> uv_os_fd_t (= int)
                   ───> [Win]  _get_osfhandle()   ───> uv_os_fd_t (= HANDLE)

os_fd (uv_os_fd_t) ──> [Unix] パススルー         ───> int (= os_fd)
                   ───> [Win]  _open_osfhandle()  ───> int (CRT FD)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（L1288-1289） |
| core.c | `src/unix/core.c` | ソース | Unix実装（L1658-1663） |
| handle.c | `src/win/handle.c` | ソース | Windows実装 |
