Subject: Re: bug#77389: 31.0.50; Restarting Emacs with (kill-emacs ... t) looses noninteractivity

From: Jens Schmidt <[email-masked]>
Date: Wed, 2 Apr 2025 22:54:23 +0200

On 2025-04-02  13:43, Eli Zaretskii wrote:

>>> Please describe your use case.
>>
>> TL;DR:
>>
>> 1. Start foo.el in batch mode with "emacs --script foo.el".
>> 2. foo.el reads the user init file and writes a modified copy of
>>    it to init-new.el.
>> 3. Then foo.el calls (kill-emacs ... t), thus restarting itself,
>>    (hopefully) still in batch mode.
>> 4. The newly started foo.el senses the presence of init-new.el
>>    and, hence, processes that in a final step.
>>
>> In the above it is important that steps 2 and 4 are executed
>> from different, newly started Emacs processes which share STDOUT
>> and STDERR.
> 
> Why do you need to write Lisp to a file, only to have that file read
> and executed? why not simply execute that Lisp directly in the
> original session?

Because the state of the original session (most notably the loaded
features) influences (and gets influenced by) that Lisp.  As a
minimal reproducer, consider ~/test.el as:

----- ~/test.el -----
;; -*- lexical-binding: t -*-
(gnus-message "foo")
----- ~/test.el -----

Now the Lisp I want to execute in above foo.el is, grossly simplified,

  (byte-compile-file "~/test.el").

And the result of that depends on whether gnus-utils has been loaded
in the calling Emacs session or not.

>> The only thing that bothers me a bit is that there is the following
>> memory-related initialization being executed in main *after*
>> copy_raw_args (or also the present sort_args) have already been
>> allocating memory:
> 
> Why does this bother you?  The old session is going down, and the new
> one will re-execute that part anew, no?  What did I miss?

I'm not talking about old or new session here.  What bothers me is
also independent of this bug, I just came across it while staring at
the surrounding code.  Namely at the comment in this block:

  /* Call malloc at least once, to run malloc_initialize_hook.
     Also call realloc and free for consistency.  */
  free (realloc (malloc (4), 4));

This sounds like this is initialization that better should be
executed *before* any actual call to malloc is done.  Which is
currently not the case, since, for example, sort_args can call
(x)malloc and sort_args is called before the block quoted above.
But then I do not really understand what that block is about and
my concerns may be completely unsubstantiated.

But back to my patch: I did a cursory grep for initial_arg[cv]
through current master.  From the results I got the impression
that instead of setting up a second copy raw_initial_arg[cv]
like done in the first patch, one could also try to directly
use initial_arg[cv], like in the attached alternative patch.
Should I go that route instead or would that be too risky,
anyway?

Thanks!