Now that the necessary functions from log.h have been moved to macro.h,
we can stop including log.h in macro.h. This requires modifying source
files all over the tree to include log.h instead.
The identifier 'stdin' is reserved in C. It can be #defined to any
statement that evaluates to a FILE*. We do not want that for our field,
so change to a more descriptive name.
Follow-up for 329050c5e2
I don't particularly favor the duplicated strstrip()
and such, so let's ensure if we get fixed data it's
only trimmed once. Subsequently we can benefit more
by making all copies reflinks.
We initially read from temp file, then strip it, and write
back to it. If the file suddenly disappeared during the process,
it indicates someone else is touching our temp file
behind our back. Let's not silently continue.
- Add missing assertions
- Close all fds before spawning editor
- Use FOREACH_STRING() + empty_to_null() where appropriate
Note that this slightly changes the behavior, in that
empty envvars would be treated as unset and we'd try
the next candidate. But the new behavior is better IMO.
This is a fancy wrapper around "cat <<EOF", but:
- the user doesn't need to figure out the file name,
- parent directories are created automatically,
- daemon-reload is implied,
so it's a convenient way to create units or drop-ins.
Closes https://github.com/systemd/systemd/issues/21862.
If the user edits result in an empty file (after stripping), we would silently
not do anything, aborting the edit. This is rather confusing, let's emit a
notice:
$ build/systemctl --user edit asdf.service --full --stdin </dev/null
/home/zbyszek/.config/systemd/user/asdf.service: after editing, new contents are empty, not writing file.
(This also works with an editor, instead of --stdin. The message is printed on
the console and is visible after the editor exits.)
While at it, fix the condition to skip writing file after stripping. We had
"old_contents", but we modified that string. In some code flows, we would
compare the stripped old contents (i.e. a string which by defintion doesn't
have a newline at the end) with a string to which we just appended a newline
(i.e. a string which by defintion has a newline at the end).
In preparation for future changes: I want to add a mode where interactive
editing is not done, and when this preparation is moved to a helper, it's much
easier to skip it.
e->line is initialized to 1 and overwritten even if sync fails. Theoretically
this is against our style, but the alternative is to propagate a temporary
value of line through the layers, which adds a lot of noise. If we fail, this
EditFile object will not be used for anything, to the changed value of .line
has no effect.
Sometimes it makes sense to hard kill a client if we die. Let's hence
add a third FORK_DEATHSIG flag for this purpose: FORK_DEATHSIG_SIGKILL.
To make things less confusing this also renames FORK_DEATHSIG to
FORK_DEATHSIG_SIGTERM to make clear it sends SIGTERM. We already had
FORK_DEATHSIG_SIGINT, hence this makes things nicely symmetric.
A bunch of users are switched over for FORK_DEATHSIG_SIGKILL where we
know it's safe to abort things abruptly. This should make some kernel
cases more robust, since we cannot get confused by signal masks or such.
While we are at it, also fix a bunch of bugs where we didn't take
FORK_DEATHSIG_SIGINT into account in safe_fork()
strstrafter() is like strstr() but returns a pointer to the first
character *after* the found substring, not on the substring itself.
Quite often this is what we actually want.
Inspired by #27267 I think it makes sense to add a helper for this,
to avoid the potentially fragile manual pointer increment afterwards.
Before this commit, if `original_path` is given,
it will always be used to overwrite `path`.
After this commit, it's controlled by the newly-added
switch `overwrite_with_origin`.
This is a rather large change which moves
the add and install logic into edit-util.
We store an EditFile array and the number of
elements, along with the edit markers used in
temporary files and whether to remove the parent
directories of the target files if they're empty
in an EditFileContext object.
Call edit_files_add() to add an file to edit,
and do_edit_files_and_install() to do the actual
editing (through create_edit_temp_file(),
run_editor() and trim_edit_markers()).
After that, edit_file_context_done() can be used
to destroy the object.