~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/ssh.py

  • Committer: Andrew Bennetts
  • Date: 2010-10-13 00:26:41 UTC
  • mto: This revision was merged to the branch mainline in revision 5498.
  • Revision ID: andrew.bennetts@canonical.com-20101013002641-9tlh9k89mlj1666m
Keep docs-plain working.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 Robey Pointer <robey@lag.net>
 
1
# Copyright (C) 2006-2010 Robey Pointer <robey@lag.net>
2
2
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
359
359
        # whatever) chunks.
360
360
        try:
361
361
            my_sock, subproc_sock = socket.socketpair()
362
 
            osutils.set_fd_cloexec(my_sock)
363
362
        except (AttributeError, socket.error):
364
363
            # This platform doesn't support socketpair(), so just use ordinary
365
364
            # pipes instead.
366
365
            stdin = stdout = subprocess.PIPE
367
 
            my_sock, subproc_sock = None, None
 
366
            sock = None
368
367
        else:
369
368
            stdin = stdout = subproc_sock
 
369
            sock = my_sock
370
370
        proc = subprocess.Popen(argv, stdin=stdin, stdout=stdout,
371
371
                                **os_specific_subprocess_params())
372
 
        if subproc_sock is not None:
373
 
            subproc_sock.close()
374
 
        return SSHSubprocessConnection(proc, sock=my_sock)
 
372
        return SSHSubprocessConnection(proc, sock=sock)
375
373
 
376
374
    def connect_sftp(self, username, password, host, port):
377
375
        try:
408
406
                                  command=None):
409
407
        args = [self.executable_path,
410
408
                '-oForwardX11=no', '-oForwardAgent=no',
411
 
                '-oClearAllForwardings=yes',
 
409
                '-oClearAllForwardings=yes', '-oProtocol=2',
412
410
                '-oNoHostAuthenticationForLocalhost=yes']
413
411
        if port is not None:
414
412
            args.extend(['-p', str(port)])
573
571
        return True
574
572
    except paramiko.PasswordRequiredException:
575
573
        password = ui.ui_factory.get_password(
576
 
            prompt=u'SSH %(filename)s password',
577
 
            filename=filename.decode(osutils._fs_enc))
 
574
            prompt='SSH %(filename)s password', filename=filename)
578
575
        try:
579
576
            key = pkey_class.from_private_key_file(filename, password)
580
577
            paramiko_transport.auth_publickey(username, key)
656
653
import weakref
657
654
_subproc_weakrefs = set()
658
655
 
659
 
def _close_ssh_proc(proc, sock):
 
656
def _close_ssh_proc(proc):
660
657
    """Carefully close stdin/stdout and reap the SSH process.
661
658
 
662
659
    If the pipes are already closed and/or the process has already been
663
660
    wait()ed on, that's ok, and no error is raised.  The goal is to do our best
664
661
    to clean up (whether or not a clean up was already tried).
665
662
    """
666
 
    funcs = []
667
 
    for closeable in (proc.stdin, proc.stdout, sock):
668
 
        # We expect that either proc (a subprocess.Popen) will have stdin and
669
 
        # stdout streams to close, or that we will have been passed a socket to
670
 
        # close, with the option not in use being None.
671
 
        if closeable is not None:
672
 
            funcs.append(closeable.close)
673
 
    funcs.append(proc.wait)
674
 
    for func in funcs:
675
 
        try:
676
 
            func()
 
663
    dotted_names = ['stdin.close', 'stdout.close', 'wait']
 
664
    for dotted_name in dotted_names:
 
665
        attrs = dotted_name.split('.')
 
666
        try:
 
667
            obj = proc
 
668
            for attr in attrs:
 
669
                obj = getattr(obj, attr)
 
670
        except AttributeError:
 
671
            # It's ok for proc.stdin or proc.stdout to be None.
 
672
            continue
 
673
        try:
 
674
            obj()
677
675
        except OSError:
678
676
            # It's ok for the pipe to already be closed, or the process to
679
677
            # already be finished.
718
716
        # to avoid leaving processes lingering indefinitely.
719
717
        def terminate(ref):
720
718
            _subproc_weakrefs.remove(ref)
721
 
            _close_ssh_proc(proc, sock)
 
719
            _close_ssh_proc(proc)
722
720
        _subproc_weakrefs.add(weakref.ref(self, terminate))
723
721
 
724
722
    def send(self, data):
734
732
            return os.read(self.proc.stdout.fileno(), count)
735
733
 
736
734
    def close(self):
737
 
        _close_ssh_proc(self.proc, self._sock)
 
735
        _close_ssh_proc(self.proc)
738
736
 
739
737
    def get_sock_or_pipes(self):
740
738
        if self._sock is not None: