From: larsxschneider@gmail.com
To: git@vger.kernel.org
Cc: ramsay@ramsayjones.plus.com, jnareb@gmail.com, gitster@pobox.com,
j6t@kdbg.org, tboegi@web.de, peff@peff.net, mlbright@gmail.com,
Lars Schneider <larsxschneider@gmail.com>
Subject: [PATCH v9 04/14] run-command: add wait_on_exit
Date: Tue, 4 Oct 2016 14:59:37 +0200 [thread overview]
Message-ID: <20161004125947.67104-5-larsxschneider@gmail.com> (raw)
In-Reply-To: <20161004125947.67104-1-larsxschneider@gmail.com>
From: Lars Schneider <larsxschneider@gmail.com>
The flag 'clean_on_exit' kills child processes spawned by Git on exit.
A hard kill like this might not be desired in all cases.
Add 'wait_on_exit' which closes the child's stdin on Git exit and waits
until the child process has terminated.
The flag is used in a subsequent patch.
Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
---
run-command.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++--------
run-command.h | 3 +++
2 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/run-command.c b/run-command.c
index 3269362..96c54fe 100644
--- a/run-command.c
+++ b/run-command.c
@@ -21,6 +21,9 @@ void child_process_clear(struct child_process *child)
struct child_to_clean {
pid_t pid;
+ char *name;
+ int stdin;
+ int wait;
struct child_to_clean *next;
};
static struct child_to_clean *children_to_clean;
@@ -28,12 +31,33 @@ static int installed_child_cleanup_handler;
static void cleanup_children(int sig, int in_signal)
{
+ int status;
+ struct child_to_clean *p = children_to_clean;
+
+ /* Close the the child's stdin as indicator that Git will exit soon */
+ while (p) {
+ if (p->wait)
+ if (p->stdin > 0)
+ close(p->stdin);
+ p = p->next;
+ }
+
while (children_to_clean) {
- struct child_to_clean *p = children_to_clean;
+ p = children_to_clean;
children_to_clean = p->next;
+
+ if (p->wait) {
+ fprintf(stderr, _("Waiting for '%s' to finish..."), p->name);
+ while ((waitpid(p->pid, &status, 0)) < 0 && errno == EINTR)
+ ; /* nothing */
+ fprintf(stderr, _("done!\n"));
+ }
+
kill(p->pid, sig);
- if (!in_signal)
+ if (!in_signal) {
+ free(p->name);
free(p);
+ }
}
}
@@ -49,10 +73,16 @@ static void cleanup_children_on_exit(void)
cleanup_children(SIGTERM, 0);
}
-static void mark_child_for_cleanup(pid_t pid)
+static void mark_child_for_cleanup(pid_t pid, const char *name, int stdin, int wait)
{
struct child_to_clean *p = xmalloc(sizeof(*p));
p->pid = pid;
+ p->wait = wait;
+ p->stdin = stdin;
+ if (name)
+ p->name = xstrdup(name);
+ else
+ p->name = "process";
p->next = children_to_clean;
children_to_clean = p;
@@ -63,6 +93,13 @@ static void mark_child_for_cleanup(pid_t pid)
}
}
+#ifdef NO_PTHREADS
+static void mark_child_for_cleanup_no_wait(pid_t pid, const char *name, int timeout, int stdin)
+{
+ mark_child_for_cleanup(pid, NULL, 0, 0);
+}
+#endif
+
static void clear_child_for_cleanup(pid_t pid)
{
struct child_to_clean **pp;
@@ -421,8 +458,9 @@ int start_command(struct child_process *cmd)
}
if (cmd->pid < 0)
error_errno("cannot fork() for %s", cmd->argv[0]);
- else if (cmd->clean_on_exit)
- mark_child_for_cleanup(cmd->pid);
+ else if (cmd->clean_on_exit || cmd->wait_on_exit)
+ mark_child_for_cleanup(
+ cmd->pid, cmd->argv[0], cmd->in, cmd->wait_on_exit);
/*
* Wait for child's execvp. If the execvp succeeds (or if fork()
@@ -482,8 +520,9 @@ int start_command(struct child_process *cmd)
failed_errno = errno;
if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
error_errno("cannot spawn %s", cmd->argv[0]);
- if (cmd->clean_on_exit && cmd->pid >= 0)
- mark_child_for_cleanup(cmd->pid);
+ if ((cmd->clean_on_exit || cmd->wait_on_exit) && cmd->pid >= 0)
+ mark_child_for_cleanup(
+ cmd->pid, cmd->argv[0], cmd->in, cmd->clean_on_exit_timeout);
argv_array_clear(&nargv);
cmd->argv = sargv;
@@ -765,7 +804,7 @@ int start_async(struct async *async)
exit(!!async->proc(proc_in, proc_out, async->data));
}
- mark_child_for_cleanup(async->pid);
+ mark_child_for_cleanup_no_wait(async->pid);
if (need_in)
close(fdin[0]);
diff --git a/run-command.h b/run-command.h
index cf29a31..f7b9907 100644
--- a/run-command.h
+++ b/run-command.h
@@ -42,7 +42,10 @@ struct child_process {
unsigned silent_exec_failure:1;
unsigned stdout_to_stderr:1;
unsigned use_shell:1;
+ /* kill the child on Git exit */
unsigned clean_on_exit:1;
+ /* close the child's stdin on Git exit and wait until it terminates */
+ unsigned wait_on_exit:1;
};
#define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT, ARGV_ARRAY_INIT }
--
2.10.0
next prev parent reply other threads:[~2016-10-04 13:00 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-04 12:59 [PATCH v9 00/14] Git filter protocol larsxschneider
2016-10-04 12:59 ` [PATCH v9 01/14] convert: quote filter names in error messages larsxschneider
2016-10-04 12:59 ` [PATCH v9 02/14] convert: modernize tests larsxschneider
2016-10-04 12:59 ` [PATCH v9 03/14] run-command: move check_pipe() from write_or_die to run_command larsxschneider
2016-10-04 12:59 ` larsxschneider [this message]
2016-10-04 19:30 ` [PATCH v9 04/14] run-command: add wait_on_exit Junio C Hamano
2016-10-05 20:57 ` Lars Schneider
2016-10-05 21:12 ` Junio C Hamano
2016-10-06 9:32 ` Johannes Schindelin
2016-10-06 9:35 ` Lars Schneider
2016-10-06 15:53 ` Junio C Hamano
2016-10-04 12:59 ` [PATCH v9 05/14] pkt-line: rename packet_write() to packet_write_fmt() larsxschneider
2016-10-04 12:59 ` [PATCH v9 06/14] pkt-line: extract set_packet_header() larsxschneider
2016-10-04 12:59 ` [PATCH v9 07/14] pkt-line: add packet_write_fmt_gently() larsxschneider
2016-10-04 12:59 ` [PATCH v9 08/14] pkt-line: add packet_flush_gently() larsxschneider
2016-10-04 12:59 ` [PATCH v9 09/14] pkt-line: add packet_write_gently() larsxschneider
2016-10-04 19:33 ` Junio C Hamano
2016-10-05 19:06 ` Lars Schneider
2016-10-06 17:25 ` Junio C Hamano
2016-10-04 12:59 ` [PATCH v9 10/14] pkt-line: add functions to read/write flush terminated packet streams larsxschneider
2016-10-04 19:53 ` Junio C Hamano
2016-10-04 19:58 ` Junio C Hamano
2016-10-05 17:35 ` Lars Schneider
2016-10-04 12:59 ` [PATCH v9 11/14] convert: make apply_filter() adhere to standard Git error handling larsxschneider
2016-10-04 12:59 ` [PATCH v9 12/14] convert: prepare filter.<driver>.process option larsxschneider
2016-10-04 12:59 ` [PATCH v9 13/14] convert: add " larsxschneider
2016-10-04 12:59 ` [PATCH v9 14/14] contrib/long-running-filter: add long running filter example larsxschneider
2016-10-05 22:31 ` [PATCH v9 00/14] Git filter protocol Jakub Narębski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161004125947.67104-5-larsxschneider@gmail.com \
--to=larsxschneider@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=j6t@kdbg.org \
--cc=jnareb@gmail.com \
--cc=mlbright@gmail.com \
--cc=peff@peff.net \
--cc=ramsay@ramsayjones.plus.com \
--cc=tboegi@web.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).