2

Take the following command:

mysql -u root -p < load_data.sql > output.tab

The -p flag tells the mysql client - a C program - to provide the user with an interactive prompt to enter the password.

AFAIK, input like this is typically handled by writing a prompt to stderr and then blocking on a call like gets, which reads a line from stdin.

But the shell has already opened the load_data.sql file and set the stdin of the mysql client to its file descriptor - so shouldn't calling gets just get the first line from the file?

My initial thought was that the program seeks to the end before reading a line - but you can't seek like that on pipes!

So how does this work? Is there some magic?

Cera
  • 1,879
  • 2
  • 20
  • 29

2 Answers2

3

Applications that prompt for passwords generally don't actually read them from stdin, on the grounds that this would (a) cause the password to appear on the screen if it was being typed in interactively and (b) encourage plain-text passwords to be bandied around in publicly-visible places when things need to be automated (e.g. in command lines visible to others via ps). PostgreSQL's psql SQL shell opens the terminal device directly, and I suspect mysql will do the same.

Some quick searching found this related question. The top-rated answer mentions the GNU function getpass(), which does indeed open a direct connection to the terminal, bypassing stdin. I suspect that function is what most password-prompting programs use in *nix.

Community
  • 1
  • 1
j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
0

This isn't a pipe that's being opened up, but rather is a redirection of stdin to point to a file. Thus you have both a FILE* (i.e. a stream), as well as a normal file-descriptor you can work with. In the case of the lower-level file-descriptor, there are seeking operations you can do, like lseek(), etc. that can be used along with read() in order to move around the file.

If you are wanting to still read data from the controlling terminal while stdin has been re-directed to a file, you simply need to open the controlling terminal for reading on another file-descriptor. You can use ctermid() in order to determine what the controlling terminal for your process is, and reopen it on another file-descriptor.

Jason
  • 31,834
  • 7
  • 59
  • 78
  • But at any rate, if (in Python, for example) I was to call `sys.stdin.read()`, I'd get the contents of the file read into a buffer. How does an application read a line from the tty instead? – Cera Dec 06 '12 at 04:12
  • You mean you want to still read dynamic input from the user entered at the terminal? – Jason Dec 06 '12 at 04:15