Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 19701] ファイルの概要

このコミットは、Go言語のosパッケージにおける一時ディレクトリの決定ロジックに関するものです。特に、Androidプラットフォームにおいて、一時ディレクトリとして/tmpではなく/data/local/tmpを使用するように変更することで、GoアプリケーションがAndroid環境で正しく一時ファイルを作成できるようにすることを目的としています。

コミット

commit c4b714d3fe36fe5c1928711940a9e7b8c9fb7db3
Author: David Crawshaw <david.crawshaw@zentus.com>
Date:   Wed Jul 9 14:12:30 2014 -0400

    os: no /tmp on android
    
    LGTM=minux, bradfitz
    R=golang-codereviews, minux, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/104650043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/c4b714d3fe36fe5c1928711940a9e7b8c9fb7db3

元コミット内容

このコミットは、「os: no /tmp on android」という簡潔なメッセージで、GoのosパッケージがAndroid上で/tmpを使用しないように変更されたことを示しています。これは、Android環境における一時ファイルの取り扱いに関する互換性の問題を解決するための修正です。

変更の背景

Go言語のosパッケージには、一時ファイルを保存するためのディレクトリパスを返すTempDir()関数があります。この関数は通常、環境変数TMPDIRが設定されていればその値を使用し、設定されていなければUnix系システムではデフォルトで/tmpを返します。

しかし、Androidのファイルシステム構造は一般的なUnix系システムとは異なり、/tmpディレクトリは通常存在しないか、存在してもアプリケーションが書き込み権限を持たないことがほとんどです。そのため、GoアプリケーションがAndroid上でTempDir()関数を呼び出し、その結果として/tmpが返されると、一時ファイルの作成に失敗し、アプリケーションが正常に動作しない問題が発生していました。

このコミットは、Androidプラットフォームに特化した修正を導入することで、この問題を解決し、GoアプリケーションがAndroid環境でも一時ファイルを適切に扱えるようにすることを目的としています。

前提知識の解説

os.TempDir()関数

Go言語のosパッケージが提供するTempDir()関数は、一時ファイルを保存するための適切なディレクトリのパスを返します。この関数は、以下のロジックでパスを決定します。

  1. 環境変数TMPDIRが設定されている場合、その値を使用します。
  2. TMPDIRが設定されていない場合、オペレーティングシステムに応じたデフォルトのパスを使用します。
    • Unix系システム(Linux, macOSなど)では、通常/tmpが使用されます。
    • Windowsでは、TEMPまたはTMP環境変数が使用されます。

この関数は、アプリケーションが一時的なデータを保存する際に、プラットフォームに依存しない方法で適切な場所を見つけるために利用されます。

/tmpディレクトリ

/tmpは、Unix系オペレーティングシステムにおいて、一時的なファイルを保存するために広く使用されるディレクトリです。このディレクトリは、システムが再起動されると内容がクリアされることが一般的であり、アプリケーションが一時的な作業ファイルやキャッシュなどを保存するのに適しています。通常、すべてのユーザーが書き込み権限を持っています。

Androidのファイルシステム構造

AndroidはLinuxカーネルをベースにしていますが、そのファイルシステム構造は一般的なLinuxディストリビューションとは大きく異なります。セキュリティとアプリケーションの分離を重視しているため、各アプリケーションはサンドボックス化されており、特定のディレクトリにのみアクセスが許可されています。

  • /tmp: Androidでは、/tmpディレクトリは通常存在しません。存在したとしても、一般のアプリケーションが書き込み権限を持つことはありません。
  • /data: アプリケーションのデータは/dataパーティションに保存されます。
    • /data/data/<package_name>: 各アプリケーションのプライベートデータディレクトリです。他のアプリケーションからはアクセスできません。
    • /data/local/tmp: これは、開発やデバッグの目的で一時ファイルを保存するために使用されることがあるディレクトリです。一般的なアプリケーションが直接使用するものではありませんが、システムレベルのツールや一部のネイティブコードが一時的に利用する場合があります。このコミットでは、GoランタイムがAndroid上で一時ディレクトリとして利用できる場所として、このパスが選択されました。

技術的詳細

このコミットの技術的な核心は、Goのos.TempDir()関数が、実行環境がAndroidであるかどうかを判断し、その判断に基づいて異なる一時ディレクトリパスを返すように変更された点です。

