1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-24 00:19:01 +00:00

Also check fd_set operations on Windows. Fixes #455

This commit is contained in:
dmiller
2022-09-23 01:35:09 +00:00
parent 5e39a04749
commit 6fd0261731
2 changed files with 27 additions and 31 deletions

View File

@@ -321,41 +321,37 @@ extern "C" int vsnprintf (char *, size_t, const char *, va_list);
#define NORETURN
#endif
#ifndef WIN32
# define CHECK_FD_OP(_Op) \
if (fd >= FD_SETSIZE) { \
fprintf(stderr, "Attempt to " #_Op " fd %d, which is not less than " \
"FD_SETSIZE (%d). Try using a lower parallelism.", \
fd, FD_SETSIZE); \
abort(); \
} \
return _Op(fd, fds);
#else
# define CHECK_FD_OP(_Op) return _Op(fd, fds);
#endif
static inline int checked_fd_isset(int fd, fd_set *fds) {
#ifndef WIN32
if (fd >= FD_SETSIZE) {
fprintf(stderr, "Attempt to FD_ISSET fd %d, which is not less than "
"FD_SETSIZE (%d). Try using a lower parallelism.",
fd, FD_SETSIZE);
abort();
}
#endif
return FD_ISSET(fd, fds);
CHECK_FD_OP(FD_ISSET);
}
static inline void checked_fd_clr(int fd, fd_set *fds) {
#ifndef WIN32
if (fd >= FD_SETSIZE) {
fprintf(stderr, "Attempt to FD_CLR fd %d, which is not less than "
"FD_SETSIZE (%d). Try using a lower parallelism.",
fd, FD_SETSIZE);
abort();
}
#endif
FD_CLR(fd, fds);
CHECK_FD_OP(FD_CLR);
}
static inline void checked_fd_set(int fd, fd_set *fds) {
#ifndef WIN32
if (fd >= FD_SETSIZE) {
fprintf(stderr, "Attempt to FD_SET fd %d, which is not less than "
#ifdef WIN32
if (fds->fd_count >= FD_SETSIZE) {
fprintf(stderr, "Attempt to call FD_SET, but fd_count is %d, which is not less than "
"FD_SETSIZE (%d). Try using a lower parallelism.",
fd, FD_SETSIZE);
fds->fd_count, FD_SETSIZE);
abort();
}
#endif
FD_SET(fd, fds);
CHECK_FD_OP(FD_SET);
}

View File

@@ -361,17 +361,17 @@ int fselect(int s, fd_set *rmaster, fd_set *wmaster, fd_set *emaster, struct tim
int iter = -1, i;
struct timeval stv;
fd_set rset, wset, eset;
int r_stdin = rmaster != NULL && FD_ISSET(STDIN_FILENO, rmaster);
int e_stdin = emaster != NULL && FD_ISSET(STDIN_FILENO, emaster);
int r_stdin = rmaster != NULL && checked_fd_isset(STDIN_FILENO, rmaster);
int e_stdin = emaster != NULL && checked_fd_isset(STDIN_FILENO, emaster);
/* Figure out whether there are any FDs in the sets, as @$@!$# Windows
returns WSAINVAL (10022) if you call a select() with no FDs, even though
the Linux man page says that doing so is a good, reasonably portable way
to sleep with subsecond precision. Sigh. */
for(i = s; i > STDIN_FILENO; i--) {
if ((rmaster != NULL && FD_ISSET(i, rmaster))
|| (wmaster != NULL && FD_ISSET(i, wmaster))
|| (emaster != NULL && FD_ISSET(i, emaster)))
if ((rmaster != NULL && checked_fd_isset(i, rmaster))
|| (wmaster != NULL && checked_fd_isset(i, wmaster))
|| (emaster != NULL && checked_fd_isset(i, emaster)))
break;
s--;
}
@@ -412,9 +412,9 @@ int fselect(int s, fd_set *rmaster, fd_set *wmaster, fd_set *emaster, struct tim
}
if (r_stdin)
FD_CLR(STDIN_FILENO, rmaster);
checked_fd_clr(STDIN_FILENO, rmaster);
if (e_stdin)
FD_CLR(STDIN_FILENO, emaster);
checked_fd_clr(STDIN_FILENO, emaster);
if (tv) {
int usecs = (tv->tv_sec * 1000000) + tv->tv_usec;
@@ -448,7 +448,7 @@ int fselect(int s, fd_set *rmaster, fd_set *wmaster, fd_set *emaster, struct tim
usleep(stv.tv_sec * 1000000UL + stv.tv_usec);
if (fds_ready > -1 && r_stdin && win_stdin_ready()) {
FD_SET(STDIN_FILENO, &rset);
checked_fd_set(STDIN_FILENO, &rset);
fds_ready++;
}