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
Related
I am working on terminal based text editor and stuck at a point where I need to differentiate whether the input text from read() function is a clipboard paste text or a keyboard text input.
#include <unistd.h>
char read_key_input() {
char ch;
int read_count;
while ((read_count = read(STDIN_FILENO, &ch, 1)) != 1)
{
// Handle error if any
}
return ch;
}
...
Edit: Here's what I ended up doing.
void read_key_input(void (*callback)(int)) {
char* text = malloc(UINT8_MAX);
int read_count;
while ((read_count = read(STDIN_FILENO, text, UINT8_MAX)) == -1)
{
// Handle error if any
}
// Handle escape sequences if found and return early
...
if (read_count > 1) {
// It's probably a clipboard text. So change the editor mode to input and loop through all the characters one by one.
else {
// It's a user keyboard text input
}
// Revert back to the original editor mode if changed
}
I updated the code to retrieve more than one byte at a time (as suggested by #AnttiHaapala) and process each byte. Seems to be sufficient for my text editor's need for now. Will post back if I update.
Usually you can differentiate this by counting the number of characters you've received in rapid succession. So if you get the keypresses more rapidly than say 1000 characters per minute, then it is likely a clipboard paste... or nonsense.
Furthermore, if you've set the terminal to raw mode, then you can easily monitor individual keypresses. Also make read accept more than one byte at once - with read that is the maximum number of bytes to receive without blocking when available anyway.
One example of such an interactive terminal program would be IPython - here two lines typed separately:
In [1]: print("Hello")
Hello
In [2]: print("World")
World
And here pasted in one go:
In [3]: print("Hello")
...: print("World")
...:
Hello
World
Notice how the prompt is different, and the program runs only after there has been a separate Enter key hit after a small delay.
AFAIK, you cannot do what you want (reliably).
The clipboard is related (usually) to some display server, e.g. Xorg or Wayland server (Weston). And X11 might have distant clients (hence, a clipboard operation could be slow, if crossing some ocean).
Some Linux machines (perhaps the web server at Stackoverflow) do not run any display server.
You could code a GUI application, e.g. using GTK or Qt.
You could test if your standard input is a terminal with termios(3) functions or isatty(3) (i.e. with isatty(STDIN_FILENO) or isatty(STDOUT_FILENO) for standard output)
If your program is run inside a crontab(1) job, or a unix pipeline, the standard input won't be a terminal, and there might not even be any display server running.
You could take inspiration from the source code of GNU emacs, which does detect when a display server is available (probably using environ(7), e.g. getenv(3) of "DISPLAY"...)
On Linux you might open(2) /dev/tty (see tty(4)) to access your terminal. In some cases, it does not exist.
Hey #jiten not sure if you checked like
its key input detect and check wether it's input is one by one key
or its instant bulk input.
I'm trying to automatically retrieve data from a COM port using a batch file.
I'm able to configure the com port and to send the command in other to ask my device for the info.
The problem is that I'm not able to capture the data that the device sends. I've tried with RealTerm and the device is working and sends the info back to the pc, but I really need the batch file to do it automatically, here is the code:
echo off
MODE COMxx ...
COPY retrievecommand.txt \\\\.\COMxx:
COPY \\\\.\COMxx: data.txt
Any suggestions?
Use the TYPE command in a recursive loop using the DOS GOTO command to a DOS LABEL. Use 'append output' to capture text like TYPE COM1:>>Data.txt The double > means continually concatenate (or append) to Data.txt. A single > or 'redirect output' would replace the text in Data.txt every loop (if com data present on port). Add a 2nd line that redirects to the monitor screen so you can watch activity too (i.e. TYPE COM1:>CON [CON means console or monitor screen but you can omit it as console is default anyway])
Control-Z is not needed by TYPE command. It will just dump text continually until operator does a Control-C and then a Y to break the loop. You really don't need to stop the loop unless you are done with the batch file all together. The Data.txt file will be available to other programs live and will not present a 'Sharing Violation' if you try to access it with another program like NOTEPAD.EXE while this batch file is still looping.
Also if you make a 3rd line in the batch file that says TYPE COM1:>Data1.txt [notice only one redirect], you will have a single line of instant text that will disappear with next iteration. But sometimes that is helpful if you need only one line of data. There are creative ways to extract one line of data to another text file using the DOS FIND command.
When reading, the COPY command will continue until it detects the end of file. As the source is a device (with a potentially infinite stream) it only knows to stop when it detects an end of file marker. This is the Ctrl-Z (0x1A) character.
The suggestion in the duplicate question of using the TYPE command to read is likely to result in the same problem.
There is no standard mechanism to read a single line. If you can port your application to PowerShell, you should be able to read single lines with the results you expect.
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.
I have this program in C that reads the input like this:
cod1 = getch ();
if (kbhit())
cod2 = getch ();
I can read every Ctrl+Char possible sequences, except for Ctrl+C, that closes the program - that is OK, and Ctrl+S, that simple is not catch. But I wanted to make Ctrl+S to be the save function in my program; how could I do that? Furthermore, is it possible to read Alt+Char characters? Because it reads it as a regular character, e.g., Alt+A is read with the same codes as A.
Your problem is that input probably gets eaten by terminal emulator.
For example Alt+<Whatever> is often reserved for menu shortcuts (e.g. Alt+F opens File menu). Matching characters are often hilighted once you hold Alt (F get's underscored in File).
Ctrl+S is reserved for Stops all output on screen (XOFF) (again your terminal emulator does that).
As for using Alt+<...> as shortcuts in your command line application. As far as I'm concerned holding Alt doesn't affect character received, it just sets flags which are hard to access in console. Even in GUI application (in Windows) it's quite tricky and you have to use function like GetAsyncState() to check whether alt was pressed.
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.