aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/dirent.c28
-rw-r--r--win32/glob.c2
-rw-r--r--win32/inet_pton.c1
-rw-r--r--win32/ioctl.c49
-rw-r--r--win32/mingw.c9
-rw-r--r--win32/process.c3
-rw-r--r--win32/select.c7
-rw-r--r--win32/strptime.c36
-rw-r--r--win32/termios.c26
-rw-r--r--win32/termios.h29
-rw-r--r--win32/winansi.c4
11 files changed, 143 insertions, 51 deletions
diff --git a/win32/dirent.c b/win32/dirent.c
index 795fc779c..f0e8deae2 100644
--- a/win32/dirent.c
+++ b/win32/dirent.c
@@ -3,7 +3,9 @@
3struct DIR { 3struct DIR {
4 struct dirent dd_dir; 4 struct dirent dd_dir;
5 HANDLE dd_handle; /* FindFirstFile handle */ 5 HANDLE dd_handle; /* FindFirstFile handle */
6 int dd_stat; /* 0-based index */ 6 int not_first;
7 int got_dot;
8 int got_dotdot;
7}; 9};
8 10
9static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAA *fdata) 11static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAA *fdata)
@@ -59,9 +61,11 @@ DIR *opendir(const char *name)
59 } 61 }
60 62
61 /* initialize DIR structure and copy first dir entry */ 63 /* initialize DIR structure and copy first dir entry */
62 dir = xmalloc(sizeof(DIR)); 64 dir = xzalloc(sizeof(DIR));
63 dir->dd_handle = h; 65 dir->dd_handle = h;
64 dir->dd_stat = 0; 66 /* dir->not_first = 0; */
67 /* dir->got_dot = 0; */
68 /* dir->got_dotdot = 0; */
65 finddata2dirent(&dir->dd_dir, &fdata); 69 finddata2dirent(&dir->dd_dir, &fdata);
66 return dir; 70 return dir;
67} 71}
@@ -74,11 +78,17 @@ struct dirent *readdir(DIR *dir)
74 } 78 }
75 79
76 /* if first entry, dirent has already been set up by opendir */ 80 /* if first entry, dirent has already been set up by opendir */
77 if (dir->dd_stat) { 81 if (dir->not_first) {
78 /* get next entry and convert from WIN32_FIND_DATA to dirent */ 82 /* get next entry and convert from WIN32_FIND_DATA to dirent */
79 WIN32_FIND_DATAA fdata; 83 WIN32_FIND_DATAA fdata;
80 if (FindNextFileA(dir->dd_handle, &fdata)) { 84 if (FindNextFileA(dir->dd_handle, &fdata)) {
81 finddata2dirent(&dir->dd_dir, &fdata); 85 finddata2dirent(&dir->dd_dir, &fdata);
86 } else if (!dir->got_dot) {
87 strcpy(dir->dd_dir.d_name, ".");
88 dir->dd_dir.d_type = DT_DIR;
89 } else if (!dir->got_dotdot) {
90 strcpy(dir->dd_dir.d_name, "..");
91 dir->dd_dir.d_type = DT_DIR;
82 } else { 92 } else {
83 DWORD lasterr = GetLastError(); 93 DWORD lasterr = GetLastError();
84 /* POSIX says you shouldn't set errno when readdir can't 94 /* POSIX says you shouldn't set errno when readdir can't
@@ -89,7 +99,15 @@ struct dirent *readdir(DIR *dir)
89 } 99 }
90 } 100 }
91 101
92 ++dir->dd_stat; 102 /* Have we seen '.' or '..'? */
103 if (dir->dd_dir.d_name[0] == '.') {
104 if (dir->dd_dir.d_name[1] == '\0')
105 dir->got_dot = TRUE;
106 else if (dir->dd_dir.d_name[1] == '.' && dir->dd_dir.d_name[2] == '\0')
107 dir->got_dotdot = TRUE;
108 }
109
110 dir->not_first = TRUE;
93 return &dir->dd_dir; 111 return &dir->dd_dir;
94} 112}
95 113
diff --git a/win32/glob.c b/win32/glob.c
index 1cc6483e7..35a1e9a65 100644
--- a/win32/glob.c
+++ b/win32/glob.c
@@ -298,7 +298,7 @@ int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, i
298 if (append(&tail, pat, strlen(pat), 0)) 298 if (append(&tail, pat, strlen(pat), 0))
299 return GLOB_NOSPACE; 299 return GLOB_NOSPACE;
300 cnt++; 300 cnt++;
301 } else 301 } else if (!error)
302 return GLOB_NOMATCH; 302 return GLOB_NOMATCH;
303 } 303 }
304 304
diff --git a/win32/inet_pton.c b/win32/inet_pton.c
index f229a9355..eec8bd2fe 100644
--- a/win32/inet_pton.c
+++ b/win32/inet_pton.c
@@ -78,6 +78,7 @@ int inet_pton(int af, const char *restrict s, void *restrict a0)
78 if (s[j]!='.' || (i<6 && brk<0)) return 0; 78 if (s[j]!='.' || (i<6 && brk<0)) return 0;
79 need_v4=1; 79 need_v4=1;
80 i++; 80 i++;
81 ip[i&7]=0;
81 break; 82 break;
82 } 83 }
83 s += j+1; 84 s += j+1;
diff --git a/win32/ioctl.c b/win32/ioctl.c
index 93f9f504d..d0ed68d61 100644
--- a/win32/ioctl.c
+++ b/win32/ioctl.c
@@ -1,5 +1,7 @@
1#include "libbb.h" 1#include "libbb.h"
2#include "lazyload.h"
2 3
4#if ENABLE_STTY || ENABLE_TTYSIZE
3static int mingw_get_terminal_width_height(struct winsize *win) 5static int mingw_get_terminal_width_height(struct winsize *win)
4{ 6{
5 int fd; 7 int fd;
@@ -21,6 +23,45 @@ static int mingw_get_terminal_width_height(struct winsize *win)
21 23
22 return -1; 24 return -1;
23} 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
24 65
25int ioctl(int fd UNUSED_PARAM, int code, ...) 66int ioctl(int fd UNUSED_PARAM, int code, ...)
26{ 67{
@@ -31,10 +72,18 @@ int ioctl(int fd UNUSED_PARAM, int code, ...)
31 va_start(ap, code); 72 va_start(ap, code);
32 73
33 switch (code) { 74 switch (code) {
75#if ENABLE_STTY || ENABLE_TTYSIZE
34 case TIOCGWINSZ: 76 case TIOCGWINSZ:
35 arg = va_arg(ap, void *); 77 arg = va_arg(ap, void *);
36 ret = mingw_get_terminal_width_height((struct winsize *)arg); 78 ret = mingw_get_terminal_width_height((struct winsize *)arg);
37 break; 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
38 default: 87 default:
39 ret = -1; 88 ret = -1;
40 errno = EINVAL; 89 errno = EINVAL;
diff --git a/win32/mingw.c b/win32/mingw.c
index cb1f84f30..061e7bac6 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -2560,3 +2560,12 @@ int mingw_shell_execute(SHELLEXECUTEINFO *info)
2560 free(lpath); 2560 free(lpath);
2561 return ret; 2561 return ret;
2562} 2562}
2563
2564#if ENABLE_FEATURE_USE_CNG_API
2565void mingw_die_if_error(NTSTATUS status, const char *function_name) {
2566 if (!NT_SUCCESS(status)) {
2567 bb_error_msg_and_die("call to %s failed: 0x%08lX",
2568 function_name, (unsigned long)status);
2569 }
2570}
2571#endif
diff --git a/win32/process.c b/win32/process.c
index 33f45ee42..0d120936e 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -795,7 +795,7 @@ UNUSED_PARAM
795 return sp; 795 return sp;
796} 796}
797 797
798void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) 798int FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm)
799{ 799{
800 const char *str, *cmdline; 800 const char *str, *cmdline;
801 801
@@ -807,6 +807,7 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm)
807 else 807 else
808 cmdline = comm; 808 cmdline = comm;
809 safe_strncpy(buf, cmdline, col); 809 safe_strncpy(buf, cmdline, col);
810 return 0;
810} 811}
811 812
812/** 813/**
diff --git a/win32/select.c b/win32/select.c
index 2be221ac8..46a051cfc 100644
--- a/win32/select.c
+++ b/win32/select.c
@@ -273,8 +273,11 @@ mingw_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
273 int i, fd, rc; 273 int i, fd, rc;
274 clock_t tend = 0; 274 clock_t tend = 0;
275 275
276 if (nfds > FD_SETSIZE) 276 if (nfds < 0 || nfds > FD_SETSIZE)
277 nfds = FD_SETSIZE; 277 {
278 errno = EINVAL;
279 return -1;
280 }
278 281
279 if (!timeout) 282 if (!timeout)
280 wait_timeout = INFINITE; 283 wait_timeout = INFINITE;
diff --git a/win32/strptime.c b/win32/strptime.c
index 3205b95a2..c12e96202 100644
--- a/win32/strptime.c
+++ b/win32/strptime.c
@@ -1,23 +1,23 @@
1/* Copyright (C) 2002, 2004-2005, 2007, 2009-2020 Free Software Foundation, 1/* Copyright (C) 2002, 2004-2005, 2007, 2009-2024 Free Software Foundation,
2 Inc. 2 Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 4
5 This program is free software; you can redistribute it and/or modify 5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU Lesser General Public License as
7 the Free Software Foundation; either version 2, or (at your option) 7 published by the Free Software Foundation; either version 2.1 of the
8 any later version. 8 License, or (at your option) any later version.
9 9
10 This program is distributed in the hope that it will be useful, 10 This file is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details. 13 GNU Lesser General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License along 15 You should have received a copy of the GNU Lesser General Public License
16 with this program; if not, see <https://www.gnu.org/licenses/>. */ 16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 17
18/* 18/*
19 * File from gnulib (https://www.gnu.org/software/gnulib/), processed with 19 * File from gnulib (https://www.gnu.org/software/gnulib/), processed with
20 * coan source -U_LIBC -U_NL_CURRENT -UHAVE_TM_GMTOFF strptime.c 20 * coan source -U_LIBC -U_NL_CURRENT -UHAVE_STRUCT_TM_TM_GMTOFF strptime.c
21 * and lightly edited. 21 * and lightly edited.
22 * 22 *
23 * A form of support for tm_gmtoff was later restored. 23 * A form of support for tm_gmtoff was later restored.
@@ -30,7 +30,7 @@
30#include <ctype.h> 30#include <ctype.h>
31#include <limits.h> 31#include <limits.h>
32#include <string.h> 32#include <string.h>
33#include <stdbool.h> 33#include <strings.h>
34 34
35 35
36enum ptime_locale_status { not, loc, raw }; 36enum ptime_locale_status { not, loc, raw };
@@ -543,23 +543,23 @@ __strptime_internal (const char *rp, const char *fmt, struct tm *tm,
543 543
544 if ((have_uweek || have_wweek) && have_wday) 544 if ((have_uweek || have_wweek) && have_wday)
545 { 545 {
546 int save_wday = tm->tm_wday; 546 int saved_wday = tm->tm_wday;
547 int save_mday = tm->tm_mday; 547 int saved_mday = tm->tm_mday;
548 int save_mon = tm->tm_mon; 548 int saved_mon = tm->tm_mon;
549 int w_offset = have_uweek ? 0 : 1; 549 int w_offset = have_uweek ? 0 : 1;
550 550
551 tm->tm_mday = 1; 551 tm->tm_mday = 1;
552 tm->tm_mon = 0; 552 tm->tm_mon = 0;
553 day_of_the_week (tm); 553 day_of_the_week (tm);
554 if (have_mday) 554 if (have_mday)
555 tm->tm_mday = save_mday; 555 tm->tm_mday = saved_mday;
556 if (have_mon) 556 if (have_mon)
557 tm->tm_mon = save_mon; 557 tm->tm_mon = saved_mon;
558 558
559 if (!have_yday) 559 if (!have_yday)
560 tm->tm_yday = ((7 - (tm->tm_wday - w_offset)) % 7 560 tm->tm_yday = ((7 - (tm->tm_wday - w_offset)) % 7
561 + (week_no - 1) *7 561 + (week_no - 1) *7
562 + save_wday - w_offset); 562 + saved_wday - w_offset);
563 563
564 if (!have_mday || !have_mon) 564 if (!have_mday || !have_mon)
565 { 565 {
@@ -575,7 +575,7 @@ __strptime_internal (const char *rp, const char *fmt, struct tm *tm,
575 - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); 575 - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1);
576 } 576 }
577 577
578 tm->tm_wday = save_wday; 578 tm->tm_wday = saved_wday;
579 } 579 }
580 580
581 return (char *) rp; 581 return (char *) rp;
diff --git a/win32/termios.c b/win32/termios.c
index f18ff7c3b..b94f68f59 100644
--- a/win32/termios.c
+++ b/win32/termios.c
@@ -2,12 +2,10 @@
2 2
3int tcsetattr(int fd, int mode UNUSED_PARAM, const struct termios *t) 3int tcsetattr(int fd, int mode UNUSED_PARAM, const struct termios *t)
4{ 4{
5 if (terminal_mode(FALSE) & VT_INPUT) { 5 HANDLE h = (HANDLE)_get_osfhandle(fd);
6 HANDLE h = (HANDLE)_get_osfhandle(fd); 6 if (!SetConsoleMode(h, t->w_mode)) {
7 if (!SetConsoleMode(h, t->imode)) { 7 errno = err_win_to_posix();
8 errno = err_win_to_posix(); 8 return -1;
9 return -1;
10 }
11 } 9 }
12 10
13 return 0; 11 return 0;
@@ -15,16 +13,20 @@ int tcsetattr(int fd, int mode UNUSED_PARAM, const struct termios *t)
15 13
16int tcgetattr(int fd, struct termios *t) 14int tcgetattr(int fd, struct termios *t)
17{ 15{
18 if (terminal_mode(FALSE) & VT_INPUT) { 16 HANDLE h = (HANDLE)_get_osfhandle(fd);
19 HANDLE h = (HANDLE)_get_osfhandle(fd); 17 if (!GetConsoleMode(h, &t->w_mode)) {
20 if (!GetConsoleMode(h, &t->imode)) { 18 errno = err_win_to_posix();
21 errno = err_win_to_posix(); 19 return -1;
22 return -1;
23 }
24 } 20 }
21
25 t->c_cc[VINTR] = 3; // ctrl-c 22 t->c_cc[VINTR] = 3; // ctrl-c
26 t->c_cc[VEOF] = 4; // ctrl-d 23 t->c_cc[VEOF] = 4; // ctrl-d
27 24
25 if (t->w_mode & ENABLE_ECHO_INPUT)
26 t->c_lflag |= ECHO;
27 else
28 t->c_lflag &= ~ECHO;
29
28 return 0; 30 return 0;
29} 31}
30 32
diff --git a/win32/termios.h b/win32/termios.h
index 8408aa3e3..60c51119b 100644
--- a/win32/termios.h
+++ b/win32/termios.h
@@ -1,23 +1,32 @@
1#ifndef TERMIOS_H 1#ifndef TERMIOS_H
2#define TERMIOS_H 2#define TERMIOS_H
3 3
4#define VINTR 0 4#define ECHO 0x0004
5#define VEOF 1
6 5
7#define TCIFLUSH 0 6#define VINTR 0
8#define TCSAFLUSH 1 7#define VEOF 1
9#define TCSANOW 2 8
10#define TCSADRAIN 3 9#define TCIFLUSH 0
11#define TCSADFLUSH 4 10#define TCSAFLUSH 1
11#define TCSANOW 2
12#define TCSADRAIN 3
13#define TCSADFLUSH 4
14
15#define CSIZE 0
12 16
13typedef unsigned char cc_t; 17typedef unsigned char cc_t;
18typedef unsigned int tcflag_t;
14typedef unsigned int speed_t; 19typedef unsigned int speed_t;
15 20
16#define NCCS 2 21#define NCCS 18
17struct termios { 22struct termios {
23 tcflag_t c_iflag;
24 tcflag_t c_oflag;
25 tcflag_t c_cflag;
26 tcflag_t c_lflag;
27 char c_line;
18 cc_t c_cc[NCCS]; 28 cc_t c_cc[NCCS];
19 unsigned long imode; 29 unsigned long w_mode;
20 unsigned long omode;
21}; 30};
22 31
23struct winsize { 32struct winsize {
diff --git a/win32/winansi.c b/win32/winansi.c
index c7529c453..427c71f11 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -160,7 +160,7 @@ int FAST_FUNC terminal_mode(int reset)
160 mode |= VT_INPUT; 160 mode |= VT_INPUT;
161 } 161 }
162 162
163 if (newmode != oldmode) { 163 if (reset && newmode != oldmode) {
164 if (!SetConsoleMode(h, newmode)) { 164 if (!SetConsoleMode(h, newmode)) {
165 if (mode >= 4) 165 if (mode >= 4)
166 mode &= ~VT_INPUT; 166 mode &= ~VT_INPUT;
@@ -1182,7 +1182,7 @@ char *winansi_fgets(char *s, int size, FILE *stream)
1182/* Ensure that isatty(fd) returns 0 for the NUL device */ 1182/* Ensure that isatty(fd) returns 0 for the NUL device */
1183int mingw_isatty(int fd) 1183int mingw_isatty(int fd)
1184{ 1184{
1185 int result = _isatty(fd); 1185 int result = _isatty(fd) != 0;
1186 1186
1187 if (result) { 1187 if (result) {
1188 HANDLE handle = (HANDLE) _get_osfhandle(fd); 1188 HANDLE handle = (HANDLE) _get_osfhandle(fd);