summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2011-12-22 19:27:23 (GMT)
committerJunio C Hamano <gitster@pobox.com>2011-12-22 19:27:23 (GMT)
commitded408fd20e2fedb76850c9fa9bbaa26b888aa7c (patch)
treef048693eb0afb979809bee23bd03f3f2dd53564a /compat
parent200888ef3bbc150cc20b99e0aa039c751c00e07a (diff)
parent34961d30dae69b00a8a5aabd568fb87f376ebb87 (diff)
downloadgit-ded408fd20e2fedb76850c9fa9bbaa26b888aa7c.zip
git-ded408fd20e2fedb76850c9fa9bbaa26b888aa7c.tar.gz
git-ded408fd20e2fedb76850c9fa9bbaa26b888aa7c.tar.bz2
Merge branch 'jk/git-prompt'
* jk/git-prompt: contrib: add credential helper for OS X Keychain Makefile: OS X has /dev/tty Makefile: linux has /dev/tty credential: use git_prompt instead of git_getpass prompt: use git_terminal_prompt add generic terminal prompt function refactor git_getpass into generic prompt function move git_getpass to its own source file imap-send: don't check return value of git_getpass imap-send: avoid buffer overflow Conflicts: Makefile
Diffstat (limited to 'compat')
-rw-r--r--compat/terminal.c81
-rw-r--r--compat/terminal.h6
2 files changed, 87 insertions, 0 deletions
diff --git a/compat/terminal.c b/compat/terminal.c
new file mode 100644
index 0000000..6d16c8f
--- /dev/null
+++ b/compat/terminal.c
@@ -0,0 +1,81 @@
+#include "git-compat-util.h"
+#include "compat/terminal.h"
+#include "sigchain.h"
+#include "strbuf.h"
+
+#ifdef HAVE_DEV_TTY
+
+static int term_fd = -1;
+static struct termios old_term;
+
+static void restore_term(void)
+{
+ if (term_fd < 0)
+ return;
+
+ tcsetattr(term_fd, TCSAFLUSH, &old_term);
+ term_fd = -1;
+}
+
+static void restore_term_on_signal(int sig)
+{
+ restore_term();
+ sigchain_pop(sig);
+ raise(sig);
+}
+
+char *git_terminal_prompt(const char *prompt, int echo)
+{
+ static struct strbuf buf = STRBUF_INIT;
+ int r;
+ FILE *fh;
+
+ fh = fopen("/dev/tty", "w+");
+ if (!fh)
+ return NULL;
+
+ if (!echo) {
+ struct termios t;
+
+ if (tcgetattr(fileno(fh), &t) < 0) {
+ fclose(fh);
+ return NULL;
+ }
+
+ old_term = t;
+ term_fd = fileno(fh);
+ sigchain_push_common(restore_term_on_signal);
+
+ t.c_lflag &= ~ECHO;
+ if (tcsetattr(fileno(fh), TCSAFLUSH, &t) < 0) {
+ term_fd = -1;
+ fclose(fh);
+ return NULL;
+ }
+ }
+
+ fputs(prompt, fh);
+ fflush(fh);
+
+ r = strbuf_getline(&buf, fh, '\n');
+ if (!echo) {
+ putc('\n', fh);
+ fflush(fh);
+ }
+
+ restore_term();
+ fclose(fh);
+
+ if (r == EOF)
+ return NULL;
+ return buf.buf;
+}
+
+#else
+
+char *git_terminal_prompt(const char *prompt, int echo)
+{
+ return getpass(prompt);
+}
+
+#endif
diff --git a/compat/terminal.h b/compat/terminal.h
new file mode 100644
index 0000000..97db7cd
--- /dev/null
+++ b/compat/terminal.h
@@ -0,0 +1,6 @@
+#ifndef COMPAT_TERMINAL_H
+#define COMPAT_TERMINAL_H
+
+char *git_terminal_prompt(const char *prompt, int echo);
+
+#endif /* COMPAT_TERMINAL_H */