# 機能設計書 152-ホスト名取得

## 概要

本ドキュメントは、libuvライブラリにおけるuv_os_gethostname()関数によるホスト名取得機能の設計を記述する。

### 本機能の処理概要

uv_os_gethostname()関数は、現在のシステムのホスト名を取得するクロスプラットフォームAPIを提供する。

**業務上の目的・背景**：分散システムやクラスタ環境において、各ノードの識別にホスト名が使われることは一般的である。ログ出力時のホスト名付与、ネットワークサービスの自ノード識別、クラスタメンバーの認識など、ホスト名取得のニーズに対し、POSIX gethostname()やWindows GetComputerNameExW()をラップした統一的なインターフェースを提供する。

**機能の利用シーン**：サーバーアプリケーション起動時のホスト名ログ出力、分散システムでのノード識別子生成、ネットワークサービスのバインドアドレス決定補助、テレメトリデータへのホスト名埋め込みなどに利用される。

**主要な処理内容**：
1. 引数（buffer, size）のNULLチェックとゼロサイズチェック
2. 内部バッファ（UV_MAXHOSTNAMESIZEバイト）にホスト名を取得
3. ホスト名の長さと呼び出し元バッファサイズの比較
4. 十分なサイズがあれば呼び出し元バッファにコピー
5. バッファ不足の場合は必要サイズを返してUV_ENOBUFS

**関連システム・外部連携**：POSIXのgethostname()システムコール、WindowsのGetComputerNameExW() APIと連携する。

**権限による制御**：特別な権限は不要。一般ユーザー権限で実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_os_gethostname()によるホスト名取得のAPI定義 |

## 機能種別

データ取得処理（ホスト名の読み取り）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| buffer | char* | Yes | ホスト名を格納するバッファ | NULLの場合UV_EINVAL |
| size | size_t* | Yes | バッファサイズ（入力）／実際の長さ（出力） | NULLまたは*size==0の場合UV_EINVAL |

### 入力データソース

呼び出し元からのバッファポインタとサイズ。ホスト名はOSカーネルから取得する。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| buffer | char* | NUL終端されたホスト名文字列 |
| *size | size_t | ホスト名の長さ（NUL終端を含まない） |
| 戻り値 | int | 成功時0、失敗時負のエラーコード |

### 出力先

呼び出し元が提供するバッファに書き込む。

## 処理フロー

### 処理シーケンス

