helpers.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import errno
  2. import fcntl
  3. import os
  4. import sys
  5. import pathlib
  6. import shutil
  7. import signal
  8. import subprocess
  9. import tempfile
  10. import threading
  11. from openpilot.common.basedir import BASEDIR
  12. from openpilot.common.params import Params
  13. def unblock_stdout() -> None:
  14. # get a non-blocking stdout
  15. child_pid, child_pty = os.forkpty()
  16. if child_pid != 0: # parent
  17. # child is in its own process group, manually pass kill signals
  18. signal.signal(signal.SIGINT, lambda signum, frame: os.kill(child_pid, signal.SIGINT))
  19. signal.signal(signal.SIGTERM, lambda signum, frame: os.kill(child_pid, signal.SIGTERM))
  20. fcntl.fcntl(sys.stdout, fcntl.F_SETFL, fcntl.fcntl(sys.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
  21. while True:
  22. try:
  23. dat = os.read(child_pty, 4096)
  24. except OSError as e:
  25. if e.errno == errno.EIO:
  26. break
  27. continue
  28. if not dat:
  29. break
  30. try:
  31. sys.stdout.write(dat.decode('utf8'))
  32. except (OSError, UnicodeDecodeError):
  33. pass
  34. # os.wait() returns a tuple with the pid and a 16 bit value
  35. # whose low byte is the signal number and whose high byte is the exit status
  36. exit_status = os.wait()[1] >> 8
  37. os._exit(exit_status)
  38. def write_onroad_params(started, params):
  39. params.put_bool("IsOnroad", started)
  40. params.put_bool("IsOffroad", not started)
  41. def save_bootlog():
  42. # copy current params
  43. tmp = tempfile.mkdtemp()
  44. params_dirname = pathlib.Path(Params().get_param_path()).name
  45. params_dir = os.path.join(tmp, params_dirname)
  46. shutil.copytree(Params().get_param_path(), params_dir, dirs_exist_ok=True)
  47. def fn(tmpdir):
  48. env = os.environ.copy()
  49. env['PARAMS_COPY_PATH'] = tmpdir
  50. subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"), env=env)
  51. shutil.rmtree(tmpdir)
  52. t = threading.Thread(target=fn, args=(tmp, ))
  53. t.daemon = True
  54. t.start()