~bzr/ubuntu/maverick/bzr/sru-2.2.4

« back to all changes in this revision

Viewing changes to bzrlib/transport/ssh.py

  • Committer: Jelmer Vernooij
  • Date: 2011-03-16 11:04:57 UTC
  • mfrom: (1.4.10 upstream)
  • Revision ID: jelmer@samba.org-20110316110457-qm29aunyhitce7ao
* New upstream release.
 + Fixes closing of leaked sockets to SSH subprocesses, which causes
   dput sftp uploads to hang. LP: #659590
 + Fixes the use of 'lp:' urls behind a http proxy. LP: #558343
 + Correctly sets the Content-Type header when http POSTing to comply 
   with stricter web frameworks. LP: #665100
 + Fixes propagating tags to the master branch in a bound branch or
   heavyweight checkout. LP: #603395
 + Fixes the use of 'bzr resolve --take-other' if the file is
   involved in an unresolved text conflict. LP: #646961
 + Fixes https access with newer versions of python2.7. LP: #693880
 + Fixes crash during pack caused by a concurrent repository pack
   operation. LP: #701940
 + Fixes communication with the Launchpad web service when using
   launchpadlib >= 1.5.5. LP: #707075
 + Switches away from deprecated 'edge.launchpad.net' LP: #583667
 + Fixes resolving of content (and path) conflicts for files in subdirs.
   LP: #660935
 + Fixes nasty recursion loop while displaying branch opening error.
   LP: #687653

Show diffs side-by-side

added added

removed removed

Lines of Context:
361
361
            # This platform doesn't support socketpair(), so just use ordinary
362
362
            # pipes instead.
363
363
            stdin = stdout = subprocess.PIPE
364
 
            sock = None
 
364
            my_sock, subproc_sock = None, None
365
365
        else:
366
366
            stdin = stdout = subproc_sock
367
 
            sock = my_sock
368
367
        proc = subprocess.Popen(argv, stdin=stdin, stdout=stdout,
369
368
                                **os_specific_subprocess_params())
370
 
        return SSHSubprocessConnection(proc, sock=sock)
 
369
        if subproc_sock is not None:
 
370
            subproc_sock.close()
 
371
        return SSHSubprocessConnection(proc, sock=my_sock)
371
372
 
372
373
    def connect_sftp(self, username, password, host, port):
373
374
        try:
644
645
import weakref
645
646
_subproc_weakrefs = set()
646
647
 
647
 
def _close_ssh_proc(proc):
 
648
def _close_ssh_proc(proc, sock):
648
649
    """Carefully close stdin/stdout and reap the SSH process.
649
650
 
650
651
    If the pipes are already closed and/or the process has already been
651
652
    wait()ed on, that's ok, and no error is raised.  The goal is to do our best
652
653
    to clean up (whether or not a clean up was already tried).
653
654
    """
654
 
    dotted_names = ['stdin.close', 'stdout.close', 'wait']
655
 
    for dotted_name in dotted_names:
656
 
        attrs = dotted_name.split('.')
657
 
        try:
658
 
            obj = proc
659
 
            for attr in attrs:
660
 
                obj = getattr(obj, attr)
661
 
        except AttributeError:
662
 
            # It's ok for proc.stdin or proc.stdout to be None.
663
 
            continue
664
 
        try:
665
 
            obj()
 
655
    funcs = []
 
656
    for closeable in (proc.stdin, proc.stdout, sock):
 
657
        # We expect that either proc (a subprocess.Popen) will have stdin and
 
658
        # stdout streams to close, or that we will have been passed a socket to
 
659
        # close, with the option not in use being None.
 
660
        if closeable is not None:
 
661
            funcs.append(closeable.close)
 
662
    funcs.append(proc.wait)
 
663
    for func in funcs:
 
664
        try:
 
665
            func()
666
666
        except OSError:
667
667
            # It's ok for the pipe to already be closed, or the process to
668
668
            # already be finished.
707
707
        # to avoid leaving processes lingering indefinitely.
708
708
        def terminate(ref):
709
709
            _subproc_weakrefs.remove(ref)
710
 
            _close_ssh_proc(proc)
 
710
            _close_ssh_proc(proc, sock)
711
711
        _subproc_weakrefs.add(weakref.ref(self, terminate))
712
712
 
713
713
    def send(self, data):
723
723
            return os.read(self.proc.stdout.fileno(), count)
724
724
 
725
725
    def close(self):
726
 
        _close_ssh_proc(self.proc)
 
726
        _close_ssh_proc(self.proc, self._sock)
727
727
 
728
728
    def get_sock_or_pipes(self):
729
729
        if self._sock is not None: