| 73 | } |
| 74 | |
| 75 | int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, const char *cmd, |
| 76 | subprocess_start_fn startfn) |
| 77 | { |
| 78 | int err; |
| 79 | struct child_process *process; |
| 80 | |
| 81 | entry->cmd = cmd; |
| 82 | process = &entry->process; |
| 83 | |
| 84 | child_process_init(process); |
| 85 | strvec_push(&process->args, cmd); |
| 86 | process->use_shell = 1; |
| 87 | process->in = -1; |
| 88 | process->out = -1; |
| 89 | process->clean_on_exit = 1; |
| 90 | process->clean_on_exit_handler = subprocess_exit_handler; |
| 91 | process->trace2_child_class = "subprocess"; |
| 92 | |
| 93 | err = start_command(process); |
| 94 | if (err) { |
| 95 | error("cannot fork to run subprocess '%s'", cmd); |
| 96 | return err; |
| 97 | } |
| 98 | |
| 99 | hashmap_entry_init(&entry->ent, strhash(cmd)); |
| 100 | |
| 101 | err = startfn(entry); |
| 102 | if (err) { |
| 103 | error("initialization for subprocess '%s' failed", cmd); |
| 104 | subprocess_stop(hashmap, entry); |
| 105 | return err; |
| 106 | } |
| 107 | |
| 108 | hashmap_add(hashmap, &entry->ent); |
| 109 | return 0; |
| 110 | } |
| 111 | |
| 112 | static int handshake_version(struct child_process *process, |
| 113 | const char *welcome_prefix, int *versions, |
no test coverage detected