# 機能設計書 151-システム名取得

## 概要

本ドキュメントは、libuvライブラリにおけるuv_os_uname()関数によるOS名・バージョン・アーキテクチャ等のシステム情報取得機能の設計を記述する。

### 本機能の処理概要

uv_os_uname()関数は、実行環境のオペレーティングシステムに関する基本情報（システム名、リリース、バージョン、マシンアーキテクチャ）をクロスプラットフォームで取得する機能を提供する。

**業務上の目的・背景**：アプリケーションが実行環境のOS情報を把握する必要がある場面は多い。環境依存の処理分岐、ログ出力時のシステム情報付与、デバッグ情報の収集、互換性チェックなど、プラットフォーム情報をプログラムから取得するニーズに対し、POSIXのuname()やWindowsのGetVersionEx()といったOS固有APIをラップし、統一的なインターフェースを提供する。

**機能の利用シーン**：アプリケーション起動時のシステム情報ログ出力、プラットフォーム固有の挙動切り替え判定、テレメトリやクラッシュレポートへの環境情報埋め込み、アプリケーション要件チェック（対応OS/バージョンの確認）などに利用される。

**主要な処理内容**：
1. 引数（bufferポインタ）のNULLチェック
2. Unix系ではuname()システムコール呼び出しによるシステム情報取得
3. WindowsではGetVersionEx()やRtlGetVersion()等のWin32 API呼び出し
4. 取得した情報をuv_utsname_t構造体のフィールド（sysname, release, version, machine）へコピー
5. AIX/PASEでのリリース文字列フォーマット特別処理
6. バッファオーバーフロー時のエラーハンドリング

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

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

## 関連画面

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

## 機能種別

データ取得処理（OSシステム情報の読み取り）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| buffer | uv_utsname_t* | Yes | システム情報を格納する構造体へのポインタ | NULLの場合UV_EINVAL |

### 入力データソース

呼び出し元からのポインタ引数。OS情報はカーネルから取得する。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| buffer->sysname | char[256] | システム名（例: "Linux", "Darwin", "Windows_NT"） |
| buffer->release | char[256] | リリースバージョン（例: "5.15.0", "22.1.0"） |
| buffer->version | char[256] | カーネルバージョン文字列 |
| buffer->machine | char[256] | マシンアーキテクチャ（例: "x86_64", "arm64", "ppc64"） |
| 戻り値 | int | 成功時0、失敗時負のエラーコード |

### 出力先

呼び出し元が提供するuv_utsname_t構造体に書き込む。

## 処理フロー

### 処理シーケンス

