1
0
Fork 0
mirror of https://github.com/restic/restic.git synced 2025-01-03 13:45:20 +00:00

fs: add file handle helpers

This commit is contained in:
Michael Eischer 2024-11-03 16:38:34 +01:00
parent ea1446f50b
commit 8072b999a6
3 changed files with 73 additions and 0 deletions

View file

@ -0,0 +1,25 @@
package fs
import (
"os"
"golang.org/x/sys/unix"
)
func openMetadataHandle(path string, flag int) (*os.File, error) {
flags := O_RDONLY
if flag&O_NOFOLLOW != 0 {
// open symlink instead of following it
flags |= unix.O_SYMLINK
}
if flag&O_DIRECTORY != 0 {
flags |= O_DIRECTORY
}
f, err := os.OpenFile(path, flags, 0)
if err != nil {
return nil, err
}
_ = setFlags(f)
return f, nil
}

25
internal/fs/meta_linux.go Normal file
View file

@ -0,0 +1,25 @@
package fs
import (
"os"
"golang.org/x/sys/unix"
)
func openMetadataHandle(path string, flag int) (*os.File, error) {
// O_PATH|O_NOFOLLOW is necessary to also be able to get a handle to symlinks
flags := unix.O_PATH
if flag&O_NOFOLLOW != 0 {
flags |= O_NOFOLLOW
}
if flag&O_DIRECTORY != 0 {
flags |= O_DIRECTORY
}
f, err := os.OpenFile(path, flags, 0)
if err != nil {
return nil, err
}
_ = setFlags(f)
return f, nil
}

View file

@ -1,6 +1,9 @@
package fs
import (
"os"
"syscall"
"github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/restic"
@ -58,3 +61,23 @@ func (p *fdMetadataHandle) SecurityDescriptor() (*[]byte, error) {
// FIXME
return getSecurityDescriptor(p.name)
}
func openMetadataHandle(path string, flag int) (*os.File, error) {
path = fixpath(path)
// OpenFile from go does not request FILE_READ_EA so we need our own low-level implementation
// according to the windows docs, STANDARD_RIGHTS_READ + FILE_FLAG_BACKUP_SEMANTICS disable security checks on access
// if the process holds the SeBackupPrivilege
fileAccess := windows.FILE_READ_EA | windows.FILE_READ_ATTRIBUTES | windows.STANDARD_RIGHTS_READ
shareMode := windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE
attrs := windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_BACKUP_SEMANTICS
if flag&O_NOFOLLOW != 0 {
attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT
}
utf16Path := windows.StringToUTF16Ptr(path)
handle, err := windows.CreateFile(utf16Path, uint32(fileAccess), uint32(shareMode), nil, windows.OPEN_EXISTING, uint32(attrs), 0)
if err != nil {
return nil, err
}
return os.NewFile(uintptr(handle), path), nil
}