Implement __zipos_dup (#972)

* Implement __zipos_dup

Makes ZiposHandle reference-counted by an `rc` field in a union with its
freelist `next` pointer. The functions `__zipos_free` and `__zipos_keep`
function as incref/decref for it. Adds `__zipos_postdup` to fix metadata
on file descriptors after dup-like operations, and adds zipos support to
`sys_dup_nt` + `sys_close_nt`.

* Remove noop __zipos_postdup

rc is never a zipos file because it is always a previously unused file
descriptor. fd is never a zipos file because that case has been handled
above by __zipos_fcntl.
This commit is contained in:
Jōshin 2023-12-01 03:08:30 -05:00 committed by GitHub
parent 6556dd2673
commit d1a745c17c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 138 additions and 39 deletions

View file

@ -22,7 +22,9 @@
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/sysv/errfuns.h"
#include "libc/runtime/zipos.internal.h"
/**
* Duplicates file descriptor.
@ -51,10 +53,11 @@
*/
int dup(int fd) {
int rc;
if (__isfdkind(fd, kFdZip)) {
rc = enotsup();
} else if (!IsWindows()) {
if (!IsWindows()) {
rc = sys_dup(fd);
if (rc != -1 && __isfdkind(fd, kFdZip)) {
_weaken(__zipos_postdup)(fd, rc);
}
} else {
rc = sys_dup_nt(fd, -1, 0, -1);
}