summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibC/unistd.cpp
diff options
context:
space:
mode:
authorJulian Eigmüller <j.eigmueller17@gmail.com>2022-10-28 15:37:20 +0200
committerAndrew Kaster <andrewdkaster@gmail.com>2022-11-13 17:29:27 -0700
commit26a4327b06fbdd186f8fac4181e94aefc1811fed (patch)
tree68523df066dd514466321c9cc50a2f3df8241c1e /Userland/Libraries/LibC/unistd.cpp
parent9fbc4138bb39a6f9abbb3bc04b1b386890bcdc20 (diff)
downloadserenity-26a4327b06fbdd186f8fac4181e94aefc1811fed.zip
LibC: Implement getpass()
This function is a deprecated POSIX function which prints a prompt and receives a password from the user, not echoing back to the terminal.
Diffstat (limited to 'Userland/Libraries/LibC/unistd.cpp')
-rw-r--r--Userland/Libraries/LibC/unistd.cpp54
1 files changed, 51 insertions, 3 deletions
diff --git a/Userland/Libraries/LibC/unistd.cpp b/Userland/Libraries/LibC/unistd.cpp
index cd2f91bc89..d866e15165 100644
--- a/Userland/Libraries/LibC/unistd.cpp
+++ b/Userland/Libraries/LibC/unistd.cpp
@@ -972,11 +972,59 @@ int unveil(char const* path, char const* permissions)
__RETURN_WITH_ERRNO(rc, rc, -1);
}
-// https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpass.html
+// https://pubs.opengroup.org/onlinepubs/7908799/xsh/getpass.html
char* getpass(char const* prompt)
{
- dbgln("FIXME: getpass('{}')", prompt);
- TODO();
+ int tty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
+ if (tty < 0)
+ return nullptr;
+
+ static char password[PASS_MAX];
+ ssize_t chars_read;
+
+ {
+ auto close_tty = ScopeGuard([tty] {
+ close(tty);
+ });
+
+ struct termios backup { };
+ if (tcgetattr(tty, &backup) < 0)
+ return nullptr;
+
+ {
+ auto restore_termios = ScopeGuard([tty, backup] {
+ tcsetattr(tty, TCSAFLUSH, &backup);
+ });
+
+ struct termios noecho = backup;
+ noecho.c_lflag &= ~(ECHO);
+ noecho.c_lflag |= ICANON;
+
+ if (tcsetattr(tty, TCSAFLUSH, &noecho) < 0)
+ return nullptr;
+ if (tcdrain(tty) < 0)
+ return nullptr;
+
+ if (prompt) {
+ if (write(tty, prompt, strlen(prompt)) < 0)
+ return nullptr;
+ }
+
+ chars_read = read(tty, password, sizeof(password));
+ }
+
+ write(tty, "\n", 1);
+ }
+
+ if (chars_read < 0)
+ return nullptr;
+
+ if (chars_read > 0 && (password[chars_read - 1] == '\n' || chars_read == sizeof(password)))
+ password[chars_read - 1] = '\0';
+ else
+ password[chars_read] = '\0';
+
+ return password;
}
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html