add 'flags' param to SFTPHandle and make the default impl avoid calling tell() when in append mode; add proper append-mode support to stub_sftp
This commit is contained in:
parent
49418d1145
commit
cc3e383baf
|
@ -35,7 +35,16 @@ class SFTPHandle (object):
|
||||||
Server implementations can (and should) subclass SFTPHandle to implement
|
Server implementations can (and should) subclass SFTPHandle to implement
|
||||||
features of a file handle, like L{stat} or L{chattr}.
|
features of a file handle, like L{stat} or L{chattr}.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, flags=0):
|
||||||
|
"""
|
||||||
|
Create a new file handle representing a local file being served over
|
||||||
|
SFTP. If C{flags} is passed in, it's used to determine if the file
|
||||||
|
is open in append mode.
|
||||||
|
|
||||||
|
@param flags: optional flags as passed to L{SFTPServerInterface.open}
|
||||||
|
@type flags: int
|
||||||
|
"""
|
||||||
|
self.__flags = flags
|
||||||
self.__name = None
|
self.__name = None
|
||||||
# only for handles to folders:
|
# only for handles to folders:
|
||||||
self.__files = { }
|
self.__files = { }
|
||||||
|
@ -121,17 +130,20 @@ class SFTPHandle (object):
|
||||||
if writefile is None:
|
if writefile is None:
|
||||||
return SFTP_OP_UNSUPPORTED
|
return SFTP_OP_UNSUPPORTED
|
||||||
try:
|
try:
|
||||||
if self.__tell is None:
|
# in append mode, don't care about seeking
|
||||||
self.__tell = writefile.tell()
|
if (self.__flags & os.O_APPEND) == 0:
|
||||||
if offset != self.__tell:
|
if self.__tell is None:
|
||||||
writefile.seek(offset)
|
self.__tell = writefile.tell()
|
||||||
self.__tell = offset
|
if offset != self.__tell:
|
||||||
|
writefile.seek(offset)
|
||||||
|
self.__tell = offset
|
||||||
writefile.write(data)
|
writefile.write(data)
|
||||||
writefile.flush()
|
writefile.flush()
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
self.__tell = None
|
self.__tell = None
|
||||||
return SFTPServer.convert_errno(e.errno)
|
return SFTPServer.convert_errno(e.errno)
|
||||||
self.__tell += len(data)
|
if self.__tell is not None:
|
||||||
|
self.__tell += len(data)
|
||||||
return SFTP_OK
|
return SFTP_OK
|
||||||
|
|
||||||
def stat(self):
|
def stat(self):
|
||||||
|
|
|
@ -104,9 +104,15 @@ class StubSFTPServer (SFTPServerInterface):
|
||||||
attr._flags &= ~attr.FLAG_PERMISSIONS
|
attr._flags &= ~attr.FLAG_PERMISSIONS
|
||||||
SFTPServer.set_file_attr(path, attr)
|
SFTPServer.set_file_attr(path, attr)
|
||||||
if flags & os.O_WRONLY:
|
if flags & os.O_WRONLY:
|
||||||
fstr = 'wb'
|
if flags & os.O_APPEND:
|
||||||
|
fstr = 'ab'
|
||||||
|
else:
|
||||||
|
fstr = 'wb'
|
||||||
elif flags & os.O_RDWR:
|
elif flags & os.O_RDWR:
|
||||||
fstr = 'r+b'
|
if flags & os.O_APPEND:
|
||||||
|
fstr = 'a+b'
|
||||||
|
else:
|
||||||
|
fstr = 'r+b'
|
||||||
else:
|
else:
|
||||||
# O_RDONLY (== 0)
|
# O_RDONLY (== 0)
|
||||||
fstr = 'rb'
|
fstr = 'rb'
|
||||||
|
@ -114,7 +120,7 @@ class StubSFTPServer (SFTPServerInterface):
|
||||||
f = os.fdopen(fd, fstr)
|
f = os.fdopen(fd, fstr)
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
return SFTPServer.convert_errno(e.errno)
|
return SFTPServer.convert_errno(e.errno)
|
||||||
fobj = StubSFTPHandle()
|
fobj = StubSFTPHandle(flags)
|
||||||
fobj.filename = path
|
fobj.filename = path
|
||||||
fobj.readfile = f
|
fobj.readfile = f
|
||||||
fobj.writefile = f
|
fobj.writefile = f
|
||||||
|
|
Loading…
Reference in New Issue