Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,10 @@ one), `:batch`/`:daemon` (see below), `:quick` (default t; nil drops
Emacs (event loop, timers, frame machinery, real init with
`:quick nil`) with no visible frame. Right for driving a new build
off-screen. Promote it to visible later by evaluating a
`make-frame` form in it.
`make-frame` form in it. The child's Emacs server gets a private
name (an Emacs daemon refuses to start while another server holds
its name, so this keeps it clear of a daemon you already run);
pass a string instead of t to choose the name.
- both nil — the child starts normally and opens a frame on the
parent's display: trying the new build as a user, or watching a
sandboxed agent's Emacs.
Expand Down
18 changes: 13 additions & 5 deletions parenting-parent.el
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,13 @@ connection closes; with DAEMON non-nil it runs with --fg-daemon
instead — a full interactive Emacs with no visible frame, which you
can promote later by evaluating a `make-frame' form in it; with both
nil the child starts normally and shows a frame on the parent's
display. With QUICK nil, -Q is dropped so the child starts with its
normal init files. NAME names the child process. Signal
`parenting-timeout' if the child has not connected after TIMEOUT
seconds.
display. A daemon child gets its own Emacs server name, so it does
not collide with any daemon already running under the default name
\(a daemon refuses to start when its server name is taken); DAEMON
may also be a string naming that server explicitly. With QUICK
nil, -Q is dropped so the child starts with its normal init files.
NAME names the child process. Signal `parenting-timeout' if the
child has not connected after TIMEOUT seconds.

The remaining keywords exist for launching the child inside a
sandbox or on another machine. COMMAND-WRAPPER is either a list of
Expand Down Expand Up @@ -421,7 +424,12 @@ host network. See `parenting--sandbox-command-wrapper'."
(list emacs)
(and quick '("-Q"))
(and batch '("--batch"))
(and daemon '("--fg-daemon"))
(and daemon
(list (concat "--fg-daemon="
(if (stringp daemon)
daemon
(make-temp-name
(concat name "-"))))))
args
(cl-mapcan (lambda (dir) (list "-L" dir))
extra-load-path)
Expand Down
24 changes: 24 additions & 0 deletions test/parenting-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,30 @@
(should (> (parenting-eval conn '(length (frame-list))) 0)))
(parenting-shutdown conn))))

(ert-deftest parenting-spawn-daemon-children-do-not-collide ()
;; Each daemon child names its own Emacs server: an Emacs daemon
;; refuses to start when its server name is already taken, so two
;; children under the default name (or one beside the user's own
;; daemon) could not coexist.
(let ((a (parenting-spawn :daemon t :timeout 60)))
(unwind-protect
(let ((b (parenting-spawn :daemon t :timeout 60)))
(unwind-protect
(progn
(should (eq t (parenting-eval b '(and (daemonp) t))))
(should-not (equal "server" (parenting-eval a 'server-name)))
(should-not (equal (parenting-eval a 'server-name)
(parenting-eval b 'server-name))))
(parenting-shutdown b)))
(parenting-shutdown a))))

(ert-deftest parenting-spawn-daemon-name-is-honored ()
(let ((conn (parenting-spawn :daemon "parenting-test-named" :timeout 60)))
(unwind-protect
(should (equal "parenting-test-named"
(parenting-eval conn 'server-name)))
(parenting-shutdown conn))))

(ert-deftest parenting-spawn-rejects-batch-plus-daemon ()
(should-error (parenting-spawn :batch t :daemon t)))

Expand Down
Loading