]> Cypherpunks repositories - gostls13.git/commitdiff
os: add Root.ReadFile and Root.WriteFile
authorDamien Neil <dneil@google.com>
Mon, 19 May 2025 22:51:14 +0000 (15:51 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 21 May 2025 18:59:27 +0000 (11:59 -0700)
For #73126

Change-Id: Ie69cc274e7b59f958c239520318b89ff0141e26b
Reviewed-on: https://go-review.googlesource.com/c/go/+/674315
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>

api/next/73126.txt [new file with mode: 0644]
doc/next/6-stdlib/99-minor/os/67002.md
doc/next/6-stdlib/99-minor/os/73126.md [new file with mode: 0644]
src/os/root.go
src/os/root_test.go

diff --git a/api/next/73126.txt b/api/next/73126.txt
new file mode 100644 (file)
index 0000000..9392448
--- /dev/null
@@ -0,0 +1,2 @@
+pkg os, method (*Root) ReadFile(string) ([]uint8, error) #73126
+pkg os, method (*Root) WriteFile(string, []uint8, fs.FileMode) error #73126
index a8e79437b645eb556d1a7ef7c2aa3bebb517f07c..481a2c171c97f607e908e80631e25ed97b3d8948 100644 (file)
@@ -6,7 +6,9 @@ The [os.Root] type supports the following additional methods:
   * [os.Root.Lchown]
   * [os.Root.Link]
   * [os.Root.MkdirAll]
+  * [os.Root.ReadFile]
   * [os.Root.Readlink]
   * [os.Root.RemoveAll]
   * [os.Root.Rename]
   * [os.Root.Symlink]
+  * [os.Root.WriteFile]
diff --git a/doc/next/6-stdlib/99-minor/os/73126.md b/doc/next/6-stdlib/99-minor/os/73126.md
new file mode 100644 (file)
index 0000000..1cd40d7
--- /dev/null
@@ -0,0 +1 @@
+<!-- go.dev/issue/73126 is documented as part of 67002 -->
index 02bf0b5a3aec9d3ce7264a639ac707f62b0b4dd1..953cd6b9b963dc3ab9da8356c088ba6e0427baf7 100644 (file)
@@ -248,6 +248,31 @@ func (r *Root) Symlink(oldname, newname string) error {
        return rootSymlink(r, oldname, newname)
 }
 
+// ReadFile reads the named file in the root and returns its contents.
+// See [ReadFile] for more details.
+func (r *Root) ReadFile(name string) ([]byte, error) {
+       f, err := r.Open(name)
+       if err != nil {
+               return nil, err
+       }
+       defer f.Close()
+       return readFileContents(statOrZero(f), f.Read)
+}
+
+// WriteFile writes data to the named file in the root, creating it if necessary.
+// See [WriteFile] for more details.
+func (r *Root) WriteFile(name string, data []byte, perm FileMode) error {
+       f, err := r.OpenFile(name, O_WRONLY|O_CREATE|O_TRUNC, perm)
+       if err != nil {
+               return err
+       }
+       _, err = f.Write(data)
+       if err1 := f.Close(); err == nil {
+               err = err1
+       }
+       return err
+}
+
 func (r *Root) logOpen(name string) {
        if log := testlog.Logger(); log != nil {
                // This won't be right if r's name has changed since it was opened,
index 4e09cb9621a3aedfd67cb9d524d0165c7ff0a085..effcdeab433e780e451b8b7edcdbaa8c6558e6bf 100644 (file)
@@ -1899,3 +1899,23 @@ func TestRootRemoveDot(t *testing.T) {
                t.Error(`root.Remove(All)?(".") removed the root`)
        }
 }
+
+func TestRootWriteReadFile(t *testing.T) {
+       dir := t.TempDir()
+       root, err := os.OpenRoot(dir)
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer root.Close()
+
+       name := "filename"
+       want := []byte("file contents")
+       if err := root.WriteFile(name, want, 0o666); err != nil {
+               t.Fatalf("root.WriteFile(%q, %q, 0o666) = %v; want nil", name, want, err)
+       }
+
+       got, err := root.ReadFile(name)
+       if err != nil {
+               t.Fatalf("root.ReadFile(%q) = %q, %v; want %q, nil", name, got, err, want)
+       }
+}