summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--NEWS12
-rw-r--r--paramiko/__init__.py2
-rw-r--r--paramiko/channel.py20
-rw-r--r--paramiko/client.py8
-rw-r--r--paramiko/config.py2
-rw-r--r--paramiko/file.py4
-rw-r--r--setup.py2
7 files changed, 41 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index 55420463..1a6427a1 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,18 @@ Issues noted as "Fabric #NN" can be found at https://github.com/fabric/fabric/.
Releases
========
+v1.10.0 (DD MM YYYY)
+--------------------
+
+* #113: Add `timeout` parameter to `SSHClient.exec_command` for easier setting
+ of the command's internal channel object's timeout. Thanks to Cernov Vladimir
+ for the patch.
+* #94: Remove duplication of SSH port constant. Thanks to Olle Lundberg for the
+ catch.
+* #80: Expose the internal "is closed" property of the file transfer class
+ `BufferedFile` as `.closed`, better conforming to Python's file interface.
+ Thanks to `@smunaut` and James Hiscock for catch & patch.
+
v1.9.0 (6th Nov 2012)
---------------------
diff --git a/paramiko/__init__.py b/paramiko/__init__.py
index 29e470a6..7d7dcbf4 100644
--- a/paramiko/__init__.py
+++ b/paramiko/__init__.py
@@ -55,7 +55,7 @@ if sys.version_info < (2, 2):
__author__ = "Jeff Forcier <jeff@bitprophet.org>"
-__version__ = "1.9.0"
+__version__ = "1.10.0"
__license__ = "GNU Lesser General Public License (LGPL)"
diff --git a/paramiko/channel.py b/paramiko/channel.py
index 534f8d7c..9a1bb874 100644
--- a/paramiko/channel.py
+++ b/paramiko/channel.py
@@ -25,6 +25,7 @@ import sys
import time
import threading
import socket
+import errno
import os
from paramiko.common import *
@@ -605,6 +606,10 @@ class Channel (object):
@raise socket.timeout: if no data is ready before the timeout set by
L{settimeout}.
"""
+ if self.closed:
+ # this doesn't seem useful, but it is the documented behavior of Socket
+ raise socket.error(errno.EBADF, 'Socket is closed')
+
try:
out = self.in_buffer.read(nbytes, self.timeout)
except PipeTimeout, e:
@@ -655,6 +660,10 @@ class Channel (object):
@since: 1.1
"""
+ if self.closed:
+ # this doesn't seem useful, but it is the documented behavior of Socket
+ raise socket.error(errno.EBADF, 'Socket is closed')
+
try:
out = self.in_stderr_buffer.read(nbytes, self.timeout)
except PipeTimeout, e:
@@ -708,6 +717,10 @@ class Channel (object):
@raise socket.timeout: if no data could be sent before the timeout set
by L{settimeout}.
"""
+ if self.closed:
+ # this doesn't seem useful, but it is the documented behavior of Socket
+ raise socket.error(errno.EBADF, 'Socket is closed')
+
size = len(s)
self.lock.acquire()
try:
@@ -745,6 +758,10 @@ class Channel (object):
@since: 1.1
"""
+ if self.closed:
+ # this doesn't seem useful, but it is the documented behavior of Socket
+ raise socket.error(errno.EBADF, 'Socket is closed')
+
size = len(s)
self.lock.acquire()
try:
@@ -783,9 +800,6 @@ class Channel (object):
This is irritating, but identically follows python's API.
"""
while s:
- if self.closed:
- # this doesn't seem useful, but it is the documented behavior of Socket
- raise socket.error('Socket is closed')
sent = self.send(s)
s = s[sent:]
return None
diff --git a/paramiko/client.py b/paramiko/client.py
index 07560a39..a777b45b 100644
--- a/paramiko/client.py
+++ b/paramiko/client.py
@@ -28,6 +28,7 @@ import warnings
from paramiko.agent import Agent
from paramiko.common import *
+from paramiko.config import SSH_PORT
from paramiko.dsskey import DSSKey
from paramiko.hostkeys import HostKeys
from paramiko.resource import ResourceManager
@@ -37,8 +38,6 @@ from paramiko.transport import Transport
from paramiko.util import retry_on_signal
-SSH_PORT = 22
-
class MissingHostKeyPolicy (object):
"""
Interface for defining the policy that L{SSHClient} should use when the
@@ -350,7 +349,7 @@ class SSHClient (object):
self._agent.close()
self._agent = None
- def exec_command(self, command, bufsize=-1):
+ def exec_command(self, command, bufsize=-1, timeout=None):
"""
Execute a command on the SSH server. A new L{Channel} is opened and
the requested command is executed. The command's input and output
@@ -361,12 +360,15 @@ class SSHClient (object):
@type command: str
@param bufsize: interpreted the same way as by the built-in C{file()} function in python
@type bufsize: int
+ @param timeout: set command's channel timeout. See L{Channel.settimeout}.settimeout
+ @type timeout: int
@return: the stdin, stdout, and stderr of the executing command
@rtype: tuple(L{ChannelFile}, L{ChannelFile}, L{ChannelFile})
@raise SSHException: if the server fails to execute the command
"""
chan = self._transport.open_session()
+ chan.settimeout(timeout)
chan.exec_command(command)
stdin = chan.makefile('wb', bufsize)
stdout = chan.makefile('rb', bufsize)
diff --git a/paramiko/config.py b/paramiko/config.py
index 2828d903..d1ce9490 100644
--- a/paramiko/config.py
+++ b/paramiko/config.py
@@ -25,7 +25,7 @@ import os
import re
import socket
-SSH_PORT=22
+SSH_PORT = 22
proxy_re = re.compile(r"^(proxycommand)\s*=*\s*(.*)", re.I)
diff --git a/paramiko/file.py b/paramiko/file.py
index d4aec8e3..7e2904e1 100644
--- a/paramiko/file.py
+++ b/paramiko/file.py
@@ -354,6 +354,10 @@ class BufferedFile (object):
"""
return self
+ @property
+ def closed(self):
+ return self._closed
+
### overrides...
diff --git a/setup.py b/setup.py
index 1bb1a715..9812a4f4 100644
--- a/setup.py
+++ b/setup.py
@@ -52,7 +52,7 @@ if sys.platform == 'darwin':
setup(name = "paramiko",
- version = "1.9.0",
+ version = "1.10.0",
description = "SSH2 protocol library",
author = "Jeff Forcier",
author_email = "jeff@bitprophet.org",