#include "hexdecoct.h"
#include "io-util.h"
#include "iovec-util.h"
+#include "journal-send.h"
#include "missing_ioprio.h"
#include "missing_prctl.h"
#include "missing_securebits.h"
#define SNDBUF_SIZE (8*1024*1024)
-static int shift_fds(int fds[], size_t n_fds) {
- if (n_fds <= 0)
- return 0;
-
- /* Modifies the fds array! (sorts it) */
-
- assert(fds);
-
- for (int start = 0;;) {
- int restart_from = -1;
-
- for (int i = start; i < (int) n_fds; i++) {
- int nfd;
-
- /* Already at right index? */
- if (fds[i] == i+3)
- continue;
-
- nfd = fcntl(fds[i], F_DUPFD, i + 3);
- if (nfd < 0)
- return -errno;
-
- safe_close(fds[i]);
- fds[i] = nfd;
-
- /* Hmm, the fd we wanted isn't free? Then
- * let's remember that and try again from here */
- if (nfd != i+3 && restart_from < 0)
- restart_from = i;
- }
-
- if (restart_from < 0)
- break;
-
- start = restart_from;
- }
-
- return 0;
-}
-
static int flag_fds(
const int fds[],
size_t n_socket_fds,
const char *j;
int r;
- j = log_namespace ?
- strjoina("/run/systemd/journal.", log_namespace, "/stdout") :
- "/run/systemd/journal/stdout";
+ assert(fd >= 0);
+
+ j = journal_stream_path(log_namespace);
+ if (!j)
+ return -EINVAL;
if (gid_is_valid(gid)) {
oldgid = getgid();
case EXEC_INPUT_DATA: {
int fd;
- fd = acquire_data_fd(context->stdin_data, context->stdin_data_size, 0);
+ fd = acquire_data_fd_full(context->stdin_data, context->stdin_data_size, /* flags = */ 0);
if (fd < 0)
return fd;
/* Block SIGTERM, so that we know that it won't get lost in the child */
- assert_se(sigprocmask_many(SIG_BLOCK, &old_ss, SIGTERM, -1) >= 0);
+ assert_se(sigprocmask_many(SIG_BLOCK, &old_ss, SIGTERM) >= 0);
parent_pid = getpid_cached();
* to inherit the $TERM set for PID 1. This is useful for containers so that the $TERM the
* container manager passes to PID 1 ends up all the way in the console login shown. */
- if (path_equal_ptr(tty_path, "/dev/console") && getppid() == 1)
+ if (path_equal(tty_path, "/dev/console") && getppid() == 1)
term = getenv("TERM");
else if (tty_path && in_charset(skip_dev_prefix(tty_path), ALPHANUMERICAL)) {
_cleanup_free_ char *key = NULL;
#if ENABLE_UTMP
if (context->utmp_id) {
+ _cleanup_free_ char *username_alloc = NULL;
+
+ if (!username && context->utmp_mode == EXEC_UTMP_USER) {
+ username_alloc = uid_to_name(uid_is_valid(uid) ? uid : saved_uid);
+ if (!username_alloc) {
+ *exit_status = EXIT_USER;
+ return log_oom();
+ }
+ }
+
const char *line = context->tty_path ?
(path_startswith(context->tty_path, "/dev/") ?: context->tty_path) :
NULL;
context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS :
context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
USER_PROCESS,
- username);
+ username ?: username_alloc);
}
#endif
}
if (context->memory_ksm >= 0)
- if (prctl(PR_SET_MEMORY_MERGE, context->memory_ksm) < 0) {
+ if (prctl(PR_SET_MEMORY_MERGE, context->memory_ksm, 0, 0, 0) < 0) {
if (ERRNO_IS_NOT_SUPPORTED(errno))
log_exec_debug_errno(context,
params,
_cleanup_close_ int executable_fd = -EBADF;
r = find_executable_full(command->path, /* root= */ NULL, context->exec_search_path, false, &executable, &executable_fd);
if (r < 0) {
- if (r != -ENOMEM && (command->flags & EXEC_COMMAND_IGNORE_FAILURE)) {
- log_exec_struct_errno(context, params, LOG_INFO, r,
- "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
- LOG_EXEC_INVOCATION_ID(params),
- LOG_EXEC_MESSAGE(params,
- "Executable %s missing, skipping: %m",
- command->path),
- "EXECUTABLE=%s", command->path);
- *exit_status = EXIT_SUCCESS;
- return 0;
- }
-
*exit_status = EXIT_EXEC;
- return log_exec_struct_errno(context, params, LOG_INFO, r,
- "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
- LOG_EXEC_INVOCATION_ID(params),
- LOG_EXEC_MESSAGE(params,
- "Failed to locate executable %s: %m",
- command->path),
- "EXECUTABLE=%s", command->path);
+ log_exec_struct_errno(context, params, LOG_NOTICE, r,
+ "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
+ LOG_EXEC_MESSAGE(params,
+ "Unable to locate executable '%s': %m",
+ command->path),
+ "EXECUTABLE=%s", command->path);
+ /* If the error will be ignored by manager, tune down the log level here. Missing executable
+ * is very much expected in this case. */
+ return r != -ENOMEM && FLAGS_SET(command->flags, EXEC_COMMAND_IGNORE_FAILURE) ? 1 : r;
}
r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, &executable_fd);
r = close_all_fds(keep_fds, n_keep_fds);
if (r >= 0)
- r = shift_fds(params->fds, n_fds);
+ r = pack_fds(params->fds, n_fds);
if (r >= 0)
r = flag_fds(params->fds, n_socket_fds, n_fds, context->non_blocking);
if (r < 0) {