mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Fix some bugs with dup2() and ZipOS
On UNIX if dup2(newfd) was a ZipOS file descriptor, then its resources weren't being released, and the newly created file descriptor would be mistaken for ZipOS due to its memory not being cleared. On Windows, an issue also existed relating to newfd resources not being released.
This commit is contained in:
parent
26c70e08bf
commit
4b7ba9a4c5
4 changed files with 36 additions and 3 deletions
|
@ -24,9 +24,11 @@
|
|||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/zipos.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
@ -57,7 +59,11 @@ static textwindows int sys_dup_nt_impl(int oldfd, int newfd, int flags,
|
|||
return -1;
|
||||
}
|
||||
if (g_fds.p[newfd].kind) {
|
||||
sys_close_nt(newfd, newfd);
|
||||
if (g_fds.p[newfd].kind == kFdZip) {
|
||||
_weaken(__zipos_close)(newfd);
|
||||
} else {
|
||||
sys_close_nt(newfd, newfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,15 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/runtime/zipos.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -74,6 +77,11 @@ int dup2(int oldfd, int newfd) {
|
|||
#endif
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_dup2(oldfd, newfd, 0);
|
||||
if (rc != -1 && oldfd != newfd && __isfdkind(newfd, kFdZip) && !__vforked) {
|
||||
_weaken(__zipos_free)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[newfd].handle);
|
||||
bzero(g_fds.p + newfd, sizeof(*g_fds.p));
|
||||
}
|
||||
} else if (newfd < 0) {
|
||||
rc = ebadf();
|
||||
} else if (oldfd == newfd) {
|
||||
|
|
|
@ -18,12 +18,15 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/runtime/zipos.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -71,6 +74,11 @@ int dup3(int oldfd, int newfd, int flags) {
|
|||
rc = enotsup();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_dup3(oldfd, newfd, flags);
|
||||
if (rc != -1 && __isfdkind(newfd, kFdZip) && !__vforked) {
|
||||
_weaken(__zipos_free)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[newfd].handle);
|
||||
bzero(g_fds.p + newfd, sizeof(*g_fds.p));
|
||||
}
|
||||
} else {
|
||||
rc = sys_dup_nt(oldfd, newfd, flags, -1);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/xspawn.h"
|
||||
|
||||
__static_yoink("libc/testlib/hyperion.txt");
|
||||
|
||||
void SetUpOnce(void) {
|
||||
testlib_enable_tmp_setup_teardown();
|
||||
}
|
||||
|
@ -50,7 +52,6 @@ static textstartup void TestInit(int argc, char **argv) {
|
|||
|
||||
const void *const TestCtor[] initarray = {TestInit};
|
||||
|
||||
#if 0
|
||||
TEST(dup, ebadf) {
|
||||
ASSERT_SYS(EBADF, -1, dup(-1));
|
||||
ASSERT_SYS(EBADF, -1, dup2(-1, 0));
|
||||
|
@ -72,7 +73,17 @@ TEST(dup, bigNumber) {
|
|||
ASSERT_SYS(0, 100, dup2(0, 100));
|
||||
ASSERT_SYS(0, 0, close(100));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(dup2, zipos) {
|
||||
ASSERT_SYS(0, 3, creat("real", 0644));
|
||||
ASSERT_SYS(0, 4, open("/zip/libc/testlib/hyperion.txt", O_RDONLY));
|
||||
ASSERT_SYS(0, 2, write(3, "hi", 2));
|
||||
ASSERT_SYS(EBADF, -1, write(4, "hi", 2));
|
||||
ASSERT_SYS(0, 4, dup2(3, 4));
|
||||
ASSERT_SYS(0, 2, write(4, "hi", 2));
|
||||
ASSERT_SYS(0, 0, close(4));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
TEST(dup, clearsCloexecFlag) {
|
||||
|
|
Loading…
Reference in a new issue