return 0;
}
-int exec_spawn(const ExecCommand *command,
+int exec_spawn(ExecCommand *command,
const ExecContext *context,
int *fds, unsigned n_fds,
bool apply_permissions,
pid_t pid;
int r;
+ char *line;
assert(command);
assert(context);
assert(ret);
assert(fds || n_fds <= 0);
- log_debug("About to execute %s", command->path);
+ if (!(line = exec_command_line(command)))
+ return -ENOMEM;
+
+ log_debug("About to execute: %s", line);
+ free(line);
if (cgroup_bondings)
if ((r = cgroup_bonding_realize_list(cgroup_bondings)))
log_debug("Forked %s as %llu", command->path, (unsigned long long) pid);
+ command->exec_status.pid = pid;
+ command->exec_status.start_timestamp = now(CLOCK_REALTIME);
+
*ret = pid;
return 0;
}
}
}
+void exec_command_done(ExecCommand *c) {
+ assert(c);
+
+ free(c->path);
+ c->path = NULL;
+
+ strv_free(c->argv);
+ c->argv = NULL;
+}
+
+void exec_command_done_array(ExecCommand *c, unsigned n) {
+ unsigned i;
+
+ for (i = 0; i < n; i++)
+ exec_command_done(c+i);
+}
+
void exec_command_free_list(ExecCommand *c) {
ExecCommand *i;
while ((i = c)) {
LIST_REMOVE(ExecCommand, command, c, i);
-
- free(i->path);
- strv_free(i->argv);
+ exec_command_done(i);
free(i);
}
}
assert(s);
s->pid = pid;
+ s->exit_timestamp = now(CLOCK_REALTIME);
+
s->code = code;
s->status = status;
- s->timestamp = now(CLOCK_REALTIME);
+}
+
+void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
+ char buf[FORMAT_TIMESTAMP_MAX];
+
+ assert(s);
+ assert(f);
+
+ if (!prefix)
+ prefix = "";
+
+ if (s->pid <= 0)
+ return;
+
+ fprintf(f,
+ "%sPID: %llu\n",
+ prefix, (unsigned long long) s->pid);
+
+ if (s->start_timestamp > 0)
+ fprintf(f,
+ "%sStart Timestamp: %s\n",
+ prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp));
+
+ if (s->exit_timestamp > 0)
+ fprintf(f,
+ "%sExit Timestamp: %s\n"
+ "%sExit Code: %s\n"
+ "%sExit Status: %i\n",
+ prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp),
+ prefix, sigchld_code_to_string(s->code),
+ prefix, s->status);
}
char *exec_command_line(ExecCommand *c) {
}
void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
+ char *p2;
+ const char *prefix2;
+
char *cmd;
assert(c);
if (!prefix)
prefix = "";
+ p2 = strappend(prefix, "\t");
+ prefix2 = p2 ? p2 : prefix;
cmd = exec_command_line(c);
prefix, cmd ? cmd : strerror(ENOMEM));
free(cmd);
+
+ exec_status_dump(&c->exec_status, f, prefix2);
+
+ free(p2);
}
void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
*l = e;
}
+int exec_command_set(ExecCommand *c, const char *path, ...) {
+ va_list ap;
+ char **l, *p;
+
+ assert(c);
+ assert(path);
+
+ va_start(ap, path);
+ l = strv_new_ap(path, ap);
+ va_end(ap);
+
+ if (!l)
+ return -ENOMEM;
+
+ if (!(p = strdup(path))) {
+ strv_free(l);
+ return -ENOMEM;
+ }
+
+ free(c->path);
+ c->path = p;
+
+ strv_free(c->argv);
+ c->argv = l;
+
+ return 0;
+}
+
static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
[EXEC_OUTPUT_CONSOLE] = "console",
[EXEC_OUTPUT_NULL] = "null",