1#ifndef SUBPROCESS_H 2#define SUBPROCESS_H 3 4#include"git-compat-util.h" 5#include"hashmap.h" 6#include"run-command.h" 7 8/* 9 * The sub-process API makes it possible to run background sub-processes 10 * for the entire lifetime of a Git invocation. If Git needs to communicate 11 * with an external process multiple times, then this can reduces the process 12 * invocation overhead. Git and the sub-process communicate through stdin and 13 * stdout. 14 * 15 * The sub-processes are kept in a hashmap by command name and looked up 16 * via the subprocess_find_entry function. If an existing instance can not 17 * be found then a new process should be created and started. When the 18 * parent git command terminates, all sub-processes are also terminated. 19 * 20 * This API is based on the run-command API. 21 */ 22 23/* data structures */ 24 25/* Members should not be accessed directly. */ 26struct subprocess_entry { 27struct hashmap_entry ent;/* must be the first member! */ 28const char*cmd; 29struct child_process process; 30}; 31 32struct subprocess_capability { 33const char*name; 34 35/* 36 * subprocess_handshake will "|=" this value to supported_capabilities 37 * if the server reports that it supports this capability. 38 */ 39unsigned int flag; 40}; 41 42/* subprocess functions */ 43 44/* Function to test two subprocess hashmap entries for equality. */ 45externintcmd2process_cmp(const void*unused_cmp_data, 46const void*e1, 47const void*e2, 48const void*unused_keydata); 49 50/* 51 * User-supplied function to initialize the sub-process. This is 52 * typically used to negotiate the interface version and capabilities. 53 */ 54typedefint(*subprocess_start_fn)(struct subprocess_entry *entry); 55 56/* Start a subprocess and add it to the subprocess hashmap. */ 57intsubprocess_start(struct hashmap *hashmap,struct subprocess_entry *entry,const char*cmd, 58 subprocess_start_fn startfn); 59 60/* Kill a subprocess and remove it from the subprocess hashmap. */ 61voidsubprocess_stop(struct hashmap *hashmap,struct subprocess_entry *entry); 62 63/* Find a subprocess in the subprocess hashmap. */ 64struct subprocess_entry *subprocess_find_entry(struct hashmap *hashmap,const char*cmd); 65 66/* subprocess helper functions */ 67 68/* Get the underlying `struct child_process` from a subprocess. */ 69staticinlinestruct child_process *subprocess_get_child_process( 70struct subprocess_entry *entry) 71{ 72return&entry->process; 73} 74 75/* 76 * Perform the version and capability negotiation as described in the 77 * "Handshake" section of long-running-process-protocol.txt using the 78 * given requested versions and capabilities. The "versions" and "capabilities" 79 * parameters are arrays terminated by a 0 or blank struct. 80 * 81 * This function is typically called when a subprocess is started (as part of 82 * the "startfn" passed to subprocess_start). 83 */ 84intsubprocess_handshake(struct subprocess_entry *entry, 85const char*welcome_prefix, 86int*versions, 87int*chosen_version, 88struct subprocess_capability *capabilities, 89unsigned int*supported_capabilities); 90 91/* 92 * Helper function that will read packets looking for "status=<foo>" 93 * key/value pairs and return the value from the last "status" packet 94 */ 95 96intsubprocess_read_status(int fd,struct strbuf *status); 97 98#endif