diff options
Diffstat (limited to 'third_party/git/sub-process.c')
-rw-r--r-- | third_party/git/sub-process.c | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/third_party/git/sub-process.c b/third_party/git/sub-process.c deleted file mode 100644 index dfa790d3ff91..000000000000 --- a/third_party/git/sub-process.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Generic implementation of background process infrastructure. - */ -#include "sub-process.h" -#include "sigchain.h" -#include "pkt-line.h" - -int cmd2process_cmp(const void *unused_cmp_data, - const struct hashmap_entry *eptr, - const struct hashmap_entry *entry_or_key, - const void *unused_keydata) -{ - const struct subprocess_entry *e1, *e2; - - e1 = container_of(eptr, const struct subprocess_entry, ent); - e2 = container_of(entry_or_key, const struct subprocess_entry, ent); - - return strcmp(e1->cmd, e2->cmd); -} - -struct subprocess_entry *subprocess_find_entry(struct hashmap *hashmap, const char *cmd) -{ - struct subprocess_entry key; - - hashmap_entry_init(&key.ent, strhash(cmd)); - key.cmd = cmd; - return hashmap_get_entry(hashmap, &key, ent, NULL); -} - -int subprocess_read_status(int fd, struct strbuf *status) -{ - struct strbuf **pair; - char *line; - int len; - - for (;;) { - len = packet_read_line_gently(fd, NULL, &line); - if ((len < 0) || !line) - break; - pair = strbuf_split_str(line, '=', 2); - if (pair[0] && pair[0]->len && pair[1]) { - /* the last "status=<foo>" line wins */ - if (!strcmp(pair[0]->buf, "status=")) { - strbuf_reset(status); - strbuf_addbuf(status, pair[1]); - } - } - strbuf_list_free(pair); - } - - return (len < 0) ? len : 0; -} - -void subprocess_stop(struct hashmap *hashmap, struct subprocess_entry *entry) -{ - if (!entry) - return; - - entry->process.clean_on_exit = 0; - kill(entry->process.pid, SIGTERM); - finish_command(&entry->process); - - hashmap_remove(hashmap, &entry->ent, NULL); -} - -static void subprocess_exit_handler(struct child_process *process) -{ - sigchain_push(SIGPIPE, SIG_IGN); - /* Closing the pipe signals the subprocess to initiate a shutdown. */ - close(process->in); - close(process->out); - sigchain_pop(SIGPIPE); - /* Finish command will wait until the shutdown is complete. */ - finish_command(process); -} - -int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, const char *cmd, - subprocess_start_fn startfn) -{ - int err; - struct child_process *process; - - entry->cmd = cmd; - process = &entry->process; - - child_process_init(process); - strvec_push(&process->args, cmd); - process->use_shell = 1; - process->in = -1; - process->out = -1; - process->clean_on_exit = 1; - process->clean_on_exit_handler = subprocess_exit_handler; - process->trace2_child_class = "subprocess"; - - err = start_command(process); - if (err) { - error("cannot fork to run subprocess '%s'", cmd); - return err; - } - - hashmap_entry_init(&entry->ent, strhash(cmd)); - - err = startfn(entry); - if (err) { - error("initialization for subprocess '%s' failed", cmd); - subprocess_stop(hashmap, entry); - return err; - } - - hashmap_add(hashmap, &entry->ent); - return 0; -} - -static int handshake_version(struct child_process *process, - const char *welcome_prefix, int *versions, - int *chosen_version) -{ - int version_scratch; - int i; - char *line; - const char *p; - - if (!chosen_version) - chosen_version = &version_scratch; - - if (packet_write_fmt_gently(process->in, "%s-client\n", - welcome_prefix)) - return error("Could not write client identification"); - for (i = 0; versions[i]; i++) { - if (packet_write_fmt_gently(process->in, "version=%d\n", - versions[i])) - return error("Could not write requested version"); - } - if (packet_flush_gently(process->in)) - return error("Could not write flush packet"); - - if (!(line = packet_read_line(process->out, NULL)) || - !skip_prefix(line, welcome_prefix, &p) || - strcmp(p, "-server")) - return error("Unexpected line '%s', expected %s-server", - line ? line : "<flush packet>", welcome_prefix); - if (!(line = packet_read_line(process->out, NULL)) || - !skip_prefix(line, "version=", &p) || - strtol_i(p, 10, chosen_version)) - return error("Unexpected line '%s', expected version", - line ? line : "<flush packet>"); - if ((line = packet_read_line(process->out, NULL))) - return error("Unexpected line '%s', expected flush", line); - - /* Check to make sure that the version received is supported */ - for (i = 0; versions[i]; i++) { - if (versions[i] == *chosen_version) - break; - } - if (!versions[i]) - return error("Version %d not supported", *chosen_version); - - return 0; -} - -static int handshake_capabilities(struct child_process *process, - struct subprocess_capability *capabilities, - unsigned int *supported_capabilities) -{ - int i; - char *line; - - for (i = 0; capabilities[i].name; i++) { - if (packet_write_fmt_gently(process->in, "capability=%s\n", - capabilities[i].name)) - return error("Could not write requested capability"); - } - if (packet_flush_gently(process->in)) - return error("Could not write flush packet"); - - while ((line = packet_read_line(process->out, NULL))) { - const char *p; - if (!skip_prefix(line, "capability=", &p)) - continue; - - for (i = 0; - capabilities[i].name && strcmp(p, capabilities[i].name); - i++) - ; - if (capabilities[i].name) { - if (supported_capabilities) - *supported_capabilities |= capabilities[i].flag; - } else { - die("subprocess '%s' requested unsupported capability '%s'", - process->argv[0], p); - } - } - - return 0; -} - -int subprocess_handshake(struct subprocess_entry *entry, - const char *welcome_prefix, - int *versions, - int *chosen_version, - struct subprocess_capability *capabilities, - unsigned int *supported_capabilities) -{ - int retval; - struct child_process *process = &entry->process; - - sigchain_push(SIGPIPE, SIG_IGN); - - retval = handshake_version(process, welcome_prefix, versions, - chosen_version) || - handshake_capabilities(process, capabilities, - supported_capabilities); - - sigchain_pop(SIGPIPE); - return retval; -} |