1
#include <unistd.h>
#include <stdio.h>

int main() {
    char *password = getpass("Password: ");
    puts(password);
    return 0;
}

I see that getpass can not take input from stdin.

$ ./getpass <<< abc
Password:
xxx

It seems that this is related to termios. Could anybody show me the underlying code equivalent to this program on how this done?

1 Answers1

1

It's not that getpass "can not" read from stdin. It doesn't read from stdin because that's the way it's designed as its manpage indicates, it reads from /dev/tty:

The getpass() function opens /dev/tty (the controlling terminal of the process), outputs the string prompt, turns off echoing, reads one line (the "password"), restores the terminal state and closes /dev/tty again.

An example of how to use the functions in termios to turn echoing off appears in Michael Kerrisk's excellent The Linux Programming Interface; the sample code is available online.

rici
  • 234,347
  • 28
  • 237
  • 341
  • Could you provide the exact equivalent code? The link you mentioned is not equivalent. It will just terminate if I pipe something to its stdin without waiting to take any input from the terminal. –  Mar 29 '21 at 01:48
  • The easiest way to get the behaviour of your program (reading from `/dev/tty` instead of `stdin`) is to reopen `stdin` as `/dev/tty`, which you can do by adding the line ` dup2(open("/dev/tty", O_RDWR), STDIN_FILENO);` just after the declaration of `buf`. You'll also need to add `#include ` to the includes, in order to get the declaration of `open` and `O_RDWR`. – rici Mar 29 '21 at 03:39
  • Is it exact the same as what `getpass()` does it? –  Mar 29 '21 at 13:43
  • Getpass doesn't reassign stdin, so no it's not identical. But I think it shows you all the things you need to know to write a function which does what you want. If there is something specific you don't know how to do, you could ask a specific question. – rici Mar 29 '21 at 14:25
  • I just want to have the identical underlying code of password, but not just a similar one. –  Mar 30 '21 at 14:01
  • @user15483624: then find the source code for getpass and copy it. I was under the impression that you were trying to learn how to write the code. [Here's one which you can copy.](https://opensource.apple.com/source/Libc/Libc-167/gen.subproj/getpass.c.auto.html). Or if you want the Gnu version, [there's this one](https://code.woboq.org/userspace/glibc/misc/getpass.c.html). – rici Mar 30 '21 at 16:00
  • No. this code is not standalone. It should not include internal function calls. –  Mar 30 '21 at 20:20
  • Many. For example, __fsetlocking –  Mar 30 '21 at 20:29
  • No. They only works on linux. But the original function getpass works on both linux and macos. The equivalent program should as compatible as getpass. That is what "equivalent" mean. –  Mar 30 '21 at 21:30
  • So `termios` can not be used as the base of both so that the same code can be used for both systems? –  Mar 30 '21 at 23:36