diff options
author | Julian Eigmüller <j.eigmueller17@gmail.com> | 2022-10-28 15:37:20 +0200 |
---|---|---|
committer | Andrew Kaster <andrewdkaster@gmail.com> | 2022-11-13 17:29:27 -0700 |
commit | 26a4327b06fbdd186f8fac4181e94aefc1811fed (patch) | |
tree | 68523df066dd514466321c9cc50a2f3df8241c1e /Userland/Libraries/LibC/unistd.cpp | |
parent | 9fbc4138bb39a6f9abbb3bc04b1b386890bcdc20 (diff) | |
download | serenity-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.cpp | 54 |
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 |