Hello Chris,

our continuous integration server found an issues with this patch
("module 'shlex' has no attribute 'join'"):

+ cd rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8
+ ./waf distclean configure --prefix=/opt/rtems/6
'distclean' finished successfully (0.001s)
Setting top to : /home/minna/src/rtems-source-builder/rtems/build/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8 Setting out to : /home/minna/src/rtems-source-builder/rtems/build/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8/build
invalid version file: module 'shlex' has no attribute 'join'
(complete log in /home/minna/src/rtems-source-builder/rtems/build/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8/build/config.log) shell cmd failed: /bin/sh -ex /home/minna/src/rtems-source-builder/rtems/build/rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1/do-build
error: building rtems-tools-3ea0c249346fda427bf0d3c169aa3e7c2a521df8-1

Our CI build RTEMS Source Builder git commit 0860f9948dec7c001391948337723b313c052d1b correctly over the weekend. Tonight it failed with git commit 9ca95760eefadccd90e651b248efbe42810d2ed6. The failing build was a build with the following parameters:

Container: opensuse-leap 15.5
Python: 3.6.15
Nativ gcc: 7.5.0
Command Line: ../source-builder/sb-set-builder --rtems-version 6 --prefix /opt/rtems/6 --with_cxx --with_fortran --with_objc --jobs=12 --trace --log /home/minna/src/rtems6-devtools-arm-6+git.4303.9ca95760ee.x86_64_sb-set-builder.log 6/rtems-arm
Git head: 9ca95760eefadccd90e651b248efbe42810d2ed6
RTEMS Version: 6
RTEMS Tools for: ARM
Build host arch: x86_64

Your RSB commit triggered only this single build (opensuse 15.5/ARM). I have not tested to build on different Linux distributions or architectures, yet. If you need more infos, drop me an email. If you have a fix, I am happy to test it.

Greetings,
Frank

On 8/28/23 08:47, chr...@rtems.org wrote:
Subject:
[rtems-tools PATCH] rtemstoolkit: Fix shell execution
From:
chr...@rtems.org
Date:
8/28/23, 08:47

To:
devel@rtems.org


From: Chris Johns<chr...@rtems.org>

The fixes to parse the command along with the pipe options broke
a simple shell command such as '/sbin/sysctl hw.ncpu' on FreeBSD.
This patch fixes the shell command by passing a string for the
various options.

The unit test has been updated to catch errors and report them.
---
  rtemstoolkit/execute.py | 80 ++++++++++++++++++++++++++---------------
  1 file changed, 51 insertions(+), 29 deletions(-)

