How to read from keyboard when stdin is set to a file in C - c

I think this is simple, but not for me obviously!
I have a console-application. I need to read input from the keyboard, but stdin has been redirected to a file. So how do I create a FILE-Handle that points at the keyboard-stream which i can use with fgets etc.?
I found out that ttyname(0) seems to be what i look for in a POSIX-environment, which I don't have here. I'm in a Windows-system with standard Visual Studio compiler.
Any ideas? Thank you in advance.

There's no easy/portable way to tell if a keyboard exists (your application may be being run from a terminal emulator from a serial port, a telnet session or anything else). If a keyboard actually does exist (including a picture of a keyboard on a touch screen), then you can't really tell how many layers of software the keystrokes need to pass through before they get to your application (e.g. keystrokes might go from a keyboard driver to an input method editor to a GUI to a shell to your application). This means that attempting to get keystrokes directly from a keyboard driver or something is a bad idea that will fail in almost all cases.
The best way to solve your problem is to find out which series of design failures led to STDIN being redirected in the first place.
For example; maybe the application should've had a command line option to read some data from a file; so that the application can get some data from the file and some from STDIN (and get all data from STDIN if the command line option isn't present).

Pulling from the dim dark days of DOS programming here: try opening "CON:" (Console), a reserved word. Hopefully it will open the same way in Windows. The colon may or may not be required. Both "dir >con:" and "dir >con" still work in command prompt.
Also, be sure to use something from the setbuf() family on the output handle to avoid buffering... it's not supposed to buffer terminal I/O, but it never hurts to be sure.
Again, not sure, but I suspect opening separate FILE *conin, *conout for output and one for input may help if you seem to have troubles with one handle doing both input and output.

Related

Delete current terminal input line

I am trying to code a little console chat-program in C on linux.
So far I coded it in a way that both chatting partners are only able to alternately send/recv, because these function calls are blocking by default.
Now I would like to modify that program, so that both are able to send and receive simultaneously.
The problem that I find is, that once you typed some input to the terminal, I don't know how to output received messages, without messing up the current input line of the terminal.
If there was a way to delete that current input line, you could temporarily save that line, print the new message and put the input line right back.
However, I was not able to find a solution for this problem on the internet.
Is it possible to delete the current input line, and if not, how else could I achieve what I want?
I think you should look into ncurses as Edd said in his comment.
It would allow you to easily manage contents in your terminal window, which sounds like a good idea for your chat program.
All you'd need to do is store your messages in 2 character arrays:
char incoming[MSG_MAX]
and
char outgoing[MSG_MAX]
Then you can output those messages wherever you want in your terminal window, since ncurses allows you to specify x,y coordinates on where to put your text.
Then a simple wrapper for one of ncurses erase() family functions would allow you to delete characters from specify x,y coordinates in your terminal window.
Edit: MSG_MAX is not an actual ncurses macro.

How do applications read lines from stdin without consuming existing buffered data from a pipe?

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?
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.
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.

What is it meant by Console in windows programming?

I've got a problem with windows consoles... In windows api, does a console always has to be a screen or a keyboard or can it be any character buffer or something like a text file ?
thanx
If I be more specific, SetConsoleMode fnction in windows api has a parameter called hConsoleHandle which has a flag called ENABLE_ECHO_INPUT that can be used to echo every character we read to the screen.. So I thought in windows system programming, Console means something more than it's normal meaning... So am I write and if so what is the true meaning..?
thanx again
No, a "console" implies an application that has a text-based interface.
Win32 Console on Wikipedia says that that label specifies a text mode program that runs under the Windows API, and would use, for example, a function like WriteConsole instead of printf or cout.
So, the console's the same, but the underlying library is different.
As it's well described here
Consoles manage input and output (I/O) for character-mode applications
(applications that do not provide their own graphical user interface).
so you have your answer right there. As asked before, try to explain better your context, your objective and what is your idea, so maybe we can help you out more.
Under Windows, the console is always a window that resembles the Command Prompt window. You can open and read and write from/to that thing in your windows program. It's not a buffer or a text file, but you can write a buffer or text file and then transfer that entity to the console.
Here are the C-language functions you can use when you address the console window:
_cgets, _cgetws, _cgets_s, _cgetws_s
Read string from console
_cprintf, _cwprintf, _cprintf_s, _cprintf_s_l, _cwprintf_s, _cwprintf_s_l
Write formatted data to console
_cputs
Write string to console
_cscanf, _cwscanf, _cscanf_s, _cscanf_s_l, _cwscanf_s, _cwscanf_s_l
Read formatted data from console
_getch, _getwch
Read character from console
_getche, _getwche
Read character from console and echo it
_inp
Read one byte from specified I/O port
_inpd
Read double word from specified I/O port
_inpw
Read 2-byte word from specified I/O port
_kbhit
Check for keystroke at console; use before attempting to read from console
_outp
Write one byte to specified I/O port
_outpd
Write double word to specified I/O port
_outpw
Write word to specified I/O port
_putch, _putwch
Write character to console
_ungetch, _ungetwch
"Unget" last character read from console so it becomes next character read

ftp client controlled by pipe in C

I am trying to control ftp client from C program (OS X). I did fork and execve - process is started ok. The problem is with pipes - I can send command to ftp client process and get feedback from it just fine (If i send "help\n" i get back help output) but what I never get in pipe is "ftp> " prompt. Any ideas?
Ivan
Your ftp client is probably behaving differently if stdin/stdout is a terminal or something else (lots of program do, for a start the C library does buffering in a different way...) If you want to control that, search information about pseudo-terminals, that's a little too technical to be explained here. (And looks first at programs like expect, it's possible you won't have to write yours).
A program can examine stdin to find out whether it's a terminal or a pipe. In your case, the FTP program probably does that (for example to know whether it can use escape sequences to render progress bars or offer command line editing).
If you really need the prompt, you have to look into PTYs (pseudo terminals) which emulate a console.
wild guess: isn't the "ftp>" prompt written to STDERR ?

How to access the default stdin while using file redirection?

I need to run a script and have access to the default stdin (terminal input) in my program. I could do ./program "script", opening and parsing the script through the program, but I want to make it POSIX style, accepting input from pipes or from redirection.
I mean, since my program is a parser, I could run ./program, type the script and still use stdin (in a scanf, for example). But I'd like to run ./program < script and still be able to use stdin (in a scanf).
My program is a simplified Pascal interpreter, that's why I need to run read(x) and write(x) in my scripts.
Yes, it's homework (the intepreter), but the doubt just popped up in the brainstorming process.
The current controlling terminal can be accessed using /dev/tty, even if stdin has been redirected.
ttyname(0) will return the filename of the current terminal associated with stdin. You can then open that and read from it.
If I understand what you're asking, you're asking for the ability to take in interactive input from a user when using file redirection, like the ./program < script bit above.
I don't believe there's a way to do that. A POSIX system will feed the script in via stdin and that's that. No interaction from the user.
It's also worth noting that you don't have to do anything special to realize that. Just treat stdin like you normally would. You don't have to think about whether it's coming in interactively or from a file, which is really quite nice.

Resources