[systemd-commits] 5 commits - src/core src/journal src/libsystemd-network src/login src/shared src/systemctl TODO

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Sat Apr 12 07:59:25 PDT 2014


 TODO                                      |    2 
 src/core/timer.c                          |   40 +++++++++------
 src/journal/catalog.c                     |   78 ++++++++++++++++++------------
 src/journal/coredump.c                    |   30 +++++------
 src/journal/journal-remote.c              |   13 ++---
 src/journal/test-catalog.c                |    3 -
 src/libsystemd-network/sd-dhcp-client.c   |    3 +
 src/libsystemd-network/sd-dhcp-lease.c    |    4 -
 src/libsystemd-network/test-dhcp-client.c |   11 +++-
 src/login/logind-seat.c                   |    2 
 src/shared/fileio.c                       |   18 +++---
 src/shared/util.c                         |   17 +++---
 src/shared/util.h                         |   22 ++------
 src/systemctl/systemctl.c                 |    4 -
 14 files changed, 135 insertions(+), 112 deletions(-)

New commits:
commit 472fc28fdade525e700ebf4b25d026a8c907796d
Author: Thomas Bächler <thomas at archlinux.org>
Date:   Wed Apr 2 20:18:44 2014 +0200

    core: Make sure a stamp file exists for all Persistent=true timers
    
    If a persistent timer has no stamp file yet, it behaves just like a normal
    timer until it runs for the first time. If the system is always shut down
    while the timer is supposed to run, a stamp file is never created and
    Peristent=true has no effect.
    
    This patch fixes this by creating a stamp file with the current time
    when the timer is first started.

diff --git a/src/core/timer.c b/src/core/timer.c
index 6c85304..b0a9023 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -111,6 +111,23 @@ static int timer_add_default_dependencies(Timer *t) {
         return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
 }
 
