Make improvements

- Improved async signal safety of read() particularly for longjmp()
- Started adding cancel cleanup handlers for locks / etc on Windows
- Make /dev/tty work better particularly for uses like `foo | less`
- Eagerly read console input into a linked list, so poll can signal
- Fix some libc definitional bugs, which configure scripts detected
This commit is contained in:
Justine Tunney 2023-09-21 07:30:39 -07:00
parent d6c2830850
commit 0c5dd7b342
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
85 changed files with 1062 additions and 671 deletions

View file

@ -16,10 +16,12 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/calls/bo.internal.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/timeval.h"
#include "libc/limits.h"
#include "libc/macros.internal.h"
#include "libc/sock/select.h"
#include "libc/sock/sock.h"
@ -34,11 +36,10 @@
int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout,
const sigset_t *sigmask) {
uint64_t millis;
int i, pfds, events, fdcount;
struct pollfd fds[64];
// convert bitsets to pollfd
struct pollfd fds[64];
for (pfds = i = 0; i < nfds; ++i) {
events = 0;
if (readfds && FD_ISSET(i, readfds)) events |= POLLIN;
@ -57,26 +58,49 @@ int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
}
// convert the wait time to a word
uint32_t millis;
if (!timeout) {
millis = -1;
} else {
millis = timeval_tomillis(*timeout);
int64_t ms = timeval_tomillis(*timeout);
if (ms < 0 || ms > UINT32_MAX) {
millis = -1u;
} else {
millis = ms;
}
}
// call our nt poll implementation
BEGIN_BLOCKING_OPERATION;
fdcount = sys_poll_nt(fds, pfds, &millis, sigmask);
unassert(fdcount < 64);
END_BLOCKING_OPERATION;
if (fdcount == -1) return -1;
if (fdcount < 0) return -1;
// convert pollfd back to bitsets
if (readfds) FD_ZERO(readfds);
if (writefds) FD_ZERO(writefds);
if (exceptfds) FD_ZERO(exceptfds);
for (i = 0; i < fdcount; ++i) {
if (fds[i].revents & POLLIN) FD_SET(fds[i].fd, readfds);
if (fds[i].revents & POLLOUT) FD_SET(fds[i].fd, writefds);
if (fds[i].revents & (POLLERR | POLLNVAL)) FD_SET(fds[i].fd, exceptfds);
int bits = 0;
for (i = 0; i < pfds; ++i) {
if (fds[i].revents & POLLIN) {
if (readfds) {
FD_SET(fds[i].fd, readfds);
++bits;
}
}
if (fds[i].revents & POLLOUT) {
if (writefds) {
FD_SET(fds[i].fd, writefds);
++bits;
}
}
if (fds[i].revents & (POLLERR | POLLNVAL)) {
if (exceptfds) {
FD_SET(fds[i].fd, exceptfds);
++bits;
}
}
}
// store remaining time back in caller's timeval
@ -84,7 +108,7 @@ int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
*timeout = timeval_frommillis(millis);
}
return fdcount;
return bits;
}
#endif /* __x86_64__ */