numam-dpdk/lib/cmdline/cmdline_os_windows.c
Bruce Richardson 99a2dd955f lib: remove librte_ prefix from directory names
There is no reason for the DPDK libraries to all have 'librte_' prefix on
the directory names. This prefix makes the directory names longer and also
makes it awkward to add features referring to individual libraries in the
build - should the lib names be specified with or without the prefix.
Therefore, we can just remove the library prefix and use the library's
unique name as the directory name, i.e. 'eal' rather than 'librte_eal'

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
2021-04-21 14:04:09 +02:00

206 lines
4.6 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2020 Dmitry Kozlyuk
*/
#include <io.h>
#include "cmdline_private.h"
/* Missing from some MinGW-w64 distributions. */
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
#endif
void
terminal_adjust(struct cmdline *cl)
{
HANDLE handle;
DWORD mode;
ZeroMemory(&cl->oldterm, sizeof(cl->oldterm));
/* Detect console input, set it up and make it emulate VT100. */
handle = GetStdHandle(STD_INPUT_HANDLE);
if (GetConsoleMode(handle, &mode)) {
cl->oldterm.is_console_input = 1;
cl->oldterm.input_mode = mode;
mode &= ~(
ENABLE_LINE_INPUT | /* no line buffering */
ENABLE_ECHO_INPUT | /* no echo */
ENABLE_PROCESSED_INPUT | /* pass Ctrl+C to program */
ENABLE_MOUSE_INPUT | /* no mouse events */
ENABLE_WINDOW_INPUT); /* no window resize events */
mode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
SetConsoleMode(handle, mode);
}
/* Detect console output and make it emulate VT100. */
handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (GetConsoleMode(handle, &mode)) {
cl->oldterm.is_console_output = 1;
cl->oldterm.output_mode = mode;
mode &= ~ENABLE_WRAP_AT_EOL_OUTPUT;
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(handle, mode);
}
}
void
terminal_restore(const struct cmdline *cl)
{
if (cl->oldterm.is_console_input) {
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleMode(handle, cl->oldterm.input_mode);
}
if (cl->oldterm.is_console_output) {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleMode(handle, cl->oldterm.output_mode);
}
}
static int
cmdline_is_key_down(const INPUT_RECORD *record)
{
return (record->EventType == KEY_EVENT) &&
record->Event.KeyEvent.bKeyDown;
}
static int
cmdline_poll_char_console(HANDLE handle)
{
INPUT_RECORD record;
DWORD events;
if (!PeekConsoleInput(handle, &record, 1, &events)) {
/* Simulate poll(3) behavior on EOF. */
return (GetLastError() == ERROR_HANDLE_EOF) ? 1 : -1;
}
if ((events == 0) || !cmdline_is_key_down(&record))
return 0;
return 1;
}
static int
cmdline_poll_char_file(struct cmdline *cl, HANDLE handle)
{
DWORD type = GetFileType(handle);
/* Since console is handled by cmdline_poll_char_console(),
* this is either a serial port or input handle had been replaced.
*/
if (type == FILE_TYPE_CHAR)
return cmdline_poll_char_console(handle);
/* PeekNamedPipe() can handle all pipes and also sockets. */
if (type == FILE_TYPE_PIPE) {
DWORD bytes_avail;
if (!PeekNamedPipe(handle, NULL, 0, NULL, &bytes_avail, NULL))
return (GetLastError() == ERROR_BROKEN_PIPE) ? 1 : -1;
return bytes_avail ? 1 : 0;
}
/* There is no straightforward way to peek a file in Windows
* I/O model. Read the byte, if it is not the end of file,
* buffer it for subsequent read. This will not work with
* a file being appended and probably some other edge cases.
*/
if (type == FILE_TYPE_DISK) {
char c;
int ret;
ret = _read(cl->s_in, &c, sizeof(c));
if (ret == 1) {
cl->repeat_count = 1;
cl->repeated_char = c;
}
return ret;
}
/* GetFileType() failed or file of unknown type,
* which we do not know how to peek anyway.
*/
return -1;
}
int
cmdline_poll_char(struct cmdline *cl)
{
HANDLE handle = (HANDLE)_get_osfhandle(cl->s_in);
return cl->oldterm.is_console_input ?
cmdline_poll_char_console(handle) :
cmdline_poll_char_file(cl, handle);
}
ssize_t
cmdline_read_char(struct cmdline *cl, char *c)
{
HANDLE handle;
INPUT_RECORD record;
KEY_EVENT_RECORD *key;
DWORD events;
if (!cl->oldterm.is_console_input)
return _read(cl->s_in, c, 1);
/* Return repeated strokes from previous event. */
if (cl->repeat_count > 0) {
*c = cl->repeated_char;
cl->repeat_count--;
return 1;
}
handle = (HANDLE)_get_osfhandle(cl->s_in);
key = &record.Event.KeyEvent;
do {
if (!ReadConsoleInput(handle, &record, 1, &events)) {
if (GetLastError() == ERROR_HANDLE_EOF) {
*c = EOF;
return 0;
}
return -1;
}
} while (!cmdline_is_key_down(&record));
*c = key->uChar.AsciiChar;
/* Save repeated strokes from a single event. */
if (key->wRepeatCount > 1) {
cl->repeated_char = *c;
cl->repeat_count = key->wRepeatCount - 1;
}
return 1;
}
int
cmdline_vdprintf(int fd, const char *format, va_list op)
{
int copy, ret;
FILE *file;
copy = _dup(fd);
if (copy < 0)
return -1;
file = _fdopen(copy, "a");
if (file == NULL) {
_close(copy);
return -1;
}
ret = vfprintf(file, format, op);
fclose(file); /* also closes copy */
return ret;
}