int finish_connect(struct child_process *conn) { int code; if (!conn || git_connection_is_socket(conn)) return 0; code = finish_command(conn); free(conn); return code; }
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); }
static int rpc_service(struct rpc_state *rpc, struct discovery *heads) { const char *svc = rpc->service_name; struct strbuf buf = STRBUF_INIT; struct child_process client; int err = 0; memset(&client, 0, sizeof(client)); client.in = -1; client.out = -1; client.git_cmd = 1; client.argv = rpc->argv; if (start_command(&client)) exit(1); if (heads) write_or_die(client.in, heads->buf, heads->len); rpc->alloc = http_post_buffer; rpc->buf = xmalloc(rpc->alloc); rpc->in = client.in; rpc->out = client.out; strbuf_init(&rpc->result, 0); strbuf_addf(&buf, "%s%s", url, svc); rpc->service_url = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc); rpc->hdr_content_type = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "Accept: application/x-%s-result", svc); rpc->hdr_accept = strbuf_detach(&buf, NULL); while (!err) { int n = packet_read_line(rpc->out, rpc->buf, rpc->alloc); if (!n) break; rpc->pos = 0; rpc->len = n; err |= post_rpc(rpc); } strbuf_read(&rpc->result, client.out, 0); close(client.in); close(client.out); client.in = -1; client.out = -1; err |= finish_command(&client); free(rpc->service_url); free(rpc->hdr_content_type); free(rpc->hdr_accept); free(rpc->buf); strbuf_release(&buf); return err; }
/* * Make a pack stream and spit it out into file descriptor fd */ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args) { /* * The child becomes pack-objects --revs; we feed * the revision parameters to it via its stdin and * let its stdout go back to the other end. */ const char *argv[] = { "pack-objects", "--all-progress", "--revs", "--stdout", NULL, NULL, NULL, }; struct child_process po; int i; i = 4; if (args->use_thin_pack) argv[i++] = "--thin"; if (args->use_ofs_delta) argv[i++] = "--delta-base-offset"; memset(&po, 0, sizeof(po)); po.argv = argv; po.in = -1; po.out = fd; po.git_cmd = 1; if (start_command(&po)) die_errno("git pack-objects failed"); /* * We feed the pack-objects we just spawned with revision * parameters by writing to the pipe. */ for (i = 0; i < extra->nr; i++) if (!feed_object(extra->array[i], po.in, 1)) break; while (refs) { if (!is_null_sha1(refs->old_sha1) && !feed_object(refs->old_sha1, po.in, 1)) break; if (!is_null_sha1(refs->new_sha1) && !feed_object(refs->new_sha1, po.in, 0)) break; refs = refs->next; } close(po.in); if (finish_command(&po)) return error("pack-objects died with strange error"); return 0; }
/* * Run "gpg" to see if the payload matches the detached signature. * gpg_output, when set, receives the diagnostic output from GPG. * gpg_status, when set, receives the status output from GPG. */ int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status) { struct child_process gpg = CHILD_PROCESS_INIT; const char *args_gpg[] = {NULL, "--status-fd=1", "--verify", "FILE", "-", NULL}; char path[PATH_MAX]; int fd, ret; struct strbuf buf = STRBUF_INIT; struct strbuf *pbuf = &buf; args_gpg[0] = gpg_program; fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX"); if (fd < 0) return error(_("could not create temporary file '%s': %s"), path, strerror(errno)); if (write_in_full(fd, signature, signature_size) < 0) return error(_("failed writing detached signature to '%s': %s"), path, strerror(errno)); close(fd); gpg.argv = args_gpg; gpg.in = -1; gpg.out = -1; if (gpg_output) gpg.err = -1; args_gpg[3] = path; if (start_command(&gpg)) { unlink(path); return error(_("could not run gpg.")); } sigchain_push(SIGPIPE, SIG_IGN); write_in_full(gpg.in, payload, payload_size); close(gpg.in); if (gpg_output) { strbuf_read(gpg_output, gpg.err, 0); close(gpg.err); } if (gpg_status) pbuf = gpg_status; strbuf_read(pbuf, gpg.out, 0); close(gpg.out); ret = finish_command(&gpg); sigchain_pop(SIGPIPE); unlink_or_warn(path); ret |= !strstr(pbuf->buf, "\n[GNUPG:] GOODSIG "); strbuf_release(&buf); /* no matter it was used or not */ return ret; }
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, NULL); }
static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state) { struct child_process proc = CHILD_PROCESS_INIT; struct async muxer; const char *argv[2]; int code; argv[0] = find_hook(hook_name); if (!argv[0]) return 0; argv[1] = NULL; proc.argv = argv; proc.in = -1; proc.stdout_to_stderr = 1; if (use_sideband) { memset(&muxer, 0, sizeof(muxer)); muxer.proc = copy_to_sideband; muxer.in = -1; code = start_async(&muxer); if (code) return code; proc.err = muxer.in; } prepare_push_cert_sha1(&proc); code = start_command(&proc); if (code) { if (use_sideband) finish_async(&muxer); return code; } sigchain_push(SIGPIPE, SIG_IGN); while (1) { const char *buf; size_t n; if (feed(feed_state, &buf, &n)) break; if (write_in_full(proc.in, buf, n) != n) break; } close(proc.in); if (use_sideband) finish_async(&muxer); sigchain_pop(SIGPIPE); return finish_command(&proc); }
int finish_connect(struct child_process *conn) { int code; if (!conn || conn == &no_fork) return 0; code = finish_command(conn); free(conn->argv); free(conn); return code; }
static void changed_files(struct hashmap *result, const char *index_path, const char *workdir) { struct child_process update_index = CHILD_PROCESS_INIT; struct child_process diff_files = CHILD_PROCESS_INIT; struct strbuf index_env = STRBUF_INIT, buf = STRBUF_INIT; const char *git_dir = absolute_path(get_git_dir()), *env[] = { NULL, NULL }; FILE *fp; strbuf_addf(&index_env, "GIT_INDEX_FILE=%s", index_path); env[0] = index_env.buf; argv_array_pushl(&update_index.args, "--git-dir", git_dir, "--work-tree", workdir, "update-index", "--really-refresh", "-q", "--unmerged", NULL); update_index.no_stdin = 1; update_index.no_stdout = 1; update_index.no_stderr = 1; update_index.git_cmd = 1; update_index.use_shell = 0; update_index.clean_on_exit = 1; update_index.dir = workdir; update_index.env = env; /* Ignore any errors of update-index */ run_command(&update_index); argv_array_pushl(&diff_files.args, "--git-dir", git_dir, "--work-tree", workdir, "diff-files", "--name-only", "-z", NULL); diff_files.no_stdin = 1; diff_files.git_cmd = 1; diff_files.use_shell = 0; diff_files.clean_on_exit = 1; diff_files.out = -1; diff_files.dir = workdir; diff_files.env = env; if (start_command(&diff_files)) die("could not obtain raw diff"); fp = xfdopen(diff_files.out, "r"); while (!strbuf_getline_nul(&buf, fp)) { struct path_entry *entry; FLEX_ALLOC_STR(entry, path, buf.buf); hashmap_entry_init(entry, strhash(buf.buf)); hashmap_add(result, entry); } fclose(fp); if (finish_command(&diff_files)) die("diff-files did not exit properly"); strbuf_release(&index_env); strbuf_release(&buf); }
int cmd_upload_archive(int argc, const char **argv, const char *prefix) { struct child_process writer = { argv }; /* * Set up sideband subprocess. * * We (parent) monitor and read from child, sending its fd#1 and fd#2 * multiplexed out to our fd#1. If the child dies, we tell the other * end over channel #3. */ argv[0] = "upload-archive--writer"; writer.out = writer.err = -1; writer.git_cmd = 1; if (start_command(&writer)) { int err = errno; packet_write(1, "NACK unable to spawn subprocess\n"); die("upload-archive: %s", strerror(err)); } packet_write(1, "ACK\n"); packet_flush(1); while (1) { struct pollfd pfd[2]; pfd[0].fd = writer.out; pfd[0].events = POLLIN; pfd[1].fd = writer.err; pfd[1].events = POLLIN; if (poll(pfd, 2, -1) < 0) { if (errno != EINTR) { error("poll failed resuming: %s", strerror(errno)); sleep(1); } continue; } if (pfd[1].revents & POLLIN) /* Status stream ready */ if (process_input(pfd[1].fd, 2)) continue; if (pfd[0].revents & POLLIN) /* Data stream ready */ if (process_input(pfd[0].fd, 1)) continue; if (finish_command(&writer)) error_clnt("%s", deadchild); packet_flush(1); break; } return 0; }
static int run_credential_helper(struct credential *c, const char *cmd, int want_output) { struct child_process helper = CHILD_PROCESS_INIT; const char *argv[] = { NULL, NULL }; FILE *fp; argv[0] = cmd; helper.argv = argv; helper.use_shell = 1; helper.in = -1; if (want_output) helper.out = -1; else helper.no_stdout = 1; if (start_command(&helper) < 0) return -1; fp = xfdopen(helper.in, "w"); sigchain_push(SIGPIPE, SIG_IGN); credential_write(c, fp); fclose(fp); sigchain_pop(SIGPIPE); if (want_output) { int r; fp = xfdopen(helper.out, "r"); r = credential_read(c, fp); fclose(fp); if (r < 0) { finish_command(&helper); return -1; } } if (finish_command(&helper)) return -1; return 0; }
static char *shell_prompt(const char *prompt, int echo) { const char *read_input[] = { /* Note: call 'bash' explicitly, as 'read -s' is bash-specific */ "bash", "-c", echo ? "test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&" " read -r line </dev/tty && echo \"$line\"" : "test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&" " read -r -s line </dev/tty && echo \"$line\" && echo >/dev/tty", NULL }; struct child_process child = CHILD_PROCESS_INIT; static struct strbuf buffer = STRBUF_INIT; int prompt_len = strlen(prompt), len = -1, code; child.argv = read_input; child.in = -1; child.out = -1; child.silent_exec_failure = 1; if (start_command(&child)) return NULL; if (write_in_full(child.in, prompt, prompt_len) != prompt_len) { error("could not write to prompt script"); close(child.in); goto ret; } close(child.in); strbuf_reset(&buffer); len = strbuf_read(&buffer, child.out, 1024); if (len < 0) { error("could not read from prompt script"); goto ret; } strbuf_strip_suffix(&buffer, "\n"); strbuf_strip_suffix(&buffer, "\r"); ret: close(child.out); code = finish_command(&child); if (code) { if (code != 127) error("failed to execute prompt script (exit code %d)", code); return NULL; } return len < 0 ? NULL : buffer.buf; }
int run_command(struct child_process *cmd) { int code; if (cmd->out < 0 || cmd->err < 0) die("BUG: run_command with a pipe can cause deadlock"); code = start_command(cmd); if (code) return code; return finish_command(cmd); }
static int run_credential_helper(struct credential *c, const char *cmd, int want_output) { struct child_process helper; const char *argv[] = { NULL, NULL }; FILE *fp; memset(&helper, 0, sizeof(helper)); argv[0] = cmd; helper.argv = argv; helper.use_shell = 1; helper.in = -1; if (want_output) helper.out = -1; else helper.no_stdout = 1; if (start_command(&helper) < 0) return -1; fp = xfdopen(helper.in, "w"); credential_write(c, fp); fclose(fp); if (want_output) { int r; fp = xfdopen(helper.out, "r"); r = credential_read(c, fp); fclose(fp); if (r < 0) { finish_command(&helper); return -1; } } if (finish_command(&helper)) return -1; return 0; }
int stop_column_filter(void) { if (fd_out == -1) return -1; fflush(stdout); close(1); finish_command(&column_process); dup2(fd_out, 1); close(fd_out); fd_out = -1; return 0; }
int is_submodule_modified(const char *path) { int len, i; struct child_process cp; const char *argv[] = { "status", "--porcelain", NULL, }; const char *env[LOCAL_REPO_ENV_SIZE + 3]; struct strbuf buf = STRBUF_INIT; for (i = 0; i < LOCAL_REPO_ENV_SIZE; i++) env[i] = local_repo_env[i]; strbuf_addf(&buf, "%s/.git/", path); if (!is_directory(buf.buf)) { strbuf_release(&buf); /* The submodule is not checked out, so it is not modified */ return 0; } strbuf_reset(&buf); strbuf_addf(&buf, "GIT_WORK_TREE=%s", path); env[i++] = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "GIT_DIR=%s/.git", path); env[i++] = strbuf_detach(&buf, NULL); env[i] = NULL; memset(&cp, 0, sizeof(cp)); cp.argv = argv; cp.env = env; cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; if (start_command(&cp)) die("Could not run git status --porcelain"); len = strbuf_read(&buf, cp.out, 1024); close(cp.out); if (finish_command(&cp)) die("git status --porcelain failed"); for (i = LOCAL_REPO_ENV_SIZE; env[i]; i++) free((char *)env[i]); strbuf_release(&buf); return len != 0; }
int is_submodule_modified(const char *path) { int len; struct child_process cp; const char *argv[] = { "status", "--porcelain", NULL, }; char *env[4]; struct strbuf buf = STRBUF_INIT; strbuf_addf(&buf, "%s/.git/", path); if (!is_directory(buf.buf)) { strbuf_release(&buf); /* The submodule is not checked out, so it is not modified */ return 0; } strbuf_reset(&buf); strbuf_addf(&buf, "GIT_WORK_TREE=%s", path); env[0] = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "GIT_DIR=%s/.git", path); env[1] = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "GIT_INDEX_FILE"); env[2] = strbuf_detach(&buf, NULL); env[3] = NULL; memset(&cp, 0, sizeof(cp)); cp.argv = argv; cp.env = (const char *const *)env; cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; if (start_command(&cp)) die("Could not run git status --porcelain"); len = strbuf_read(&buf, cp.out, 1024); close(cp.out); if (finish_command(&cp)) die("git status --porcelain failed"); free(env[0]); free(env[1]); free(env[2]); strbuf_release(&buf); return len != 0; }
static int disconnect_helper(struct transport *transport) { struct helper_data *data = transport->data; if (data->helper) { write_str_in_full(data->helper->in, "\n"); close(data->helper->in); finish_command(data->helper); free((char *)data->helper->argv[0]); free(data->helper->argv); free(data->helper); data->helper = NULL; } return 0; }
static void wait_for_pager(int in_signal) { if (!in_signal) { fflush(stdout); fflush(stderr); } /* signal EOF to pager */ close(1); close(2); if (in_signal) finish_command_in_signal(&pager_process); else finish_command(&pager_process); }
static void run_service(const char **argv) { const char *encoding = getenv("HTTP_CONTENT_ENCODING"); const char *user = getenv("REMOTE_USER"); const char *host = getenv("REMOTE_ADDR"); char *env[3]; struct strbuf buf = STRBUF_INIT; int gzipped_request = 0; struct child_process cld; if (encoding && !strcmp(encoding, "gzip")) gzipped_request = 1; else if (encoding && !strcmp(encoding, "x-gzip")) gzipped_request = 1; if (!user || !*user) user = "******"; if (!host || !*host) host = "(none)"; memset(&env, 0, sizeof(env)); strbuf_addf(&buf, "GIT_COMMITTER_NAME=%s", user); env[0] = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "GIT_COMMITTER_EMAIL=%[email protected]%s", user, host); env[1] = strbuf_detach(&buf, NULL); env[2] = NULL; memset(&cld, 0, sizeof(cld)); cld.argv = argv; cld.env = (const char *const *)env; if (gzipped_request) cld.in = -1; cld.git_cmd = 1; if (start_command(&cld)) exit(1); close(1); if (gzipped_request) inflate_request(argv[0], cld.in); else close(0); if (finish_command(&cld)) exit(1); free(env[0]); free(env[1]); strbuf_release(&buf); }
static int run_service_command(struct child_process *cld) { argv_array_push(&cld->args, "."); cld->git_cmd = 1; cld->err = -1; if (start_command(cld)) return -1; close(0); close(1); copy_to_log(cld->err); return finish_command(cld); }
static int run_child(const char *arg, const char *service) { int r; struct child_process child; memset(&child, 0, sizeof(child)); child.in = -1; child.out = -1; child.err = 0; child.argv = parse_argv(arg, service); if (start_command(&child) < 0) die("Can't run specified command"); if (git_req) send_git_request(child.in, service, git_req, git_req_vhost); r = bidirectional_transfer_loop(child.out, child.in); if (!r) r = finish_command(&child); else finish_command(&child); return r; }
static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state) { struct child_process proc; struct async muxer; const char *argv[2]; int code; if (access(hook_name, X_OK) < 0) return 0; argv[0] = hook_name; argv[1] = NULL; memset(&proc, 0, sizeof(proc)); proc.argv = argv; proc.in = -1; proc.stdout_to_stderr = 1; if (use_sideband) { memset(&muxer, 0, sizeof(muxer)); muxer.proc = copy_to_sideband; muxer.in = -1; code = start_async(&muxer); if (code) return code; proc.err = muxer.in; } code = start_command(&proc); if (code) { if (use_sideband) finish_async(&muxer); return code; } while (1) { const char *buf; size_t n; if (feed(feed_state, &buf, &n)) break; if (write_in_full(proc.in, buf, n) != n) break; } close(proc.in); if (use_sideband) finish_async(&muxer); return finish_command(&proc); }
static void run_service(const char **argv, int buffer_input) { const char *encoding = getenv("HTTP_CONTENT_ENCODING"); const char *user = getenv("REMOTE_USER"); const char *host = getenv("REMOTE_ADDR"); int gzipped_request = 0; struct child_process cld = CHILD_PROCESS_INIT; ssize_t req_len = get_content_length(); if (encoding && !strcmp(encoding, "gzip")) gzipped_request = 1; else if (encoding && !strcmp(encoding, "x-gzip")) gzipped_request = 1; if (!user || !*user) user = "******"; if (!host || !*host) host = "(none)"; if (!getenv("GIT_COMMITTER_NAME")) argv_array_pushf(&cld.env_array, "GIT_COMMITTER_NAME=%s", user); if (!getenv("GIT_COMMITTER_EMAIL")) argv_array_pushf(&cld.env_array, "GIT_COMMITTER_EMAIL=%[email protected]%s", user, host); cld.argv = argv; if (buffer_input || gzipped_request || req_len >= 0) cld.in = -1; cld.git_cmd = 1; cld.clean_on_exit = 1; cld.wait_after_clean = 1; if (start_command(&cld)) exit(1); close(1); if (gzipped_request) inflate_request(argv[0], cld.in, buffer_input, req_len); else if (buffer_input) copy_request(argv[0], cld.in, req_len); else if (req_len >= 0) pipe_fixed_length(argv[0], cld.in, req_len); else close(0); if (finish_command(&cld)) exit(1); }
/* * If we feed all the commits we want to verify to this command * * $ git rev-list --objects --stdin --not --all * * and if it does not error out, that means everything reachable from * these commits locally exists and is connected to our existing refs. * Note that this does _not_ validate the individual objects. * * Returns 0 if everything is connected, non-zero otherwise. */ int check_everything_connected(sha1_iterate_fn fn, int quiet, void *cb_data) { struct child_process rev_list; const char *argv[] = {"rev-list", "--objects", "--stdin", "--not", "--all", NULL, NULL}; char commit[41]; unsigned char sha1[20]; int err = 0; if (fn(cb_data, sha1)) return err; if (quiet) argv[5] = "--quiet"; memset(&rev_list, 0, sizeof(rev_list)); rev_list.argv = argv; rev_list.git_cmd = 1; rev_list.in = -1; rev_list.no_stdout = 1; rev_list.no_stderr = quiet; if (start_command(&rev_list)) return error(_("Could not run 'git rev-list'")); sigchain_push(SIGPIPE, SIG_IGN); commit[40] = '\n'; do { memcpy(commit, sha1_to_hex(sha1), 40); if (write_in_full(rev_list.in, commit, 41) < 0) { if (errno != EPIPE && errno != EINVAL) error(_("failed write to rev-list: %s"), strerror(errno)); err = -1; break; } } while (!fn(cb_data, sha1)); if (close(rev_list.in)) { error(_("failed to close rev-list's stdin: %s"), strerror(errno)); err = -1; } sigchain_pop(SIGPIPE); return finish_command(&rev_list) || err; }
static int check_emacsclient_version(void) { struct strbuf buffer = STRBUF_INIT; struct child_process ec_process; const char *argv_ec[] = { "emacsclient", "--version", NULL }; int version; int ret = -1; /* emacsclient prints its version number on stderr */ memset(&ec_process, 0, sizeof(ec_process)); ec_process.argv = argv_ec; ec_process.err = -1; ec_process.stdout_to_stderr = 1; if (start_command(&ec_process)) { fprintf(stderr, "Failed to start emacsclient.\n"); return -1; } if (strbuf_read(&buffer, ec_process.err, 20) < 0) { fprintf(stderr, "Failed to read emacsclient version\n"); goto out; } close(ec_process.err); /* * Don't bother checking return value, because "emacsclient --version" * seems to always exits with code 1. */ finish_command(&ec_process); if (prefixcmp(buffer.buf, "emacsclient")) { fprintf(stderr, "Failed to parse emacsclient version.\n"); goto out; } version = atoi(buffer.buf + strlen("emacsclient")); if (version < 22) { fprintf(stderr, "emacsclient version '%d' too old (< 22).\n", version); } else ret = 0; out: strbuf_release(&buffer); return ret; }
static int run_service_command(const char **argv) { struct child_process cld = CHILD_PROCESS_INIT; cld.argv = argv; cld.git_cmd = 1; cld.err = -1; if (start_command(&cld)) return -1; close(0); close(1); copy_to_log(cld.err); return finish_command(&cld); }
static int run_service_command(const char **argv) { struct child_process cld; memset(&cld, 0, sizeof(cld)); cld.argv = argv; cld.git_cmd = 1; cld.err = -1; if (start_command(&cld)) return -1; close(0); close(1); copy_to_log(cld.err); return finish_command(&cld); }
int use_selected() { register SUBJECT *sp; register ARTICLE *ap; bool want_read; char *cmdstr; int len, ret = 1; int subj_mask = (sel_mode == SM_THREAD? (SF_THREAD|SF_VISIT) : SF_VISIT); if (!finish_command(TRUE)) /* get rest of command */ return 0; if (!buf[1]) return -1; cmdstr = savestr(buf+1); want_read = (sel_rereading || *cmdstr =='m'); perform_cnt = 0; page_line = 1; len = strlen(cmdstr); /* A few commands can just loop through the subjects. */ if ((len == 1 && (*cmdstr == 't' || *cmdstr == 'J')) || (len == 2 && (((*cmdstr == '+' || *cmdstr == '-') && cmdstr[0] == cmdstr[1]) || *cmdstr == 'T'))) { for (sp = first_subject; sp; sp = sp->next) { if ((sp->flags & subj_mask) == subj_mask) { artp = first_art(sp); if (artp) { art = article_num(artp); if (perform(cmdstr, FALSE)) { fputs("\nInterrupted\n", stdout) FLUSH; goto break_out; } } #ifdef VERBOSE IF(verbose) if (mode != 't' && *cmdstr != 't' && *cmdstr != 'T') putchar('\n') FLUSH; #endif } } } else if (strEQ(cmdstr, "E")) {
static void run_service(const char **argv) { const char *encoding = getenv("HTTP_CONTENT_ENCODING"); const char *user = getenv("REMOTE_USER"); const char *host = getenv("REMOTE_ADDR"); struct argv_array env = ARGV_ARRAY_INIT; int gzipped_request = 0; struct child_process cld; if (encoding && !strcmp(encoding, "gzip")) gzipped_request = 1; else if (encoding && !strcmp(encoding, "x-gzip")) gzipped_request = 1; if (!user || !*user) user = "******"; if (!host || !*host) host = "(none)"; if (!getenv("GIT_COMMITTER_NAME")) argv_array_pushf(&env, "GIT_COMMITTER_NAME=%s", user); if (!getenv("GIT_COMMITTER_EMAIL")) argv_array_pushf(&env, "GIT_COMMITTER_EMAIL=%[email protected]%s", user, host); memset(&cld, 0, sizeof(cld)); cld.argv = argv; cld.env = env.argv; if (gzipped_request) cld.in = -1; cld.git_cmd = 1; if (start_command(&cld)) exit(1); close(1); if (gzipped_request) inflate_request(argv[0], cld.in); else close(0); if (finish_command(&cld)) exit(1); argv_array_clear(&env); }