summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-04-10 05:03:14 +0200
committerLennart Poettering <lennart@poettering.net>2010-04-10 18:00:21 +0200
commit9fb867204f3f7a1107f4a4d27d8003c093a05139 (patch)
tree7fb4a31581fd7ecbdb0b9f87d7a7e94c9bd2f9ad
parent302e8c4c4c7c776531d33fddae9cc0cac90846c3 (diff)
execute: automatically record start/exit timestamps for forked processes
-rw-r--r--execute.c48
-rw-r--r--execute.h6
2 files changed, 50 insertions, 4 deletions
diff --git a/execute.c b/execute.c
index 0374eaec5d..e4a70cd09a 100644
--- a/execute.c
+++ b/execute.c
@@ -447,7 +447,7 @@ static int enforce_user(const ExecContext *context, uid_t uid) {
return 0;
}
-int exec_spawn(const ExecCommand *command,
+int exec_spawn(ExecCommand *command,
const ExecContext *context,
int *fds, unsigned n_fds,
bool apply_permissions,
@@ -698,6 +698,9 @@ int exec_spawn(const ExecCommand *command,
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;
}
@@ -925,9 +928,41 @@ void exec_status_fill(ExecStatus *s, pid_t pid, int code, int status) {
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) {
@@ -971,6 +1006,9 @@ 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);
@@ -978,6 +1016,8 @@ void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
if (!prefix)
prefix = "";
+ p2 = strappend(prefix, "\t");
+ prefix2 = p2 ? p2 : prefix;
cmd = exec_command_line(c);
@@ -986,6 +1026,10 @@ void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
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) {
diff --git a/execute.h b/execute.h
index 5099a82435..8275d636fe 100644
--- a/execute.h
+++ b/execute.h
@@ -59,7 +59,8 @@ typedef enum ExecInput {
struct ExecStatus {
pid_t pid;
- usec_t timestamp;
+ usec_t start_timestamp;
+ usec_t exit_timestamp;
int code; /* as in siginfo_t::si_code */
int status; /* as in sigingo_t::si_status */
};
@@ -153,7 +154,7 @@ typedef enum ExitStatus {
EXIT_SETSID
} ExitStatus;
-int exec_spawn(const ExecCommand *command,
+int exec_spawn(ExecCommand *command,
const ExecContext *context,
int *fds, unsigned n_fds,
bool apply_permissions,
@@ -174,6 +175,7 @@ void exec_context_done(ExecContext *c);
void exec_context_dump(ExecContext *c, FILE* f, const char *prefix);
void exec_status_fill(ExecStatus *s, pid_t pid, int code, int status);
+void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix);
const char* exec_output_to_string(ExecOutput i);
int exec_output_from_string(const char *s);