mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-02 23:18:44 +00:00
Fix select() on Windows for timeout (#141)
This commit is contained in:
parent
3085ac7837
commit
50937be752
6 changed files with 108 additions and 36 deletions
|
@ -5725,13 +5725,12 @@ static void ShellCompletion(const char *p, linenoiseCompletions *c) {
|
|||
}
|
||||
}
|
||||
|
||||
static char *ShellHint(const char *p, int *color, int *bold) {
|
||||
static char *ShellHint(const char *p, const char **ansi1, const char **ansi2) {
|
||||
char *h = 0;
|
||||
linenoiseCompletions c = {0};
|
||||
ShellCompletion(p, &c);
|
||||
if (c.len == 1) {
|
||||
h = strdup(c.cvec[0] + strlen(p));
|
||||
*bold = 2;
|
||||
}
|
||||
linenoiseFreeCompletions(&c);
|
||||
return h;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/nt/winsock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/yoink.inc"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static int GetFdsPopcnt(int nfds, fd_set *fds) {
|
||||
int i, n = 0;
|
||||
|
@ -92,22 +93,38 @@ static struct NtTimeval *TimevalToNtTimeval(struct timeval *tv,
|
|||
}
|
||||
}
|
||||
|
||||
int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
struct timeval *timeout) {
|
||||
int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timeval *timeout) {
|
||||
int n, rc;
|
||||
struct timespec req, rem;
|
||||
struct NtTimeval nttimeout, *nttimeoutp;
|
||||
struct NtFdSet *ntreadfds, *ntwritefds, *ntexceptfds;
|
||||
nfds = MIN(ARRAYLEN(readfds->fds_bits), ROUNDUP(nfds, 8)) >> 3;
|
||||
ntreadfds = FdSetToNtFdSet(nfds, readfds);
|
||||
ntwritefds = FdSetToNtFdSet(nfds, writefds);
|
||||
ntexceptfds = FdSetToNtFdSet(nfds, exceptfds);
|
||||
nttimeoutp = TimevalToNtTimeval(timeout, &nttimeout);
|
||||
rc = __sys_select_nt(0, ntreadfds, ntwritefds, ntexceptfds, nttimeoutp);
|
||||
NtFdSetToFdSet(nfds, readfds, ntreadfds);
|
||||
NtFdSetToFdSet(nfds, writefds, ntwritefds);
|
||||
NtFdSetToFdSet(nfds, exceptfds, ntexceptfds);
|
||||
free(ntreadfds);
|
||||
free(ntwritefds);
|
||||
free(ntexceptfds);
|
||||
if (readfds || writefds || exceptfds) {
|
||||
nfds = MIN(ARRAYLEN(readfds->fds_bits), ROUNDUP(nfds, 8)) >> 3;
|
||||
ntreadfds = FdSetToNtFdSet(nfds, readfds);
|
||||
ntwritefds = FdSetToNtFdSet(nfds, writefds);
|
||||
ntexceptfds = FdSetToNtFdSet(nfds, exceptfds);
|
||||
nttimeoutp = TimevalToNtTimeval(timeout, &nttimeout);
|
||||
if ((rc = __sys_select_nt(0, ntreadfds, ntwritefds, ntexceptfds,
|
||||
nttimeoutp)) != -1) {
|
||||
NtFdSetToFdSet(nfds, readfds, ntreadfds);
|
||||
NtFdSetToFdSet(nfds, writefds, ntwritefds);
|
||||
NtFdSetToFdSet(nfds, exceptfds, ntexceptfds);
|
||||
} else {
|
||||
__winsockerr();
|
||||
}
|
||||
free(ntreadfds);
|
||||
free(ntwritefds);
|
||||
free(ntexceptfds);
|
||||
} else if (timeout) {
|
||||
req.tv_sec = timeout->tv_sec;
|
||||
req.tv_nsec = timeout->tv_usec * 1000;
|
||||
if ((rc = sys_nanosleep_nt(&req, &rem)) != -1) {
|
||||
timeout->tv_sec = rem.tv_sec;
|
||||
timeout->tv_usec = rem.tv_nsec / 1000;
|
||||
}
|
||||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
43
test/libc/sock/select_test.c
Normal file
43
test/libc/sock/select_test.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/sock/select.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
TEST(select, allZero) {
|
||||
/* blocks indefinitely not worth supporting */
|
||||
/* EXPECT_SYS(0, 0, select(0, 0, 0, 0, 0)); */
|
||||
}
|
||||
|
||||
TEST(select, testSleep) {
|
||||
int64_t e;
|
||||
long double n;
|
||||
struct timeval t = {0, 2000};
|
||||
n = nowl();
|
||||
EXPECT_SYS(0, 0, select(0, 0, 0, 0, &t));
|
||||
e = (nowl() - n) * 1e6;
|
||||
EXPECT_GT(e, 1000);
|
||||
if (!IsBsd()) {
|
||||
/* maybe we should polyfill */
|
||||
EXPECT_EQ(0, t.tv_sec);
|
||||
EXPECT_EQ(0, t.tv_usec);
|
||||
}
|
||||
}
|
47
third_party/linenoise/linenoise.c
vendored
47
third_party/linenoise/linenoise.c
vendored
|
@ -59,6 +59,27 @@
|
|||
│ - Ctrl+R search │
|
||||
│ - Thompson-Pike Encoding │
|
||||
│ │
|
||||
│ SHORTCUTS │
|
||||
│ │
|
||||
│ CTRL-L CLEAR SCREEN │
|
||||
│ CTRL-N NEXT HISTORY │
|
||||
│ CTRL-P PREVIOUS HISTORY │
|
||||
│ CTRL-F FORWARD CHAR │
|
||||
│ CTRL-B BACKWARD CHAR │
|
||||
│ CTRL-A BEGINNING OF LINE │
|
||||
│ CTRL-E END OF LINE │
|
||||
│ ALT-F FORWARD WORD │
|
||||
│ ALT-B BACKWARD WORD │
|
||||
│ CTRL-H DELETE CHAR BACKWARDS │
|
||||
│ CTRL-ALT-H DELETE WORD BACKWARDS │
|
||||
│ ALT-H DELETE WORD BACKWARDS │
|
||||
│ CTRL-W DELETE WORD BACKWARDS │
|
||||
│ CTRL-D DELETE CHAR FORWARDS │
|
||||
│ ALT-D DELETE WORD FORWARDS │
|
||||
│ CTRL-T TRANSPOSE CHARS │
|
||||
│ CTRL-K DELETE LINE FORWARDS │
|
||||
│ CTRL-U DELETE LINE BACKWARDS │
|
||||
│ │
|
||||
│ REFERENCE │
|
||||
│ │
|
||||
│ The big scary coding you 𝘮𝘶𝘴𝘵 use curses to abstract. │
|
||||
|
@ -533,25 +554,14 @@ static void abFree(struct abuf *ab) {
|
|||
/* Helper of refreshSingleLine() and refreshMultiLine() to show hints
|
||||
* to the right of the prompt. */
|
||||
static void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
|
||||
char seq[26], *p;
|
||||
if (hintsCallback && plen+l->len < l->cols) {
|
||||
int color = 0, bold = 0;
|
||||
char *hint = hintsCallback(l->buf,&color,&bold);
|
||||
const char *ansi1 = "\e[90m";
|
||||
const char *ansi2 = "\e[39m";
|
||||
char *hint = hintsCallback(l->buf,&ansi1,&ansi2);
|
||||
if (hint) {
|
||||
int hintlen = strlen(hint);
|
||||
int hintmaxlen = l->cols-(plen+l->len);
|
||||
if (hintlen > hintmaxlen) hintlen = hintmaxlen;
|
||||
if (bold && !color) color = 37;
|
||||
if (color || bold) {
|
||||
p=stpcpy(seq,"\e[");
|
||||
p+=int64toarray_radix10(bold&255,p),*p++=';';
|
||||
p+=int64toarray_radix10(color&255,p);
|
||||
p=stpcpy(p,";49m");
|
||||
abAppend(ab,seq,p-seq);
|
||||
}
|
||||
abAppend(ab,hint,hintlen);
|
||||
if (color != -1 || bold)
|
||||
abAppend(ab,"\e[0m",4);
|
||||
if (ansi1) abAppend(ab,ansi1,strlen(ansi1));
|
||||
abAppend(ab,hint,MIN(l->cols-(plen+l->len),strlen(hint)));
|
||||
if (ansi2) abAppend(ab,ansi2,strlen(ansi2));
|
||||
/* Call the function to free the hint returned. */
|
||||
if (freeHintsCallback) {
|
||||
freeHintsCallback(hint);
|
||||
|
@ -1061,6 +1071,9 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
|
|||
case 'd': /* "\ed" is alt-d */
|
||||
linenoiseEditDeleteNextWord(&l);
|
||||
break;
|
||||
case 'h': /* "\e" is alt-h */
|
||||
linenoiseEditDeletePrevWord(&l);
|
||||
break;
|
||||
case CTRL('H'): /* "\e\b" is ctrl-alt-h */
|
||||
linenoiseEditDeletePrevWord(&l);
|
||||
break;
|
||||
|
|
3
third_party/linenoise/linenoise.h
vendored
3
third_party/linenoise/linenoise.h
vendored
|
@ -9,7 +9,8 @@ typedef struct linenoiseCompletions {
|
|||
} linenoiseCompletions;
|
||||
|
||||
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
|
||||
typedef char *(linenoiseHintsCallback)(const char *, int *, int *);
|
||||
typedef char *(linenoiseHintsCallback)(const char *, const char **,
|
||||
const char **);
|
||||
typedef void(linenoiseFreeHintsCallback)(void *);
|
||||
|
||||
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
|
||||
|
|
3
third_party/python/Programs/python.c
vendored
3
third_party/python/Programs/python.c
vendored
|
@ -778,14 +778,13 @@ TerminalCompletion(const char *p, linenoiseCompletions *c)
|
|||
}
|
||||
|
||||
static char *
|
||||
TerminalHint(const char *p, int *color, int *bold)
|
||||
TerminalHint(const char *p, const char **ansi1, const char **ansi2)
|
||||
{
|
||||
char *h = 0;
|
||||
linenoiseCompletions c = {0};
|
||||
TerminalCompletion(p, &c);
|
||||
if (c.len == 1) {
|
||||
h = strdup(c.cvec[0] + strlen(p));
|
||||
*bold = 2;
|
||||
}
|
||||
linenoiseFreeCompletions(&c);
|
||||
return h;
|
||||
|
|
Loading…
Add table
Reference in a new issue