fetch-root.lisp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. (in-package :hurd)
  2. (defcfun ("helper_fetch_root" %helper-fetch-root)
  3. err
  4. (dotdot port)
  5. (fetch-root-callback :pointer)
  6. (uid uid-t)
  7. (gid gid-t)
  8. (argz :pointer)
  9. (argz-len :unsigned-int)
  10. (control-port port-pointer))
  11. (defun %fetch-root (dotdot fetch-root-callback uid gid translator)
  12. (let* ((len-args (string-list-len translator))
  13. (argz-len (sum-list len-args)))
  14. (with-foreign-pointer (control (foreign-type-size 'port))
  15. (with-foreign-pointer (argz argz-len)
  16. (list-to-foreign-string-zero-separated translator argz len-args)
  17. (let ((return-code (%helper-fetch-root dotdot
  18. fetch-root-callback
  19. uid
  20. gid
  21. argz
  22. argz-len
  23. control)))
  24. (select-error return-code (mem-ref control 'port)))))))
  25. (defun %try-start-translator (dotdot fetch-root-callback path uid gid)
  26. (multiple-value-bind (ret err)
  27. (%fetch-root dotdot fetch-root-callback uid gid path)
  28. (cond
  29. (err err)
  30. ((port-valid-p ret) ret)
  31. (t :translator-died))))
  32. (defun fetch-root (box dotdot flags user get-translator-callback fetch-root-callback)
  33. "Fetch the child translator port, starting the passive translator if needed."
  34. (unless (box-active-p box)
  35. (multiple-value-bind (path uid gid) (funcall get-translator-callback box)
  36. (unless (and path uid gid)
  37. (return-from fetch-root path)) ; return error
  38. (let ((control (%try-start-translator dotdot
  39. fetch-root-callback
  40. path
  41. uid
  42. gid)))
  43. (unless (port-valid-p control)
  44. (return-from fetch-root control)) ; error
  45. ; Set the now _active_ translator port
  46. (box-set-active box control t))))
  47. ; If we have come this far, it means that the box has an active port now!
  48. (let ((control (active box)))
  49. (port-mod-refs control :right-send 1)
  50. (multiple-value-bind (retry retry-name port)
  51. (fsys-getroot control dotdot :copy-send user flags)
  52. (port-deallocate control)
  53. (cond
  54. ((not (port-valid-p port))
  55. (box-set-active box nil nil)
  56. nil)
  57. (t
  58. (values retry retry-name port))))))