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

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

このコミットは、Go言語の syscall パッケージにおけるPlan 9ビルドに関する修正を目的としています。具体的には、システムコールからのエラーハンドリングの改善と、関連するコードのクリーンアップが行われています。

コミット

commit 8ec32e8d84c1ec2f0a843e1ecfce7052842c8461
Author: Lucio De Re <lucio.dere@gmail.com>
Date:   Mon Nov 21 09:55:15 2011 -0500

    syscall: fix for Plan 9 build

    exec_plan9.go:
    . Adjusted return argument to match other changes.
    #mksyscall.pl:
    . Replaced "err = e1" with "err = NewError(e1)".
    * Change abandoned, Russ made a better suggestion involving
      syscall_plan9.go.
    syscall_plan9.go:
    . Removed redundant "err = nil" lines.
    . Adjusted //sys lines for mksyscall.pl.
    * Replaced "err string" with "err ErrorString" in return arguments.
    zsyscall_plan9_386.go:
    . This module ought to be generated, but as it exists in the
      repository, I rebuilt it and checked that it matched expectations.
      Anybody is welcome to remove this from the repository if
      they feel it should go, but remember that not all Plan 9
      installations have a working Perl.

    R=rsc
    CC=ality, golang-dev
    https://golang.org/cl/5411046

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

https://github.com/golang/go/commit/8ec32e8d84c1ec2f0a843e1ecfce7052842c8461

元コミット内容

このコミットは、Go言語の syscall パッケージにおけるPlan 9固有のビルド問題を解決するためのものです。主な変更点は以下の通りです。

  • exec_plan9.go: 戻り値の引数が他の変更と一致するように調整されました。
  • mksyscall.pl: 当初提案された err = NewError(e1) という変更は破棄され、syscall_plan9.go に関連するより良い提案が採用されました。これはエラー処理の戦略変更を示唆しています。
  • syscall_plan9.go:
    • 冗長な err = nil の行が削除されました。
    • mksyscall.pl のための //sys 行が調整されました。
    • 戻り値の引数において、エラー型が string から ErrorString に変更されました。これはこのコミットの最も重要な変更点の一つです。
  • zsyscall_plan9_386.go: このファイルは本来自動生成されるべきものですが、リポジトリに存在していたため、再ビルドされ、期待通りに動作することが確認されました。Plan 9環境によってはPerlが動作しない場合があるため、このファイルの存在意義についてコメントが残されています。

変更の背景

Go言語は、その設計当初から複数のオペレーティングシステム(OS)をサポートすることを目指していました。Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、Go言語の開発者の一部がPlan 9の経験者であったため、Goの初期段階からサポート対象となっていました。

syscall パッケージは、GoプログラムがOSのシステムコールを直接呼び出すためのインターフェースを提供します。OSごとにシステムコールのインターフェースやエラーの表現方法が異なるため、各OS向けに固有の実装が必要となります。

このコミットが行われた2011年当時、Go言語はまだ活発に開発されており、APIの安定化や改善が頻繁に行われていました。特に、エラーハンドリングはGo言語の重要な設計原則の一つであり、その表現方法や伝播方法については継続的に議論され、改善が加えられていました。

このコミットの背景には、Plan 9環境における syscall パッケージのビルドが正しく行われない、またはエラーハンドリングの整合性が取れていないという問題があったと考えられます。特に、システムコールが返すエラーの型が string であったことが、Goのエラーインターフェースの進化と合致しなくなっていた可能性があります。Goのエラーは error インターフェースを実装する型であるべきであり、単なる string ではないため、この変更はGoのエラーハンドリングの慣習に合わせるための重要なステップでした。

また、mksyscall.pl の変更が破棄され、syscall_plan9.go で直接エラー型を変更するアプローチが採用されたことは、自動生成スクリプトに依存するよりも、Goのコード内で直接型を定義・使用する方が、より柔軟でGoらしいエラーハンドリングを実現できるという判断があったことを示唆しています。

前提知識の解説

1. Plan 9

Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの後継として設計され、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルシステムとして表現するというユニークな哲学を持っています。Go言語の開発者の一部はPlan 9の設計に深く関わっており、Go言語の設計思想にもPlan 9の影響が見られます。

2. Go言語の syscall パッケージ

syscall パッケージは、Goプログラムが基盤となるオペレーティングシステムのシステムコールに直接アクセスするための低レベルなインターフェースを提供します。これにより、ファイル操作、プロセス管理、ネットワーク通信など、OSカーネルが提供する機能を利用できます。OSごとにシステムコールの呼び出し規約やエラーの返却方法が異なるため、syscall パッケージは各OS(Linux, Windows, macOS, Plan 9など)向けに異なる実装を持っています。