```
1. 引数バリデーション
   └─ bufferがNULLの場合UV_EINVALを返す
2. プラットフォーム固有のシステム情報取得
   ├─ [Unix系] uname()システムコール呼び出し
   │      └─ 失敗時はerrnoをlibuvエラーに変換してerrorラベルへ
   └─ [Windows] RtlGetVersion()/GetNativeSystemInfo()呼び出し
3. 各フィールドへのコピー
   ├─ sysname: uv__strscpy()でコピー（UV_E2BIG時エラー）
   ├─ release: AIXでは"version.release"形式にフォーマット、その他はそのままコピー
   ├─ version: uv__strscpy()でコピー
   └─ machine: AIX/PASEでは"ppc64"固定、その他はそのままコピー
4. 正常完了（0を返す）
   └─ エラー時は全フィールドを空文字列にクリアしてエラーコードを返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{buffer == NULL?}
    B -->|Yes| C[return UV_EINVAL]
    B -->|No| D{プラットフォーム判定}
    D -->|Unix| E[uname 呼び出し]
    D -->|Windows| F[RtlGetVersion 呼び出し]
    E --> G{uname成功?}
    G -->|No| H[error ラベルへ]
    G -->|Yes| I[sysname コピー]
    F --> I
    I --> J{AIX?}
    J -->|Yes| K[release を version.release 形式でフォーマット]
    J -->|No| L[release をそのままコピー]
    K --> M[version コピー]
    L --> M
    M --> N{AIX/PASE?}
    N -->|Yes| O[machine = ppc64]
    N -->|No| P[machine をそのままコピー]
    O --> Q[return 0]
    P --> Q
    H --> R[全フィールドクリア]
    R --> S[return エラーコード]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-151-01 | NULLチェック | buffer引数がNULLの場合UV_EINVALを返す | 常時 |
| BR-151-02 | バッファオーバーフロー保護 | フィールドサイズ（256バイト）を超える文字列はUV_E2BIGエラー | 各フィールドコピー時 |
| BR-151-03 | AIXリリース形式 | AIXではversion.release形式でrelease文字列を構築 | AIXプラットフォーム |
| BR-151-04 | AIX/PASEマシン名 | AIX/PASEではmachineを"ppc64"固定 | AIX/PASEプラットフォーム |
| BR-151-05 | エラー時フィールドクリア | エラー発生時は全フィールドを空文字列にする | エラー発生時 |

### 計算ロジック

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | 引数不正 | bufferがNULL | 有効なポインタを渡す |
| UV_E2BIG | バッファ不足 | OS情報文字列が256バイトを超える | 通常発生しない（構造体サイズは十分） |
| UV__ERR(errno) | システムエラー | uname()システムコール失敗 | OSの状態を確認 |

### リトライ仕様

リトライは不要。uname()の失敗は通常システムの深刻な問題を示す。

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

該当なし。

## パフォーマンス要件

単一のシステムコール呼び出しであり、即座に完了する。ブロッキング処理だがレイテンシは極めて低い。

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

OS情報はセンシティブではないが、攻撃者がOS/バージョンを特定するために利用する可能性がある。公開する場合は注意が必要。

## 備考

- uv_utsname_t構造体にはPOSIX utsnameのnodenameとdomainnameフィールドが含まれていない。これらは「意味がない（meaningless）」とされているため省略されている。
- Windowsでの実装ではRtlGetVersion()を使用しており、GetVersionEx()のバージョン偽装問題を回避している。

---

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

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

### 推奨読解順序

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

uv_utsname_t構造体の定義を確認し、出力データの形式を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_utsname_t構造体の定義（各フィールドchar[256]） |

**読解のコツ**: uv_utsname_t（1245-1253行目）は4つのchar配列で構成される。POSIXのutsname構造体と異なり、nodenameとdomainnameを意図的に省略している点に注意。

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

APIの宣言と呼び出しインターフェースを確認する。

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

**主要処理フロー**:
1. **1388行目**: `UV_EXTERN int uv_os_uname(uv_utsname_t* buffer);` - API宣言

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

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

**主要処理フロー**:
- **1850行目**: 関数エントリーポイント
- **1854-1855行目**: NULLチェック
- **1857-1860行目**: uname()システムコール呼び出し
- **1862-1864行目**: sysnameフィールドのコピー
- **1866-1880行目**: releaseフィールドのコピー（AIX特別処理あり）
- **1882-1884行目**: versionフィールドのコピー
- **1886-1893行目**: machineフィールドのコピー（AIX/PASE特別処理あり）
- **1897-1903行目**: エラー時の全フィールドクリア処理

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

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

**主要処理フロー**:
- **1568行目**: 関数エントリーポイント
- **1587行目**: `pRtlGetVersion(&os_info)` によるOSバージョン情報取得
- **1591-1606行目**: レジストリ `SOFTWARE\Microsoft\Windows NT\CurrentVersion` からProductName取得
- **1615-1623行目**: Windows 11判定（dwBuildNumber >= 22000 かつ ProductNameが"Windows 10"で始まる場合に修正）
- **1650-1660行目**: sysname設定（通常: "Windows_NT"、MINGW32: "MINGW32_NT-x.y"）
- **1662-1668行目**: release設定（"major.minor.build"形式）

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

```
uv_os_uname(buffer)
    |
    +-- [Unix] uname(&buf)                    ... POSIX システムコール
    |       +-- uv__strscpy(sysname)          ... 安全な文字列コピー
    |       +-- uv__strscpy(release)          ... AIX: snprintf("ver.rel")
    |       +-- uv__strscpy(version)
    |       +-- uv__strscpy(machine)          ... AIX/PASE: "ppc64" 固定
    |
    +-- [Windows] RtlGetVersion()             ... Win32 API
            +-- GetNativeSystemInfo()         ... アーキテクチャ取得
            +-- snprintf(sysname/release/version/machine)
```

### データフロー図

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

buffer (uv_utsname_t*) --> uv_os_uname()                --> buffer->sysname
                           |                                buffer->release
                           +-- uname() / RtlGetVersion()    buffer->version
                           |   (OS固有API)                   buffer->machine
                           +-- uv__strscpy()                 戻り値: 0 or error
                               (文字列コピー)
```

### 関連ファイル一覧

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