mirror of
https://github.com/restic/restic.git
synced 2025-12-29 03:46:52 +00:00
12
vendor/github.com/pkg/errors/.travis.yml
generated
vendored
12
vendor/github.com/pkg/errors/.travis.yml
generated
vendored
@@ -1,10 +1,14 @@
|
||||
language: go
|
||||
go_import_path: github.com/pkg/errors
|
||||
go:
|
||||
- 1.4.3
|
||||
- 1.5.4
|
||||
- 1.6.2
|
||||
- 1.7.1
|
||||
- 1.4.x
|
||||
- 1.5.x
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- tip
|
||||
|
||||
script:
|
||||
|
||||
4
vendor/github.com/pkg/errors/README.md
generated
vendored
4
vendor/github.com/pkg/errors/README.md
generated
vendored
@@ -1,4 +1,4 @@
|
||||
# errors [](https://travis-ci.org/pkg/errors) [](https://ci.appveyor.com/project/davecheney/errors/branch/master) [](http://godoc.org/github.com/pkg/errors) [](https://goreportcard.com/report/github.com/pkg/errors)
|
||||
# errors [](https://travis-ci.org/pkg/errors) [](https://ci.appveyor.com/project/davecheney/errors/branch/master) [](http://godoc.org/github.com/pkg/errors) [](https://goreportcard.com/report/github.com/pkg/errors) [](https://sourcegraph.com/github.com/pkg/errors?badge)
|
||||
|
||||
Package errors provides simple error handling primitives.
|
||||
|
||||
@@ -47,6 +47,6 @@ We welcome pull requests, bug fixes and issue reports. With that said, the bar f
|
||||
|
||||
Before proposing a change, please discuss your change by raising an issue.
|
||||
|
||||
## Licence
|
||||
## License
|
||||
|
||||
BSD-2-Clause
|
||||
|
||||
43
vendor/github.com/pkg/errors/errors.go
generated
vendored
43
vendor/github.com/pkg/errors/errors.go
generated
vendored
@@ -6,7 +6,7 @@
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// which applied recursively up the call stack results in error reports
|
||||
// which when applied recursively up the call stack results in error reports
|
||||
// without context or debugging information. The errors package allows
|
||||
// programmers to add context to the failure path in their code in a way
|
||||
// that does not destroy the original value of the error.
|
||||
@@ -15,16 +15,17 @@
|
||||
//
|
||||
// The errors.Wrap function returns a new error that adds context to the
|
||||
// original error by recording a stack trace at the point Wrap is called,
|
||||
// and the supplied message. For example
|
||||
// together with the supplied message. For example
|
||||
//
|
||||
// _, err := ioutil.ReadAll(r)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(err, "read failed")
|
||||
// }
|
||||
//
|
||||
// If additional control is required the errors.WithStack and errors.WithMessage
|
||||
// functions destructure errors.Wrap into its component operations of annotating
|
||||
// an error with a stack trace and an a message, respectively.
|
||||
// If additional control is required, the errors.WithStack and
|
||||
// errors.WithMessage functions destructure errors.Wrap into its component
|
||||
// operations: annotating an error with a stack trace and with a message,
|
||||
// respectively.
|
||||
//
|
||||
// Retrieving the cause of an error
|
||||
//
|
||||
@@ -38,7 +39,7 @@
|
||||
// }
|
||||
//
|
||||
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
|
||||
// the topmost error which does not implement causer, which is assumed to be
|
||||
// the topmost error that does not implement causer, which is assumed to be
|
||||
// the original cause. For example:
|
||||
//
|
||||
// switch err := errors.Cause(err).(type) {
|
||||
@@ -48,16 +49,16 @@
|
||||
// // unknown error
|
||||
// }
|
||||
//
|
||||
// causer interface is not exported by this package, but is considered a part
|
||||
// of stable public API.
|
||||
// Although the causer interface is not exported by this package, it is
|
||||
// considered a part of its stable public interface.
|
||||
//
|
||||
// Formatted printing of errors
|
||||
//
|
||||
// All error values returned from this package implement fmt.Formatter and can
|
||||
// be formatted by the fmt package. The following verbs are supported
|
||||
// be formatted by the fmt package. The following verbs are supported:
|
||||
//
|
||||
// %s print the error. If the error has a Cause it will be
|
||||
// printed recursively
|
||||
// printed recursively.
|
||||
// %v see %s
|
||||
// %+v extended format. Each Frame of the error's StackTrace will
|
||||
// be printed in detail.
|
||||
@@ -65,13 +66,13 @@
|
||||
// Retrieving the stack trace of an error or wrapper
|
||||
//
|
||||
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
|
||||
// invoked. This information can be retrieved with the following interface.
|
||||
// invoked. This information can be retrieved with the following interface:
|
||||
//
|
||||
// type stackTracer interface {
|
||||
// StackTrace() errors.StackTrace
|
||||
// }
|
||||
//
|
||||
// Where errors.StackTrace is defined as
|
||||
// The returned errors.StackTrace type is defined as
|
||||
//
|
||||
// type StackTrace []Frame
|
||||
//
|
||||
@@ -85,8 +86,8 @@
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// stackTracer interface is not exported by this package, but is considered a part
|
||||
// of stable public API.
|
||||
// Although the stackTracer interface is not exported by this package, it is
|
||||
// considered a part of its stable public interface.
|
||||
//
|
||||
// See the documentation for Frame.Format for more details.
|
||||
package errors
|
||||
@@ -192,7 +193,7 @@ func Wrap(err error, message string) error {
|
||||
}
|
||||
|
||||
// Wrapf returns an error annotating err with a stack trace
|
||||
// at the point Wrapf is call, and the format specifier.
|
||||
// at the point Wrapf is called, and the format specifier.
|
||||
// If err is nil, Wrapf returns nil.
|
||||
func Wrapf(err error, format string, args ...interface{}) error {
|
||||
if err == nil {
|
||||
@@ -220,6 +221,18 @@ func WithMessage(err error, message string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// WithMessagef annotates err with the format specifier.
|
||||
// If err is nil, WithMessagef returns nil.
|
||||
func WithMessagef(err error, format string, args ...interface{}) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &withMessage{
|
||||
cause: err,
|
||||
msg: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
type withMessage struct {
|
||||
cause error
|
||||
msg string
|
||||
|
||||
51
vendor/github.com/pkg/errors/stack.go
generated
vendored
51
vendor/github.com/pkg/errors/stack.go
generated
vendored
@@ -46,7 +46,8 @@ func (f Frame) line() int {
|
||||
//
|
||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||
//
|
||||
// %+s path of source file relative to the compile time GOPATH
|
||||
// %+s function name and path of source file relative to the compile time
|
||||
// GOPATH separated by \n\t (<funcname>\n\t<path>)
|
||||
// %+v equivalent to %+s:%d
|
||||
func (f Frame) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
@@ -79,6 +80,14 @@ func (f Frame) Format(s fmt.State, verb rune) {
|
||||
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
|
||||
type StackTrace []Frame
|
||||
|
||||
// Format formats the stack of Frames according to the fmt.Formatter interface.
|
||||
//
|
||||
// %s lists source files for each Frame in the stack
|
||||
// %v lists the source file and line number for each Frame in the stack
|
||||
//
|
||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||
//
|
||||
// %+v Prints filename, function, and line number for each Frame in the stack.
|
||||
func (st StackTrace) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
@@ -136,43 +145,3 @@ func funcname(name string) string {
|
||||
i = strings.Index(name, ".")
|
||||
return name[i+1:]
|
||||
}
|
||||
|
||||
func trimGOPATH(name, file string) string {
|
||||
// Here we want to get the source file path relative to the compile time
|
||||
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
|
||||
// GOPATH at runtime, but we can infer the number of path segments in the
|
||||
// GOPATH. We note that fn.Name() returns the function name qualified by
|
||||
// the import path, which does not include the GOPATH. Thus we can trim
|
||||
// segments from the beginning of the file path until the number of path
|
||||
// separators remaining is one more than the number of path separators in
|
||||
// the function name. For example, given:
|
||||
//
|
||||
// GOPATH /home/user
|
||||
// file /home/user/src/pkg/sub/file.go
|
||||
// fn.Name() pkg/sub.Type.Method
|
||||
//
|
||||
// We want to produce:
|
||||
//
|
||||
// pkg/sub/file.go
|
||||
//
|
||||
// From this we can easily see that fn.Name() has one less path separator
|
||||
// than our desired output. We count separators from the end of the file
|
||||
// path until it finds two more than in the function name and then move
|
||||
// one character forward to preserve the initial path segment without a
|
||||
// leading separator.
|
||||
const sep = "/"
|
||||
goal := strings.Count(name, sep) + 2
|
||||
i := len(file)
|
||||
for n := 0; n < goal; n++ {
|
||||
i = strings.LastIndex(file[:i], sep)
|
||||
if i == -1 {
|
||||
// not enough separators found, set i so that the slice expression
|
||||
// below leaves file unmodified
|
||||
i = -len(sep)
|
||||
break
|
||||
}
|
||||
}
|
||||
// get back to 0 or trim the leading separator
|
||||
file = file[i+len(sep):]
|
||||
return file
|
||||
}
|
||||
|
||||
4
vendor/github.com/pkg/sftp/.travis.yml
generated
vendored
4
vendor/github.com/pkg/sftp/.travis.yml
generated
vendored
@@ -4,8 +4,8 @@ go_import_path: github.com/pkg/sftp
|
||||
# current and previous stable releases, plus tip
|
||||
# remember to exclude previous and tip for macs below
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- tip
|
||||
|
||||
os:
|
||||
@@ -15,7 +15,7 @@ os:
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
go: 1.9.x
|
||||
go: 1.10.x
|
||||
- os: osx
|
||||
go: tip
|
||||
|
||||
|
||||
1
vendor/github.com/pkg/sftp/client.go
generated
vendored
1
vendor/github.com/pkg/sftp/client.go
generated
vendored
@@ -122,6 +122,7 @@ func NewClientPipe(rd io.Reader, wr io.WriteCloser, opts ...ClientOption) (*Clie
|
||||
WriteCloser: wr,
|
||||
},
|
||||
inflight: make(map[uint32]chan<- result),
|
||||
closed: make(chan struct{}),
|
||||
},
|
||||
maxPacket: 1 << 15,
|
||||
maxConcurrentRequests: 64,
|
||||
|
||||
13
vendor/github.com/pkg/sftp/conn.go
generated
vendored
13
vendor/github.com/pkg/sftp/conn.go
generated
vendored
@@ -36,6 +36,17 @@ type clientConn struct {
|
||||
wg sync.WaitGroup
|
||||
sync.Mutex // protects inflight
|
||||
inflight map[uint32]chan<- result // outstanding requests
|
||||
|
||||
closed chan struct{}
|
||||
err error
|
||||
}
|
||||
|
||||
// Wait blocks until the conn has shut down, and return the error
|
||||
// causing the shutdown. It can be called concurrently from multiple
|
||||
// goroutines.
|
||||
func (c *clientConn) Wait() error {
|
||||
<-c.closed
|
||||
return c.err
|
||||
}
|
||||
|
||||
// Close closes the SFTP session.
|
||||
@@ -122,6 +133,8 @@ func (c *clientConn) broadcastErr(err error) {
|
||||
for _, ch := range listeners {
|
||||
ch <- result{err: err}
|
||||
}
|
||||
c.err = err
|
||||
close(c.closed)
|
||||
}
|
||||
|
||||
type serverConn struct {
|
||||
|
||||
2
vendor/github.com/pkg/sftp/packet-manager.go
generated
vendored
2
vendor/github.com/pkg/sftp/packet-manager.go
generated
vendored
@@ -176,8 +176,10 @@ func (s *packetManager) maybeSendPackets() {
|
||||
s.sender.sendPacket(out.(encoding.BinaryMarshaler))
|
||||
// pop off heads
|
||||
copy(s.incoming, s.incoming[1:]) // shift left
|
||||
s.incoming[len(s.incoming)-1] = nil // clear last
|
||||
s.incoming = s.incoming[:len(s.incoming)-1] // remove last
|
||||
copy(s.outgoing, s.outgoing[1:]) // shift left
|
||||
s.outgoing[len(s.outgoing)-1] = nil // clear last
|
||||
s.outgoing = s.outgoing[:len(s.outgoing)-1] // remove last
|
||||
} else {
|
||||
break
|
||||
|
||||
15
vendor/github.com/pkg/sftp/packet.go
generated
vendored
15
vendor/github.com/pkg/sftp/packet.go
generated
vendored
@@ -125,15 +125,14 @@ func sendPacket(w io.Writer, m encoding.BinaryMarshaler) error {
|
||||
} else if debugDumpTxPacket {
|
||||
debug("send packet: %s %d bytes", fxp(bb[0]), len(bb))
|
||||
}
|
||||
l := uint32(len(bb))
|
||||
hdr := []byte{byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l)}
|
||||
_, err = w.Write(hdr)
|
||||
// Slide packet down 4 bytes to make room for length header.
|
||||
packet := append(bb, make([]byte, 4)...) // optimistically assume bb has capacity
|
||||
copy(packet[4:], bb)
|
||||
binary.BigEndian.PutUint32(packet[:4], uint32(len(bb)))
|
||||
|
||||
_, err = w.Write(packet)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to send packet header: %v", err)
|
||||
}
|
||||
_, err = w.Write(bb)
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to send packet body: %v", err)
|
||||
return errors.Errorf("failed to send packet: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
21
vendor/github.com/pkg/sftp/request-example.go
generated
vendored
21
vendor/github.com/pkg/sftp/request-example.go
generated
vendored
@@ -12,6 +12,7 @@ import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -29,6 +30,7 @@ func (fs *root) Fileread(r *Request) (io.ReaderAt, error) {
|
||||
if fs.mockErr != nil {
|
||||
return nil, fs.mockErr
|
||||
}
|
||||
_ = r.WithContext(r.Context()) // initialize context for deadlock testing
|
||||
fs.filesLock.Lock()
|
||||
defer fs.filesLock.Unlock()
|
||||
file, err := fs.fetch(r.Filepath)
|
||||
@@ -48,6 +50,7 @@ func (fs *root) Filewrite(r *Request) (io.WriterAt, error) {
|
||||
if fs.mockErr != nil {
|
||||
return nil, fs.mockErr
|
||||
}
|
||||
_ = r.WithContext(r.Context()) // initialize context for deadlock testing
|
||||
fs.filesLock.Lock()
|
||||
defer fs.filesLock.Unlock()
|
||||
file, err := fs.fetch(r.Filepath)
|
||||
@@ -69,6 +72,7 @@ func (fs *root) Filecmd(r *Request) error {
|
||||
if fs.mockErr != nil {
|
||||
return fs.mockErr
|
||||
}
|
||||
_ = r.WithContext(r.Context()) // initialize context for deadlock testing
|
||||
fs.filesLock.Lock()
|
||||
defer fs.filesLock.Unlock()
|
||||
switch r.Method {
|
||||
@@ -129,11 +133,20 @@ func (fs *root) Filelist(r *Request) (ListerAt, error) {
|
||||
if fs.mockErr != nil {
|
||||
return nil, fs.mockErr
|
||||
}
|
||||
_ = r.WithContext(r.Context()) // initialize context for deadlock testing
|
||||
fs.filesLock.Lock()
|
||||
defer fs.filesLock.Unlock()
|
||||
|
||||
file, err := fs.fetch(r.Filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case "List":
|
||||
if !file.IsDir() {
|
||||
return nil, syscall.ENOTDIR
|
||||
}
|
||||
ordered_names := []string{}
|
||||
for fn, _ := range fs.files {
|
||||
if filepath.Dir(fn) == r.Filepath {
|
||||
@@ -147,16 +160,8 @@ func (fs *root) Filelist(r *Request) (ListerAt, error) {
|
||||
}
|
||||
return listerat(list), nil
|
||||
case "Stat":
|
||||
file, err := fs.fetch(r.Filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return listerat([]os.FileInfo{file}), nil
|
||||
case "Readlink":
|
||||
file, err := fs.fetch(r.Filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if file.symlink != "" {
|
||||
file, err = fs.fetch(file.symlink)
|
||||
if err != nil {
|
||||
|
||||
62
vendor/github.com/pkg/sftp/request-server.go
generated
vendored
62
vendor/github.com/pkg/sftp/request-server.go
generated
vendored
@@ -3,7 +3,6 @@ package sftp
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -56,37 +55,24 @@ func (rs *RequestServer) nextRequest(r *Request) string {
|
||||
defer rs.openRequestLock.Unlock()
|
||||
rs.handleCount++
|
||||
handle := strconv.Itoa(rs.handleCount)
|
||||
r.handle = handle
|
||||
rs.openRequests[handle] = r
|
||||
return handle
|
||||
}
|
||||
|
||||
// Returns Request from openRequests, bool is false if it is missing
|
||||
// If the method is different, save/return a new Request w/ that Method.
|
||||
// Returns Request from openRequests, bool is false if it is missing.
|
||||
//
|
||||
// The Requests in openRequests work essentially as open file descriptors that
|
||||
// you can do different things with. What you are doing with it are denoted by
|
||||
// the first packet of that type (read/write/etc). We create a new Request when
|
||||
// it changes to set the request.Method attribute in a thread safe way.
|
||||
func (rs *RequestServer) getRequest(handle, method string) (*Request, bool) {
|
||||
// the first packet of that type (read/write/etc).
|
||||
func (rs *RequestServer) getRequest(handle string) (*Request, bool) {
|
||||
rs.openRequestLock.RLock()
|
||||
defer rs.openRequestLock.RUnlock()
|
||||
r, ok := rs.openRequests[handle]
|
||||
rs.openRequestLock.RUnlock()
|
||||
if !ok || r.Method == method {
|
||||
return r, ok
|
||||
}
|
||||
// if we make it here we need to replace the request
|
||||
rs.openRequestLock.Lock()
|
||||
defer rs.openRequestLock.Unlock()
|
||||
r, ok = rs.openRequests[handle]
|
||||
if !ok || r.Method == method { // re-check needed b/c lock race
|
||||
return r, ok
|
||||
}
|
||||
r = r.copy()
|
||||
r.Method = method
|
||||
rs.openRequests[handle] = r
|
||||
return r, ok
|
||||
}
|
||||
|
||||
// Close the Request and clear from openRequests map
|
||||
func (rs *RequestServer) closeRequest(handle string) error {
|
||||
rs.openRequestLock.Lock()
|
||||
defer rs.openRequestLock.Unlock()
|
||||
@@ -173,28 +159,24 @@ func (rs *RequestServer) packetWorker(
|
||||
rpkt = cleanPacketPath(pkt)
|
||||
case *sshFxpOpendirPacket:
|
||||
request := requestFromPacket(ctx, pkt)
|
||||
rpkt = request.call(rs.Handlers, pkt)
|
||||
if stat, ok := rpkt.(*sshFxpStatResponse); ok {
|
||||
if stat.info.IsDir() {
|
||||
handle := rs.nextRequest(request)
|
||||
rpkt = sshFxpHandlePacket{ID: pkt.id(), Handle: handle}
|
||||
} else {
|
||||
rpkt = statusFromError(pkt, &os.PathError{
|
||||
Path: request.Filepath, Err: syscall.ENOTDIR})
|
||||
}
|
||||
}
|
||||
rs.nextRequest(request)
|
||||
rpkt = request.opendir(rs.Handlers, pkt)
|
||||
case *sshFxpOpenPacket:
|
||||
request := requestFromPacket(ctx, pkt)
|
||||
handle := rs.nextRequest(request)
|
||||
rpkt = sshFxpHandlePacket{ID: pkt.id(), Handle: handle}
|
||||
if pkt.hasPflags(ssh_FXF_CREAT) {
|
||||
if p := request.call(rs.Handlers, pkt); !statusOk(p) {
|
||||
rpkt = p // if error in write, return it
|
||||
}
|
||||
rs.nextRequest(request)
|
||||
rpkt = request.open(rs.Handlers, pkt)
|
||||
case *sshFxpFstatPacket:
|
||||
handle := pkt.getHandle()
|
||||
request, ok := rs.getRequest(handle)
|
||||
if !ok {
|
||||
rpkt = statusFromError(pkt, syscall.EBADF)
|
||||
} else {
|
||||
request = NewRequest("Stat", request.Filepath)
|
||||
rpkt = request.call(rs.Handlers, pkt)
|
||||
}
|
||||
case hasHandle:
|
||||
handle := pkt.getHandle()
|
||||
request, ok := rs.getRequest(handle, requestMethod(pkt))
|
||||
request, ok := rs.getRequest(handle)
|
||||
if !ok {
|
||||
rpkt = statusFromError(pkt, syscall.EBADF)
|
||||
} else {
|
||||
@@ -214,12 +196,6 @@ func (rs *RequestServer) packetWorker(
|
||||
return nil
|
||||
}
|
||||
|
||||
// True is responsePacket is an OK status packet
|
||||
func statusOk(rpkt responsePacket) bool {
|
||||
p, ok := rpkt.(sshFxpStatusPacket)
|
||||
return ok && p.StatusError.Code == ssh_FX_OK
|
||||
}
|
||||
|
||||
// clean and return name packet for file
|
||||
func cleanPacketPath(pkt *sshFxpRealpathPacket) responsePacket {
|
||||
path := cleanPath(pkt.getPath())
|
||||
|
||||
134
vendor/github.com/pkg/sftp/request.go
generated
vendored
134
vendor/github.com/pkg/sftp/request.go
generated
vendored
@@ -24,6 +24,7 @@ type Request struct {
|
||||
Flags uint32
|
||||
Attrs []byte // convert to sub-struct
|
||||
Target string // for renames and sym-links
|
||||
handle string
|
||||
// reader/writer/readdir from handlers
|
||||
state state
|
||||
// context lasts duration of request
|
||||
@@ -116,34 +117,12 @@ func (r *Request) lsInc(offset int64) {
|
||||
}
|
||||
|
||||
// manage file read/write state
|
||||
func (r *Request) setWriterState(wa io.WriterAt) {
|
||||
r.state.Lock()
|
||||
defer r.state.Unlock()
|
||||
r.state.writerAt = wa
|
||||
}
|
||||
func (r *Request) setReaderState(ra io.ReaderAt) {
|
||||
r.state.Lock()
|
||||
defer r.state.Unlock()
|
||||
r.state.readerAt = ra
|
||||
}
|
||||
func (r *Request) setListerState(la ListerAt) {
|
||||
r.state.Lock()
|
||||
defer r.state.Unlock()
|
||||
r.state.listerAt = la
|
||||
}
|
||||
|
||||
func (r *Request) getWriter() io.WriterAt {
|
||||
r.state.RLock()
|
||||
defer r.state.RUnlock()
|
||||
return r.state.writerAt
|
||||
}
|
||||
|
||||
func (r *Request) getReader() io.ReaderAt {
|
||||
r.state.RLock()
|
||||
defer r.state.RUnlock()
|
||||
return r.state.readerAt
|
||||
}
|
||||
|
||||
func (r *Request) getLister() ListerAt {
|
||||
r.state.RLock()
|
||||
defer r.state.RUnlock()
|
||||
@@ -157,11 +136,15 @@ func (r *Request) close() error {
|
||||
r.cancelCtx()
|
||||
}
|
||||
}()
|
||||
rd := r.getReader()
|
||||
r.state.RLock()
|
||||
rd := r.state.readerAt
|
||||
r.state.RUnlock()
|
||||
if c, ok := rd.(io.Closer); ok {
|
||||
return c.Close()
|
||||
}
|
||||
wt := r.getWriter()
|
||||
r.state.RLock()
|
||||
wt := r.state.writerAt
|
||||
r.state.RUnlock()
|
||||
if c, ok := wt.(io.Closer); ok {
|
||||
return c.Close()
|
||||
}
|
||||
@@ -173,7 +156,7 @@ func (r *Request) call(handlers Handlers, pkt requestPacket) responsePacket {
|
||||
switch r.Method {
|
||||
case "Get":
|
||||
return fileget(handlers.FileGet, r, pkt)
|
||||
case "Put", "Open":
|
||||
case "Put":
|
||||
return fileput(handlers.FilePut, r, pkt)
|
||||
case "Setstat", "Rename", "Rmdir", "Mkdir", "Symlink", "Remove":
|
||||
return filecmd(handlers.FileCmd, r, pkt)
|
||||
@@ -187,30 +170,47 @@ func (r *Request) call(handlers Handlers, pkt requestPacket) responsePacket {
|
||||
}
|
||||
}
|
||||
|
||||
// file data for additional read/write packets
|
||||
func packetData(p requestPacket) (data []byte, offset int64, length uint32) {
|
||||
switch p := p.(type) {
|
||||
case *sshFxpReadPacket:
|
||||
length = p.Len
|
||||
offset = int64(p.Offset)
|
||||
case *sshFxpWritePacket:
|
||||
data = p.Data
|
||||
length = p.Length
|
||||
offset = int64(p.Offset)
|
||||
// Additional initialization for Open packets
|
||||
func (r *Request) open(h Handlers, pkt requestPacket) responsePacket {
|
||||
flags := r.Pflags()
|
||||
var err error
|
||||
switch {
|
||||
case flags.Write, flags.Append, flags.Creat, flags.Trunc:
|
||||
r.Method = "Put"
|
||||
r.state.writerAt, err = h.FilePut.Filewrite(r)
|
||||
case flags.Read:
|
||||
r.Method = "Get"
|
||||
r.state.readerAt, err = h.FileGet.Fileread(r)
|
||||
default:
|
||||
return statusFromError(pkt, errors.New("bad file flags"))
|
||||
}
|
||||
return
|
||||
if err != nil {
|
||||
return statusFromError(pkt, err)
|
||||
}
|
||||
return &sshFxpHandlePacket{ID: pkt.id(), Handle: r.handle}
|
||||
}
|
||||
func (r *Request) opendir(h Handlers, pkt requestPacket) responsePacket {
|
||||
var err error
|
||||
r.Method = "List"
|
||||
r.state.listerAt, err = h.FileList.Filelist(r)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case syscall.Errno:
|
||||
err = &os.PathError{Path: r.Filepath, Err: err}
|
||||
}
|
||||
return statusFromError(pkt, err)
|
||||
}
|
||||
return &sshFxpHandlePacket{ID: pkt.id(), Handle: r.handle}
|
||||
}
|
||||
|
||||
// wrap FileReader handler
|
||||
func fileget(h FileReader, r *Request, pkt requestPacket) responsePacket {
|
||||
var err error
|
||||
reader := r.getReader()
|
||||
//fmt.Println("fileget", r)
|
||||
r.state.RLock()
|
||||
reader := r.state.readerAt
|
||||
r.state.RUnlock()
|
||||
if reader == nil {
|
||||
reader, err = h.Fileread(r)
|
||||
if err != nil {
|
||||
return statusFromError(pkt, err)
|
||||
}
|
||||
r.setReaderState(reader)
|
||||
return statusFromError(pkt, errors.New("unexpected read packet"))
|
||||
}
|
||||
|
||||
_, offset, length := packetData(pkt)
|
||||
@@ -229,21 +229,33 @@ func fileget(h FileReader, r *Request, pkt requestPacket) responsePacket {
|
||||
|
||||
// wrap FileWriter handler
|
||||
func fileput(h FileWriter, r *Request, pkt requestPacket) responsePacket {
|
||||
var err error
|
||||
writer := r.getWriter()
|
||||
//fmt.Println("fileput", r)
|
||||
r.state.RLock()
|
||||
writer := r.state.writerAt
|
||||
r.state.RUnlock()
|
||||
if writer == nil {
|
||||
writer, err = h.Filewrite(r)
|
||||
if err != nil {
|
||||
return statusFromError(pkt, err)
|
||||
}
|
||||
r.setWriterState(writer)
|
||||
return statusFromError(pkt, errors.New("unexpected write packet"))
|
||||
}
|
||||
|
||||
data, offset, _ := packetData(pkt)
|
||||
_, err = writer.WriteAt(data, offset)
|
||||
_, err := writer.WriteAt(data, offset)
|
||||
return statusFromError(pkt, err)
|
||||
}
|
||||
|
||||
// file data for additional read/write packets
|
||||
func packetData(p requestPacket) (data []byte, offset int64, length uint32) {
|
||||
switch p := p.(type) {
|
||||
case *sshFxpReadPacket:
|
||||
length = p.Len
|
||||
offset = int64(p.Offset)
|
||||
case *sshFxpWritePacket:
|
||||
data = p.Data
|
||||
length = p.Length
|
||||
offset = int64(p.Offset)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// wrap FileCmder handler
|
||||
func filecmd(h FileCmder, r *Request, pkt requestPacket) responsePacket {
|
||||
|
||||
@@ -261,11 +273,7 @@ func filelist(h FileLister, r *Request, pkt requestPacket) responsePacket {
|
||||
var err error
|
||||
lister := r.getLister()
|
||||
if lister == nil {
|
||||
lister, err = h.Filelist(r)
|
||||
if err != nil {
|
||||
return statusFromError(pkt, err)
|
||||
}
|
||||
r.setListerState(lister)
|
||||
return statusFromError(pkt, errors.New("unexpected dir packet"))
|
||||
}
|
||||
|
||||
offset := r.lsNext()
|
||||
@@ -350,16 +358,10 @@ func filestat(h FileLister, r *Request, pkt requestPacket) responsePacket {
|
||||
// init attributes of request object from packet data
|
||||
func requestMethod(p requestPacket) (method string) {
|
||||
switch p.(type) {
|
||||
case *sshFxpReadPacket:
|
||||
method = "Get"
|
||||
case *sshFxpWritePacket:
|
||||
method = "Put"
|
||||
case *sshFxpReaddirPacket:
|
||||
method = "List"
|
||||
case *sshFxpOpenPacket:
|
||||
method = "Open"
|
||||
case *sshFxpOpendirPacket:
|
||||
method = "Stat"
|
||||
case *sshFxpReadPacket, *sshFxpWritePacket, *sshFxpOpenPacket:
|
||||
// set in open() above
|
||||
case *sshFxpOpendirPacket, *sshFxpReaddirPacket:
|
||||
// set in opendir() above
|
||||
case *sshFxpSetstatPacket, *sshFxpFsetstatPacket:
|
||||
method = "Setstat"
|
||||
case *sshFxpRenamePacket:
|
||||
|
||||
3
vendor/github.com/pkg/xattr/.gitignore
generated
vendored
3
vendor/github.com/pkg/xattr/.gitignore
generated
vendored
@@ -18,6 +18,9 @@ _cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
# Dependencies
|
||||
go.sum
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
|
||||
2
vendor/github.com/pkg/xattr/.travis.sh
generated
vendored
2
vendor/github.com/pkg/xattr/.travis.sh
generated
vendored
@@ -11,4 +11,4 @@ GOOS=freebsd go build
|
||||
|
||||
echo "Running tests..."
|
||||
go vet
|
||||
go test -v -race -covermode=atomic
|
||||
go test -v -race -coverprofile=coverage.txt -covermode=atomic
|
||||
|
||||
17
vendor/github.com/pkg/xattr/.travis.yml
generated
vendored
17
vendor/github.com/pkg/xattr/.travis.yml
generated
vendored
@@ -2,22 +2,23 @@ language: go
|
||||
sudo: false
|
||||
|
||||
go:
|
||||
- "1.8.x"
|
||||
- "1.9.x"
|
||||
- "1.10"
|
||||
- "1.11"
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
install:
|
||||
before_install:
|
||||
- go version
|
||||
- export GOBIN="$GOPATH/bin"
|
||||
- export PATH="$PATH:$GOBIN"
|
||||
- go get golang.org/x/sys/unix
|
||||
- export GO111MODULE=on
|
||||
- go get golang.org/x/tools/cmd/goimports
|
||||
|
||||
install:
|
||||
- go build
|
||||
|
||||
script:
|
||||
- ./.travis.sh
|
||||
- diff <(GOPATH="$PWD:$PWD/vendor" goimports -d .) <(printf "")
|
||||
- diff <(goimports -d .) <(printf "")
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
5
vendor/github.com/pkg/xattr/README.md
generated
vendored
5
vendor/github.com/pkg/xattr/README.md
generated
vendored
@@ -2,6 +2,7 @@
|
||||
[](https://goreportcard.com/report/github.com/pkg/xattr)
|
||||
[](https://travis-ci.org/pkg/xattr)
|
||||
[](https://github.com/pkg/xattr/releases)
|
||||
[](https://codecov.io/gh/pkg/xattr)
|
||||
|
||||
xattr
|
||||
=====
|
||||
@@ -23,12 +24,12 @@ do not reference a symlink that appears at the end of a path. See
|
||||
if err := xattr.Set(path, prefix+"test", []byte("test-attr-value")); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
var list []string
|
||||
if list, err = xattr.List(path); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
var data []byte
|
||||
if data, err = xattr.Get(path, prefix+"test"); err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
2
vendor/github.com/pkg/xattr/go.mod
generated
vendored
2
vendor/github.com/pkg/xattr/go.mod
generated
vendored
@@ -1,3 +1,3 @@
|
||||
module github.com/pkg/xattr
|
||||
|
||||
require golang.org/x/sys v0.0.0-20180525142821-c11f84a56e43
|
||||
require golang.org/x/sys v0.0.0-20181021155630-eda9bb28ed51
|
||||
|
||||
1
vendor/github.com/pkg/xattr/go.sum
generated
vendored
1
vendor/github.com/pkg/xattr/go.sum
generated
vendored
@@ -1 +0,0 @@
|
||||
golang.org/x/sys v0.0.0-20180525142821-c11f84a56e43/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
72
vendor/github.com/pkg/xattr/xattr.go
generated
vendored
72
vendor/github.com/pkg/xattr/xattr.go
generated
vendored
@@ -5,10 +5,11 @@ similar to the environment strings associated with a process.
|
||||
An attribute may be defined or undefined. If it is defined, its value may be empty or non-empty.
|
||||
More details you can find here: https://en.wikipedia.org/wiki/Extended_file_attributes .
|
||||
|
||||
All functions are provided in pairs: Get/LGet, Set/LSet etc. The "L"
|
||||
variant will not follow a symlink at the end of the path.
|
||||
All functions are provided in triples: Get/LGet/FGet, Set/LSet/FSet etc. The "L"
|
||||
variant will not follow a symlink at the end of the path, and "F" variant accepts
|
||||
a file descriptor instead of a path.
|
||||
|
||||
Example assuming path is "/symlink1/symlink2", where both components are
|
||||
Example for "L" variant, assuming path is "/symlink1/symlink2", where both components are
|
||||
symlinks:
|
||||
Get will follow "symlink1" and "symlink2" and operate on the target of
|
||||
"symlink2". LGet will follow "symlink1" but operate directly on "symlink2".
|
||||
@@ -16,6 +17,7 @@ Get will follow "symlink1" and "symlink2" and operate on the target of
|
||||
package xattr
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
@@ -34,15 +36,26 @@ func (e *Error) Error() string {
|
||||
// Get retrieves extended attribute data associated with path. It will follow
|
||||
// all symlinks along the path.
|
||||
func Get(path, name string) ([]byte, error) {
|
||||
return get(path, name, getxattr)
|
||||
return get(path, name, func(name string, data []byte) (int, error) {
|
||||
return getxattr(path, name, data)
|
||||
})
|
||||
}
|
||||
|
||||
// LGet is like Get but does not follow a symlink at the end of the path.
|
||||
func LGet(path, name string) ([]byte, error) {
|
||||
return get(path, name, lgetxattr)
|
||||
return get(path, name, func(name string, data []byte) (int, error) {
|
||||
return lgetxattr(path, name, data)
|
||||
})
|
||||
}
|
||||
|
||||
type getxattrFunc func(path string, name string, data []byte) (int, error)
|
||||
// FGet is like Get but accepts a os.File instead of a file path.
|
||||
func FGet(f *os.File, name string) ([]byte, error) {
|
||||
return get(f.Name(), name, func(name string, data []byte) (int, error) {
|
||||
return fgetxattr(f, name, data)
|
||||
})
|
||||
}
|
||||
|
||||
type getxattrFunc func(name string, data []byte) (int, error)
|
||||
|
||||
// get contains the buffer allocation logic used by both Get and LGet.
|
||||
func get(path string, name string, getxattrFunc getxattrFunc) ([]byte, error) {
|
||||
@@ -62,7 +75,7 @@ func get(path string, name string, getxattrFunc getxattrFunc) ([]byte, error) {
|
||||
size := initialBufSize
|
||||
for {
|
||||
data := make([]byte, size)
|
||||
read, err := getxattrFunc(path, name, data)
|
||||
read, err := getxattrFunc(name, data)
|
||||
|
||||
// If the buffer was too small to fit the value, Linux and MacOS react
|
||||
// differently:
|
||||
@@ -105,6 +118,14 @@ func LSet(path, name string, data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FSet is like Set but accepts a os.File instead of a file path.
|
||||
func FSet(f *os.File, name string, data []byte) error {
|
||||
if err := fsetxattr(f, name, data, 0); err != nil {
|
||||
return &Error{"xattr.FSet", f.Name(), name, err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetWithFlags associates name and data together as an attribute of path.
|
||||
// Forwards the flags parameter to the syscall layer.
|
||||
func SetWithFlags(path, name string, data []byte, flags int) error {
|
||||
@@ -123,6 +144,14 @@ func LSetWithFlags(path, name string, data []byte, flags int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FSetWithFlags is like SetWithFlags but accepts a os.File instead of a file path.
|
||||
func FSetWithFlags(f *os.File, name string, data []byte, flags int) error {
|
||||
if err := fsetxattr(f, name, data, flags); err != nil {
|
||||
return &Error{"xattr.FSetWithFlags", f.Name(), name, err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove removes the attribute associated with the given path.
|
||||
func Remove(path, name string) error {
|
||||
if err := removexattr(path, name); err != nil {
|
||||
@@ -140,25 +169,44 @@ func LRemove(path, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FRemove is like Remove but accepts a os.File instead of a file path.
|
||||
func FRemove(f *os.File, name string) error {
|
||||
if err := fremovexattr(f, name); err != nil {
|
||||
return &Error{"xattr.FRemove", f.Name(), name, err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// List retrieves a list of names of extended attributes associated
|
||||
// with the given path in the file system.
|
||||
func List(path string) ([]string, error) {
|
||||
return list(path, listxattr)
|
||||
return list(path, func(data []byte) (int, error) {
|
||||
return listxattr(path, data)
|
||||
})
|
||||
}
|
||||
|
||||
// LList is like List but does not follow a symlink at the end of the
|
||||
// path.
|
||||
func LList(path string) ([]string, error) {
|
||||
return list(path, llistxattr)
|
||||
return list(path, func(data []byte) (int, error) {
|
||||
return llistxattr(path, data)
|
||||
})
|
||||
}
|
||||
|
||||
type listxattrFunc func(path string, data []byte) (int, error)
|
||||
// FList is like List but accepts a os.File instead of a file path.
|
||||
func FList(f *os.File) ([]string, error) {
|
||||
return list(f.Name(), func(data []byte) (int, error) {
|
||||
return flistxattr(f, data)
|
||||
})
|
||||
}
|
||||
|
||||
type listxattrFunc func(data []byte) (int, error)
|
||||
|
||||
// list contains the buffer allocation logic used by both List and LList.
|
||||
func list(path string, listxattrFunc listxattrFunc) ([]string, error) {
|
||||
myname := "xattr.list"
|
||||
// find size.
|
||||
size, err := listxattrFunc(path, nil)
|
||||
size, err := listxattrFunc(nil)
|
||||
if err != nil {
|
||||
return nil, &Error{myname, path, "", err}
|
||||
}
|
||||
@@ -167,7 +215,7 @@ func list(path string, listxattrFunc listxattrFunc) ([]string, error) {
|
||||
// from a SMB1 mount point (https://github.com/pkg/xattr/issues/16).
|
||||
buf := make([]byte, size+1)
|
||||
// Read into buffer of that size.
|
||||
read, err := listxattrFunc(path, buf)
|
||||
read, err := listxattrFunc(buf)
|
||||
if err != nil {
|
||||
return nil, &Error{myname, path, "", err}
|
||||
}
|
||||
|
||||
17
vendor/github.com/pkg/xattr/xattr_darwin.go
generated
vendored
17
vendor/github.com/pkg/xattr/xattr_darwin.go
generated
vendored
@@ -3,6 +3,7 @@
|
||||
package xattr
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
@@ -48,6 +49,10 @@ func lgetxattr(path string, name string, data []byte) (int, error) {
|
||||
return int(r0), nil
|
||||
}
|
||||
|
||||
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
|
||||
return getxattr(f.Name(), name, data)
|
||||
}
|
||||
|
||||
func setxattr(path string, name string, data []byte, flags int) error {
|
||||
return unix.Setxattr(path, name, data, flags)
|
||||
}
|
||||
@@ -56,6 +61,10 @@ func lsetxattr(path string, name string, data []byte, flags int) error {
|
||||
return unix.Setxattr(path, name, data, flags|XATTR_NOFOLLOW)
|
||||
}
|
||||
|
||||
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
|
||||
return setxattr(f.Name(), name, data, flags)
|
||||
}
|
||||
|
||||
func removexattr(path string, name string) error {
|
||||
return unix.Removexattr(path, name)
|
||||
}
|
||||
@@ -76,6 +85,10 @@ func lremovexattr(path string, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func fremovexattr(f *os.File, name string) error {
|
||||
return removexattr(f.Name(), name)
|
||||
}
|
||||
|
||||
func listxattr(path string, data []byte) (int, error) {
|
||||
return unix.Listxattr(path, data)
|
||||
}
|
||||
@@ -98,6 +111,10 @@ func llistxattr(path string, data []byte) (int, error) {
|
||||
return int(r0), nil
|
||||
}
|
||||
|
||||
func flistxattr(f *os.File, data []byte) (int, error) {
|
||||
return listxattr(f.Name(), data)
|
||||
}
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On Darwin and Linux, each entry is a NULL-terminated string.
|
||||
func stringsFromByteSlice(buf []byte) (result []string) {
|
||||
|
||||
17
vendor/github.com/pkg/xattr/xattr_freebsd.go
generated
vendored
17
vendor/github.com/pkg/xattr/xattr_freebsd.go
generated
vendored
@@ -3,6 +3,7 @@
|
||||
package xattr
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
@@ -24,6 +25,10 @@ func lgetxattr(path string, name string, data []byte) (int, error) {
|
||||
return sysGet(syscall.SYS_EXTATTR_GET_LINK, path, name, data)
|
||||
}
|
||||
|
||||
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
|
||||
return getxattr(f.Name(), name, data)
|
||||
}
|
||||
|
||||
// sysGet is called by getxattr and lgetxattr with the appropriate syscall
|
||||
// number. This works because syscalls have the same signature and return
|
||||
// values.
|
||||
@@ -61,6 +66,10 @@ func lsetxattr(path string, name string, data []byte, flags int) error {
|
||||
return sysSet(syscall.SYS_EXTATTR_SET_LINK, path, name, data)
|
||||
}
|
||||
|
||||
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
|
||||
return setxattr(f.Name(), name, data, flags)
|
||||
}
|
||||
|
||||
// sysSet is called by setxattr and lsetxattr with the appropriate syscall
|
||||
// number. This works because syscalls have the same signature and return
|
||||
// values.
|
||||
@@ -103,6 +112,10 @@ func lremovexattr(path string, name string) error {
|
||||
return sysRemove(syscall.SYS_EXTATTR_DELETE_LINK, path, name)
|
||||
}
|
||||
|
||||
func fremovexattr(f *os.File, name string) error {
|
||||
return removexattr(f.Name(), name)
|
||||
}
|
||||
|
||||
// sysSet is called by removexattr and lremovexattr with the appropriate syscall
|
||||
// number. This works because syscalls have the same signature and return
|
||||
// values.
|
||||
@@ -137,6 +150,10 @@ func llistxattr(path string, data []byte) (int, error) {
|
||||
return sysList(syscall.SYS_EXTATTR_LIST_LINK, path, data)
|
||||
}
|
||||
|
||||
func flistxattr(f *os.File, data []byte) (int, error) {
|
||||
return listxattr(f.Name(), data)
|
||||
}
|
||||
|
||||
// sysSet is called by listxattr and llistxattr with the appropriate syscall
|
||||
// number. This works because syscalls have the same signature and return
|
||||
// values.
|
||||
|
||||
17
vendor/github.com/pkg/xattr/xattr_linux.go
generated
vendored
17
vendor/github.com/pkg/xattr/xattr_linux.go
generated
vendored
@@ -3,6 +3,7 @@
|
||||
package xattr
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -26,6 +27,10 @@ func lgetxattr(path string, name string, data []byte) (int, error) {
|
||||
return unix.Lgetxattr(path, name, data)
|
||||
}
|
||||
|
||||
func fgetxattr(f *os.File, name string, data []byte) (int, error) {
|
||||
return unix.Fgetxattr(int(f.Fd()), name, data)
|
||||
}
|
||||
|
||||
func setxattr(path string, name string, data []byte, flags int) error {
|
||||
return unix.Setxattr(path, name, data, flags)
|
||||
}
|
||||
@@ -34,6 +39,10 @@ func lsetxattr(path string, name string, data []byte, flags int) error {
|
||||
return unix.Lsetxattr(path, name, data, flags)
|
||||
}
|
||||
|
||||
func fsetxattr(f *os.File, name string, data []byte, flags int) error {
|
||||
return unix.Fsetxattr(int(f.Fd()), name, data, flags)
|
||||
}
|
||||
|
||||
func removexattr(path string, name string) error {
|
||||
return unix.Removexattr(path, name)
|
||||
}
|
||||
@@ -42,6 +51,10 @@ func lremovexattr(path string, name string) error {
|
||||
return unix.Lremovexattr(path, name)
|
||||
}
|
||||
|
||||
func fremovexattr(f *os.File, name string) error {
|
||||
return unix.Fremovexattr(int(f.Fd()), name)
|
||||
}
|
||||
|
||||
func listxattr(path string, data []byte) (int, error) {
|
||||
return unix.Listxattr(path, data)
|
||||
}
|
||||
@@ -50,6 +63,10 @@ func llistxattr(path string, data []byte) (int, error) {
|
||||
return unix.Llistxattr(path, data)
|
||||
}
|
||||
|
||||
func flistxattr(f *os.File, data []byte) (int, error) {
|
||||
return unix.Flistxattr(int(f.Fd()), data)
|
||||
}
|
||||
|
||||
// stringsFromByteSlice converts a sequence of attributes to a []string.
|
||||
// On Darwin and Linux, each entry is a NULL-terminated string.
|
||||
func stringsFromByteSlice(buf []byte) (result []string) {
|
||||
|
||||
Reference in New Issue
Block a user