3. Go言語のエラーハンドリング

Go言語では、エラーは組み込みの error インターフェースによって表現されます。このインターフェースは、Error() string というメソッドを一つだけ持ちます。慣習として、関数は通常、最後の戻り値として error 型の値を返します。エラーが発生しなかった場合は nil を返し、エラーが発生した場合は nil ではない error 値を返します。

初期のGo言語では、システムコールからのエラーが string 型で返されることがありましたが、これはGoのエラーハンドリングの慣習とは異なります。このコミットは、この不整合を解消し、よりGoらしいエラーハンドリングに近づけるためのものです。

4. mksyscall.pl//sys ディレクティブ

mksyscall.pl は、Goの syscall パッケージでシステムコールを自動生成するためのPerlスクリプトです。Goのソースコード内に //sys という特殊なコメント行を記述することで、このスクリプトがそのコメントを解析し、対応するシステムコールラッパー関数を生成します。これにより、各OSのシステムコールをGoから呼び出すためのボイラープレートコードの手間を省くことができます。

このコミットでは、mksyscall.pl の生成ロジックに影響を与える //sys 行の調整が行われています。

5. zsyscall_*.go ファイル

zsyscall_*.go という命名規則のファイルは、通常 mksyscall.pl のようなツールによって自動生成されるGoのソースファイルです。これらのファイルには、システムコールを呼び出すための低レベルなGoコードが含まれています。自動生成されるため、手動で編集することは推奨されません。

技術的詳細

このコミットの技術的詳細は、Go言語の syscall パッケージにおけるPlan 9固有のエラーハンドリングの改善に集約されます。

1. エラー型の変更: string から ErrorString

最も重要な変更は、syscall_plan9.go における Syscall および Syscall6 関数の戻り値の型が err string から err ErrorString に変更された点です。

  • 変更前: func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string)
  • 変更後: func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString)

ここで ErrorString は、Goの error インターフェースを実装するカスタム型であると推測されます。これにより、システムコールが返すエラーがGoのエラーハンドリングの慣習に沿うようになります。NewError(e1) のような関数は、おそらく string 型のエラーメッセージを受け取り、それを ErrorString 型(または error インターフェースを実装する別の型)にラップして返す役割を担っていたと考えられます。

exec_plan9.goExec 関数では、以前は NewError(e) を呼び出してエラーをラップしていましたが、この変更により、Syscall が直接 ErrorString を返すようになったため、e1 をそのまま返すように修正されています。

2. 冗長な err = nil の削除

syscall_plan9.go および zsyscall_plan9_386.go の複数の箇所で、err = nil という冗長な行が削除されています。Go言語では、関数の戻り値として名前付き戻り値(named return values)を使用する場合、関数が正常に終了すると、名前付き戻り値は自動的にゼロ値(エラー型の場合は nil)に初期化されます。したがって、明示的に err = nil と記述する必要はありません。この変更はコードのクリーンアップとGoの慣習への準拠を目的としています。

3. mksyscall.pl//sys ディレクティブの調整

syscall_plan9.go 内の //sys コメント行が調整されています。これは、mksyscall.pl スクリプトがこれらのコメントを解析してシステムコールラッパーを生成する際に、新しいエラー型 error (Goの組み込みインターフェース) を正しく認識し、適切なコードを生成できるようにするためです。

元のコミットメッセージでは、mksyscall.plerr = NewError(e1)err = e1 に置き換える変更が検討されたものの、最終的には破棄され、syscall_plan9.go で直接エラー型を変更するアプローチが採用されたことが示されています。これは、自動生成されるコードの複雑さを減らし、Goのコード内でエラーハンドリングのロジックをより直接的に制御することを意図していると考えられます。

4. zsyscall_plan9_386.go の再ビルドと検証

zsyscall_plan9_386.go は自動生成されるファイルであるため、上記の変更(特に syscall_plan9.go//sys 行の変更)が反映されるように再ビルドされました。コミットメッセージには、Plan 9環境によってはPerlが利用できない場合があるため、このファイルがリポジトリに存在することの是非についてのコメントが含まれています。これは、ビルド環境の多様性に対応するための配慮を示しています。

これらの変更は、Go言語の syscall パッケージがPlan 9環境でより堅牢に動作し、Goのエラーハンドリングのベストプラクティスに準拠するようにするための重要なステップでした。

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

src/pkg/syscall/exec_plan9.go

--- a/src/pkg/syscall/exec_plan9.go
+++ b/src/pkg/syscall/exec_plan9.go
@@ -516,10 +516,10 @@ func Exec(argv0 string, argv []string, envv []string) (err error) {
 		}
 	}
 
