[インデックス 14354] ファイルの概要
このコミットは、Go言語プロジェクトのlib9
ライブラリから、参照されていない外部宣言(extern
)と、getuser()
関数に関連するコードを削除するものです。具体的には、include/libc.h
ヘッダーファイルからgetuser()
, mktemp()
, opentemp()
, searchpath()
の宣言が削除され、src/lib9/getuser.c
ファイル全体が削除されています。これは、コードベースのクリーンアップと、不要な依存関係の排除を目的としています。
コミット
commit 148154b7e7bb026e91208344b3c9c27af7226272
Author: Carl Mastrangelo <notcarl@google.com>
Date: Thu Nov 8 09:39:24 2012 -0500
lib9: remove unreferenced externs and getuser()
R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/6820115
---
include/libc.h | 4 ----
src/lib9/getuser.c | 43 -------------------------------------------\n 2 files changed, 47 deletions(-)
diff --git a/include/libc.h b/include/libc.h
index 6ae3df2408..ac83ea685f 100644
--- a/include/libc.h
+++ b/include/libc.h
@@ -85,16 +85,12 @@ extern char*\tp9getenv(char*);\n extern int\tp9putenv(char*, char*);\n extern int\tgetfields(char*, char**, int, int, char*);\n extern int\tgettokens(char *, char **, int, char *);\n-extern char*\tgetuser(void);\n extern char*\tp9getwd(char*, int);\n extern void\tp9longjmp(p9jmp_buf, int);\n-extern char*\tmktemp(char*);\n-extern int\t\topentemp(char*);\n extern void\tp9notejmp(void*, p9jmp_buf, int);\n extern void\tperror(const char*);\n extern int\tpostnote(int, int, char *);\n extern double\tp9pow10(int);\n-extern char*\tsearchpath(char*);\n extern char*\tp9ctime(long);\n #define p9setjmp(b)\tsigsetjmp((void*)(b), 1)\n \ndiff --git a/src/lib9/getuser.c b/src/lib9/getuser.c
deleted file mode 100644
index d611f44671..0000000000
--- a/src/lib9/getuser.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// +build !windows
-\n-/*\n-Plan 9 from User Space src/lib9/getuser.c\n-http://code.swtch.com/plan9port/src/tip/src/lib9/getuser.c\n-\n-Copyright 2001-2007 Russ Cox. All Rights Reserved.\n-\n-Permission is hereby granted, free of charge, to any person obtaining a copy\n-of this software and associated documentation files (the \"Software\"), to deal\n-in the Software without restriction, including without limitation the rights\n-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n-copies of the Software, and to permit persons to whom the Software is\n-furnished to do so, subject to the following conditions:\n-\n-The above copyright notice and this permission notice shall be included in\n-all copies or substantial portions of the Software.\n-\n-THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n-THE SOFTWARE.\n-*/\n-\n-#include <u.h>\n-#include <pwd.h>\n-#include <libc.h>\n-\n-char*\n-getuser(void)\n-{\\n-\tstatic char user[64];\n-\tstruct passwd *pw;\n-\n-\tpw = getpwuid(getuid());\n-\tif(pw == nil)\n-\t\treturn \"none\";\n-\tstrecpy(user, user+sizeof user, pw->pw_name);\n-\treturn user;\n-}\n```
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/148154b7e7bb026e91208344b3c9c27af7226272](https://github.com/golang/go/commit/148154b7e7bb026e91208344b3c9c27af7226272)
## 元コミット内容
lib9: remove unreferenced externs and getuser()
R=golang-dev, dave, rsc CC=golang-dev https://golang.org/cl/6820115
## 変更の背景
このコミットは、Go言語プロジェクトにおけるコードベースの健全性を維持し、不要なコードを排除する取り組みの一環として行われました。Go言語の初期段階では、ランタイムやツールチェインの一部に、Plan 9オペレーティングシステム由来のC言語ライブラリである`lib9`が利用されていました。しかし、Go言語が成熟し、より多くの機能がGo言語自体で実装されるにつれて、`lib9`内の特定の関数や宣言がGoコードベースのどこからも参照されなくなることがありました。
具体的には、`getuser()`関数はユーザー名を取得する機能を提供していましたが、Go言語の標準ライブラリ(例えば`os/user`パッケージ)に同等の機能がGoネイティブで実装されたか、あるいはGoの設計思想においてその機能が直接的に必要とされなくなった可能性があります。同様に、`mktemp()`, `opentemp()`, `searchpath()`といった関数も、Goのファイルシステム操作やパス検索のメカニズムが確立されたことで、`lib9`経由での利用が不要になったと考えられます。
参照されていない`extern`宣言や未使用のコードが存在することは、以下のような問題を引き起こす可能性があります。
* **コードの肥大化**: 不要なコードはコンパイルされたバイナリサイズを増加させます。
* **メンテナンスの複雑化**: 誰も使用していないコードであっても、それが何のために存在し、安全に削除できるのかを判断するために、将来の開発者が時間を費やす可能性があります。
* **潜在的なバグ**: 未使用のコードであっても、コンパイル時の警告や、将来の変更によって意図しない副作用を引き起こす可能性があります。
* **ビルド時間の増加**: 不要なファイルのコンパイルやリンクは、ビルドプロセス全体の時間をわずかながら増加させます。
このコミットは、これらの問題を解消し、Goプロジェクトのコードベースをよりクリーンで効率的な状態に保つための、定期的なクリーンアップ作業の一環と見なすことができます。
## 前提知識の解説
### `lib9` (Plan 9 from User Space)
`lib9`は、Bell Labsで開発されたオペレーティングシステム「Plan 9」の標準Cライブラリの一部を、Unix系システム上で利用できるように移植したものです。Go言語の初期のランタイムやツールチェインは、Plan 9の設計思想やコードベースから大きな影響を受けており、その名残として`lib9`がGoプロジェクト内に存在していました。`lib9`は、ファイルシステム操作、プロセス管理、文字列処理など、基本的なシステムプログラミング機能を提供していました。
### `extern` キーワード (C言語)
C言語における`extern`キーワードは、変数が別のファイルで定義されていることをコンパイラに伝えるために使用されます。これにより、複数のソースファイルにまたがるプログラムで、グローバル変数や関数の宣言と定義を分離し、リンク時にそれらを解決することができます。
`extern char* getuser(void);` のような宣言は、「`getuser`という名前の関数がどこか別の場所で定義されているので、このファイルではその関数を使用できます」という意味になります。参照されていない`extern`宣言は、その関数がもはやプログラムのどこからも呼び出されていないことを意味します。
### `getuser()` 関数
`getuser()`関数は、現在のユーザーのログイン名を取得するために使用される一般的なC言語の関数です。通常、Unix系システムでは`getpwuid()`や`getlogin()`などのシステムコールを内部的に利用して、ユーザー情報を取得します。このコミットで削除された`src/lib9/getuser.c`には、`getpwuid(getuid())`を使用してユーザー名を取得する実装が含まれていました。
### `mktemp()` 関数
`mktemp()`関数は、一意な一時ファイル名を生成するために使用されるC言語の関数です。セキュリティ上の問題(競合状態による脆弱性)があるため、現代のプログラミングでは`mkstemp()`や`mkdtemp()`などのより安全な関数が推奨されています。
### `opentemp()` 関数
`opentemp()`関数は、一時ファイルを開くための関数で、`mktemp()`と組み合わせて使用されることが多かったです。これも一時ファイルの安全な作成に関連する機能です。
### `searchpath()` 関数
`searchpath()`関数は、指定された実行可能ファイルやライブラリを、システムの`PATH`環境変数で指定されたディレクトリパスの中から検索するために使用される関数です。
## 技術的詳細
このコミットの技術的な詳細は、主にC言語のリンケージとGo言語の進化の観点から理解できます。
1. **未使用の`extern`宣言の削除**:
`include/libc.h`から`getuser()`, `mktemp()`, `opentemp()`, `searchpath()`の`extern`宣言が削除されました。これは、これらの関数がGoプロジェクトのCコードベースのどこからも呼び出されなくなったことを意味します。C言語では、宣言が存在しても定義がなければリンクエラーになりますが、定義が存在しても宣言が参照されなければ、それは単に不要なメタデータとなります。これらの宣言を削除することで、ヘッダーファイルのクリーンアップと、コードの意図の明確化が図られます。
2. **`src/lib9/getuser.c`の削除**:
`getuser.c`ファイル全体が削除されたことは、`getuser()`関数の実装がもはやGoプロジェクトにとって不要になったことを明確に示しています。これは以下のいずれかの理由によるものと考えられます。
* **Goネイティブな代替の実装**: Go言語の標準ライブラリ(例: `os/user`パッケージ)に、よりGoらしい方法でユーザー情報を取得する機能が提供され、C言語の`getuser()`が不要になった。GoはC言語のコードを減らし、Goネイティブな実装を増やす方向で進化してきました。
* **機能の非推奨化または不要化**: Goの特定のコンポーネントが、もはやユーザー名を取得する必要がなくなったか、あるいはその機能が別の方法で処理されるようになった。
* **セキュリティと移植性**: `mktemp()`のような関数はセキュリティ上の懸念があるため、より安全なGoネイティブのAPIに置き換えられた可能性があります。また、C言語のシステムコールに依存する実装は、異なるOSへの移植性を損なう可能性があるため、Goネイティブな実装への移行は移植性の向上にも寄与します。
3. **ビルドシステムへの影響**:
`getuser.c`ファイルの削除は、ビルドシステムからこのファイルをコンパイル対象から外すことを意味します。これにより、ビルド時間がわずかに短縮され、最終的なバイナリサイズも削減されます。
このコミットは、Go言語が初期のPlan 9由来のCコードベースから脱却し、より自己完結的でGoらしいエコシステムを構築していく過程における、小さなしかし重要な一歩と言えます。
## コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は以下の2つのファイルです。
1. **`include/libc.h`**:
このヘッダーファイルから、以下の4つの`extern`関数宣言が削除されました。
```diff
--- a/include/libc.h
+++ b/include/libc.h
@@ -85,16 +85,12 @@ extern char*\tp9getenv(char*);\n extern int\tp9putenv(char*, char*);\n extern int\tgetfields(char*, char**, int, int, char*);\n extern int\tgettokens(char *, char **, int, char *);\n-extern char*\tgetuser(void);\n extern char*\tp9getwd(char*, int);\n extern void\tp9longjmp(p9jmp_buf, int);\n-extern char*\tmktemp(char*);\n-extern int\t\topentemp(char*);\n extern void\tp9notejmp(void*, p9jmp_buf, int);\n extern void\tperror(const char*);\n extern int\tpostnote(int, int, char *);\n extern double\tp9pow10(int);\n-extern char*\tsearchpath(char*);\n extern char*\tp9ctime(long);\n #define p9setjmp(b)\tsigsetjmp((void*)(b), 1)\n \n ```
具体的に削除された行は以下の通りです。
* `extern char*\tgetuser(void);`
* `extern char*\tmktemp(char*);`
* `extern int\t\topentemp(char*);`
* `extern char*\tsearchpath(char*);`
2. **`src/lib9/getuser.c`**:
このファイル全体が削除されました。
```diff
--- a/src/lib9/getuser.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// +build !windows
-\n-/*\n-Plan 9 from User Space src/lib9/getuser.c
-http://code.swtch.com/plan9port/src/tip/src/lib9/getuser.c
-\n-Copyright 2001-2007 Russ Cox. All Rights Reserved.\n-\n ... (以下、ファイルの内容全体が削除) ...
-\n-char*\n-getuser(void)\n-{\n-\tstatic char user[64];\n-\tstruct passwd *pw;\n-\n-\tpw = getpwuid(getuid());\n-\tif(pw == nil)\n-\t\treturn \"none\";\n-\tstrecpy(user, user+sizeof user, pw->pw_name);\n-\treturn user;\n-}\
```
このファイルには、`getuser()`関数の具体的なC言語による実装が含まれていました。
## コアとなるコードの解説
### `include/libc.h` からの宣言削除
`include/libc.h`は、`lib9`ライブラリのC言語関数群の宣言を含むヘッダーファイルです。ここから`getuser()`, `mktemp()`, `opentemp()`, `searchpath()`の宣言が削除されたことは、これらの関数がGoプロジェクトのCコードベースのどこからも呼び出されなくなったことを意味します。Cコンパイラは、これらの宣言がなくても、もしどこかで関数が定義されていればリンク時に解決しようとしますが、宣言が不要になったということは、その関数自体がGoプロジェクトのビルドプロセスから完全に排除されるか、Goネイティブな代替に置き換えられたことを示唆しています。これは、コードの依存関係を減らし、ビルドプロセスを簡素化する上で重要なステップです。
### `src/lib9/getuser.c` の削除
`src/lib9/getuser.c`ファイルは、`getuser()`関数の具体的な実装を提供していました。このファイルが完全に削除されたことは、この機能がGoプロジェクトにとって完全に不要になったか、あるいはGo言語の標準ライブラリ内でGoネイティブな実装に置き換えられたことを意味します。
`getuser.c`の内部実装は以下の通りでした。
```c
char*
getuser(void)
{
static char user[64];
struct passwd *pw;
pw = getpwuid(getuid());
if(pw == nil)
return "none";
strecpy(user, user+sizeof user, pw->pw_name);
return user;
}
このコードは、Unix系システムでユーザー情報を取得するための標準的なCライブラリ関数であるgetuid()
(現在のユーザーIDを取得)とgetpwuid()
(ユーザーIDからパスワードエントリを取得)を使用しています。取得したパスワードエントリ構造体pw
からユーザー名(pw->pw_name
)を取り出し、静的バッファuser
にコピーして返していました。
このファイルの削除は、Go言語がC言語のシステムコールに直接依存する部分を減らし、よりプラットフォームに依存しないGoネイティブなAPI(例えば、os/user
パッケージ)に移行する戦略の一環と見なすことができます。これにより、Goプログラムの移植性が向上し、Cgo(GoからCコードを呼び出すメカニズム)のオーバーヘッドを削減できる可能性があります。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/148154b7e7bb026e91208344b3c9c27af7226272
- Go Change List (CL): https://golang.org/cl/6820115
参考にした情報源リンク
- Plan 9 from User Space: http://code.swtch.com/plan9port/src/tip/src/lib9/getuser.c (削除された
getuser.c
の元のソースコードへのリンク) - Go言語の
os/user
パッケージ: https://pkg.go.dev/os/user (Goネイティブなユーザー情報取得APIの例) - C言語
mktemp
のmanページ (セキュリティに関する注意喚起): https://man7.org/linux/man-pages/man3/mktemp.3.html - C言語
getpwuid
のmanページ: https://man7.org/linux/man-pages/man3/getpwuid.3.html - C言語
extern
キーワード: (一般的なC言語のチュートリアルやリファレンス) - Go言語の歴史とPlan 9の影響: (Go言語の公式ドキュメントや歴史に関する記事)