mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-30 01:02:29 +00:00
Improve zip read-only filesystem
readdir() will now always yield an inode that's consistent with stat() on ZipOS and Windows in general. More APIs have been updated to return the appropriate error code when inappropriately trying to do ops, like sockets, with a zip file descriptor. The path normalization algorithms are now fully fleshed out. Some socket APIs have been fixed so they'll raise EBADF vs. ENOTSOCK appropriately. Lastly seekdir() will now work properly on NetBSD and FreeBSD (not sure why anyone would even use it)
This commit is contained in:
parent
dc6c67256f
commit
b76b2be2d0
47 changed files with 644 additions and 269 deletions
|
@ -47,14 +47,16 @@ int accept4(int fd, struct sockaddr *opt_out_addr, uint32_t *opt_inout_addrsize,
|
|||
struct sockaddr_storage ss = {0};
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
|
||||
if (IsWindows()) {
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_accept_nt(g_fds.p + fd, &ss, flags);
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
} else {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_accept4(fd, &ss, flags);
|
||||
} else if (!__isfdopen(fd)) {
|
||||
rc = ebadf();
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_accept_nt(g_fds.p + fd, &ss, flags);
|
||||
} else {
|
||||
rc = enotsock();
|
||||
}
|
||||
|
||||
if (rc != -1) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
@ -50,12 +51,16 @@ int bind(int fd, const struct sockaddr *addr, uint32_t addrsize) {
|
|||
if (!addr || (IsAsan() && !__asan_is_valid(addr, addrsize))) {
|
||||
rc = efault();
|
||||
} else if (addrsize >= sizeof(struct sockaddr_in)) {
|
||||
if (!IsWindows()) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_bind(fd, addr, addrsize);
|
||||
} else if (!__isfdopen(fd)) {
|
||||
rc = ebadf();
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_bind_nt(&g_fds.p[fd], addr, addrsize);
|
||||
} else {
|
||||
rc = ebadf();
|
||||
rc = enotsock();
|
||||
}
|
||||
} else {
|
||||
rc = einval();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
@ -45,12 +46,16 @@ int connect(int fd, const struct sockaddr *addr, uint32_t addrsize) {
|
|||
BEGIN_CANCELLATION_POINT;
|
||||
|
||||
if (addr && !(IsAsan() && !__asan_is_valid(addr, addrsize))) {
|
||||
if (!IsWindows()) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_connect(fd, addr, addrsize);
|
||||
} else if (!__isfdopen(fd)) {
|
||||
rc = ebadf();
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_connect_nt(&g_fds.p[fd], addr, addrsize);
|
||||
} else {
|
||||
rc = ebadf();
|
||||
rc = enotsock();
|
||||
}
|
||||
} else {
|
||||
rc = efault();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
|
@ -45,18 +46,22 @@ int getsockopt(int fd, int level, int optname, void *out_opt_optval,
|
|||
int rc;
|
||||
|
||||
if (level == -1 || !optname) {
|
||||
rc = enoprotoopt(); /* see libc/sysv/consts.sh */
|
||||
rc = enoprotoopt(); // see libc/sysv/consts.sh
|
||||
} else if (IsAsan() && (out_opt_optval && out_optlen &&
|
||||
(!__asan_is_valid(out_optlen, sizeof(uint32_t)) ||
|
||||
!__asan_is_valid(out_opt_optval, *out_optlen)))) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_getsockopt(fd, level, optname, out_opt_optval, out_optlen);
|
||||
} else if (!__isfdopen(fd)) {
|
||||
rc = ebadf();
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_getsockopt_nt(&g_fds.p[fd], level, optname, out_opt_optval,
|
||||
out_optlen);
|
||||
} else {
|
||||
rc = ebadf();
|
||||
rc = enotsock();
|
||||
}
|
||||
|
||||
#ifdef SYSDEBUG
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
|
@ -37,12 +38,16 @@
|
|||
*/
|
||||
int listen(int fd, int backlog) {
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_listen(fd, backlog);
|
||||
} else if (!__isfdopen(fd)) {
|
||||
rc = ebadf();
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_listen_nt(&g_fds.p[fd], backlog);
|
||||
} else {
|
||||
rc = ebadf();
|
||||
rc = enotsock();
|
||||
}
|
||||
STRACE("listen(%d, %d) → %d% lm", fd, backlog, rc);
|
||||
return rc;
|
||||
|
|
|
@ -47,6 +47,8 @@ ssize_t recv(int fd, void *buf, size_t size, int flags) {
|
|||
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_recvfrom(fd, buf, size, flags, 0, 0);
|
||||
} else if (__isfdopen(fd)) {
|
||||
|
|
|
@ -62,6 +62,8 @@ ssize_t recvfrom(int fd, void *buf, size_t size, int flags,
|
|||
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_recvfrom(fd, buf, size, flags, &addr, &addrsize);
|
||||
} else if (__isfdopen(fd)) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/assert.h"
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/iovec.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -54,6 +55,8 @@ ssize_t recvmsg(int fd, struct msghdr *msg, int flags) {
|
|||
BEGIN_CANCELLATION_POINT;
|
||||
if (IsAsan() && !__asan_is_valid_msghdr(msg)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
if (IsBsd() && msg->msg_name) {
|
||||
memcpy(&msg2, msg, sizeof(msg2));
|
||||
|
|
|
@ -48,6 +48,8 @@ ssize_t send(int fd, const void *buf, size_t size, int flags) {
|
|||
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_sendto(fd, buf, size, flags, 0, 0);
|
||||
} else if (__isfdopen(fd)) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/assert.h"
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/iovec.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -56,6 +57,8 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) {
|
|||
BEGIN_CANCELLATION_POINT;
|
||||
if (IsAsan() && !__asan_is_valid_msghdr(msg)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
if (IsBsd() && msg->msg_name) {
|
||||
memcpy(&msg2, msg, sizeof(msg2));
|
||||
|
|
|
@ -64,31 +64,31 @@ ssize_t sendto(int fd, const void *buf, size_t size, int flags,
|
|||
if (IsAsan() && (!__asan_is_valid(buf, size) ||
|
||||
(opt_addr && !__asan_is_valid(opt_addr, addrsize)))) {
|
||||
rc = efault();
|
||||
} else {
|
||||
if (!IsWindows()) {
|
||||
if (!IsBsd() || !opt_addr) {
|
||||
rc = sys_sendto(fd, buf, size, flags, opt_addr, addrsize);
|
||||
} else if (!(rc = sockaddr2bsd(opt_addr, addrsize, &bsd, &bsdaddrsize))) {
|
||||
rc = sys_sendto(fd, buf, size, flags, &bsd, bsdaddrsize);
|
||||
}
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_sendto_nt(fd, (struct iovec[]){{buf, size}}, 1, flags,
|
||||
opt_addr, addrsize);
|
||||
} else if (__isfdkind(fd, kFdFile)) {
|
||||
if (flags) {
|
||||
rc = einval();
|
||||
} else if (opt_addr) {
|
||||
rc = eisconn();
|
||||
} else {
|
||||
rc = sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, -1);
|
||||
}
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
if (!IsBsd() || !opt_addr) {
|
||||
rc = sys_sendto(fd, buf, size, flags, opt_addr, addrsize);
|
||||
} else if (!(rc = sockaddr2bsd(opt_addr, addrsize, &bsd, &bsdaddrsize))) {
|
||||
rc = sys_sendto(fd, buf, size, flags, &bsd, bsdaddrsize);
|
||||
}
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_sendto_nt(fd, (struct iovec[]){{buf, size}}, 1, flags, opt_addr,
|
||||
addrsize);
|
||||
} else if (__isfdkind(fd, kFdFile)) {
|
||||
if (flags) {
|
||||
rc = einval();
|
||||
} else if (opt_addr) {
|
||||
rc = eisconn();
|
||||
} else {
|
||||
rc = enotsock();
|
||||
rc = sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, -1);
|
||||
}
|
||||
} else {
|
||||
rc = ebadf();
|
||||
rc = enotsock();
|
||||
}
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
|
||||
END_CANCELLATION_POINT;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
|
@ -61,10 +62,12 @@ int setsockopt(int fd, int level, int optname, const void *optval,
|
|||
int e, rc;
|
||||
|
||||
if (level == -1 || !optname) {
|
||||
rc = enoprotoopt(); /* see libc/sysv/consts.sh */
|
||||
rc = enoprotoopt(); // see libc/sysv/consts.sh
|
||||
} else if ((!optval && optlen) ||
|
||||
(IsAsan() && !__asan_is_valid(optval, optlen))) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = -1;
|
||||
e = errno;
|
||||
|
@ -75,10 +78,12 @@ int setsockopt(int fd, int level, int optname, const void *optval,
|
|||
break;
|
||||
}
|
||||
} while (setsockopt_polyfill(&optname));
|
||||
} else if (!__isfdopen(fd)) {
|
||||
rc = ebadf();
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_setsockopt_nt(&g_fds.p[fd], level, optname, optval, optlen);
|
||||
} else {
|
||||
rc = ebadf();
|
||||
rc = enotsock();
|
||||
}
|
||||
|
||||
#ifdef SYSDEBUG
|
||||
|
|
|
@ -35,12 +35,16 @@
|
|||
*/
|
||||
int shutdown(int fd, int how) {
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_shutdown(fd, how);
|
||||
} else if (!__isfdopen(fd)) {
|
||||
rc = ebadf();
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_shutdown_nt(&g_fds.p[fd], how);
|
||||
} else {
|
||||
rc = ebadf();
|
||||
rc = enotsock();
|
||||
}
|
||||
STRACE("shutdown(%d, %d) -> %d% lm", fd, how, rc);
|
||||
return rc;
|
||||
|
|
|
@ -54,7 +54,9 @@ int sockatmark(int fd) {
|
|||
} else { //
|
||||
magnum = 0x40047307; // SIOCATMARK (BSD, Windows)
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotsock();
|
||||
} else if (!IsWindows()) {
|
||||
if (sys_ioctl(fd, magnum, &rc) == -1) {
|
||||
rc = -1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue