summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/developer/memtypes.rst7
-rw-r--r--lib/memory.c6
-rw-r--r--lib/memory.h3
-rw-r--r--vtysh/vtysh.c8
-rw-r--r--vtysh/vtysh_config.c4
5 files changed, 22 insertions, 6 deletions
diff --git a/doc/developer/memtypes.rst b/doc/developer/memtypes.rst
index e04049001d..952b316ea0 100644
--- a/doc/developer/memtypes.rst
+++ b/doc/developer/memtypes.rst
@@ -131,3 +131,10 @@ Usage
- if ptr is NULL, no operation is performed (as is guaranteed by system
implementations.) Do not surround XFREE with ``if (ptr != NULL)``
checks.
+
+.. c:function:: void XCOUNTFREE(struct memtype *mtype, void *ptr)
+
+ This macro is used to count the ``ptr`` as freed without actually freeing
+ it. This may be needed in some very specific cases, for example, when the
+ ``ptr`` was allocated using any of the above wrappers and will be freed
+ by some external library using simple ``free()``.
diff --git a/lib/memory.c b/lib/memory.c
index f715044ea3..a377d3b945 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -127,6 +127,12 @@ void *qstrdup(struct memtype *mt, const char *str)
return str ? mt_checkalloc(mt, strdup(str), strlen(str) + 1) : NULL;
}
+void qcountfree(struct memtype *mt, void *ptr)
+{
+ if (ptr)
+ mt_count_free(mt, ptr);
+}
+
void qfree(struct memtype *mt, void *ptr)
{
if (ptr)
diff --git a/lib/memory.h b/lib/memory.h
index 13f2f9b11a..e9db12fce2 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -162,12 +162,15 @@ extern void *qrealloc(struct memtype *mt, void *ptr, size_t size)
__attribute__((_ALLOC_SIZE(3), nonnull(1) _RET_NONNULL));
extern void *qstrdup(struct memtype *mt, const char *str)
__attribute__((malloc, nonnull(1) _RET_NONNULL));
+extern void qcountfree(struct memtype *mt, void *ptr)
+ __attribute__((nonnull(1)));
extern void qfree(struct memtype *mt, void *ptr) __attribute__((nonnull(1)));
#define XMALLOC(mtype, size) qmalloc(mtype, size)
#define XCALLOC(mtype, size) qcalloc(mtype, size)
#define XREALLOC(mtype, ptr, size) qrealloc(mtype, ptr, size)
#define XSTRDUP(mtype, str) qstrdup(mtype, str)
+#define XCOUNTFREE(mtype, ptr) qcountfree(mtype, ptr)
#define XFREE(mtype, ptr) \
do { \
qfree(mtype, ptr); \
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index ace4139551..ef0dfccba9 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -1144,12 +1144,10 @@ static char *command_generator(const char *text, int state)
cmd_free_strvec(vline);
}
- if (matched && matched[index])
- /*
- * this is free()'d by readline, but we leak 1 count of
- * MTYPE_COMPLETION
- */
+ if (matched && matched[index]) {
+ XCOUNTFREE(MTYPE_COMPLETION, matched[index]);
return matched[index++];
+ }
XFREE(MTYPE_TMP, matched);
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 7dcf019888..f35a8af4b9 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -485,8 +485,10 @@ void vtysh_config_dump(void)
* are not under the VRF node.
*/
if (config->index == INTERFACE_NODE
- && list_isempty(config->line))
+ && list_isempty(config->line)) {
+ config_del(config);
continue;
+ }
vty_out(vty, "%s\n", config->name);