+static void update_stampfile(Timer *t, usec_t timestamp) {
+        _cleanup_close_ int fd = -1;
+
+        mkdir_parents_label(t->stamp_path, 0755);
+
+        /* Update the file atime + mtime, if we can */
+        fd = open(t->stamp_path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
+        if (fd >= 0) {
+                struct timespec ts[2];
+
+                timespec_store(&ts[0], timestamp);
+                ts[1] = ts[0];
+
+                futimens(fd, ts);
+        }
+}
+
 static int timer_setup_persistent(Timer *t) {
         int r;
 
@@ -496,22 +513,8 @@ static void timer_enter_running(Timer *t) {
 
         dual_timestamp_get(&t->last_trigger);
 
-        if (t->stamp_path) {
-                _cleanup_close_ int fd = -1;
-
-                mkdir_parents_label(t->stamp_path, 0755);
-
-                /* Update the file atime + mtime, if we can */
-                fd = open(t->stamp_path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
-                if (fd >= 0) {
-                        struct timespec ts[2];
-
-                        timespec_store(&ts[0], t->last_trigger.realtime);
-                        ts[1] = ts[0];
-
-                        futimens(fd, ts);
-                }
-        }
+        if (t->stamp_path)
+                update_stampfile(t, t->last_trigger.realtime);
 
         timer_set_state(t, TIMER_RUNNING);
         return;
@@ -539,6 +542,11 @@ static int timer_start(Unit *u) {
 
                 if (stat(t->stamp_path, &st) >= 0)
                         t->last_trigger.realtime = timespec_load(&st.st_atim);
+                else if (errno == ENOENT)
+                        /* The timer has never run before,
+                         * make sure a stamp file exists.
+                         */
+                        update_stampfile(t, now(CLOCK_REALTIME));
         }
 
         t->result = TIMER_SUCCESS;

commit baf167ee0a2953f98e4e7d4c35752ef737832674
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Apr 11 20:57:27 2014 -0400

    journal: properly detect language specified in line
    
    ... it turns out that the duplicates in our own catalog were not real
    duplicates, but translations.

diff --git a/TODO b/TODO
index 0343b94..a7307f7 100644
--- a/TODO
+++ b/TODO
@@ -709,6 +709,8 @@ External:
 
 * fedora: update policy to declare access mode and ownership of unit files to root:root 0644, and add an rpmlint check for it
 
+* register catalog database signature as file magic
+
 Regularly:
 
 * look for close() vs. close_nointr() vs. close_nointr_nofail()
diff --git a/src/journal/catalog.c b/src/journal/catalog.c
index 02dedc4..f03357d 100644
--- a/src/journal/catalog.c
+++ b/src/journal/catalog.c
@@ -159,6 +159,37 @@ int catalog_file_lang(const char* filename, char **lang) {
         return 1;
 }
 
+static int catalog_entry_lang(const char* filename, int line,
+                              const char* t, const char* deflang, char **lang) {
+        size_t c;
+
+        c = strlen(t);
+        if (c == 0) {
+                log_error("[%s:%u] Language too short.", filename, line);
+                return -EINVAL;
+        }
+        if (c > 31) {
+                log_error("[%s:%u] language too long.", filename, line);
+                return -EINVAL;
+        }
+
+        if (deflang) {
+                if (streq(t, deflang)) {
+                        log_warning("[%s:%u] language specified unnecessarily",
+                                    filename, line);
+                        return 0;
+                } else
+                        log_warning("[%s:%u] language differs from default for file",
+                                    filename, line);
+        }
+
+        *lang = strdup(t);
+        if (!*lang)
+                        return -ENOMEM;
+
+        return 0;
+}
+
 int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_free_ char *payload = NULL;
@@ -238,25 +269,9 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
                                 if (with_language) {
                                         t = strstrip(line + 2 + 1 + 32 + 1);
 
-                                        c = strlen(t);
-                                        if (c <= 0) {
-                                                log_error("[%s:%u] Language too short.", path, n);
-                                                return -EINVAL;
-                                        }
-                                        if (c > 31) {
-                                                log_error("[%s:%u] language too long.", path, n);
-                                                return -EINVAL;
-                                        }
-
-                                        if (deflang) {
-                                                log_warning("[%s:%u] language %s", path, n,
-                                                            streq(t, deflang) ?
-                                                            "specified unnecessarily" :
-                                                            "differs from default for file");
-                                                lang = strdup(t);
-                                                if (!lang)
-                                                        return -ENOMEM;
-                                        }
+                                        r = catalog_entry_lang(path, n, t, deflang, &lang);
+                                        if (r < 0)
+                                                return r;
                                 }
 
                                 got_id = true;

commit e3b9d9c8027a7c4c55cf1614e0fe9423fad69e8f
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Apr 11 08:44:55 2014 -0400

    journal: cleanup up error handling in update_catalog()
    
    - Negative/positive errno mixup caused duplicates not to be detected properly.
      Now we get a warning about some duplicate entries in our own catalogs...
    - Errors in update_catalog would be ignored, but they should not be.

diff --git a/src/journal/catalog.c b/src/journal/catalog.c
index 3ed0b7e..02dedc4 100644
--- a/src/journal/catalog.c
+++ b/src/journal/catalog.c
@@ -103,7 +103,7 @@ static int finish_item(
                 const char *payload) {
 
         ssize_t offset;
-        CatalogItem *i;
+        _cleanup_free_ CatalogItem *i = NULL;
         int r;
 
         assert(h);
@@ -126,13 +126,14 @@ static int finish_item(
         i->offset = htole64((uint64_t) offset);
 
         r = hashmap_put(h, i, i);
-        if (r == EEXIST) {
+        if (r == -EEXIST) {
                 log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.",
                             SD_ID128_FORMAT_VAL(id), language ? language : "C");
-                free(i);
                 return 0;
-        }
+        } else if (r < 0)
+                return r;
 
+        i = NULL;
         return 0;
 }
 
@@ -383,8 +384,8 @@ error:
 int catalog_update(const char* database, const char* root, const char* const* dirs) {
         _cleanup_strv_free_ char **files = NULL;
         char **f;
-        Hashmap *h;
         struct strbuf *sb = NULL;
+        _cleanup_hashmap_free_free_ Hashmap *h = NULL;
         _cleanup_free_ CatalogItem *items = NULL;
         CatalogItem *i;
         Iterator j;
@@ -406,13 +407,17 @@ int catalog_update(const char* database, const char* root, const char* const* di
         }
 
         STRV_FOREACH(f, files) {
-                log_debug("reading file '%s'", *f);
-                catalog_import_file(h, sb, *f);
+                log_debug("Reading file '%s'", *f);
+                r = catalog_import_file(h, sb, *f);
+                if (r < 0) {
+                        log_error("Failed to import file '%s': %s.",
+                                  *f, strerror(-r));
+                        goto finish;
+                }
         }
 
         if (hashmap_size(h) <= 0) {
                 log_info("No items in catalog.");
-                r = 0;
                 goto finish;
         } else
                 log_debug("Found %u items in catalog.", hashmap_size(h));
@@ -443,11 +448,7 @@ int catalog_update(const char* database, const char* root, const char* const* di
                 log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.",
                           database, n, sb->len, r);
 
-        r = 0;
-
 finish:
-        if (h)
-                hashmap_free_free(h);
         if (sb)
                 strbuf_cleanup(sb);
 
diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c
index b087a8b..967ab67 100644
--- a/src/journal/test-catalog.c
+++ b/src/journal/test-catalog.c
@@ -157,7 +157,8 @@ int main(int argc, char *argv[]) {
 
         setlocale(LC_ALL, "de_DE.UTF-8");
 
-        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
 
         test_catalog_file_lang();
 

commit 6e00a80641aaba814204c65365c2fd5a90768394
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Apr 10 23:45:46 2014 -0400

    test-dhcp-client: unref lease objects to make valgrind happy
    
    Also unref client objects in test code, and initalize logging,
    to DEBUG by default.

diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index c67de71..4892203 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -805,6 +805,7 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
                 }
         }
 
+        sd_dhcp_lease_unref(client->lease);
         client->lease = lease;
         lease = NULL;
 
@@ -1330,6 +1331,8 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
 
                 sd_dhcp_client_detach_event(client);
 
+                sd_dhcp_lease_unref(client->lease);
+
                 free(client->req_opts);
                 free(client);
 
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 159bb50..aa479ff 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -271,7 +271,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
 }
 
 int dhcp_lease_new(sd_dhcp_lease **ret) {
-        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
+        sd_dhcp_lease *lease;
 
         lease = new0(sd_dhcp_lease, 1);
         if (!lease)
@@ -280,8 +280,6 @@ int dhcp_lease_new(sd_dhcp_lease **ret) {
         lease->n_ref = REFCNT_INIT;
 
         *ret = lease;
-        lease = NULL;
-
         return 0;
 }
 
diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
index 9c316d7..e7787fa 100644
--- a/src/libsystemd-network/test-dhcp-client.c
+++ b/src/libsystemd-network/test-dhcp-client.c
@@ -29,6 +29,8 @@
 
 #include "util.h"
 #include "socket-util.h"
+#include "sd-event.h"
+#include "event-util.h"
 
 #include "dhcp-protocol.h"
 #include "dhcp-internal.h"
@@ -109,6 +111,8 @@ static void test_request_basic(sd_event *e)
         assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
         assert_se(sd_dhcp_client_set_request_option(client, 44) == 0);
         assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
+
+        sd_dhcp_client_unref(client);
 }
 
 static void test_checksum(void)
@@ -373,6 +377,7 @@ static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
         if (verbose)
                 printf("  DHCP address acquired\n");
 
+        sd_dhcp_lease_unref(lease);
         sd_event_exit(e, 0);
 }
 
@@ -485,7 +490,11 @@ static void test_addr_acq(sd_event *e) {
 }
 
 int main(int argc, char *argv[]) {
-        sd_event *e;
+        _cleanup_event_unref_ sd_event *e;
+
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
 
         assert_se(sd_event_new(&e) >= 0);
 

commit ca2d37841476e6272c9957c3f5a0cbe869a531ca
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Apr 10 09:48:59 2014 -0400

    Unify GREEDY_REALLOC and GREEDY_REALLOC_T
    
    greedy_realloc() and greedy_realloc0() now store the allocated
    size as the count, not bytes.
    
    Replace GREEDY_REALLOC uses with GREEDY_REALLOC_T everywhere,
    and then rename GREEDY_REALLOC_T to GREEDY_REALLOC. It is just
    too error-prone to have two slightly different macros which do the
    same thing.

diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index 29342de..74b1dbd 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -39,10 +39,10 @@
 #include "journald-native.h"
 
 /* Few programs have less than 3MiB resident */
-#define COREDUMP_MIN_START (3*1024*1024)
+#define COREDUMP_MIN_START (3*1024*1024u)
 /* Make sure to not make this larger than the maximum journal entry
  * size. See ENTRY_SIZE_MAX in journald-native.c. */
-#define COREDUMP_MAX (767*1024*1024)
+#define COREDUMP_MAX (767*1024*1024u)
 assert_cc(COREDUMP_MAX <= ENTRY_SIZE_MAX);
 
 enum {
@@ -107,7 +107,7 @@ int main(int argc, char* argv[]) {
         uid_t uid;
         gid_t gid;
         struct iovec iovec[14];
-        size_t coredump_bufsize, coredump_size;
+        size_t coredump_bufsize = 0, coredump_size = 0;
         _cleanup_free_ char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL,
                 *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL,
                 *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *coredump_data = NULL;
@@ -239,17 +239,18 @@ int main(int argc, char* argv[]) {
                 goto finish;
         }
 
-        coredump_bufsize = COREDUMP_MIN_START;
-        coredump_data = malloc(coredump_bufsize);
-        if (!coredump_data) {
-                log_warning("Failed to allocate memory for core, core will not be stored.");
-                goto finalize;
-        }
+        for (;;) {
+                if (!GREEDY_REALLOC(coredump_data, coredump_bufsize,
+                                    MAX(coredump_size + 1, COREDUMP_MIN_START/2))) {
+                        log_warning("Failed to allocate memory for core, core will not be stored.");
+                        goto finalize;
+                }
 
-        memcpy(coredump_data, "COREDUMP=", 9);
-        coredump_size = 9;
+                if (coredump_size == 0) {
+                        memcpy(coredump_data, "COREDUMP=", 9);
+                        coredump_size = 9;
+                }
 
-        for (;;) {
                 n = loop_read(STDIN_FILENO, coredump_data + coredump_size,
                               coredump_bufsize - coredump_size, false);
                 if (n < 0) {
@@ -265,11 +266,6 @@ int main(int argc, char* argv[]) {
                         log_error("Core too large, core will not be stored.");
                         goto finalize;
                 }
-
-                if (!GREEDY_REALLOC(coredump_data, coredump_bufsize, coredump_size + 1)) {
-                        log_warning("Failed to allocate memory for core, core will not be stored.");
-                        goto finalize;
-                }
         }
 
         iovec[j].iov_base = coredump_data;
diff --git a/src/journal/journal-remote.c b/src/journal/journal-remote.c
index 4ece14e..794298f 100644
--- a/src/journal/journal-remote.c
+++ b/src/journal/journal-remote.c
@@ -226,8 +226,8 @@ typedef struct MHDDaemonWrapper {
 
 typedef struct RemoteServer {
         RemoteSource **sources;
-        ssize_t sources_size;
-        ssize_t active;
+        size_t sources_size;
+        size_t active;
 
         sd_event *events;
         sd_event_source *sigterm_event, *sigint_event, *listen_event;
@@ -257,7 +257,7 @@ static int get_source_for_fd(RemoteServer *s, int fd, RemoteSource **source) {
         assert(fd >= 0);
         assert(source);
 
-        if (!GREEDY_REALLOC0_T(s->sources, s->sources_size, fd + 1))
+        if (!GREEDY_REALLOC0(s->sources, s->sources_size, fd + 1))
                 return log_oom();
 
         if (s->sources[fd] == NULL) {
@@ -276,8 +276,7 @@ static int remove_source(RemoteServer *s, int fd) {
         RemoteSource *source;
 
         assert(s);
-        assert(fd >= 0);
-        assert(fd < s->sources_size);
+        assert(fd >= 0 && fd < (ssize_t) s->sources_size);
 
         source = s->sources[fd];
         if (source) {
@@ -837,7 +836,7 @@ static int remoteserver_init(RemoteServer *s) {
 
 static int server_destroy(RemoteServer *s) {
         int r;
-        ssize_t i;
+        size_t i;
         MHDDaemonWrapper *d;
 
         r = writer_close(&s->writer);
@@ -879,7 +878,7 @@ static int dispatch_raw_source_event(sd_event_source *event,
         RemoteSource *source;
         int r;
 
-        assert(fd < s->sources_size);
+        assert(fd >= 0 && fd < (ssize_t) s->sources_size);
         source = s->sources[fd];
         assert(source->fd == fd);
 
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index 5350e77..3114de8 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -485,7 +485,7 @@ void seat_claim_position(Seat *s, Session *session, unsigned int pos) {
         if (seat_has_vts(s))
                 pos = session->vtnr;
 
-        if (!GREEDY_REALLOC0_T(s->positions, s->position_count, pos + 1))
+        if (!GREEDY_REALLOC0(s->positions, s->position_count, pos + 1))
                 return;
 
         seat_evict_position(s, session);
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
index f101269..c7b2cd8 100644
--- a/src/shared/fileio.c
+++ b/src/shared/fileio.c
@@ -294,7 +294,7 @@ static int parse_env_file_internal(
                                 state = KEY;
                                 last_key_whitespace = (size_t) -1;
 
-                                if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
+                                if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -317,7 +317,7 @@ static int parse_env_file_internal(
                                 else if (last_key_whitespace == (size_t) -1)
                                          last_key_whitespace = n_key;
 
-                                if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
+                                if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -357,7 +357,7 @@ static int parse_env_file_internal(
                         else if (!strchr(WHITESPACE, c)) {
                                 state = VALUE;
 
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -402,7 +402,7 @@ static int parse_env_file_internal(
                                 else if (last_value_whitespace == (size_t) -1)
                                         last_value_whitespace = n_value;
 
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -417,7 +417,7 @@ static int parse_env_file_internal(
 
                         if (!strchr(newline, c)) {
                                 /* Escaped newlines we eat up entirely */
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -432,7 +432,7 @@ static int parse_env_file_internal(
                         else if (c == '\\')
                                 state = SINGLE_QUOTE_VALUE_ESCAPE;
                         else {
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -446,7 +446,7 @@ static int parse_env_file_internal(
                         state = SINGLE_QUOTE_VALUE;
 
                         if (!strchr(newline, c)) {
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -461,7 +461,7 @@ static int parse_env_file_internal(
                         else if (c == '\\')
                                 state = DOUBLE_QUOTE_VALUE_ESCAPE;
                         else {
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -475,7 +475,7 @@ static int parse_env_file_internal(
                         state = DOUBLE_QUOTE_VALUE;
 
                         if (!strchr(newline, c)) {
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
diff --git a/src/shared/util.c b/src/shared/util.c
index ffe6624..1a727ca 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -5819,8 +5819,8 @@ char *strrep(const char *s, unsigned n) {
         return r;
 }
 
-void* greedy_realloc(void **p, size_t *allocated, size_t need) {
-        size_t a;
+void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
+        size_t a, newalloc;
         void *q;
 
         assert(p);
@@ -5829,10 +5829,11 @@ void* greedy_realloc(void **p, size_t *allocated, size_t need) {
         if (*allocated >= need)
                 return *p;
 
-        a = MAX(64u, need * 2);
+        newalloc = MAX(need * 2, 64u / size);
+        a = newalloc * size;
 
         /* check for overflows */
-        if (a < need)
+        if (a < size * need)
                 return NULL;
 
         q = realloc(*p, a);
@@ -5840,11 +5841,11 @@ void* greedy_realloc(void **p, size_t *allocated, size_t need) {
                 return NULL;
 
         *p = q;
-        *allocated = a;
+        *allocated = newalloc;
         return q;
 }
 
-void* greedy_realloc0(void **p, size_t *allocated, size_t need) {
+void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
         size_t prev;
         uint8_t *q;
 
@@ -5853,12 +5854,12 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need) {
 
         prev = *allocated;
 
-        q = greedy_realloc(p, allocated, need);
+        q = greedy_realloc(p, allocated, need, size);
         if (!q)
                 return NULL;
 
         if (*allocated > prev)
-                memzero(&q[prev], *allocated - prev);
+                memzero(q + prev * size, (*allocated - prev) * size);
 
         return q;
 }
diff --git a/src/shared/util.h b/src/shared/util.h
index 90464c9..900f1cf 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -730,21 +730,13 @@ void *unhexmem(const char *p, size_t l);
 char *strextend(char **x, ...) _sentinel_;
 char *strrep(const char *s, unsigned n);
 
-void* greedy_realloc(void **p, size_t *allocated, size_t need);
-void* greedy_realloc0(void **p, size_t *allocated, size_t need);
-#define GREEDY_REALLOC(array, allocated, need) \
-        greedy_realloc((void**) &(array), &(allocated), sizeof((array)[0]) * (need))
-#define GREEDY_REALLOC0(array, allocated, need) \
-        greedy_realloc0((void**) &(array), &(allocated), sizeof((array)[0]) * (need))
-
-#define GREEDY_REALLOC0_T(array, count, need)                           \
-        ({                                                              \
-                size_t _size = (count) * sizeof((array)[0]);            \
-                void *_ptr = GREEDY_REALLOC0((array), _size, (need));   \
-                if (_ptr)                                               \
-                        (count) = _size / sizeof((array)[0]);           \
-                _ptr;                                                   \
-        })
+void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
+void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
+#define GREEDY_REALLOC(array, allocated, need)                          \
+        greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
+
+#define GREEDY_REALLOC0(array, allocated, need)                         \
+        greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0]))
 
 static inline void _reset_errno_(int *saved_errno) {
         errno = *saved_errno;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 653a324..8fd7bc9 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -515,7 +515,7 @@ static int get_unit_list(
 
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        size_t size;
+        size_t size = c;
         int r;
         UnitInfo u;
 
@@ -523,8 +523,6 @@ static int get_unit_list(
         assert(unit_infos);
         assert(_reply);
 
-        size = sizeof(UnitInfo) * c;
-
         r = sd_bus_call_method(
                         bus,
                         "org.freedesktop.systemd1",



More information about the systemd-commits mailing list