diff --git a/rtemstoolkit/execute.py b/rtemstoolkit/execute.py
index 3b7dcb0..d183b14 100755
--- a/rtemstoolkit/execute.py
+++ b/rtemstoolkit/execute.py
@@ -356,10 +356,17 @@ class execute(object):
          a string."""
          if self.output is None:
              raise error.general('capture needs an output handler')
-        cs = command
-        if type(command) is list:
-            def add(x, y): return x + ' ' + str(y)
-            cs = functools.reduce(add, command, '')[1:]
+        # If a string split and not a shell command split
+        if not shell and isinstance(command, str):
+            command = shlex.split(command)
+        if shell and isinstance(command, list):
+            command = shlex.join(command)
+            if self.shell_exe:
+                command = self.shell_exe + ' ' + command
+        if isinstance(command, list):
+            cs = shlex.join(command)
+        else:
+            cs = command
          what = 'spawn'
          if shell:
              what = 'shell'
@@ -367,9 +374,6 @@ class execute(object):
          if self.verbose:
              log.output(what + ': ' + cs)
          log.trace('exe: %s' % (cs))
-        if shell and self.shell_exe:
-            command = arg_list(command)
-            command[:0] = self.shell_exe
          if not stdin and self.input:
              stdin = subprocess.PIPE
          if not stdout:
@@ -390,21 +394,21 @@ class execute(object):
                      r, e = os.path.splitext(command[0])
                      if e not in ['.exe', '.com', '.bat']:
                          command[0] = command[0] + '.exe'
-            # If a string split
-            if isinstance(command, str):
-                command = shlex.split(command)
-            # See if there is a pipe operator in the command. If present
-            # split the commands by the pipe and run them with the pipe.
-            # if no pipe it is the normal stdin and stdout
              pipe_commands = []
-            current_command = []
-            for cmd in command:
-                if cmd == '|':
-                    pipe_commands.append(current_command)
-                    current_command = []
-                else:
-                    current_command.append(cmd)
-            pipe_commands.append(current_command)
+            if shell:
+                pipe_commands.append(command)
+            else:
+                # See if there is a pipe operator in the command. If present
+                # split the commands by the pipe and run them with the pipe.
+                # if no pipe it is the normal stdin and stdout
+                current_command = []
+                for cmd in command:
+                    if cmd == '|':
+                        pipe_commands.append(current_command)
+                        current_command = []
+                    else:
+                        current_command.append(cmd)
+                pipe_commands.append(current_command)
              proc = None
              if len(pipe_commands) == 1:
                  cmd = pipe_commands[0]
@@ -600,16 +604,28 @@ class capture_execution(execute):
  if __name__ == "__main__":
      def run_tests(e, commands, use_shell):
          for c in commands['shell']:
-            e.shell(c)
+            ec, out = e.shell(c)
+            if ec != 0:
+              raise RuntimeError('ec = {}'.format(ec))
+        for c in commands['error']:
+            ec, out = e.shell(c)
+            if ec == 0:
+              raise RuntimeError('ec = {}'.format(ec))
          for c in commands['spawn']:
-            e.spawn(c)
+            ec, out = e.spawn(c)
+            if ec != 0:
+              raise RuntimeError('ec = {}'.format(ec))
          for c in commands['cmd']:
              if type(c) is str:
-                e.command(c, shell = use_shell)
+                ec, out = e.command(c, shell = use_shell)
              else:
-                e.command(c[0], c[1], shell = use_shell)
+                ec, out = e.command(c[0], c[1], shell = use_shell)
+            if ec != 0:
+              raise RuntimeError('ec = {}'.format(ec))
          for c in commands['csubsts']:
-            e.command_subst(c[0], c[1], shell = use_shell)
+            ec, out = e.command_subst(c[0], c[1], shell = use_shell)
+            if ec != 0:
+              raise RuntimeError('ec = {}'.format(ec))
          ec, proc = e.command(commands['pipe'][0], commands['pipe'][1],
                               capture = False, stdin = subprocess.PIPE)
          if ec == 0:
@@ -623,11 +639,15 @@ if __name__ == "__main__":
              proc.stdin.close()
              e.capture(proc)
              del proc
+        else:
+            raise RuntimeError('ec = {}'.format(ec))
          for c in commands['open']:
              ec, proc = e.open(c)
              if ec == 0:
                  e.capture(proc)
                  del proc
+            else:
+                raise RuntimeError('ec = {}'.format(ec))
def capture_output(text):
          print(text, end = '')
@@ -640,7 +660,8 @@ if __name__ == "__main__":
      commands = {}
      commands['windows'] = {}
      commands['unix'] = {}
-    commands['windows']['shell'] = ['cd', 'dir /w', '.\\xyz', cmd_shell_test]
+    commands['windows']['shell'] = ['cd', 'dir /w', cmd_shell_test]
+    commands['windows']['error'] = ['.\\xyz']
      commands['windows']['spawn'] = ['hostname', 'hostnameZZ', ['netstat', 
'/e']]
      commands['windows']['cmd'] = [('ipconfig'), ('nslookup', 
'www.python.org')]
      commands['windows']['csubsts'] = [('netstat %0', ['-a']),
@@ -650,8 +671,9 @@ if __name__ == "__main__":
              ["echo",  "hello rtems", "|", "findstr", "rtems"],
              " ".join(["echo",  "hello rtems", "|", "findstr", "rtems"])
              ]
-    commands['unix']['shell'] = ['pwd', 'ls -las', './xyz', sh_shell_test]
-    commands['unix']['spawn'] = ['ls', 'execute.pyc', ['ls', '-i']]
+    commands['unix']['shell'] = ['pwd', 'ls -las', sh_shell_test, 'ls -las']
+    commands['unix']['error'] = ['./xyz']
+    commands['unix']['spawn'] = ['ls', ['ls', '-i'], 'ls -l']
      commands['unix']['cmd'] = [('date'), ('date', '-R'), ('date', ['-u', '+%d 
%D']),
                                 ('date', '-u "+%d %D %S"')]
      commands['unix']['csubsts'] = [('date %0 "+%d %D %S"', ['-u']),
-- 2.37.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel


--
embedded brains GmbH & Co. KG
Herr Frank KÜHNDEL
Dornierstr. 4
82178 Puchheim
Germany
email: frank.kuehn...@embedded-brains.de
phone:  +49-89-18 94 741 - 23
mobile: +49-176-15 22 06 - 11

Registergericht: Amtsgericht München
Registernummer: HRA 117265
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to