変更前は、TempDir()関数はTMPDIR環境変数が設定されていない場合、無条件に/tmpを返していました。これは、一般的なUnix系システムでは問題ありませんが、/tmpが存在しないか書き込み権限がないAndroidでは問題となります。

変更後は、runtime.GOOSというGoの組み込み変数を使用して、現在のオペレーティングシステムが"android"であるかどうかをチェックします。

  • もしruntime.GOOS"android"であれば、dir変数に/data/local/tmpが設定されます。
  • そうでなければ(つまり、Android以外のUnix系システムであれば)、これまで通り/tmpが設定されます。

この条件分岐により、GoアプリケーションはAndroid環境下で一時ファイルを/data/local/tmpに作成しようと試みるようになり、一般的なUnix系システムでは引き続き/tmpを使用するという、プラットフォームに合わせた適切な挙動を実現しています。

/data/local/tmpは、Androidデバイス上で一時的なファイルを保存するための、より適切な場所です。これは、開発者や一部のシステムプロセスが利用できる領域であり、Goランタイムが一時ファイルを扱う上で現実的な選択肢となります。

コアとなるコードの変更箇所

src/pkg/os/file_unix.goファイルのTempDir()関数が変更されました。

--- a/src/pkg/os/file_unix.go
+++ b/src/pkg/os/file_unix.go
@@ -308,7 +308,11 @@ func basename(name string) string {
 func TempDir() string {
 	dir := Getenv("TMPDIR")
 	if dir == "" {
-		dir = "/tmp"
+		if runtime.GOOS == "android" {
+			dir = "/data/local/tmp"
+		} else {
+			dir = "/tmp"
+		}
 	}
 	return dir
 }

コアとなるコードの解説

変更されたTempDir()関数のコードを詳しく見ていきます。

func TempDir() string {
	dir := Getenv("TMPDIR") // 環境変数TMPDIRの値を取得
	if dir == "" {          // TMPDIRが設定されていない場合
		if runtime.GOOS == "android" { // 現在のOSがAndroidであるかチェック
			dir = "/data/local/tmp"    // Androidの場合は/data/local/tmpを使用
		} else {
			dir = "/tmp"               // それ以外(Unix系)の場合は/tmpを使用
		}
	}
	return dir // 決定された一時ディレクトリパスを返す
}
  1. dir := Getenv("TMPDIR"): まず、TMPDIRという環境変数の値を取得し、dir変数に格納します。Goのos.Getenv関数は、指定された環境変数の値を文字列として返します。もし環境変数が設定されていない場合、空文字列を返します。
  2. if dir == "": TMPDIR環境変数が設定されていなかった場合(つまり、dirが空文字列の場合)に、デフォルトの一時ディレクトリパスを決定するロジックに入ります。
  3. if runtime.GOOS == "android": ここがこのコミットの主要な変更点です。runtime.GOOSは、Goプログラムがコンパイルされ、現在実行されているオペレーティングシステムの名前を文字列で保持する組み込み変数です。この条件文は、現在のOSが"android"であるかどうかをチェックします。
    • もしruntime.GOOS"android"と一致する場合、dir変数に"/data/local/tmp"が代入されます。これは、Android環境で一時ファイルを保存するための適切なパスです。
    • elseブロック: runtime.GOOS"android"ではない場合(つまり、Linux、macOSなどの他のUnix系システムの場合)、dir変数には"/tmp"が代入されます。これは、従来のUnix系システムにおけるデフォルトの一時ディレクトリパスです。
  4. return dir: 最終的に、決定された一時ディレクトリのパスが関数の呼び出し元に返されます。

この変更により、GoアプリケーションはAndroid環境で一時ファイルを扱う際に、より適切なパスを選択できるようになり、互換性と安定性が向上しました。

関連リンク

参考にした情報源リンク

  • Go言語のosパッケージドキュメント: https://pkg.go.dev/os
  • Androidファイルシステムに関する一般的な情報 (Web検索結果に基づく)
  • Unix系システムにおける/tmpディレクトリに関する一般的な情報 (Web検索結果に基づく)
  • runtimeパッケージドキュメント: https://pkg.go.dev/runtime

[インデックス 19701] ファイルの概要

このコミットは、Go言語のosパッケージにおける一時ディレクトリの決定ロジックに関するものです。特に、Androidプラットフォームにおいて、一時ディレクトリとして/tmpではなく/data/local/tmpを使用するように変更することで、GoアプリケーションがAndroid環境で正しく一時ファイルを作成できるようにすることを目的としています。

コミット

commit c4b714d3fe36fe5c1928711940a9e7b8c9fb7db3
Author: David Crawshaw <david.crawshaw@zentus.com>
Date:   Wed Jul 9 14:12:30 2014 -0400

    os: no /tmp on android
    
    LGTM=minux, bradfitz
    R=golang-codereviews, minux, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/104650043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/c4b714d3fe36fe5c1928711940a9e7b8c9fb7db3

元コミット内容

このコミットは、「os: no /tmp on android」という簡潔なメッセージで、GoのosパッケージがAndroid上で/tmpを使用しないように変更されたことを示しています。これは、Android環境における一時ファイルの取り扱いに関する互換性の問題を解決するための修正です。

変更の背景

Go言語のosパッケージには、一時ファイルを保存するためのディレクトリパスを返すTempDir()関数があります。この関数は通常、環境変数TMPDIRが設定されていればその値を使用し、設定されていなければUnix系システムではデフォルトで/tmpを返します。

しかし、Androidのファイルシステム構造は一般的なUnix系システムとは異なり、/tmpディレクトリは通常存在しないか、存在してもアプリケーションが書き込み権限を持たないことがほとんどです。Androidアプリケーションは通常、Context.getCacheDir()Context.getExternalCacheDir()といったAPIを通じて、アプリケーション固有のキャッシュディレクトリを利用して一時ファイルを扱います。

GoランタイムがAndroid上で動作する場合、一般的なUnix系システムと同様に/tmpを使用しようとすると、一時ファイルの作成に失敗し、Goアプリケーションが正常に動作しない問題が発生していました。このコミットは、GoランタイムがAndroid環境で一時ファイルを扱う際に、より適切な場所である/data/local/tmpを使用するように変更することで、この問題を解決し、GoアプリケーションがAndroid環境でも一時ファイルを適切に扱えるようにすることを目的としています。/data/local/tmpは、Androidデバイス上で開発やデバッグの目的で一時ファイルを保存するために使用されることがあり、Goランタイムのような低レベルのプロセスにとってはアクセス可能な場所となり得ます。

前提知識の解説

os.TempDir()関数

Go言語のosパッケージが提供するTempDir()関数は、一時ファイルを保存するための適切なディレクトリのパスを返します。この関数は、以下のロジックでパスを決定します。

  1. 環境変数TMPDIRが設定されている場合、その値を使用します。
  2. TMPDIRが設定されていない場合、オペレーティングシステムに応じたデフォルトのパスを使用します。
    • Unix系システム(Linux, macOSなど)では、通常/tmpが使用されます。
    • Windowsでは、TEMPまたはTMP環境変数が使用されます。

この関数は、アプリケーションが一時的なデータを保存する際に、プラットフォームに依存しない方法で適切な場所を見つけるために利用されます。

/tmpディレクトリ

/tmpは、Unix系オペレーティングシステムにおいて、一時的なファイルを保存するために広く使用されるディレクトリです。このディレクトリは、システムが再起動されると内容がクリアされることが一般的であり、アプリケーションが一時的な作業ファイルやキャッシュなどを保存するのに適しています。通常、すべてのユーザーが書き込み権限を持っています。

Androidのファイルシステム構造と一時ファイル

AndroidはLinuxカーネルをベースにしていますが、そのファイルシステム構造は一般的なLinuxディストリビューションとは大きく異なります。セキュリティとアプリケーションの分離を重視しているため、各アプリケーションはサンドボックス化されており、特定のディレクトリにのみアクセスが許可されています。

  • /tmp: Androidでは、/tmpディレクトリは通常存在しません。存在したとしても、一般のアプリケーションが書き込み権限を持つことはありません。
  • アプリケーション固有のキャッシュディレクトリ: Androidアプリケーションは通常、Java/KotlinのContext.getCacheDir()(内部ストレージ)やContext.getExternalCacheDir()(外部ストレージ)といったAPIを使用して、アプリケーション固有の一時ファイルを保存します。これらのディレクトリは、システムによってストレージが不足した場合にクリアされる可能性があります。
  • /data/local/tmp: これは、開発やデバッグの目的、あるいは一部のシステムレベルのプロセスが一時ファイルを保存するために使用されることがあるディレクトリです。一般的なアプリケーションが直接使用するものではありませんが、Goランタイムのような低レベルのコンポーネメントが一時ディレクトリとして利用できる場合があります。

技術的詳細

このコミットの技術的な核心は、Goのos.TempDir()関数が、実行環境がAndroidであるかどうかを判断し、その判断に基づいて異なる一時ディレクトリパスを返すように変更された点です。

変更前は、TempDir()関数はTMPDIR環境変数が設定されていない場合、無条件に/tmpを返していました。これは、一般的なUnix系システムでは問題ありませんが、/tmpが存在しないか書き込み権限がないAndroidでは問題となります。

変更後は、runtime.GOOSというGoの組み込み変数を使用して、現在のオペレーティングシステムが"android"であるかどうかをチェックします。

  • もしruntime.GOOS"android"であれば、dir変数に/data/local/tmpが設定されます。
  • そうでなければ(つまり、Android以外のUnix系システムであれば)、これまで通り/tmpが設定されます。

この条件分岐により、GoアプリケーションはAndroid環境下で一時ファイルを/data/local/tmpに作成しようと試みるようになり、一般的なUnix系システムでは引き続き/tmpを使用するという、プラットフォームに合わせた適切な挙動を実現しています。

/data/local/tmpは、Androidデバイス上で一時的なファイルを保存するための、より適切な場所です。これは、開発者や一部のシステムプロセスが利用できる領域であり、Goランタイムが一時ファイルを扱う上で現実的な選択肢となります。この変更は、GoアプリケーションがAndroid上でより堅牢に動作するための重要なステップです。

コアとなるコードの変更箇所

src/pkg/os/file_unix.goファイルのTempDir()関数が変更されました。

--- a/src/pkg/os/file_unix.go
+++ b/src/pkg/os/file_unix.go
@@ -308,7 +308,11 @@ func basename(name string) string {
 func TempDir() string {
 	dir := Getenv("TMPDIR")
 	if dir == "" {
-		dir = "/tmp"
+		if runtime.GOOS == "android" {
+			dir = "/data/local/tmp"
+		} else {
+			dir = "/tmp"
+		}
 	}
 	return dir
 }

コアとなるコードの解説

変更されたTempDir()関数のコードを詳しく見ていきます。

func TempDir() string {
	dir := Getenv("TMPDIR") // 環境変数TMPDIRの値を取得
	if dir == "" {          // TMPDIRが設定されていない場合
		if runtime.GOOS == "android" { // 現在のOSがAndroidであるかチェック
			dir = "/data/local/tmp"    // Androidの場合は/data/local/tmpを使用
		} else {
			dir = "/tmp"               // それ以外(Unix系)の場合は/tmpを使用
		}
	}
	return dir // 決定された一時ディレクトリパスを返す
}
  1. dir := Getenv("TMPDIR"): まず、TMPDIRという環境変数の値を取得し、dir変数に格納します。Goのos.Getenv関数は、指定された環境変数の値を文字列として返します。もし環境変数が設定されていない場合、空文字列を返します。
  2. if dir == "": TMPDIR環境変数が設定されていなかった場合(つまり、dirが空文字列の場合)に、デフォルトの一時ディレクトリパスを決定するロジックに入ります。
  3. if runtime.GOOS == "android": ここがこのコミットの主要な変更点です。runtime.GOOSは、Goプログラムがコンパイルされ、現在実行されているオペレーティングシステムの名前を文字列で保持する組み込み変数です。この条件文は、現在のOSが"android"であるかどうかをチェックします。
    • もしruntime.GOOS"android"と一致する場合、dir変数に"/data/local/tmp"が代入されます。これは、Android環境で一時ファイルを保存するための適切なパスです。
    • elseブロック: runtime.GOOS"android"ではない場合(つまり、Linux、macOSなどの他のUnix系システムの場合)、dir変数には"/tmp"が代入されます。これは、従来のUnix系システムにおけるデフォルトの一時ディレクトリパスです。
  4. return dir: 最終的に、決定された一時ディレクトリのパスが関数の呼び出し元に返されます。

この変更により、GoアプリケーションはAndroid環境で一時ファイルを扱う際に、より適切なパスを選択できるようになり、互換性と安定性が向上しました。

関連リンク

参考にした情報源リンク