Add /dev/fd support to Windows

GNU bash needs this functionality, otherwise it can't do <(cmd...).
This commit is contained in:
Justine Tunney 2024-01-06 18:05:14 -08:00
parent 2e5f662dfe
commit b3fb6cff43
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
6 changed files with 113 additions and 6 deletions

View file

@ -33,11 +33,27 @@
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/errfuns.h"
static int Atoi(const char *str) {
int c;
unsigned x = 0;
if (!*str) return -1;
while ((c = *str++)) {
if ('0' <= c && c <= '9') {
x *= 10;
x += c - '0';
} else {
return -1;
}
}
return x;
}
textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
int flags) {
// handle special files
if (startswith(path, "/dev/")) {
int fd;
if (!strcmp(path + 5, "tty")) {
return sys_fstat_nt_special(kFdConsole, st);
} else if (!strcmp(path + 5, "null")) {
@ -48,6 +64,8 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
return sys_fstat_nt(STDOUT_FILENO, st);
} else if (!strcmp(path + 5, "stderr")) {
return sys_fstat_nt(STDERR_FILENO, st);
} else if (startswith(path + 5, "fd/") && (fd = Atoi(path + 8)) != -1) {
return sys_fstat_nt(fd, st);
} else {
return enoent();
}

View file

@ -181,10 +181,25 @@ static textwindows int sys_open_nt_dup(int fd, int flags, int mode, int oldfd) {
}
}
static int Atoi(const char *str) {
int c;
unsigned x = 0;
if (!*str) return -1;
while ((c = *str++)) {
if ('0' <= c && c <= '9') {
x *= 10;
x += c - '0';
} else {
return -1;
}
}
return x;
}
textwindows int sys_open_nt(int dirfd, const char *file, uint32_t flags,
int32_t mode) {
int fd;
ssize_t rc;
int fd, oldfd;
BLOCK_SIGNALS;
__fds_lock();
if (!(flags & _O_CREAT)) mode = 0;
@ -200,6 +215,9 @@ textwindows int sys_open_nt(int dirfd, const char *file, uint32_t flags,
rc = sys_open_nt_dup(fd, flags, mode, STDOUT_FILENO);
} else if (!strcmp(file + 5, "stderr")) {
rc = sys_open_nt_dup(fd, flags, mode, STDERR_FILENO);
} else if (startswith(file + 5, "fd/") &&
(oldfd = Atoi(file + 8)) != -1) {
rc = sys_open_nt_dup(fd, flags, mode, oldfd);
} else {
rc = enoent();
}