Skip to content

Commit 4bca4af

Browse files
authored
Merge pull request #64 from Wenzel/handle_keyboardinterrupt
Handle keyboardinterrupt
2 parents e62c8e6 + c06352e commit 4bca4af

File tree

3 files changed

+55
-28
lines changed

3 files changed

+55
-28
lines changed

checksec/__main__.py

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,38 +76,51 @@ def main(args):
7676
output_cls = JSONOutput
7777

7878
with output_cls() as check_output:
79-
# we need to consume the iterator once to get the total
80-
# for the progress bar
81-
check_output.enumerating_tasks_start()
82-
count = sum(1 for i in walk_lief_parsable_list(filepath_list, recursive))
83-
check_output.enumerating_tasks_stop(count)
84-
with ProcessPoolExecutor(max_workers=workers) as pool:
85-
check_output.processing_tasks_start()
86-
future_to_checksec = {
87-
pool.submit(checksec_file, filepath): filepath
88-
for filepath in walk_lief_parsable_list(filepath_list, recursive)
89-
}
90-
for future in as_completed(future_to_checksec):
91-
filepath = future_to_checksec[future]
79+
try:
80+
# we need to consume the iterator once to get the total
81+
# for the progress bar
82+
check_output.enumerating_tasks_start()
83+
count = sum(1 for i in walk_lief_parsable_list(filepath_list, recursive))
84+
check_output.enumerating_tasks_stop(count)
85+
with ProcessPoolExecutor(max_workers=workers) as pool:
9286
try:
93-
data = future.result()
94-
except FileNotFoundError:
95-
logging.debug("%s does not exist", filepath)
96-
except ErrorParsingFailed:
97-
logging.debug("%s LIEF parsing failed")
98-
except NotImplementedError:
99-
logging.debug("%s: Not an ELF/PE. Skipping", filepath)
100-
else:
101-
check_output.add_checksec_result(filepath, data)
102-
finally:
103-
check_output.checksec_result_end()
104-
105-
check_output.print()
87+
check_output.processing_tasks_start()
88+
future_to_checksec = {
89+
pool.submit(checksec_file, filepath): filepath
90+
for filepath in walk_lief_parsable_list(filepath_list, recursive)
91+
}
92+
for future in as_completed(future_to_checksec):
93+
filepath = future_to_checksec[future]
94+
try:
95+
data = future.result()
96+
except FileNotFoundError:
97+
logging.debug("%s does not exist", filepath)
98+
except ErrorParsingFailed:
99+
logging.debug("%s LIEF parsing failed")
100+
except NotImplementedError:
101+
logging.debug("%s: Not an ELF/PE. Skipping", filepath)
102+
else:
103+
check_output.add_checksec_result(filepath, data)
104+
finally:
105+
check_output.checksec_result_end()
106+
except KeyboardInterrupt:
107+
# remove progress bars before waiting for ProcessPoolExecutor to shutdown
108+
check_output.__exit__(None, None, None)
109+
logging.info("Shutdown Process Pool ...")
110+
pool.shutdown(wait=True)
111+
raise
112+
except KeyboardInterrupt:
113+
pass
114+
else:
115+
check_output.print()
106116

107117

108118
def entrypoint():
109119
args = docopt(__doc__)
110-
main(args)
120+
try:
121+
main(args)
122+
except KeyboardInterrupt:
123+
pass
111124

112125

113126
if __name__ == "__main__":

checksec/output.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,15 @@ def __init__(self):
110110

111111
self.process_task_id = None
112112

113+
def __exit__(self, exc_type, exc_val, exc_tb):
114+
# cleanup the Rich progress bars
115+
if self.enumerate_bar is not None:
116+
self.enumerate_bar.stop()
117+
if self.process_bar is not None:
118+
self.process_bar.stop()
119+
if self.display_res_bar is not None:
120+
self.display_res_bar.stop()
121+
113122
def enumerating_tasks_start(self):
114123
# start progress bar
115124
self.enumerate_bar.start()
@@ -118,6 +127,7 @@ def enumerating_tasks_start(self):
118127
def enumerating_tasks_stop(self, total: int):
119128
super().enumerating_tasks_stop(total)
120129
self.enumerate_bar.stop()
130+
self.enumerate_bar = None
121131

122132
def processing_tasks_start(self):
123133
# init progress bar
@@ -287,6 +297,7 @@ def checksec_result_end(self):
287297

288298
def print(self):
289299
self.process_bar.stop()
300+
self.process_bar = None
290301

291302
if self.table_elf.row_count > 0:
292303
with self.display_res_bar:
@@ -299,6 +310,9 @@ def print(self):
299310
self.console.print(self.table_pe)
300311
self.display_res_bar.remove_task(task_id)
301312

313+
self.display_res_bar.stop()
314+
self.display_res_bar = None
315+
302316

303317
class JSONOutput(AbstractChecksecOutput):
304318
def __init__(self):

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
setuptools.setup(
1010
name="checksec.py",
11-
version="0.3.8",
11+
version="0.3.9",
1212
author="Mathieu Tarral",
1313
author_email="[email protected]",
1414
description="Checksec tool implemented in Python",

0 commit comments

Comments
 (0)