```
1. 引数バリデーション
   └─ buffer==NULL, size==NULL, *size==0の場合UV_EINVALを返す
2. 内部バッファ（UV_MAXHOSTNAMESIZE=256バイト）にgethostname()呼び出し
   └─ 失敗時はerrnoをlibuvエラーに変換して返す
3. NUL終端の安全確保
   └─ 内部バッファの末尾をNUL文字で上書き
4. ホスト名長さの計算（strlen）
5. バッファサイズ判定
   ├─ [不足] *sizeにlen+1を設定しUV_ENOBUFSを返す
   └─ [十分] memcpy()でコピーし*sizeにlenを設定
6. 正常完了（0を返す）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{buffer==NULL or size==NULL or *size==0?}
    B -->|Yes| C[return UV_EINVAL]
    B -->|No| D[gethostname で内部バッファに取得]
    D --> E{gethostname 成功?}
    E -->|No| F[return UV__ERR errno]
    E -->|Yes| G[NUL終端を保証]
    G --> H[len = strlen buf]
    H --> I{len >= *size?}
    I -->|Yes| J[*size = len + 1]
    J --> K[return UV_ENOBUFS]
    I -->|No| L[memcpy buffer buf len+1]
    L --> M[*size = len]
    M --> N[return 0]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-152-01 | NULLチェック | buffer, sizeがNULLまたは*sizeが0の場合UV_EINVAL | 常時 |
| BR-152-02 | バッファサイズ確認 | 呼び出し元バッファが不足する場合、必要サイズを*sizeに設定しUV_ENOBUFS | ホスト名長 >= *size |
| BR-152-03 | NUL終端保証 | 内部バッファの最終バイトを常にNULで上書きし安全性を確保 | 常時 |
| BR-152-04 | 最大ホスト名長 | UV_MAXHOSTNAMESIZEは256バイト | 常時 |

### 計算ロジック

特別な計算ロジックはない。

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

該当なし（データベース操作は行わない）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 引数不正 | buffer==NULL, size==NULL, *size==0 | 有効な引数を渡す |
| UV_ENOBUFS | バッファ不足 | 提供バッファがホスト名を格納するのに不十分 | *sizeに返された必要サイズ以上のバッファを用意 |
| UV__ERR(errno) | システムエラー | gethostname()失敗 | OSの状態を確認 |

### リトライ仕様

リトライは不要。

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

該当なし。

## パフォーマンス要件

単一のシステムコール呼び出しであり、即座に完了する。

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

ホスト名はネットワーク上で識別情報として使用されるため、外部に公開する際はセキュリティを考慮する。

## 備考

- UV_MAXHOSTNAMESIZEは256バイトと定義されている。Windows gethostname()のドキュメントによれば、256バイトで常にNUL終端を含むホスト名を格納できるとされている。
- Unix版とWindows版で実装が異なる。Windows版ではpGetHostNameW()（GetHostNameW関数のポインタ）によるUnicode取得後にUTF-8変換を行う。pGetHostNameWが利用できない環境ではUV_ENOSYSを返す。

---

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

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

### 推奨読解順序

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

ホスト名取得に特別なデータ構造はないが、UV_MAXHOSTNAMESIZEマクロの定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | UV_MAXHOSTNAMESIZEの定義（256） |

**読解のコツ**: 1376-1384行目でプラットフォーム別にUV_MAXHOSTNAMESIZEが定義されている。値はいずれも256。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | uv_os_gethostname()のAPI宣言（1386行目） |

**主要処理フロー**:
1. **1386行目**: `UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);`

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | core.c | `src/unix/core.c` | uv_os_gethostname()のUnix実装 |

**主要処理フロー**:
- **1628行目**: 関数エントリーポイント
- **1635行目**: 内部バッファ `char buf[UV_MAXHOSTNAMESIZE]` 宣言
- **1638-1639行目**: 引数NULLチェック
- **1641-1642行目**: gethostname()呼び出し
- **1644行目**: NUL終端を強制（安全対策）
- **1647-1649行目**: バッファサイズ不足時にUV_ENOBUFS返却
- **1652行目**: memcpy()でバッファにコピー
- **1653行目**: *sizeにホスト名の長さを設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | util.c | `src/win/util.c` | uv_os_gethostname()のWindows実装 |

**主要処理フロー**:
- **1404行目**: 関数エントリーポイント
- **1405行目**: `WCHAR buf[UV_MAXHOSTNAMESIZE]` 内部バッファ宣言
- **1407-1408行目**: 引数NULLチェック
- **1410行目**: `uv__once_init()` でWinsock初期化
- **1412-1413行目**: `pGetHostNameW` がNULLの場合UV_ENOSYSを返す
- **1415-1416行目**: `pGetHostNameW(buf, UV_MAXHOSTNAMESIZE)` でUnicode版ホスト名取得
- **1418行目**: `uv__copy_utf16_to_utf8()` でUTF-16からUTF-8に変換

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

```
uv_os_gethostname(buffer, size)
    |
    +-- [Unix] gethostname(buf, sizeof(buf))   ... POSIX システムコール
    |       +-- strlen(buf)                     ... 長さ計算
    |       +-- memcpy(buffer, buf, len + 1)    ... バッファコピー
    |
    +-- [Windows] pGetHostNameW(buf, UV_MAXHOSTNAMESIZE)  ... WinSock API
            +-- uv__copy_utf16_to_utf8()                ... UTF-16→UTF-8変換
```

### データフロー図

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

buffer (char*)      ----> uv_os_gethostname()            ---> buffer にホスト名
size (size_t*)            |                                    *size にホスト名長
                          +-- gethostname() / GetComputerNameExW()
                          +-- strlen() / memcpy()              戻り値: 0 or error
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | UV_MAXHOSTNAMESIZE定義、API宣言 |
| core.c | `src/unix/core.c` | ソース | Unix系プラットフォームのuv_os_gethostname()実装 |
| util.c | `src/win/util.c` | ソース | Windows版のuv_os_gethostname()実装 |
