|
|
a135b2 |
From 0157f74a31adc1bd999ea5e5bc3a9c34af90b98c Mon Sep 17 00:00:00 2001
|
|
|
a135b2 |
From: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
|
|
|
a135b2 |
Date: Thu, 2 Apr 2020 16:03:57 +0530
|
|
|
a135b2 |
Subject: [PATCH] Fix StringIO/BytesIO stuck issue
|
|
|
a135b2 |
|
|
|
a135b2 |
We all know the way python3 handles strings is a bit different.
|
|
|
a135b2 |
|
|
|
a135b2 |
$ python2
|
|
|
a135b2 |
Python 2.7.16 (default, Apr 30 2019, 15:54:43)
|
|
|
a135b2 |
[GCC 9.0.1 20190312 (Red Hat 9.0.1-0.10)] on linux2
|
|
|
a135b2 |
Type "help", "copyright", "credits" or "license" for more information.
|
|
|
a135b2 |
>>> import io
|
|
|
a135b2 |
>>> s=io.BytesIO()
|
|
|
a135b2 |
>>> s.write('hello')
|
|
|
a135b2 |
5L
|
|
|
a135b2 |
>>> s.getvalue()
|
|
|
a135b2 |
'hello'
|
|
|
a135b2 |
>>> s=io.StringIO()
|
|
|
a135b2 |
>>> s.write('hello')
|
|
|
a135b2 |
Traceback (most recent call last):
|
|
|
a135b2 |
File "<stdin>", line 1, in <module>
|
|
|
a135b2 |
TypeError: unicode argument expected, got 'str'
|
|
|
a135b2 |
>>> s.write(u'hello')
|
|
|
a135b2 |
5L
|
|
|
a135b2 |
>>> s.getvalue()
|
|
|
a135b2 |
u'hello'
|
|
|
a135b2 |
>>>
|
|
|
a135b2 |
|
|
|
a135b2 |
$ python3
|
|
|
a135b2 |
Python 3.6.8 (default, Dec 5 2019, 15:45:45)
|
|
|
a135b2 |
[GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] on linux
|
|
|
a135b2 |
Type "help", "copyright", "credits" or "license" for more information.
|
|
|
a135b2 |
>>> import io
|
|
|
a135b2 |
>>> s=io.BytesIO()
|
|
|
a135b2 |
>>> s.write('hello')
|
|
|
a135b2 |
Traceback (most recent call last):
|
|
|
a135b2 |
File "<stdin>", line 1, in <module>
|
|
|
a135b2 |
TypeError: a bytes-like object is required, not 'str'
|
|
|
a135b2 |
>>> s.write(b'hello')
|
|
|
a135b2 |
5
|
|
|
a135b2 |
>>> s.getvalue()
|
|
|
a135b2 |
b'hello'
|
|
|
a135b2 |
>>> s=io.StringIO()
|
|
|
a135b2 |
>>> s.write('hello')
|
|
|
a135b2 |
5
|
|
|
a135b2 |
>>> s.getvalue()
|
|
|
a135b2 |
'hello'
|
|
|
a135b2 |
>>>
|
|
|
a135b2 |
|
|
|
a135b2 |
The way Python2 and Python3 handles String and Bytes IO is different.
|
|
|
a135b2 |
* In Python2 BytesIO() accepts text format syntax, and StringIO() expects unicodes
|
|
|
a135b2 |
* While in Python3 StringIO() accepts text format syntax, and BytesIO() expects bytes like objects
|
|
|
a135b2 |
|
|
|
a135b2 |
I think the compatibility of using both the IO streams with python2 and python3 is compromised.
|
|
|
a135b2 |
|
|
|
a135b2 |
Hence this patch, uses BytesIO() and StringIO() based on python version.
|
|
|
a135b2 |
|
|
|
a135b2 |
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
|
|
|
a135b2 |
---
|
|
|
a135b2 |
daemon/targetclid | 15 +++++++++------
|
|
|
a135b2 |
1 file changed, 9 insertions(+), 6 deletions(-)
|
|
|
a135b2 |
|
|
|
a135b2 |
diff --git a/daemon/targetclid b/daemon/targetclid
|
|
|
a135b2 |
index d4c6562..5df6ca2 100755
|
|
|
a135b2 |
--- a/daemon/targetclid
|
|
|
a135b2 |
+++ b/daemon/targetclid
|
|
|
a135b2 |
@@ -32,9 +32,13 @@ import struct
|
|
|
a135b2 |
import fcntl
|
|
|
a135b2 |
import signal
|
|
|
a135b2 |
import errno
|
|
|
a135b2 |
-import io
|
|
|
a135b2 |
|
|
|
a135b2 |
|
|
|
a135b2 |
+if sys.version_info < (3, 0):
|
|
|
a135b2 |
+ from io import BytesIO as StringIO
|
|
|
a135b2 |
+else:
|
|
|
a135b2 |
+ from io import StringIO
|
|
|
a135b2 |
+
|
|
|
a135b2 |
err = sys.stderr
|
|
|
a135b2 |
|
|
|
a135b2 |
class TargetCLI:
|
|
|
a135b2 |
@@ -154,24 +158,23 @@ class TargetCLI:
|
|
|
a135b2 |
connection.close()
|
|
|
a135b2 |
still_listen = False
|
|
|
a135b2 |
else:
|
|
|
a135b2 |
- self.con._stdout = self.con._stderr = f = io.BytesIO()
|
|
|
a135b2 |
+ self.con._stdout = self.con._stderr = f = StringIO()
|
|
|
a135b2 |
try:
|
|
|
a135b2 |
# extract multiple commands delimited with '%'
|
|
|
a135b2 |
list_data = data.decode().split('%')
|
|
|
a135b2 |
for cmd in list_data:
|
|
|
a135b2 |
self.shell.run_cmdline(cmd)
|
|
|
a135b2 |
except Exception as e:
|
|
|
a135b2 |
- print(str(e), file=f) # push error to stream
|
|
|
a135b2 |
+ print(str(e).encode(), file=f) # push error to stream
|
|
|
a135b2 |
|
|
|
a135b2 |
# Restore
|
|
|
a135b2 |
self.con._stdout = self.con_stdout_
|
|
|
a135b2 |
self.con._stderr = self.con_stderr_
|
|
|
a135b2 |
-
|
|
|
a135b2 |
- output = f.getvalue()
|
|
|
a135b2 |
+ output = f.getvalue().encode()
|
|
|
a135b2 |
var = struct.pack('i', len(output))
|
|
|
a135b2 |
connection.sendall(var) # length of string
|
|
|
a135b2 |
if len(output):
|
|
|
a135b2 |
- connection.sendall(output.encode()) # actual string
|
|
|
a135b2 |
+ connection.sendall(output) # actual string
|
|
|
a135b2 |
|
|
|
a135b2 |
f.close()
|
|
|
a135b2 |
|
|
|
a135b2 |
--
|
|
|
a135b2 |
2.21.0
|
|
|
a135b2 |
|