# 帳票設計書 24-グループ情報

## 概要

指定GIDのグループ情報（グループ名・GID・メンバー一覧）を`uv_group_t`構造体に出力する帳票（API出力）の設計書である。`uv_os_get_group()`関数により取得する。

### 本帳票の処理概要

本帳票は、指定されたグループID（GID）に対応するグループ情報をOSのグループ管理システムから取得し、`uv_group_t`構造体に格納して出力する機能を提供する。Unix系では`getgrgid_r()`を使用し、WindowsではUV_ENOTSUPを返す。

**業務上の目的・背景**：アプリケーションがグループ情報を取得する場面で必要となる。ファイルアクセス権限の管理、グループベースの認可処理、マルチユーザー環境でのグループメンバーシップ確認、権限管理ツールの実装などに活用される。Unix系OSのグループ管理機能をクロスプラットフォームなインターフェースで提供する目的があるが、現状Windowsでは非対応である。

**帳票の利用シーン**：ファイルシステム操作時のグループ権限確認、共有リソースのアクセス管理、グループメンバーの列挙、セキュリティ監査ツールでのグループ情報収集、プロセスの実行グループ情報の表示などに利用される。

**主要な出力内容**：
1. グループ名（groupname）
2. グループID（gid）
3. グループメンバー一覧（members） - NULLターミネートされた文字列ポインタ配列

**帳票の出力タイミング**：任意のタイミングで`uv_os_get_group()`関数を呼び出すことにより出力される。同期関数であり、即座に結果が返却される。

**帳票の利用者**：libuvを利用するアプリケーション開発者、Node.jsランタイム、セキュリティツール開発者、システム管理ツール開発者。

## 帳票種別

情報取得（グループ情報構造体出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | CLIまたはAPI呼び出し | N/A（C言語API） | `uv_os_get_group()` 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | メモリ上の構造体（uv_group_t） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（ポインタ経由で返却） |
| 出力方法 | 引数ポインタの構造体メンバへの書き込み |
| 文字コード | UTF-8 |

### uv_group_t 構造体定義

```c
struct uv_group_s {
  char* groupname;    /* グループ名 */
  unsigned long gid;  /* グループID */
  char** members;     /* グループメンバー一覧（NULLターミネート） */
};
```

## 帳票レイアウト

### レイアウト概要

本帳票はuv_group_t構造体として出力される。membersはNULLで終端された文字列ポインタの配列である。

```
┌─────────────────────────────────────┐
│  uv_group_t                         │
├─────────────────────────────────────┤
│  groupname : char*                  │
│  gid       : unsigned long          │
│  members   : char**                 │
│    members[0] : "user1"             │
│    members[1] : "user2"             │
│    ...                              │
│    members[N] : NULL                │
└─────────────────────────────────────┘
```

### 出力項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | groupname | グループ名 | Unix: gr_name（getgrgid_r） | 文字列（char*） |
| 2 | gid | グループID | Unix: gr_gid（getgrgid_r） | unsigned long |
| 3 | members | グループメンバー一覧 | Unix: gr_mem（getgrgid_r） | NULLターミネートのchar*配列 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| grp | uv_group_t構造体へのポインタ。NULL不可 | Yes |
| gid | 取得対象のグループID（uv_uid_t型） | Yes |

### ソート順

N/A（単一レコード出力）

### 改ページ条件

N/A

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを参照しない。OSのグループ管理システム（/etc/group等）から情報を取得する。

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A | N/A | N/A |

### プラットフォーム別データ取得元

