diff --git a/paramiko/sftp_handle.py b/paramiko/sftp_handle.py index 9c20ee5..25387e3 100644 --- a/paramiko/sftp_handle.py +++ b/paramiko/sftp_handle.py @@ -35,7 +35,16 @@ class SFTPHandle (object): Server implementations can (and should) subclass SFTPHandle to implement 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 # only for handles to folders: self.__files = { } @@ -121,17 +130,20 @@ class SFTPHandle (object): if writefile is None: return SFTP_OP_UNSUPPORTED try: - if self.__tell is None: - self.__tell = writefile.tell() - if offset != self.__tell: - writefile.seek(offset) - self.__tell = offset + # in append mode, don't care about seeking + if (self.__flags & os.O_APPEND) == 0: + if self.__tell is None: + self.__tell = writefile.tell() + if offset != self.__tell: + writefile.seek(offset) + self.__tell = offset writefile.write(data) writefile.flush() except IOError, e: self.__tell = None return SFTPServer.convert_errno(e.errno) - self.__tell += len(data) + if self.__tell is not None: + self.__tell += len(data) return SFTP_OK def stat(self): diff --git a/tests/stub_sftp.py b/tests/stub_sftp.py index 1679e34..2eb5f24 100644 --- a/tests/stub_sftp.py +++ b/tests/stub_sftp.py @@ -104,9 +104,15 @@ class StubSFTPServer (SFTPServerInterface): attr._flags &= ~attr.FLAG_PERMISSIONS SFTPServer.set_file_attr(path, attr) if flags & os.O_WRONLY: - fstr = 'wb' + if flags & os.O_APPEND: + fstr = 'ab' + else: + fstr = 'wb' elif flags & os.O_RDWR: - fstr = 'r+b' + if flags & os.O_APPEND: + fstr = 'a+b' + else: + fstr = 'r+b' else: # O_RDONLY (== 0) fstr = 'rb' @@ -114,7 +120,7 @@ class StubSFTPServer (SFTPServerInterface): f = os.fdopen(fd, fstr) except OSError, e: return SFTPServer.convert_errno(e.errno) - fobj = StubSFTPHandle() + fobj = StubSFTPHandle(flags) fobj.filename = path fobj.readfile = f fobj.writefile = f