-	_, _, e := Syscall(SYS_EXEC,
+	_, _, e1 := Syscall(SYS_EXEC,
 		uintptr(unsafe.Pointer(StringBytePtr(argv0))),
 		uintptr(unsafe.Pointer(&StringSlicePtr(argv)[0])),
 		0)
 
-	return NewError(e)
+	return e1
 }

src/pkg/syscall/syscall_plan9.go

--- a/src/pkg/syscall/syscall_plan9.go
+++ b/src/pkg/syscall/syscall_plan9.go
@@ -38,8 +38,8 @@ var (
 // creation of IPv6 sockets to return EAFNOSUPPORT.
 var SocketDisableIPv6 bool
 
-func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string)
-func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err string)
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString)
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString)
 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
 
@@ -170,7 +170,6 @@ func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int6
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
 	newoffset, e := seek(0, fd, offset, whence)
 
-\terr = nil
 \tif newoffset == -1 {\n \t\terr = NewError(e)\n \t}\n@@ -246,7 +245,7 @@ func Unmount(name, old string) (err error) {\n \toldp := uintptr(unsafe.Pointer(StringBytePtr(old)))\n \n \tvar r0 uintptr\n-\tvar e string\n+\tvar e ErrorString\n \n \t// bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.\n \tif name == \"\" {\n@@ -255,9 +254,8 @@ func Unmount(name, old string) (err error) {\n \t\tr0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(StringBytePtr(name))), oldp, 0)\n \t}\n \n-\terr = nil\n \tif int(r0) == -1 {\n-\t\terr = NewError(e)\n+\t\terr = e\n \t}\n \treturn\n }\n@@ -288,7 +286,6 @@ func DecodeBintime(b []byte) (nsec int64, err error) {\n \tif len(b) != 8 {\n \t\treturn -1, NewError(\"bad /dev/bintime format\")\n \t}\n-\terr = nil
 \tnsec = int64(b[0])<<56 |\n \t\tint64(b[1])<<48 |\n \t\tint64(b[2])<<40 |\n@@ -335,17 +332,17 @@ func Getgroups() (gids []int, err error) {\n \treturn make([]int, 0), nil\n }\n \n-//sys\tDup(oldfd int, newfd int) (fd int, err Error)\n-//sys\tOpen(path string, mode int) (fd int, err Error)\n-//sys\tCreate(path string, mode int, perm uint32) (fd int, err Error)\n-//sys\tRemove(path string) (err Error)\n-//sys\tPread(fd int, p []byte, offset int64) (n int, err Error)\n-//sys\tPwrite(fd int, p []byte, offset int64) (n int, err Error)\n-//sys\tClose(fd int) (err Error)\n-//sys\tChdir(path string) (err Error)\n-//sys\tBind(name string, old string, flag int) (err Error)\n-//sys\tMount(fd int, afd int, old string, flag int, aname string) (err Error)\n-//sys\tStat(path string, edir []byte) (n int, err Error)\n-//sys\tFstat(fd int, edir []byte) (n int, err Error)\n-//sys\tWstat(path string, edir []byte) (err Error)\n-//sys\tFwstat(fd int, edir []byte) (err Error)\n+//sys\tDup(oldfd int, newfd int) (fd int, err error)\n+//sys\tOpen(path string, mode int) (fd int, err error)\n+//sys\tCreate(path string, mode int, perm uint32) (fd int, err error)\n+//sys\tRemove(path string) (err error)\n+//sys\tPread(fd int, p []byte, offset int64) (n int, err error)\n+//sys\tPwrite(fd int, p []byte, offset int64) (n int, err error)\n+//sys\tClose(fd int) (err error)\n+//sys\tChdir(path string) (err error)\n+//sys\tBind(name string, old string, flag int) (err error)\n+//sys\tMount(fd int, afd int, old string, flag int, aname string) (err error)\n+//sys\tStat(path string, edir []byte) (n int, err error)\n+//sys\tFstat(fd int, edir []byte) (n int, err error)\n+//sys\tWstat(path string, edir []byte) (err error)\n+//sys\tFwstat(fd int, edir []byte) (err error)

src/pkg/syscall/zsyscall_plan9_386.go

--- a/src/pkg/syscall/zsyscall_plan9_386.go
+++ b/src/pkg/syscall/zsyscall_plan9_386.go
@@ -22,9 +22,8 @@ func fd2path(fd int, buf []byte) (err error) {\n 		_p0 = unsafe.Pointer(&_zero)\n 	}\n 	r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n 	return\n }\n@@ -33,20 +32,8 @@ func fd2path(fd int, buf []byte) (err error) {\n 
 func pipe(p *[2]_C_int) (err error) {\n 	r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n-\t}\n-\treturn\n-}\n-\n-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n-\n-func sleep(millisecs int32) (err error) {\n-\tr0, _, e1 := Syscall(SYS_SLEEP, uintptr(millisecs), 0, 0)\n-\terr = nil
-\tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -62,9 +49,8 @@ func await(s []byte) (n int, err error) {\n 	}\n 	r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)\n 	n = int(r0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n 	return\n }\n@@ -74,9 +60,8 @@ func await(s []byte) (n int, err error) {\n func Dup(oldfd int, newfd int) (fd int, err error) {\n 	r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)\n 	fd = int(r0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n 	return\n }\n@@ -86,9 +71,8 @@ func Dup(oldfd int, newfd int) (fd int, err error) {\n func Open(path string, mode int) (fd int, err error) {\n 	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0)\n 	fd = int(r0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n 	return\n }\n@@ -98,9 +82,8 @@ func Open(path string, mode int) (fd int, err error) {\n func Create(path string, mode int, perm uint32) (fd int, err error) {\n 	r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(perm))\n 	fd = int(r0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -109,9 +92,8 @@ func Create(path string, mode int, perm uint32) (fd int, err error) {\n 
 func Remove(path string) (err error) {\n 	r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -127,9 +109,8 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {\n 	}\n 	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)\n 	n = int(r0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -145,9 +126,8 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) {\n 	}\n 	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)\n 	n = int(r0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -156,9 +136,8 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) {\n 
 func Close(fd int) (err error) {\n 	r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -167,9 +146,8 @@ func Close(fd int) (err error) {\n 
 func Chdir(path string) (err error) {\n 	r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -178,9 +156,8 @@ func Chdir(path string) (err error) {\n 
 func Bind(name string, old string, flag int) (err error) {\n 	r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(StringBytePtr(name))), uintptr(unsafe.Pointer(StringBytePtr(old))), uintptr(flag))\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -189,9 +166,8 @@ func Bind(name string, old string, flag int) (err error) {\n 
 func Mount(fd int, afd int, old string, flag int, aname string) (err error) {\n 	r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(StringBytePtr(old))), uintptr(flag), uintptr(unsafe.Pointer(StringBytePtr(aname))), 0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -207,9 +183,8 @@ func Stat(path string, edir []byte) (n int, err error) {\n 	}\n 	r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(_p0), uintptr(len(edir)))\n 	n = int(r0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -225,9 +200,8 @@ func Fstat(fd int, edir []byte) (n int, err error) {\n 	}\n 	r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))\n 	n = int(r0)\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -242,9 +216,8 @@ func Wstat(path string, edir []byte) (err error) {\n 		_p0 = unsafe.Pointer(&_zero)\n 	}\n 	r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(_p0), uintptr(len(edir)))\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n@@ -259,9 +232,8 @@ func Fwstat(fd int, edir []byte) (err error) {\n 		_p0 = unsafe.Pointer(&_zero)\n 	}\n 	r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))\n-\terr = nil
 \tif int(r0) == -1 {\n-\t\terr = NewError(e1)\n+\t\terr = e1
 \t}\n \treturn\n }\n```

## コアとなるコードの解説

### `src/pkg/syscall/exec_plan9.go` の変更

`Exec` 関数は、指定されたプログラムを実行するためのシステムコールを呼び出します。
変更前は、`Syscall` から返されたエラー `e` を `NewError(e)` でラップして返していました。
変更後は、`Syscall` 関数自体の戻り値の型が `ErrorString` に変更されたため、`NewError` でラップする必要がなくなり、`e1` を直接返すように修正されました。これは、エラーの型がGoのエラーインターフェースに準拠するようになったことを示しています。

### `src/pkg/syscall/syscall_plan9.go` の変更

1.  **`Syscall` および `Syscall6` 関数の戻り値の型変更**:
    *   `Syscall` と `Syscall6` は、それぞれ3つまたは6つの引数を持つシステムコールを呼び出すためのGoのラッパー関数です。
    *   変更前は、これらの関数のエラー戻り値の型が `string` でした。
    *   変更後は、エラー戻り値の型が `ErrorString` に変更されました。これは、Goのエラーハンドリングの慣習に合わせるための重要な変更であり、`ErrorString` が `error` インターフェースを実装していることを意味します。

2.  **冗長な `err = nil` の削除**:
    *   `Seek`, `Unmount`, `DecodeBintime` 関数内で、システムコール呼び出し後に `err = nil` と明示的に設定している行が削除されました。
    *   Goでは、名前付き戻り値(`err error` のように戻り値に名前を付けること)を使用する場合、関数が正常に終了すると、名前付き戻り値は自動的にその型のゼロ値(`error` 型の場合は `nil`)に初期化されます。したがって、エラーがない場合に明示的に `nil` を代入する必要はありません。この変更はコードの簡潔化とGoの慣習への準拠を目的としています。

3.  **`Unmount` 関数におけるエラーの伝播**:
    *   `Unmount` 関数では、システムコールが失敗した場合に `NewError(e)` を呼び出してエラーをラップしていましたが、`Syscall` の戻り値の型が `ErrorString` に変更されたため、`e` を直接返すように修正されました。

4.  **`//sys` ディレクティブの変更**:
    *   `Dup`, `Open`, `Create` などのシステムコールラッパー関数の定義を示す `//sys` コメント行において、エラー戻り値の型が `err Error` から `err error` に変更されました。
    *   これは、`mksyscall.pl` スクリプトがこれらのコメントを解析してGoのシステムコールラッパーを生成する際に、Goの組み込み `error` インターフェースを正しく使用するように指示するためのものです。これにより、生成されるコードがGoのエラーハンドリングの標準に準拠するようになります。

### `src/pkg/syscall/zsyscall_plan9_386.go` の変更

このファイルは `mksyscall.pl` によって自動生成されるため、手動での変更は推奨されません。このコミットでは、`syscall_plan9.go` の `//sys` ディレクティブの変更が反映されるように、このファイルが再生成されました。

変更点としては、`fd2path`, `pipe`, `await`, `Dup`, `Open`, `Create`, `Remove`, `Pread`, `Pwrite`, `Close`, `Chdir`, `Bind`, `Mount`, `Stat`, `Fstat`, `Wstat`, `Fwstat` といった各システムコールラッパー関数において、以下の修正が行われています。

1.  **冗長な `err = nil` の削除**:
    *   `syscall_plan9.go` と同様に、各関数内でシステムコール呼び出し後に `err = nil` と明示的に設定している行が削除されました。

2.  **エラーの伝播の変更**:
    *   システムコールが失敗した場合に `NewError(e1)` を呼び出してエラーをラップしていましたが、`Syscall` または `Syscall6` の戻り値の型が `ErrorString` に変更されたため、`e1` を直接返すように修正されました。

また、`sleep` 関数がこのファイルから削除されています。これは、`sleep` がもはやシステムコールとして直接扱われるべきではない、あるいは別の方法で実装されるようになったことを示唆しています。

これらの変更は、Goの `syscall` パッケージがPlan 9環境でより一貫性のある、Goらしいエラーハンドリングを提供するようにするためのものです。

## 関連リンク

*   Go言語の `syscall` パッケージ: [https://pkg.go.dev/syscall](https://pkg.go.dev/syscall)
*   Plan 9 from Bell Labs: [https://9p.io/plan9/](https://9p.io/plan9/)
*   Go言語のエラーハンドリングに関する公式ドキュメント (Go 1.13以降のエラーラッピングを含む): [https://go.dev/blog/go1.13-errors](https://go.dev/blog/go1.13-errors)

## 参考にした情報源リンク

*   Go言語のコミット履歴 (GitHub): [https://github.com/golang/go/commits/master](https://github.com/golang/go/commits/master)
*   Go言語のGerritコードレビューシステム: [https://go.dev/cl/](https://go.dev/cl/)
*   このコミットのGerritチェンジリスト: [https://golang.org/cl/5411046](https://golang.org/cl/5411046)
*   Go言語のエラーハンドリングに関する一般的な情報: [https://go.dev/blog/error-handling-and-go](https://go.dev/blog/error-handling-and-go)
*   Go言語の `mksyscall.pl` スクリプトに関する情報 (Goのソースコードリポジトリ内): [https://github.com/golang/go/blob/master/src/syscall/mksyscall.pl](https://github.com/golang/go/blob/master/src/syscall/mksyscall.pl)