aboutsummaryrefslogtreecommitdiff
path: root/win32/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--win32/ioctl.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/win32/ioctl.c b/win32/ioctl.c
new file mode 100644
index 000000000..d0ed68d61
--- /dev/null
+++ b/win32/ioctl.c
@@ -0,0 +1,95 @@
1#include "libbb.h"
2#include "lazyload.h"
3
4#if ENABLE_STTY || ENABLE_TTYSIZE
5static int mingw_get_terminal_width_height(struct winsize *win)
6{
7 int fd;
8 HANDLE handle;
9 CONSOLE_SCREEN_BUFFER_INFO sbi;
10
11 win->ws_row = 0;
12 win->ws_col = 0;
13
14 for (fd=STDOUT_FILENO; fd<=STDERR_FILENO; ++fd) {
15 handle = (HANDLE)_get_osfhandle(fd);
16 if (handle != INVALID_HANDLE_VALUE &&
17 GetConsoleScreenBufferInfo(handle, &sbi) != 0) {
18 win->ws_row = sbi.srWindow.Bottom - sbi.srWindow.Top + 1;
19 win->ws_col = sbi.srWindow.Right - sbi.srWindow.Left + 1;
20 return 0;
21 }
22 }
23
24 return -1;
25}
26#endif
27
28#if ENABLE_STTY
29static int mingw_set_terminal_width_height(struct winsize *win)
30{
31 BOOL ret;
32 DECLARE_PROC_ADDR(BOOL, GetConsoleScreenBufferInfoEx, HANDLE,
33 PCONSOLE_SCREEN_BUFFER_INFOEX);
34 DECLARE_PROC_ADDR(BOOL, SetConsoleScreenBufferInfoEx, HANDLE,
35 PCONSOLE_SCREEN_BUFFER_INFOEX);
36
37 if (!INIT_PROC_ADDR(kernel32.dll, GetConsoleScreenBufferInfoEx))
38 return -1;
39 if (!INIT_PROC_ADDR(kernel32.dll, SetConsoleScreenBufferInfoEx))
40 return -1;
41
42 for (int fd = STDOUT_FILENO; fd <= STDERR_FILENO; ++fd) {
43 CONSOLE_SCREEN_BUFFER_INFOEX sbi;
44 HANDLE handle = (HANDLE)_get_osfhandle(fd);
45
46 sbi.cbSize = sizeof(sbi);
47 if (handle != INVALID_HANDLE_VALUE &&
48 (ret=GetConsoleScreenBufferInfoEx(handle, &sbi)) != 0) {
49 if (sbi.dwSize.X != win->ws_col) {
50 sbi.dwSize.X = win->ws_col;
51 }
52 if (sbi.dwSize.Y < win->ws_row) {
53 sbi.dwSize.Y = win->ws_row;
54 }
55 sbi.srWindow.Bottom = sbi.srWindow.Top + win->ws_row;
56 sbi.srWindow.Right = sbi.srWindow.Left + win->ws_col;
57 ret = SetConsoleScreenBufferInfoEx(handle, &sbi);
58 break;
59 }
60 }
61
62 return ret ? 0 : -1;
63}
64#endif
65
66int ioctl(int fd UNUSED_PARAM, int code, ...)
67{
68 va_list ap;
69 void *arg;
70 int ret = -1;
71
72 va_start(ap, code);
73
74 switch (code) {
75#if ENABLE_STTY || ENABLE_TTYSIZE
76 case TIOCGWINSZ:
77 arg = va_arg(ap, void *);
78 ret = mingw_get_terminal_width_height((struct winsize *)arg);
79 break;
80#endif
81#if ENABLE_STTY
82 case TIOCSWINSZ:
83 arg = va_arg(ap, void *);
84 ret = mingw_set_terminal_width_height((struct winsize *)arg);
85 break;
86#endif
87 default:
88 ret = -1;
89 errno = EINVAL;
90 break;
91 }
92
93 va_end(ap);
94 return ret;
95}