From bc3674d0f0c61b5c7af9cfbc9248cf574d0998b0 Mon Sep 17 00:00:00 2001 From: Tomer Filiba Date: Fri, 26 Oct 2012 15:44:34 +0300 Subject: [PATCH 1/4] Make send() and recv() fail when channel is closed ``sendall()`` was checking if the channel has been closed, and failed accordingly, but ``send()`` and ``recv()`` did not. This meant that ``chan.send("foo")`` when the channel was already closed, just blocked forever. --- paramiko/channel.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/paramiko/channel.py b/paramiko/channel.py index 534f8d7..35991de 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -605,6 +605,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 +659,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 +716,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 +757,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 +799,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 From 537f95dbb36c578e65cfd9cbc1a1eabc03f38428 Mon Sep 17 00:00:00 2001 From: Tomer Filiba Date: Fri, 26 Oct 2012 15:46:28 +0300 Subject: [PATCH 2/4] Forgot to import errno --- paramiko/channel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/paramiko/channel.py b/paramiko/channel.py index 35991de..9a1bb87 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 * From 7a4d3c4e424e6669d091be495eb8a000b4815ebe Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 29 Nov 2012 15:18:40 -0800 Subject: [PATCH 3/4] Revert "Make send() and recv() fail when channel is closed" This reverts commit bc3674d0f0c61b5c7af9cfbc9248cf574d0998b0. --- paramiko/channel.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/paramiko/channel.py b/paramiko/channel.py index 9a1bb87..1c9ae4b 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -606,10 +606,6 @@ 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: @@ -660,10 +656,6 @@ 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: @@ -717,10 +709,6 @@ 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: @@ -758,10 +746,6 @@ 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: @@ -800,6 +784,9 @@ 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 From 682a3eff8447ef83c10b0917c06f595803db97bb Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 29 Nov 2012 15:18:48 -0800 Subject: [PATCH 4/4] Revert "Forgot to import errno" This reverts commit 537f95dbb36c578e65cfd9cbc1a1eabc03f38428. --- paramiko/channel.py | 1 - 1 file changed, 1 deletion(-) diff --git a/paramiko/channel.py b/paramiko/channel.py index 1c9ae4b..534f8d7 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -25,7 +25,6 @@ import sys import time import threading import socket -import errno import os from paramiko.common import *