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:
parent
ea1446f50b
commit
8072b999a6
3 changed files with 73 additions and 0 deletions
25
internal/fs/meta_darwin.go
Normal file
25
internal/fs/meta_darwin.go
Normal 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
25
internal/fs/meta_linux.go
Normal 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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue