~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/ssh.py

  • Committer: Patch Queue Manager
  • Date: 2011-09-22 14:12:18 UTC
  • mfrom: (6155.3.1 jam)
  • Revision ID: pqm@pqm.ubuntu.com-20110922141218-86s4uu6nqvourw4f
(jameinel) Cleanup comments bzrlib/smart/__init__.py (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Robey Pointer <robey@lag.net>
 
1
# Copyright (C) 2006-2011 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)
362
363
        except (AttributeError, socket.error):
363
364
            # This platform doesn't support socketpair(), so just use ordinary
364
365
            # pipes instead.
365
366
            stdin = stdout = subprocess.PIPE
366
 
            sock = None
 
367
            my_sock, subproc_sock = None, None
367
368
        else:
368
369
            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
 
        return SSHSubprocessConnection(proc, sock=sock)
 
372
        if subproc_sock is not None:
 
373
            subproc_sock.close()
 
374
        return SSHSubprocessConnection(proc, sock=my_sock)
373
375
 
374
376
    def connect_sftp(self, username, password, host, port):
375
377
        try:
406
408
                                  command=None):
407
409
        args = [self.executable_path,
408
410
                '-oForwardX11=no', '-oForwardAgent=no',
409
 
                '-oClearAllForwardings=yes', '-oProtocol=2',
 
411
                '-oClearAllForwardings=yes',
410
412
                '-oNoHostAuthenticationForLocalhost=yes']
411
413
        if port is not None:
412
414
            args.extend(['-p', str(port)])
571
573
        return True
572
574
    except paramiko.PasswordRequiredException:
573
575
        password = ui.ui_factory.get_password(
574
 
            prompt='SSH %(filename)s password', filename=filename)
 
576
            prompt=u'SSH %(filename)s password',
 
577
            filename=filename.decode(osutils._fs_enc))
575
578
        try:
576
579
            key = pkey_class.from_private_key_file(filename, password)
577
580
            paramiko_transport.auth_publickey(username, key)
653
656
import weakref
654
657
_subproc_weakrefs = set()
655
658
 
656
 
def _close_ssh_proc(proc):
 
659
def _close_ssh_proc(proc, sock):
657
660
    """Carefully close stdin/stdout and reap the SSH process.
658
661
 
659
662
    If the pipes are already closed and/or the process has already been
660
663
    wait()ed on, that's ok, and no error is raised.  The goal is to do our best
661
664
    to clean up (whether or not a clean up was already tried).
662
665
    """
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()
 
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()
675
677
        except OSError:
676
678
            # It's ok for the pipe to already be closed, or the process to
677
679
            # already be finished.
716
718
        # to avoid leaving processes lingering indefinitely.
717
719
        def terminate(ref):
718
720
            _subproc_weakrefs.remove(ref)
719
 
            _close_ssh_proc(proc)
 
721
            _close_ssh_proc(proc, sock)
720
722
        _subproc_weakrefs.add(weakref.ref(self, terminate))
721
723
 
722
724
    def send(self, data):
732
734
            return os.read(self.proc.stdout.fileno(), count)
733
735
 
734
736
    def close(self):
735
 
        _close_ssh_proc(self.proc)
 
737
        _close_ssh_proc(self.proc, self._sock)
736
738
 
737
739
    def get_sock_or_pipes(self):
738
740
        if self._sock is not None: