edit-util: don't leave custom editor args around if we shall fall back (#36813)
Also, let's complain loudly if the editor acquired from envvar is not present. Fixes #36796
This commit is contained in:
@@ -35,13 +35,16 @@ static inline void* mempcpy_safe(void *dst, const void *src, size_t n) {
|
||||
return mempcpy(dst, src, n);
|
||||
}
|
||||
|
||||
#define mempcpy_typesafe(dst, src, n) \
|
||||
#define _mempcpy_typesafe(dst, src, n, sz) \
|
||||
({ \
|
||||
size_t _sz_; \
|
||||
assert_se(MUL_SAFE(&_sz_, sizeof((dst)[0]), n)); \
|
||||
(typeof((dst)[0])*) mempcpy_safe(dst, src, _sz_); \
|
||||
size_t sz; \
|
||||
assert_se(MUL_SAFE(&sz, sizeof((dst)[0]), n)); \
|
||||
(typeof((dst)[0])*) mempcpy_safe(dst, src, sz); \
|
||||
})
|
||||
|
||||
#define mempcpy_typesafe(dst, src, n) \
|
||||
_mempcpy_typesafe(dst, src, n, UNIQ_T(sz, UNIQ))
|
||||
|
||||
/* Normal memcmp() requires s1 and s2 to be nonnull. We do nothing if n is 0. */
|
||||
static inline int memcmp_safe(const void *s1, const void *s2, size_t n) {
|
||||
if (n == 0)
|
||||
|
||||
+20
-12
@@ -236,8 +236,7 @@ static int create_edit_temp_file(EditFile *e, const char *contents, size_t conte
|
||||
}
|
||||
|
||||
static int run_editor_child(const EditFileContext *context) {
|
||||
_cleanup_strv_free_ char **args = NULL;
|
||||
const char *editor;
|
||||
_cleanup_strv_free_ char **args = NULL, **editor = NULL;
|
||||
int r;
|
||||
|
||||
assert(context);
|
||||
@@ -247,15 +246,14 @@ static int run_editor_child(const EditFileContext *context) {
|
||||
* If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present, we try to execute
|
||||
* well known editors. */
|
||||
FOREACH_STRING(e, "SYSTEMD_EDITOR", "EDITOR", "VISUAL") {
|
||||
editor = empty_to_null(getenv(e));
|
||||
if (editor)
|
||||
break;
|
||||
}
|
||||
const char *m = empty_to_null(getenv(e));
|
||||
if (m) {
|
||||
editor = strv_split(m, WHITESPACE);
|
||||
if (!editor)
|
||||
return log_oom();
|
||||
|
||||
if (editor) {
|
||||
args = strv_split(editor, WHITESPACE);
|
||||
if (!args)
|
||||
return log_oom();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (context->n_files == 1 && context->files[0].line > 1) {
|
||||
@@ -271,8 +269,18 @@ static int run_editor_child(const EditFileContext *context) {
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (editor)
|
||||
execvp(args[0], (char* const*) args);
|
||||
size_t editor_n = strv_length(editor);
|
||||
if (editor_n > 0) {
|
||||
/* Strings are owned by 'editor' and 'args' */
|
||||
_cleanup_free_ char **cmdline = new(char*, editor_n + strv_length(args) + 1);
|
||||
if (!cmdline)
|
||||
return log_oom();
|
||||
|
||||
*mempcpy_typesafe(mempcpy_typesafe(cmdline, editor, editor_n), args, strv_length(args)) = NULL;
|
||||
|
||||
execvp(cmdline[0], cmdline);
|
||||
log_warning_errno(errno, "Specified editor '%s' not available, trying fallbacks: %m", editor[0]);
|
||||
}
|
||||
|
||||
bool prepended = false;
|
||||
FOREACH_STRING(name, "editor", "nano", "vim", "vi") {
|
||||
|
||||
Reference in New Issue
Block a user