static int launch_specified_editor(const char *editor, const char *path, struct strbuf *buffer, const char *const *env) { if (!editor) return error("Terminal is dumb, but EDITOR unset"); if (strcmp(editor, ":")) { const char *args[] = { editor, real_path(path), NULL }; struct child_process p = CHILD_PROCESS_INIT; int ret, sig; int print_waiting_for_editor = advice_waiting_for_editor && isatty(2); if (print_waiting_for_editor) { /* * A dumb terminal cannot erase the line later on. Add a * newline to separate the hint from subsequent output. * * Make sure that our message is separated with a whitespace * from further cruft that may be written by the editor. */ const char term = is_terminal_dumb() ? '\n' : ' '; fprintf(stderr, _("hint: Waiting for your editor to close the file...%c"), term); fflush(stderr); } p.argv = args; p.env = env; p.use_shell = 1; if (start_command(&p) < 0) return error("unable to start editor '%s'", editor); sigchain_push(SIGINT, SIG_IGN); sigchain_push(SIGQUIT, SIG_IGN); ret = finish_command(&p); sig = ret - 128; sigchain_pop(SIGINT); sigchain_pop(SIGQUIT); if (sig == SIGINT || sig == SIGQUIT) raise(sig); if (ret) return error("There was a problem with the editor '%s'.", editor); if (print_waiting_for_editor && !is_terminal_dumb()) /* * Go back to the beginning and erase the entire line to * avoid wasting the vertical space. */ fputs("\r\033[K", stderr); } if (!buffer) return 0; if (strbuf_read_file(buffer, path, 0) < 0) return error_errno("could not read file '%s'", path); return 0; }
static int check_auto_color(void) { if (color_stdout_is_tty < 0) color_stdout_is_tty = isatty(1); if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) { if (!is_terminal_dumb()) return 1; } return 0; }
const char *git_editor(void) { const char *editor = getenv("GIT_EDITOR"); int terminal_is_dumb = is_terminal_dumb(); if (!editor && editor_program) editor = editor_program; if (!editor && !terminal_is_dumb) editor = getenv("VISUAL"); if (!editor) editor = getenv("EDITOR"); if (!editor && terminal_is_dumb) return NULL; if (!editor) editor = DEFAULT_EDITOR; return editor; }
int recv_sideband(const char *me, int in_stream, int out) { const char *suffix; char buf[LARGE_PACKET_MAX + 1]; struct strbuf outbuf = STRBUF_INIT; int retval = 0; if (isatty(2) && !is_terminal_dumb()) suffix = ANSI_SUFFIX; else suffix = DUMB_SUFFIX; while (!retval) { const char *b, *brk; int band, len; len = packet_read(in_stream, NULL, NULL, buf, LARGE_PACKET_MAX, 0); if (len == 0) break; if (len < 1) { strbuf_addf(&outbuf, "%s%s: protocol error: no band designator", outbuf.len ? "\n" : "", me); retval = SIDEBAND_PROTOCOL_ERROR; break; } band = buf[0] & 0xff; buf[len] = '\0'; len--; switch (band) { case 3: strbuf_addf(&outbuf, "%s%s", outbuf.len ? "\n" : "", DISPLAY_PREFIX); maybe_colorize_sideband(&outbuf, buf + 1, len); retval = SIDEBAND_REMOTE_ERROR; break; case 2: b = buf + 1; /* * Append a suffix to each nonempty line to clear the * end of the screen line. * * The output is accumulated in a buffer and * each line is printed to stderr using * write(2) to ensure inter-process atomicity. */ while ((brk = strpbrk(b, "\n\r"))) { int linelen = brk - b; if (!outbuf.len) strbuf_addstr(&outbuf, DISPLAY_PREFIX); if (linelen > 0) { maybe_colorize_sideband(&outbuf, b, linelen); strbuf_addstr(&outbuf, suffix); } strbuf_addch(&outbuf, *brk); xwrite(2, outbuf.buf, outbuf.len); strbuf_reset(&outbuf); b = brk + 1; } if (*b) { strbuf_addstr(&outbuf, outbuf.len ? "" : DISPLAY_PREFIX); maybe_colorize_sideband(&outbuf, b, strlen(b)); } break; case 1: write_or_die(out, buf + 1, len); break; default: strbuf_addf(&outbuf, "%s%s: protocol error: bad band #%d", outbuf.len ? "\n" : "", me, band); retval = SIDEBAND_PROTOCOL_ERROR; break; } } if (outbuf.len) { strbuf_addch(&outbuf, '\n'); xwrite(2, outbuf.buf, outbuf.len); } strbuf_release(&outbuf); return retval; }