add path timeout for sensitive devices

This commit is contained in:
petrucci4prez 2017-05-30 01:00:23 -04:00
parent c002fc08eb
commit dd00c560eb
2 changed files with 38 additions and 33 deletions

View File

@ -50,45 +50,50 @@ class CountdownTimer(Thread):
def __del__(self):
self.stop()
def freeBusyPath(path, logger=None):
# check if any other processes are using file path
# if found, politely ask them to exit, else nuke them
def waitForPath(path, timeout=30):
for i in range(0, timeout):
if os.path.exists(path):
return
time.sleep(1)
raise FileNotFoundError('Could not find {} after {} seconds'.format(path, timeout))
# NOTE: fuser sends diagnostic info (eg filenames and modes...which we
# don't want) to stderr. This is weird, but let's me route to /dev/null
# so I don't have to parse it later
try:
stdout = check_output(['fuser', path], universal_newlines=True, stderr=DEVNULL)
except CalledProcessError:
logger.debug('%s not in use. Execution may continue', path)
else:
# assume stdout is one PID first
try:
processes = [psutil.Process(int(stdout))]
# we shouldn't need this if we are disabling the usb hub globally and nuking any past connections
#~ def freeBusyPath(path, logger=None):
#~ # check if any other processes are using file path
#~ # if found, politely ask them to exit, else nuke them
# else assume we have multiple PIDs separated by arbitrary space
except ValueError:
processes = [psutil.Process(int(s)) for s in stdout.split()]
#~ # NOTE: fuser sends diagnostic info (eg filenames and modes...which we
#~ # don't want) to stderr. This is weird, but let's me route to /dev/null
#~ # so I don't have to parse it later
#~ try:
#~ stdout = check_output(['fuser', path], universal_newlines=True, stderr=DEVNULL)
#~ except CalledProcessError:
#~ logger.debug('%s not in use. Execution may continue', path)
#~ else:
#~ # assume stdout is one PID first
#~ try:
#~ processes = [psutil.Process(int(stdout))]
for p in processes:
if logger:
logger.warning('%s in use by PID %s. Sending SIGTERM', path, p.pid)
p.terminate()
#~ # else assume we have multiple PIDs separated by arbitrary space
#~ except ValueError:
#~ processes = [psutil.Process(int(s)) for s in stdout.split()]
dead, alive = psutil.wait_procs(processes, timeout=10)
#~ for p in processes:
#~ if logger:
#~ logger.warning('%s in use by PID %s. Sending SIGTERM', path, p.pid)
#~ p.terminate()
for p in alive:
if logger:
logger.warning('Failed to terminate PID %s. Sending SIGKILL', p.pid)
p.kill()
#~ dead, alive = psutil.wait_procs(processes, timeout=10)
# crude way to 'unplug and plug back in' for USB device
#~ for p in alive:
#~ if logger:
#~ logger.warning('Failed to terminate PID %s. Sending SIGKILL', p.pid)
#~ p.kill()
# crude way to reset USB device, pretty rough but works
def resetUSBDevice(device):
devpath = os.path.join('/sys/bus/usb/devices/' + device + '/authorized')
with open(devpath, 'w') as f:
f.write('0')
with open(devpath, 'w') as f:
f.write('1')
def fallbackLogger(module, loglevel, msg):
print('[{}] [{}] [FALLBACK LOGGER]: {}'.format(module, loglevel, msg))

View File

@ -2,7 +2,7 @@ import logging, os, sys, stat
from threading import Thread
from evdev import InputDevice, ecodes
from select import select
from auxilary import freeBusyPath
from auxilary import waitForPath, freeBusyPath
import stateMachine
logger = logging.getLogger(__name__)
@ -23,7 +23,7 @@ class KeypadListener(Thread):
devPath = '/dev/input/by-id/usb-04d9_1203-event-kbd'
freeBusyPath(devPath, logger)
waitForPath(devPath)
self._dev = InputDevice(devPath)
self._dev.grab()