Fix termios struct on Linux

The termios::c_cc field turned out to be incorrectly defined on Linux
due to some confusion between the glibc and kernel definitions. We'll
be using the kernel definition, since it has the strongest consensus.

Fields have been have been added to struct stat for BSD compatibility
such as st_birthtim, plus the GLIBC compatibility of isystem/sys/stat
has been improved.
This commit is contained in:
Justine Tunney 2021-09-03 22:19:41 -07:00
parent 0584684a82
commit 5b60e5a37d
52 changed files with 358 additions and 296 deletions

View file

@ -27,10 +27,29 @@
int ioctl_tcsets_nt(int, uint64_t, const struct termios *);
static int ioctl_tcsets_metal(int fd, uint64_t request,
const struct termios *tio) {
return 0;
}
static inline void *__termios2host(union metatermios *mt,
const struct termios *lt) {
if (!IsXnu() && !IsFreebsd() && !IsOpenbsd() && !IsNetbsd()) {
return lt;
} else if (IsXnu()) {
COPY_TERMIOS(&mt->xnu, lt);
return &mt->xnu;
} else {
COPY_TERMIOS(&mt->bsd, lt);
return &mt->bsd;
}
}
static int ioctl_tcsets_sysv(int fd, uint64_t request,
const struct termios *tio) {
union metatermios t;
return sys_ioctl(fd, request, __termios2host(&t, tio));
union metatermios mt;
if (IsAsan() && !__asan_is_valid(tio, sizeof(*tio))) return efault();
return sys_ioctl(fd, request, __termios2host(&mt, tio));
}
/**
@ -47,10 +66,11 @@ int ioctl_tcsets(int fd, uint64_t request, ...) {
tio = va_arg(va, const struct termios *);
va_end(va);
if (!tio) return efault();
if (IsAsan() && !__asan_is_valid(tio, sizeof(*tio))) return efault();
if (fd >= 0) {
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return enotty();
} else if (IsMetal()) {
return ioctl_tcsets_metal(fd, request, tio);
} else if (!IsWindows()) {
return ioctl_tcsets_sysv(fd, request, tio);
} else {