mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-26 11:35:35 +00:00
90 lines
1.9 KiB
Go
90 lines
1.9 KiB
Go
|
// 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. As this is a file, this always fails with an
|
||
|
// os.PathError.
|
||
|
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. This always fails with an os.PathError.
|
||
|
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. As this is a write-only file, it always fails
|
||
|
// with an os.PathError.
|
||
|
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
|
||
|
}
|