Skip to content

Commit 31fa1fb

Browse files
committed
run-command: add pre-exec callback for child processes
Add a pre_exec_cb function pointer to struct child_process that is invoked in the child between fork and exec. This gives callers a place to perform setup that must happen in the child's context, such as closing inherited file descriptors. Provide close_fd_above_stderr() as a ready-made callback that closes file descriptors 3 and above (skipping the child-notifier pipe), capped at sysconf(_SC_OPEN_MAX) or 4096, whichever is smaller. Signed-off-by: Paul Tarjan <github@paulisageek.com>
1 parent 03cf12d commit 31fa1fb

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

run-command.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,18 @@ static void trace_run_command(const struct child_process *cp)
674674
strbuf_release(&buf);
675675
}
676676

677+
void close_fd_above_stderr(void)
678+
{
679+
long max_fd = sysconf(_SC_OPEN_MAX);
680+
int fd;
681+
if (max_fd < 0 || max_fd > 4096)
682+
max_fd = 4096;
683+
for (fd = 3; fd < max_fd; fd++) {
684+
if (fd != child_notifier)
685+
close(fd);
686+
}
687+
}
688+
677689
int start_command(struct child_process *cmd)
678690
{
679691
int need_in, need_out, need_err;
@@ -832,6 +844,9 @@ int start_command(struct child_process *cmd)
832844
child_close(cmd->out);
833845
}
834846

847+
if (cmd->pre_exec_cb)
848+
cmd->pre_exec_cb();
849+
835850
if (cmd->dir && chdir(cmd->dir))
836851
child_die(CHILD_ERR_CHDIR);
837852

run-command.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ struct child_process {
141141
unsigned stdout_to_stderr:1;
142142
unsigned clean_on_exit:1;
143143
unsigned wait_after_clean:1;
144+
145+
/**
146+
* If set, the callback is invoked in the child between fork and
147+
* exec. It can be used, for example, to close inherited file
148+
* descriptors that the child should not keep open.
149+
*/
150+
void (*pre_exec_cb)(void);
151+
144152
void (*clean_on_exit_handler)(struct child_process *process);
145153
};
146154

@@ -149,6 +157,13 @@ struct child_process {
149157
.env = STRVEC_INIT, \
150158
}
151159

160+
/**
161+
* Close file descriptors 3 and above. Suitable for use as a
162+
* pre_exec_cb to prevent the child from inheriting pipe endpoints
163+
* or other descriptors from the parent environment.
164+
*/
165+
void close_fd_above_stderr(void);
166+
152167
/**
153168
* The functions: start_command, finish_command, run_command do the following:
154169
*

0 commit comments

Comments
 (0)