Skip to content

Commit 952b2a3

Browse files
committed
sub-process: avoid leaking cmd
In some instances (particularly the `read_object` hook), the `cmd` attribute is set to an `strdup()`ed value. This value needs to be released in the end! Since other users assign a non-`strdup()`ed value, be careful to add _another_ attribute (called `to_free`) that can hold a reference to such a string that needs to be released once the sub process is done. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent f4f85c7 commit 952b2a3

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

sub-process.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ void subprocess_stop(struct hashmap *hashmap, struct subprocess_entry *entry)
6363
finish_command(&entry->process);
6464

6565
hashmap_remove(hashmap, &entry->ent, NULL);
66+
FREE_AND_NULL(entry->to_free);
67+
entry->cmd = NULL;
6668
}
6769

6870
static void subprocess_exit_handler(struct child_process *process)
@@ -145,11 +147,13 @@ int subprocess_start_strvec(struct hashmap *hashmap,
145147
process->trace2_child_class = "subprocess";
146148

147149
sq_quote_argv_pretty(&quoted, argv->v);
148-
entry->cmd = strbuf_detach(&quoted, NULL);
150+
entry->cmd = entry->to_free = strbuf_detach(&quoted, NULL);
149151

150152
err = start_command(process);
151153
if (err) {
152154
error("cannot fork to run subprocess '%s'", entry->cmd);
155+
FREE_AND_NULL(entry->to_free);
156+
entry->cmd = NULL;
153157
return err;
154158
}
155159

@@ -158,6 +162,8 @@ int subprocess_start_strvec(struct hashmap *hashmap,
158162
err = startfn(entry);
159163
if (err) {
160164
error("initialization for subprocess '%s' failed", entry->cmd);
165+
FREE_AND_NULL(entry->to_free);
166+
entry->cmd = NULL;
161167
subprocess_stop(hashmap, entry);
162168
return err;
163169
}

sub-process.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
struct subprocess_entry {
2626
struct hashmap_entry ent;
2727
const char *cmd;
28+
/**
29+
* In case `cmd` is a `strdup()`ed value that needs to be released,
30+
* you can assign the pointer to `to_free` so that `subprocess_stop()`
31+
* will release it.
32+
*/
33+
char *to_free;
2834
struct child_process process;
2935
};
3036

0 commit comments

Comments
 (0)