Changeset 1047 in tailor


Ignore:
Timestamp:
12/26/05 19:19:34 (7 years ago)
Author:
lele@…
Hash name:
20051226181934-7a6fb-92576d41e53da346e2e33e0933849d33e2456026
Message:

Avoid execution of too long command lines
Now the mechanism that executes external commands respects a maximum
size for the command line, eventually executing the external command
multiple times operating on a slice of the original arguments at a
time.

Location:
vcpx
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • vcpx/shwrap.py

    r1016 r1047  
    4949    DRY_RUN = False 
    5050    """Don't really execute the command.""" 
     51 
     52    MAX_CMDLINE_LENGTH = 8000 
     53    """Don't execute commands longer than this number of characters.""" 
    5154 
    5255    def __init__(self, command=None, cwd=None): 
     
    128131 
    129132    def execute(self, *args, **kwargs): 
     133        """Execute the command, avoiding too long command line.""" 
     134 
     135        from cStringIO import StringIO 
     136 
     137        if len(args) == 1 and type(args[0]) == type([]): 
     138            allargs = list(args[0]) 
     139        else: 
     140            allargs = list(args) 
     141 
     142        maxlen = self.MAX_CMDLINE_LENGTH 
     143        if maxlen is None or len(allargs) < 2: 
     144            return self._execute(allargs, **kwargs) 
     145 
     146        startlen = len(' '.join(self.command)) 
     147        allout = None 
     148        allerr = None 
     149        while allargs: 
     150            thisrun = [] 
     151            clen = startlen 
     152            pop = allargs.pop 
     153            append = thisrun.append 
     154            while allargs and clen<maxlen: 
     155                thisarg = pop(0) 
     156                clen += len(thisarg)+1 
     157                append(thisarg) 
     158            thisout, thiserr = self._execute(*thisrun, **kwargs) 
     159            if thisout is not None: 
     160                if allout is None: 
     161                    allout = StringIO() 
     162                allout.write(thisout.read()) 
     163            if thiserr is not None: 
     164                if allerr is None: 
     165                    allerr = StringIO() 
     166                allerr.write(thiserr.read()) 
     167            if self.exit_status: 
     168                break 
     169        if allout is not None: 
     170            allout.seek(0) 
     171        if allerr is not None: 
     172            allerr.seek(0) 
     173        return allout, allerr 
     174 
     175    def _execute(self, *args, **kwargs): 
    130176        """Execute the command.""" 
    131177 
  • vcpx/tests/shwrap.py

    r882 r1047  
    7575        c = ExternalCommand([r'a \" backslashed quote mark\\']) 
    7676        self.assertEqual(str(c), r'$ "a \\\" backslashed quote mark\\\\"') 
     77 
     78    def testSplittedExecution(self): 
     79        """Verify the mechanism that avoids too long command lines""" 
     80 
     81        args = [str(i) * 20 for i in range(10)] 
     82        c = ExternalCommand(['echo']) 
     83        c.MAX_CMDLINE_LENGTH = 30 
     84        out = c.execute(args, stdout=PIPE)[0] 
     85        self.assertEqual(out.read(), '\n'.join([args[i]+' '+args[i+1] 
     86                                                for i in range(0,10,2)])+'\n') 
     87 
     88        c = ExternalCommand(['echo']) 
     89        c.MAX_CMDLINE_LENGTH = None 
     90        out = c.execute(args, stdout=PIPE)[0] 
     91        self.assertEqual(out.read(), ' '.join(args)+'\n') 
Note: See TracChangeset for help on using the changeset viewer.