mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 08:12:28 +00:00
Make signal handling work well across platforms
- Fix sigsuspend() on XNU - Fix strsignal() on non-Linux - Add unit tests for strsignal() - Add unit tests for setitimer() - Add unit tests for sigsuspend() - Rewrite setitimer() for New Technology - Rewrite nanosleep() for New Technology - Polyfill SIGALRM on the New Technology - select(0,0,0,0) on NT now calls pause() - Remove some NTDLL calls that aren't needed - Polyfill SA_NOCLDWAIT on the New Technology - Polyfill SA_RESETHAND on the New Technology - Polyfill sigprocmask() on the New Technology - Polyfill SIGCHLD+SIG_IGN on the New Technology - Polyfill SA_RESTART masking on the New Technology - Deliver console signals from main thread on New Technology - Document SA_RESTART behavior w/ @sarestartable / @norestart - System call trace in MODE=dbg now prints inherited FDs and signal mask
This commit is contained in:
parent
3b9e66ecba
commit
072e1d2910
82 changed files with 1388 additions and 450 deletions
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
|
@ -40,36 +41,41 @@
|
|||
* @error EINTR, EHOSTUNREACH, ECONNRESET (UDP ICMP Port Unreachable),
|
||||
* EPIPE (if MSG_NOSIGNAL), EMSGSIZE, ENOTSOCK, EFAULT, etc.
|
||||
* @asyncsignalsafe
|
||||
* @restartable (unless SO_RCVTIMEO)
|
||||
*/
|
||||
ssize_t recvfrom(int fd, void *buf, size_t size, uint32_t flags,
|
||||
void *opt_out_srcaddr, uint32_t *opt_inout_srcaddrsize) {
|
||||
ssize_t got;
|
||||
ssize_t rc, got;
|
||||
if (IsAsan() &&
|
||||
(!__asan_is_valid(buf, size) ||
|
||||
(opt_out_srcaddr &&
|
||||
!__asan_is_valid(opt_out_srcaddr, *opt_inout_srcaddrsize)))) {
|
||||
return efault();
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
rc = efault();
|
||||
} else if (IsWindows() && _check_interrupts(false, g_fds.p)) {
|
||||
rc = eintr();
|
||||
} else if (!IsWindows()) {
|
||||
got = sys_recvfrom(fd, buf, size, flags, opt_out_srcaddr,
|
||||
opt_inout_srcaddrsize);
|
||||
if (opt_out_srcaddr && IsBsd() && got != -1) {
|
||||
sockaddr2linux(opt_out_srcaddr);
|
||||
}
|
||||
return got;
|
||||
rc = got;
|
||||
} else {
|
||||
if (__isfdopen(fd)) {
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
return sys_recvfrom_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1,
|
||||
flags, opt_out_srcaddr, opt_inout_srcaddrsize);
|
||||
rc = sys_recvfrom_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1,
|
||||
flags, opt_out_srcaddr, opt_inout_srcaddrsize);
|
||||
} else if (__isfdkind(fd, kFdFile) && !opt_out_srcaddr) { /* socketpair */
|
||||
if (flags) return einval();
|
||||
return sys_read_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1);
|
||||
if (flags) rc = einval();
|
||||
rc = sys_read_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1);
|
||||
} else {
|
||||
return enotsock();
|
||||
rc = enotsock();
|
||||
}
|
||||
} else {
|
||||
return ebadf();
|
||||
rc = ebadf();
|
||||
}
|
||||
}
|
||||
STRACE("recvfrom(%d, %#.*hhs, %'zu, %#x) → %'ld% m", fd, size, buf, size,
|
||||
flags, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue