summaryrefslogtreecommitdiffhomepage
path: root/tailfs/webdavfs/writeonly_file.go
diff options
context:
space:
mode:
Diffstat (limited to 'tailfs/webdavfs/writeonly_file.go')
-rw-r--r--tailfs/webdavfs/writeonly_file.go87
1 files changed, 87 insertions, 0 deletions
diff --git a/tailfs/webdavfs/writeonly_file.go b/tailfs/webdavfs/writeonly_file.go
new file mode 100644
index 000000000..e639a92da
--- /dev/null
+++ b/tailfs/webdavfs/writeonly_file.go
@@ -0,0 +1,87 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package webdavfs
+
+import (
+ "context"
+ "errors"
+ "io"
+ "io/fs"
+ "os"
+
+ "tailscale.com/tailfs/shared"
+)
+
+type writeOnlyFile struct {
+ io.WriteCloser
+ name string
+ perm os.FileMode
+ fs *webdavFS
+ finalError chan error
+}
+
+// Readdir implements webdav.File.
+func (f *writeOnlyFile) Readdir(count int) ([]fs.FileInfo, error) {
+ return nil, &os.PathError{
+ Op: "readdir",
+ Path: f.name,
+ Err: errors.New("is a file"), // TODO(oxtoacart): make sure this and below errors match what a regular os.File does
+ }
+}
+
+// Seek implements webdav.File.
+func (f *writeOnlyFile) Seek(offset int64, whence int) (int64, error) {
+ return 0, &os.PathError{
+ Op: "seek",
+ Path: f.name,
+ Err: errors.New("seek not supported"),
+ }
+}
+
+// Stat implements webdav.File.
+func (f *writeOnlyFile) Stat() (fs.FileInfo, error) {
+ fi, err := f.fs.Stat(context.Background(), f.name)
+ if err != nil {
+ // use static info for newly created file
+ now := f.fs.now()
+ fi = &shared.StaticFileInfo{
+ Named: f.name,
+ Sized: 0,
+ Moded: f.perm,
+ BirthedTime: now,
+ ModdedTime: now,
+ Dir: false,
+ }
+ }
+ return fi, nil
+}
+
+// Read implements webdav.File.
+func (f *writeOnlyFile) Read(p []byte) (int, error) {
+ return 0, &os.PathError{
+ Op: "write",
+ Path: f.name,
+ Err: errors.New("write-only"),
+ }
+}
+
+// Write implements webdav.File.
+func (f *writeOnlyFile) Write(p []byte) (int, error) {
+ select {
+ case err := <-f.finalError:
+ return 0, err
+ default:
+ return f.WriteCloser.Write(p)
+ }
+}
+
+// Close implements webdav.File
+func (f *writeOnlyFile) Close() error {
+ err := f.WriteCloser.Close()
+ writeErr := <-f.finalError
+ if writeErr != nil {
+ return writeErr
+ }
+ return err
+}