| プラットフォーム | ファイル | 取得方法 | 備考 |
|---------------|---------|---------|------|
| Unix系 | `src/unix/core.c` | getgrgid_r(gid) でグループエントリを取得 | Android API level 24未満では UV_ENOSYS |
| Windows | `src/win/util.c` | UV_ENOTSUP を返却 | Windows非対応 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| メモリサイズ（members） | sizeof(char*) * (members_count + 1) + 各メンバー名の文字列長合計 + name_size | N/A | ポインタ配列 + 文字列データ + グループ名を一括確保 |
| メンバー数 | gr_mem[] 配列の NULL 終端までのカウント | N/A | ループカウント |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_os_get_group 呼び出し] --> B{プラットフォーム判定}
    B -->|Windows| C[UV_ENOTSUP を返却]
    B -->|Android API < 24| D[UV_ENOSYS を返却]
    B -->|Unix| E{grp == NULL?}
    E -->|Yes| F[UV_EINVAL を返却]
    E -->|No| G[バッファ確保 初期2000バイト]
    G --> H[getgrgid_r 呼び出し]
    H --> I{結果判定}
    I -->|ERANGE| J[バッファサイズ倍増して再試行]
    J --> G
    I -->|エラー| K[UV__ERR を返却]
    I -->|result==NULL| L[UV_ENOENT を返却]
    I -->|成功| M[メンバー数をカウント]
    M --> N[members配列 + 文字列 + groupname のメモリ一括確保]
    N --> O[メンバー文字列をコピー]
    O --> P[groupname をコピー]
    P --> Q[gid を設定]
    Q --> R[0 を返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| UV_EINVAL | grp引数がNULLの場合 | N/A | 有効なポインタを渡す |
| UV_ENOMEM | メモリ確保に失敗した場合 | N/A | メモリ使用量を確認 |
| UV_ENOENT | 指定GIDのグループが存在しない場合 | N/A | GIDの妥当性を確認 |
| UV_ENOTSUP | Windows で呼び出した場合 | N/A | Windowsでは使用不可 |
| UV_ENOSYS | Android API level 24未満で呼び出した場合 | N/A | API level を確認 |
| システムエラー | getgrgid_r が失敗した場合 | UV__ERR(r) | OS環境を確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1件（単一グループ情報） |
| 目標出力時間 | ミリ秒オーダー（システムコール + メモリ確保） |
| 同時出力数上限 | 制限なし（各呼び出しで独立したメモリを確保） |

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

- グループメンバー情報はセキュリティに関わる情報であり、不要な場合はログ等に出力しない配慮が望ましい
- 返却されたメモリは `uv_os_free_group()` で明示的に解放する必要がある（メモリリーク防止）
- getgrgid_r はスレッドセーフなAPI（_r バリアント）を使用している

## 備考

- 返却されたuv_group_t構造体は `uv_os_free_group()` で解放すること
- members配列は NULL ターミネートされている（members[N] == NULL）
- メモリはmembers配列 + 各メンバー名 + groupname の全体が一括確保される。解放時は `grp->members` のみを free すればよい
- Windowsでは本関数は UV_ENOTSUP を返し、グループ情報の取得はサポートされない
- Android API level 24（Nougat）未満では getgrgid_r() が利用できないため UV_ENOSYS を返す

---

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

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

### 推奨読解順序

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

uv_group_t 構造体のメンバ構成を理解することが最初のステップである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | struct uv_group_s の定義（行1239-1243）: groupname, gid, members の3フィールド |
| 1-2 | uv.h | `include/uv.h` | uv_os_get_group / uv_os_free_group の宣言（行1318-1319） |

**読解のコツ**: members は `char**` 型（文字列ポインタの配列）であり、NULLターミネートされている。配列の最後の要素は必ず NULL である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.c | `src/unix/core.c` | uv_os_get_group() 関数（行1423-1505）: getgrgid_r によるグループ情報取得の全実装 |

**主要処理フロー**:
1. **行1424-1426**: Android API level 24未満のチェック（UV_ENOSYS）
2. **行1438-1439**: 引数の NULL チェック（UV_EINVAL）
3. **行1444-1459**: バッファサイズ2000バイトから開始し、ERANGE の場合は倍増しながら getgrgid_r を繰り返す
4. **行1461-1465**: エラー・結果なしの処理（UV__ERR / UV_ENOENT）
5. **行1468-1474**: グループ名のサイズ計算とメンバー数のカウント、メンバー文字列の合計サイズを算出
6. **行1476-1480**: ポインタ配列 + 文字列データ + グループ名のメモリ一括確保
7. **行1483-1490**: メンバーポインタ配列の構築と各メンバー名のコピー
8. **行1494-1496**: グループ名のコピー
9. **行1499**: GIDの設定
10. **行1501**: 作業バッファの解放

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | util.c | `src/win/util.c` | uv_os_get_group() 関数（行1213-1215）: UV_ENOTSUP を返すのみ |

#### Step 4: メモリ解放を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | uv-common.c | `src/uv-common.c` | uv_os_free_group() 関数（行150-161）: members ポインタの解放とフィールドのNULL初期化 |

**主要処理フロー**:
1. **行158**: `uv__free(grp->members)` でmembers配列（文字列データ含む）を一括解放
2. **行159-160**: members と groupname を NULL に設定

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

```
uv_os_get_group(uv_group_t* grp, uv_uid_t gid)  [src/unix/core.c:1423]
    |
    +-- uv__malloc(bufsize)           [src/uv-common.c:75]
    +-- getgrgid_r(gid, ...)          [libc]
    +-- uv__malloc(name_size + mem_size)  [src/uv-common.c:75]
    +-- strcpy / memcpy（各フィールド）
    +-- uv__free(buf)                 [src/uv-common.c:81]

uv_os_get_group(uv_group_t* grp, uv_uid_t gid)  [src/win/util.c:1213]
    |
    +-- return UV_ENOTSUP

uv_os_free_group(uv_group_t* grp)    [src/uv-common.c:150]
    |
    +-- uv__free(grp->members)
```

### データフロー図

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

uv_uid_t gid ───> OS グループ管理         ───> uv_group_t
                  getgrgid_r (Unix)            - groupname
                  /etc/group 等                 - gid
                                                - members[] (NULL終端)
                                                戻り値: 0 または負値
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_group_t 構造体定義、API宣言 |
| core.c | `src/unix/core.c` | ソース | Unix向け uv_os_get_group() 実装 |
| util.c | `src/win/util.c` | ソース | Windows向け uv_os_get_group()（UV_ENOTSUP） |
| uv-common.c | `src/uv-common.c` | ソース | uv_os_free_group() メモリ解放関数 |
| test-get-passwd.c | `test/test-get-passwd.c` | テスト | uv_os_get_group のテスト |
