27
27
import math
28
28
import shutil
29
29
import gevent
30
+ import shlex
30
31
import cgatcore .experiment as E
31
32
import cgatcore .iotools as iotools
32
33
43
44
HAS_DRMAA = False
44
45
import platform
45
46
47
+ # Define TIME_CMD based on gtime availability
48
+ TIME_CMD = shutil .which ("gtime" ) or "time"
49
+
46
50
# global drmaa session
47
51
GLOBAL_SESSION = None
48
52
@@ -960,20 +964,16 @@ def _convert(key, v):
960
964
return JobInfo (jobId = process .pid , resourceUsage = data )
961
965
962
966
def run (self , statement_list ):
963
-
964
967
benchmark_data = []
965
968
for statement in statement_list :
966
969
self .logger .info ("running statement:\n %s" % statement )
967
970
968
971
full_statement , job_path = self .build_job_script (statement )
969
972
970
- time_command = "gtime" if platform .system () == "Darwin" else "time"
971
-
972
- # max_vmem is set to max_rss, not available by /usr/bin/time
973
+ # Use `shlex.quote()` to wrap `job_path` safely in the full statement
973
974
full_statement = (
974
- f"\\ { time_command } --output={ job_path } .times "
975
- f"-f '"
976
- f"exit_status\t %x\n "
975
+ f"{ shlex .quote (TIME_CMD )} --output={ shlex .quote (job_path + '.times' )} "
976
+ f"-f 'exit_status\t %x\n "
977
977
f"user_t\t %U\n "
978
978
f"sys_t\t %S\n "
979
979
f"wall_t\t %e\n "
@@ -995,57 +995,42 @@ def run(self, statement_list):
995
995
f"socket_sent\t %s\n "
996
996
f"major_page_fault\t %F\n "
997
997
f"unshared_data\t %D\n ' "
998
- f"{ job_path } "
998
+ f"{ shlex . quote ( job_path ) } "
999
999
)
1000
1000
1001
- while 1 :
1002
- start_time = time .time ()
1003
-
1004
- os .environ .update (
1005
- {'BASH_ENV' : os .path .join (os .environ ['HOME' ], '.bashrc' )})
1006
- process = subprocess .Popen (
1007
- full_statement ,
1008
- cwd = self .work_dir ,
1009
- shell = True ,
1010
- stdin = subprocess .PIPE ,
1011
- stdout = subprocess .PIPE ,
1012
- stderr = subprocess .PIPE ,
1013
- env = os .environ .copy (),
1014
- close_fds = True ,
1015
- executable = "/bin/bash" )
1016
-
1017
- # process.stdin.close()
1018
- stdout , stderr = process .communicate ()
1019
-
1020
- end_time = time .time ()
1021
-
1022
- if process .returncode == 126 :
1023
- self .logger .warn (
1024
- "repeating execution: message={}" .format (stderr ))
1025
- time .sleep (1 )
1026
- continue
1027
-
1028
- break
1029
- stdout = stdout .decode ("utf-8" )
1030
- stderr = stderr .decode ("utf-8" )
1001
+ start_time = time .time ()
1002
+ os .environ .update ({'BASH_ENV' : os .path .join (os .environ ['HOME' ], '.bashrc' )})
1003
+ process = subprocess .Popen (
1004
+ full_statement ,
1005
+ cwd = self .work_dir ,
1006
+ shell = True ,
1007
+ stdin = subprocess .PIPE ,
1008
+ stdout = subprocess .PIPE ,
1009
+ stderr = subprocess .PIPE ,
1010
+ env = os .environ .copy (),
1011
+ close_fds = True ,
1012
+ executable = "/bin/bash"
1013
+ )
1014
+
1015
+ stdout , stderr = process .communicate ()
1016
+ end_time = time .time ()
1031
1017
1032
1018
if process .returncode != 0 and not self .ignore_errors :
1033
1019
raise OSError (
1034
1020
"---------------------------------------\n "
1035
1021
"Child was terminated by signal %i: \n "
1036
1022
"The stderr was: \n %s\n %s\n "
1037
1023
"-----------------------------------------" %
1038
- (- process .returncode , stderr , statement ))
1024
+ (- process .returncode , stderr .decode ("utf-8" ), statement )
1025
+ )
1039
1026
1040
- resource_usage = self .collect_metric_data (process ,
1041
- start_time ,
1042
- end_time ,
1043
- time_data_file = job_path + ".times" )
1027
+ resource_usage = self .collect_metric_data (
1028
+ process , start_time , end_time , time_data_file = job_path + ".times"
1029
+ )
1044
1030
1045
1031
benchmark_data .extend (
1046
- self .collect_benchmark_data (
1047
- [statement ],
1048
- resource_usage = [resource_usage ]))
1032
+ self .collect_benchmark_data ([statement ], resource_usage = [resource_usage ])
1033
+ )
1049
1034
1050
1035
try :
1051
1036
os .unlink (job_path )
0 commit comments