os: delete os.EINVAL and so on
The set of errors forwarded by the os package varied with system and
was therefore non-portable.
Three helpers added for portable error checking: IsExist, IsNotExist, and IsPermission.
One or two more may need to come, but let's keep the set very small to discourage
thinking about errors that way.
R=mikioh.mikioh, gustavo, r, rsc
CC=golang-dev
https://golang.org/cl/5672047
diff --git a/doc/go1.html b/doc/go1.html
index b1f9233..13d7401 100644
--- a/doc/go1.html
+++ b/doc/go1.html
@@ -1494,12 +1494,31 @@
The vast majority of uses of <code>FileInfo</code> need only the methods
of the standard interface.
</p>
-
+
+<p>
+The <code>os</code> package no longer contains wrappers for the POSIX errors
+such as <code>ENOENT</code>.
+For the few programs that need to verify particular error conditions, there are
+now the boolean functions
+<a href="/pkg/os/#IsExist"><code>IsExist</code></a>,
+<a href="/pkg/os/#IsNotExist"><code>IsNotExist</code></a>
+and
+<a href="/pkg/os/#IsPermission"><code>IsPermission</code></a>.
+</p>
+
+<pre><!--{{code "progs/go1.go" `/os\.Open/` `/}/`}}
+--> f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
+ if os.IsExist(err) {
+ log.Printf("%s already exists", name)
+ }</pre>
+
<p>
<em>Updating</em>:
Running <code>go fix</code> will update code that uses the old equivalent of the current <code>os.FileInfo</code>
and <code>os.FileMode</code> API.
Code that needs system-specific file details will need to be updated by hand.
+Code that uses the old POSIX error values from the <code>os</code> package
+will fail to compile and will also need to be updated by hand.
</p>
<h3 id="path_filepath">The path/filepath package</h3>
diff --git a/doc/go1.tmpl b/doc/go1.tmpl
index 32b166a..a963b14 100644
--- a/doc/go1.tmpl
+++ b/doc/go1.tmpl
@@ -1397,12 +1397,27 @@
The vast majority of uses of <code>FileInfo</code> need only the methods
of the standard interface.
</p>
-
+
+<p>
+The <code>os</code> package no longer contains wrappers for the POSIX errors
+such as <code>ENOENT</code>.
+For the few programs that need to verify particular error conditions, there are
+now the boolean functions
+<a href="/pkg/os/#IsExist"><code>IsExist</code></a>,
+<a href="/pkg/os/#IsNotExist"><code>IsNotExist</code></a>
+and
+<a href="/pkg/os/#IsPermission"><code>IsPermission</code></a>.
+</p>
+
+{{code "progs/go1.go" `/os\.Open/` `/}/`}}
+
<p>
<em>Updating</em>:
Running <code>go fix</code> will update code that uses the old equivalent of the current <code>os.FileInfo</code>
and <code>os.FileMode</code> API.
Code that needs system-specific file details will need to be updated by hand.
+Code that uses the old POSIX error values from the <code>os</code> package
+will fail to compile and will also need to be updated by hand.
</p>
<h3 id="path_filepath">The path/filepath package</h3>
diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html
index eaa989a..5892623 100644
--- a/doc/go_tutorial.html
+++ b/doc/go_tutorial.html
@@ -623,7 +623,7 @@
<pre><!--{{code "progs/file.go" `/Close/` "$"}}
-->func (file *File) Close() error {
if file == nil {
- return os.EINVAL
+ return os.ErrInvalid
}
err := syscall.Close(file.fd)
file.fd = -1 // so it can't be closed again
@@ -632,7 +632,7 @@
func (file *File) Read(b []byte) (ret int, err error) {
if file == nil {
- return -1, os.EINVAL
+ return -1, os.ErrInvalid
}
r, err := syscall.Read(file.fd, b)
return int(r), err
@@ -640,7 +640,7 @@
func (file *File) Write(b []byte) (ret int, err error) {
if file == nil {
- return -1, os.EINVAL
+ return -1, os.ErrInvalid
}
r, err := syscall.Write(file.fd, b)
return int(r), err
@@ -659,7 +659,7 @@
The <code>String</code> method is so called because of a printing convention we'll
describe later.
<p>
-The methods use the public variable <code>os.EINVAL</code> to return the (<code>error</code>
+The methods use the public variable <code>os.ErrInvalid</code> to return the (<code>error</code>
version of the) Unix error code <code>EINVAL</code>. The <code>os</code> library defines a standard
set of such error values.
<p>
diff --git a/doc/go_tutorial.tmpl b/doc/go_tutorial.tmpl
index bde724c..3318918 100644
--- a/doc/go_tutorial.tmpl
+++ b/doc/go_tutorial.tmpl
@@ -538,7 +538,7 @@
The <code>String</code> method is so called because of a printing convention we'll
describe later.
<p>
-The methods use the public variable <code>os.EINVAL</code> to return the (<code>error</code>
+The methods use the public variable <code>os.ErrInvalid</code> to return the (<code>error</code>
version of the) Unix error code <code>EINVAL</code>. The <code>os</code> library defines a standard
set of such error values.
<p>
diff --git a/doc/progs/file.go b/doc/progs/file.go
index e1aadaa..75f0f20 100644
--- a/doc/progs/file.go
+++ b/doc/progs/file.go
@@ -49,7 +49,7 @@
func (file *File) Close() error {
if file == nil {
- return os.EINVAL
+ return os.ErrInvalid
}
err := syscall.Close(file.fd)
file.fd = -1 // so it can't be closed again
@@ -58,7 +58,7 @@
func (file *File) Read(b []byte) (ret int, err error) {
if file == nil {
- return -1, os.EINVAL
+ return -1, os.ErrInvalid
}
r, err := syscall.Read(file.fd, b)
return int(r), err
@@ -66,7 +66,7 @@
func (file *File) Write(b []byte) (ret int, err error) {
if file == nil {
- return -1, os.EINVAL
+ return -1, os.ErrInvalid
}
r, err := syscall.Write(file.fd, b)
return int(r), err
diff --git a/doc/progs/file_windows.go b/doc/progs/file_windows.go
index e6a3550..8b79ee9 100644
--- a/doc/progs/file_windows.go
+++ b/doc/progs/file_windows.go
@@ -49,7 +49,7 @@
func (file *File) Close() error {
if file == nil {
- return os.EINVAL
+ return os.ErrInvalid
}
err := syscall.Close(file.fd)
file.fd = syscall.InvalidHandle // so it can't be closed again
@@ -58,7 +58,7 @@
func (file *File) Read(b []byte) (ret int, err error) {
if file == nil {
- return -1, os.EINVAL
+ return -1, os.ErrInvalid
}
r, err := syscall.Read(file.fd, b)
return int(r), err
@@ -66,7 +66,7 @@
func (file *File) Write(b []byte) (ret int, err error) {
if file == nil {
- return -1, os.EINVAL
+ return -1, os.ErrInvalid
}
r, err := syscall.Write(file.fd, b)
return int(r), err
diff --git a/doc/progs/go1.go b/doc/progs/go1.go
index 0348aa3..653c97f 100644
--- a/doc/progs/go1.go
+++ b/doc/progs/go1.go
@@ -11,6 +11,7 @@
"flag"
"fmt"
"log"
+ "os"
"testing"
"time"
"unicode"
@@ -27,6 +28,7 @@
runeType()
errorExample()
timePackage()
+ osIsExist()
}
var timeout = flag.Duration("timeout", 30*time.Second, "how long to wait for completion")
@@ -206,3 +208,12 @@
fmt.Sprintf("%x", 23)
}
}
+
+func osIsExist() {
+ name := "go1.go"
+ f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
+ if os.IsExist(err) {
+ log.Printf("%s already exists", name)
+ }
+ _ = f
+}