|
|
84b277 |
From 0fca5aae90d5a4e292db8db7b9c31c8390799368 Mon Sep 17 00:00:00 2001
|
|
|
84b277 |
From: Daniel Mack <zonque@gmail.com>
|
|
|
84b277 |
Date: Fri, 7 Mar 2014 14:43:59 +0100
|
|
|
84b277 |
Subject: [PATCH] manager: flush memory stream before using the buffer
|
|
|
84b277 |
|
|
|
84b277 |
When the manager receives a SIGUSR2 signal, it opens a memory stream
|
|
|
84b277 |
with open_memstream(), uses the returned file handle for logging, and
|
|
|
84b277 |
dumps the logged content with log_dump().
|
|
|
84b277 |
|
|
|
84b277 |
However, the char* buffer is only safe to use after the file handle has
|
|
|
84b277 |
been flushed with fflush, as the man pages states:
|
|
|
84b277 |
|
|
|
84b277 |
When the stream is closed (fclose(3)) or flushed (fflush(3)), the
|
|
|
84b277 |
locations pointed to by ptr and sizeloc are updated to contain,
|
|
|
84b277 |
respectively, a pointer to the buffer and the current size of the
|
|
|
84b277 |
buffer.
|
|
|
84b277 |
These values remain valid only as long as the caller performs no
|
|
|
84b277 |
further output on the stream. If further output is performed, then the
|
|
|
84b277 |
stream must again be flushed before trying to access these variables.
|
|
|
84b277 |
|
|
|
84b277 |
Without that call, dump remains NULL and the daemon crashes in
|
|
|
84b277 |
log_dump().
|
|
|
84b277 |
|
|
|
84b277 |
Conflicts:
|
|
|
84b277 |
src/core/manager.c
|
|
|
84b277 |
|
|
|
84b277 |
(cherry-picked from b2cdc6664ef6b56e47d38649d69b9943d9f9f5d0)
|
|
|
84b277 |
|
|
|
84b277 |
Resolves: #1147524
|
|
|
84b277 |
---
|
|
|
84b277 |
src/core/manager.c | 17 +++++++++--------
|
|
|
84b277 |
1 file changed, 9 insertions(+), 8 deletions(-)
|
|
|
84b277 |
|
|
|
84b277 |
diff --git a/src/core/manager.c b/src/core/manager.c
|
|
|
84b277 |
index 4ad26e1..e48ea36 100644
|
|
|
84b277 |
--- a/src/core/manager.c
|
|
|
84b277 |
+++ b/src/core/manager.c
|
|
|
84b277 |
@@ -1536,11 +1536,12 @@ static int manager_process_signal_fd(Manager *m) {
|
|
|
84b277 |
}
|
|
|
84b277 |
|
|
|
84b277 |
case SIGUSR2: {
|
|
|
84b277 |
- FILE *f;
|
|
|
84b277 |
- char *dump = NULL;
|
|
|
84b277 |
+ _cleanup_free_ char *dump = NULL;
|
|
|
84b277 |
+ _cleanup_fclose_ FILE *f = NULL;
|
|
|
84b277 |
size_t size;
|
|
|
84b277 |
|
|
|
84b277 |
- if (!(f = open_memstream(&dump, &size))) {
|
|
|
84b277 |
+ f = open_memstream(&dump, &size);
|
|
|
84b277 |
+ if (!f) {
|
|
|
84b277 |
log_warning("Failed to allocate memory stream.");
|
|
|
84b277 |
break;
|
|
|
84b277 |
}
|
|
|
84b277 |
@@ -1549,16 +1550,16 @@ static int manager_process_signal_fd(Manager *m) {
|
|
|
84b277 |
manager_dump_jobs(m, f, "\t");
|
|
|
84b277 |
|
|
|
84b277 |
if (ferror(f)) {
|
|
|
84b277 |
- fclose(f);
|
|
|
84b277 |
- free(dump);
|
|
|
84b277 |
log_warning("Failed to write status stream");
|
|
|
84b277 |
break;
|
|
|
84b277 |
}
|
|
|
84b277 |
|
|
|
84b277 |
- fclose(f);
|
|
|
84b277 |
- log_dump(LOG_INFO, dump);
|
|
|
84b277 |
- free(dump);
|
|
|
84b277 |
+ if (fflush(f)) {
|
|
|
84b277 |
+ log_warning("Failed to flush status stream");
|
|
|
84b277 |
+ break;
|
|
|
84b277 |
+ }
|
|
|
84b277 |
|
|
|
84b277 |
+ log_dump(LOG_INFO, dump);
|
|
|
84b277 |
break;
|
|
|
84b277 |
}
|
|
|
84b277 |
|