Skip to content

Commit

Permalink
Check for EINTR in poll$nt()
Browse files Browse the repository at this point in the history
This is a bandaid that lets CTRL-C work in daemons until a better
solution for signals on Windows can be implemented.
  • Loading branch information
jart committed Jan 28, 2021
1 parent d8fffd2 commit 971bc81
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 12 deletions.
2 changes: 1 addition & 1 deletion libc/calls/g_sighandrvas.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/internal.h"

hidden int g_sighandrvas[NSIG];
unsigned __sighandrvas[NSIG];
4 changes: 2 additions & 2 deletions libc/calls/hefty/fork-nt.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ textwindows int fork$nt(void) {
&startinfo, &procinfo) != -1) {
CloseHandle(reader);
CloseHandle(procinfo.hThread);
if (weaken(g_sighandrvas) &&
weaken(g_sighandrvas)[SIGCHLD] == SIG_IGN) {
if (weaken(__sighandrvas) &&
weaken(__sighandrvas)[SIGCHLD] == SIG_IGN) {
CloseHandle(procinfo.hProcess);
} else {
g_fds.p[pid].kind = kFdProcess;
Expand Down
3 changes: 2 additions & 1 deletion libc/calls/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ struct Fds {

extern const struct Fd kEmptyFd;

hidden extern volatile bool __interrupted;
hidden extern int __vforked;
hidden extern int g_sighandrvas[NSIG];
hidden extern unsigned __sighandrvas[NSIG];
hidden extern struct Fds g_fds;
hidden extern struct NtSystemInfo g_ntsysteminfo;
hidden extern struct NtStartupInfo g_ntstartupinfo;
Expand Down
21 changes: 21 additions & 0 deletions libc/calls/interrupted.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*-*- 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/internal.h"

volatile bool __interrupted;
22 changes: 18 additions & 4 deletions libc/calls/onntconsoleevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
#include "libc/bits/pushpop.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/calls/typedef/sigaction_f.h"
#include "libc/nt/enum/ctrlevent.h"
#include "libc/nt/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"

textwindows bool32 __onntconsoleevent(uint32_t CtrlType) {
int sig;
unsigned rva;
siginfo_t info;
switch (CtrlType) {
case kNtCtrlCEvent:
Expand All @@ -43,8 +46,19 @@ textwindows bool32 __onntconsoleevent(uint32_t CtrlType) {
default:
return false;
}
memset(&info, 0, sizeof(info));
info.si_signo = sig;
__sigenter(sig, &info, NULL);
return true;
switch ((rva = __sighandrvas[sig])) {
case (uintptr_t)SIG_DFL:
dprintf(2, "__onntconsoleevent ExitProcess\n");
ExitProcess(128 + sig);
case (uintptr_t)SIG_IGN:
dprintf(2, "__onntconsoleevent SIG_IGN\n");
return true;
default:
dprintf(2, "__onntconsoleevent %#x\n", rva);
memset(&info, 0, sizeof(info));
info.si_signo = sig;
((sigaction_f)(_base + rva))(sig, &info, NULL);
__interrupted = true;
return true;
}
}
4 changes: 2 additions & 2 deletions libc/calls/sigaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,12 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
}
if (rc != -1) {
if (oldact) {
oldrva = g_sighandrvas[sig];
oldrva = __sighandrvas[sig];
oldact->sa_sigaction = (sigaction_f)(
oldrva < kSigactionMinRva ? oldrva : (intptr_t)&_base + oldrva);
}
if (act) {
g_sighandrvas[sig] = rva;
__sighandrvas[sig] = rva;
}
}
return rc;
Expand Down
2 changes: 1 addition & 1 deletion libc/calls/sigenter.S
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ __sigenter:
mov %rsp,%rbp
.profilable
and $NSIG-1,%edi
mov g_sighandrvas(,%rdi,4),%eax
mov __sighandrvas(,%rdi,4),%eax
cmp $kSigactionMinRva,%eax
jl 2f
lea _base(%rax),%eax
Expand Down
2 changes: 2 additions & 0 deletions libc/sock/poll-nt.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/calls/internal.h"
#include "libc/macros.h"
#include "libc/nt/struct/pollfd.h"
Expand All @@ -37,6 +38,7 @@ textwindows int poll$nt(struct pollfd *fds, uint64_t nfds, uint64_t timeoutms) {
ntfds[i].events = fds[i].events & (POLLPRI | POLLIN | POLLOUT);
}
for (;;) {
if (cmpxchg(&__interrupted, true, false)) return eintr();
waitfor = MIN(1000, timeoutms); /* for ctrl+c */
if ((got = WSAPoll(ntfds, nfds, waitfor)) != -1) {
if (!got && (timeoutms -= waitfor)) continue;
Expand Down
10 changes: 9 additions & 1 deletion tool/build/runitd.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,16 @@
#define kLogMaxBytes (2 * 1000 * 1000)

char *g_exepath;
volatile bool g_interrupted;
struct sockaddr_in g_servaddr;
unsigned char g_buf[PAGESIZE];
bool g_daemonize, g_sendready;
int g_timeout, g_devnullfd, g_servfd, g_clifd, g_exefd;

void OnInterrupt(int sig) {
g_interrupted = true;
}

void OnChildTerminated(int sig) {
int ws, pid;
for (;;) {
Expand Down Expand Up @@ -359,6 +364,7 @@ int Poll(void) {
int i, wait, evcount;
struct pollfd fds[1];
TryAgain:
if (g_interrupted) return 0;
fds[0].fd = g_servfd;
fds[0].events = POLLIN;
wait = MIN(1000, g_timeout);
Expand All @@ -377,12 +383,14 @@ int Poll(void) {

int Serve(void) {
StartTcpServer();
sigaction(SIGINT, (&(struct sigaction){.sa_handler = (void *)OnInterrupt}),
NULL);
sigaction(SIGCHLD,
(&(struct sigaction){.sa_handler = (void *)OnChildTerminated,
.sa_flags = SA_RESTART}),
NULL);
for (;;) {
if (!Poll() && !g_timeout) break;
if (!Poll() && (!g_timeout || g_interrupted)) break;
}
close(g_servfd);
LOGF("timeout expired, shutting down");
Expand Down

0 comments on commit 971bc81

Please sign in to comment.