{"action":"created","issue":{"url":"https://api.github.com/repos/paramiko/paramiko/issues/537","labels_url":"https://api.github.com/repos/paramiko/paramiko/issues/537/labels{/name}","comments_url":"https://api.github.com/repos/paramiko/paramiko/issues/537/comments","events_url":"https://api.github.com/repos/paramiko/paramiko/issues/537/events","html_url":"https://github.com/paramiko/paramiko/issues/537","id":86221828,"number":537,"title":"race condition between channel.fileno() and closing channel when using select.select() with paramiko channels.","user":{"login":"pstrzelczak","id":7737102,"avatar_url":"https://avatars.githubusercontent.com/u/7737102?v=3","gravatar_id":"","url":"https://api.github.com/users/pstrzelczak","html_url":"https://github.com/pstrzelczak","followers_url":"https://api.github.com/users/pstrzelczak/followers","following_url":"https://api.github.com/users/pstrzelczak/following{/other_user}","gists_url":"https://api.github.com/users/pstrzelczak/gists{/gist_id}","starred_url":"https://api.github.com/users/pstrzelczak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pstrzelczak/subscriptions","organizations_url":"https://api.github.com/users/pstrzelczak/orgs","repos_url":"https://api.github.com/users/pstrzelczak/repos","events_url":"https://api.github.com/users/pstrzelczak/events{/privacy}","received_events_url":"https://api.github.com/users/pstrzelczak/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-06-08T15:26:15Z","updated_at":"2015-06-08T15:28:11Z","closed_at":null,"body":"The following code\r\n```\r\nchannel.exec_command(command)\r\nselect.select([channel], [], [])\r\n```\r\nmay lead to deadlock because a pipe created internally in channel.fileno() can be created after channel is closed()."},"comment":{"url":"https://api.github.com/repos/paramiko/paramiko/issues/comments/110041315","html_url":"https://github.com/paramiko/paramiko/issues/537#issuecomment-110041315","issue_url":"https://api.github.com/repos/paramiko/paramiko/issues/537","id":110041315,"user":{"login":"pstrzelczak","id":7737102,"avatar_url":"https://avatars.githubusercontent.com/u/7737102?v=3","gravatar_id":"","url":"https://api.github.com/users/pstrzelczak","html_url":"https://github.com/pstrzelczak","followers_url":"https://api.github.com/users/pstrzelczak/followers","following_url":"https://api.github.com/users/pstrzelczak/following{/other_user}","gists_url":"https://api.github.com/users/pstrzelczak/gists{/gist_id}","starred_url":"https://api.github.com/users/pstrzelczak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pstrzelczak/subscriptions","organizations_url":"https://api.github.com/users/pstrzelczak/orgs","repos_url":"https://api.github.com/users/pstrzelczak/repos","events_url":"https://api.github.com/users/pstrzelczak/events{/privacy}","received_events_url":"https://api.github.com/users/pstrzelczak/received_events","type":"User","site_admin":false},"created_at":"2015-06-08T15:28:11Z","updated_at":"2015-06-08T15:28:11Z","body":"full working code exposing this problem (assumes passwordless ssh to localhost):\r\n```\r\n#!/usr/bin/env python\r\n\r\nimport logging\r\nimport os\r\nimport paramiko\r\nimport paramiko.rsakey\r\nimport socket\r\nimport sys\r\nimport select\r\nimport time\r\nimport getpass\r\n\r\ndef communicateChannel(channel):\r\n\tstdout, stderr = [], []\r\n\tbufferSize = 64 * 1024\r\n\tgotSomeData = True\r\n\twhile gotSomeData:\r\n\t\tlogging.info('communicateChannel(), channel closed: %s', channel.closed)\r\n\t\tready, _, _ = select.select([channel], [], [])\r\n\t\tlogging.info('communicateChannel(), ready: %s, recv_ready: %s, recv_err_ready: %s', ready, channel.recv_ready(), channel.recv_stderr_ready())\r\n\r\n\t\tif ready:\r\n\t\t\tgotSomeData = False\r\n\t\t\tif channel.recv_ready():\r\n\t\t\t\tdata = channel.recv(bufferSize)\r\n\t\t\t\tif data:\r\n\t\t\t\t\tstdout.append(data)\r\n\t\t\t\t\tgotSomeData = True\r\n\t\t\tif channel.recv_stderr_ready():\r\n\t\t\t\tdata = channel.recv_stderr(bufferSize)\r\n\t\t\t\tif data:\r\n\t\t\t\t\tstderr.append(data)\r\n\t\t\t\t\tgotSomeData = True\r\n\treturn ''.join(stdout), ''.join(stderr)\r\n\r\ndef showBug():\r\n\tsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n\tsock.connect((\"localhost\", 22))\r\n\tconn = paramiko.Transport(sock)\r\n\r\n\tconn.start_client()\r\n\tassert conn.is_active()\r\n\r\n\tuser = getpass.getuser()\r\n\tconn.auth_publickey(user, paramiko.rsakey.RSAKey.from_private_key_file(\"/home/%s/.ssh/id_rsa\" % user))\r\n\tassert conn.is_authenticated()\r\n\r\n\tchannel = conn.open_session()\r\n\tcommand = '/bin/true'\r\n\tlogging.info('showBug() #1, launching %s' % command)\r\n\tchannel.exec_command('/bin/true')\r\n\tlogging.info('showBug() #2, launched %s' % command)\r\n\ttime.sleep(1)\r\n\tlogging.info('showBug() #3, channel closed: %s' % channel.closed)\r\n\ttime.sleep(0.1)\r\n\tlogging.info('showBug() #4')\r\n\tstdout, stderr = communicateChannel(channel)\r\n\tlogging.info('showBug() #5')\r\n\tretcode = channel.recv_exit_status()\r\n\tlogging.info('showBug() #6')\r\n\r\nlogging.basicConfig(level=logging.DEBUG)\r\nshowBug()\r\n```"}}