1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 11:07:45 +00:00

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.
This commit is contained in:
Julian Eigmüller 2022-10-28 15:37:20 +02:00 committed by Andrew Kaster
parent 9fbc4138bb
commit 26a4327b06
2 changed files with 53 additions and 3 deletions

View file

@ -93,3 +93,5 @@
#define LINK_MAX 4096 #define LINK_MAX 4096
#define TZNAME_MAX 64 #define TZNAME_MAX 64
#define PASS_MAX 128

View file

@ -972,11 +972,59 @@ int unveil(char const* path, char const* permissions)
__RETURN_WITH_ERRNO(rc, rc, -1); __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) char* getpass(char const* prompt)
{ {
dbgln("FIXME: getpass('{}')", prompt); int tty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
TODO(); 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 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html