mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Refix readdir() on OpenBSD
We now have better tests which are catching these kinds of bugs.
This commit is contained in:
parent
f7c7b949fd
commit
a5f3456333
2 changed files with 25 additions and 2 deletions
|
@ -73,6 +73,19 @@ struct dirent$bsd {
|
|||
char d_name[256];
|
||||
};
|
||||
|
||||
/**
|
||||
* OpenBSD getdents() ABI.
|
||||
*/
|
||||
struct dirent$openbsd {
|
||||
uint64_t d_fileno;
|
||||
int64_t d_off;
|
||||
uint16_t d_reclen;
|
||||
uint8_t d_type;
|
||||
uint8_t d_namlen;
|
||||
uint8_t __zomg[4];
|
||||
char d_name[256];
|
||||
};
|
||||
|
||||
static textwindows noinline DIR *opendir$nt(const char *name) {
|
||||
int len;
|
||||
DIR *res;
|
||||
|
@ -194,6 +207,7 @@ struct dirent *readdir(DIR *dir) {
|
|||
long basep;
|
||||
struct dirent *ent;
|
||||
struct dirent$bsd *bsd;
|
||||
struct dirent$openbsd *obsd;
|
||||
if (!IsWindows()) {
|
||||
if (dir->buf_pos >= dir->buf_end) {
|
||||
basep = dir->tell; /* <- what does xnu do */
|
||||
|
@ -202,10 +216,19 @@ struct dirent *readdir(DIR *dir) {
|
|||
dir->buf_pos = 0;
|
||||
dir->buf_end = rc;
|
||||
}
|
||||
if (IsLinux() || IsOpenbsd()) {
|
||||
if (IsLinux()) {
|
||||
ent = (struct dirent *)(dir->buf + dir->buf_pos);
|
||||
dir->buf_pos += ent->d_reclen;
|
||||
dir->tell = ent->d_off;
|
||||
} else if (IsOpenbsd()) {
|
||||
obsd = (struct dirent$openbsd *)(dir->buf + dir->buf_pos);
|
||||
dir->buf_pos += obsd->d_reclen;
|
||||
ent = &dir->ent;
|
||||
ent->d_ino = obsd->d_fileno;
|
||||
ent->d_off = obsd->d_off;
|
||||
ent->d_reclen = obsd->d_reclen;
|
||||
ent->d_type = obsd->d_type;
|
||||
memcpy(ent->d_name, obsd->d_name, obsd->d_namlen + 1);
|
||||
} else {
|
||||
bsd = (struct dirent$bsd *)(dir->buf + dir->buf_pos);
|
||||
dir->buf_pos += bsd->d_reclen;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_DIRENT_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
struct dirent { /* openbsd and linux getdents64 abi */
|
||||
struct dirent { /* linux getdents64 abi */
|
||||
uint64_t d_ino; /* inode number */
|
||||
int64_t d_off; /* implementation-dependent location number */
|
||||
uint16_t d_reclen; /* byte length of this whole struct and string */
|
||||
|
|
Loading…
Add table
Reference in a new issue