diff --git a/ext/fsmarshall.cpp b/ext/fsmarshall.cpp index d9e3a843..48ac79c3 100644 --- a/ext/fsmarshall.cpp +++ b/ext/fsmarshall.cpp @@ -148,7 +148,7 @@ bool RespondMakeDir(int chl, ino_t ino) return RespondMessage(chl, FSM_RESP_MKDIR, &body, sizeof(body)); } -bool RespondReadDir(int chl, struct kernel_dirent* dirent) +bool RespondReadDir(int chl, struct dirent* dirent) { struct fsm_resp_readdirents body; body.ino = dirent->d_ino; @@ -371,8 +371,8 @@ void HandleReadDir(int chl, struct fsm_req_readdirents* msg, Filesystem* fs) } union { - struct kernel_dirent kernel_entry; - uint8_t padding[sizeof(struct kernel_dirent) + 256]; + struct dirent kernel_entry; + uint8_t padding[sizeof(struct dirent) + 256]; }; memset(&kernel_entry, 0, sizeof(kernel_entry)); @@ -398,13 +398,12 @@ void HandleReadDir(int chl, struct fsm_req_readdirents* msg, Filesystem* fs) if ( entry->inode && entry->name_len && !(msg->rec_num--) ) { kernel_entry.d_reclen = sizeof(kernel_entry) + entry->name_len; - kernel_entry.d_nextoff = 0; kernel_entry.d_ino = entry->inode; kernel_entry.d_dev = 0; kernel_entry.d_type = 0; // TODO: Support this! kernel_entry.d_namlen = entry->name_len; memcpy(kernel_entry.d_name, entry->name, entry->name_len); - size_t dname_offset = offsetof(struct kernel_dirent, d_name); + size_t dname_offset = offsetof(struct dirent, d_name); padding[dname_offset + kernel_entry.d_namlen] = '\0'; block->Unref(); inode->Unref(); diff --git a/kernel/descriptor.cpp b/kernel/descriptor.cpp index 5d951f8e..3493c458 100644 --- a/kernel/descriptor.cpp +++ b/kernel/descriptor.cpp @@ -351,9 +351,8 @@ int Descriptor::isatty(ioctx_t* ctx) } ssize_t Descriptor::readdirents(ioctx_t* ctx, - struct kernel_dirent* dirent, - size_t size, - size_t maxcount) + struct dirent* dirent, + size_t size) { // TODO: COMPATIBILITY HACK: Traditionally, you can open a directory with // O_RDONLY and pass it to fdopendir and then use it, which doesn't @@ -370,35 +369,12 @@ ssize_t Descriptor::readdirents(ioctx_t* ctx, // because the execute bit on directories control search permission. if ( !(dflags & (O_SEARCH | O_READ | O_WRITE)) ) return errno = EPERM, -1; - - if ( !maxcount ) - return 0; - if ( 1 < maxcount ) - maxcount = 1; if ( SSIZE_MAX < size ) size = SSIZE_MAX; if ( size < sizeof(*dirent) ) return errno = EINVAL, -1; ScopedLock lock(¤t_offset_lock); - ssize_t ret = vnode->readdirents(ctx, dirent, size, current_offset, maxcount); - if ( ret == 0 ) - { - const char* name = ""; - size_t name_length = strlen(name); - size_t needed = sizeof(*dirent) + name_length + 1; - struct kernel_dirent retdirent; - memset(&retdirent, 0, sizeof(retdirent)); - retdirent.d_reclen = needed; - retdirent.d_nextoff = 0; - retdirent.d_namlen = name_length; - if ( !ctx->copy_to_dest(dirent, &retdirent, sizeof(retdirent)) ) - return -1; - if ( size < needed ) - return errno = ERANGE, -1; - if ( !ctx->copy_to_dest(dirent->d_name, name, name_length+1) ) - return -1; - return needed; - } + ssize_t ret = vnode->readdirents(ctx, dirent, size, current_offset); if ( 0 < ret ) current_offset++; return ret; diff --git a/kernel/fs/kram.cpp b/kernel/fs/kram.cpp index 475f9d5b..97135001 100644 --- a/kernel/fs/kram.cpp +++ b/kernel/fs/kram.cpp @@ -217,39 +217,29 @@ Dir::~Dir() delete[] children; } -ssize_t Dir::readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, - size_t size, off_t start, size_t /*maxcount*/) +ssize_t Dir::readdirents(ioctx_t* ctx, struct dirent* dirent, size_t size, + off_t start) { ScopedLock lock(&dir_lock); if ( children_used <= (uintmax_t) start ) return 0; - struct kernel_dirent retdirent; + struct dirent retdirent; memset(&retdirent, 0, sizeof(retdirent)); const char* name = children[start].name; size_t namelen = strlen(name); - size_t needed = sizeof(*dirent) + namelen + 1; - ssize_t ret = -1; - if ( size < needed ) - { - errno = ERANGE; - retdirent.d_namlen = namelen; - } - else - { - Ref inode = children[start].inode; - ret = needed; - retdirent.d_reclen = needed; - retdirent.d_nextoff = 0; - retdirent.d_namlen = namelen; - retdirent.d_ino = inode->ino; - retdirent.d_dev = inode->dev; - retdirent.d_type = ModeToDT(inode->type); - } + Ref inode = children[start].inode; + retdirent.d_reclen = sizeof(*dirent) + namelen + 1; + retdirent.d_namlen = namelen; + retdirent.d_ino = inode->ino; + retdirent.d_dev = inode->dev; + retdirent.d_type = ModeToDT(inode->type); if ( !ctx->copy_to_dest(dirent, &retdirent, sizeof(retdirent)) ) return -1; - if ( 0 <= ret && !ctx->copy_to_dest(dirent->d_name, name, namelen+1) ) + if ( size < retdirent.d_reclen ) + return errno = ERANGE, -1; + if ( !ctx->copy_to_dest(dirent->d_name, name, namelen+1) ) return -1; - return ret; + return (ssize_t) retdirent.d_reclen; } size_t Dir::FindChild(const char* filename) diff --git a/kernel/fs/kram.h b/kernel/fs/kram.h index 51225635..6ea86dd5 100644 --- a/kernel/fs/kram.h +++ b/kernel/fs/kram.h @@ -65,8 +65,8 @@ class Dir : public AbstractInode public: Dir(dev_t dev, ino_t ino, uid_t owner, gid_t group, mode_t mode); virtual ~Dir(); - virtual ssize_t readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, - size_t size, off_t start, size_t maxcount); + virtual ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, + size_t size, off_t start); virtual Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode); virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode); diff --git a/kernel/fs/user.cpp b/kernel/fs/user.cpp index 373c3eca..ebc87dc7 100644 --- a/kernel/fs/user.cpp +++ b/kernel/fs/user.cpp @@ -217,8 +217,8 @@ public: const struct timespec* ctime, const struct timespec* mtime); virtual int isatty(ioctx_t* ctx); - virtual ssize_t readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, - size_t size, off_t start, size_t maxcount); + virtual ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, + size_t size, off_t start); virtual Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode); virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode); @@ -1009,8 +1009,8 @@ int Unode::isatty(ioctx_t* ctx) return ret; } -ssize_t Unode::readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, - size_t size, off_t start, size_t /*maxcount*/) +ssize_t Unode::readdirents(ioctx_t* ctx, struct dirent* dirent, size_t size, + off_t start) { Channel* channel = server->Connect(ctx); if ( !channel ) @@ -1030,9 +1030,9 @@ ssize_t Unode::readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, goto break_if; } - struct kernel_dirent entry; + struct dirent entry; + memset(&entry, 0, sizeof(entry)); entry.d_reclen = sizeof(entry) + resp.namelen + 1; - entry.d_nextoff = 0; entry.d_namlen = resp.namelen; entry.d_dev = (dev_t) server; entry.d_ino = resp.ino; @@ -1041,14 +1041,13 @@ ssize_t Unode::readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, if ( !ctx->copy_to_dest(dirent, &entry, sizeof(entry)) ) goto break_if; - size_t needed = sizeof(*dirent) + resp.namelen + 1; - if ( size < needed && (errno = ERANGE) ) + if ( size < entry.d_reclen && (errno = ERANGE) ) goto break_if; - uint8_t nul = 0; + char nul = '\0'; if ( channel->KernelRecv(ctx, dirent->d_name, resp.namelen) && ctx->copy_to_dest(&dirent->d_name[resp.namelen], &nul, 1) ) - ret = (ssize_t) needed; + ret = (ssize_t) entry.d_reclen; } break_if: channel->KernelClose(); return ret; diff --git a/kernel/include/sortix/dirent.h b/kernel/include/sortix/dirent.h index 9288496f..c544f793 100644 --- a/kernel/include/sortix/dirent.h +++ b/kernel/include/sortix/dirent.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2012, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2012, 2014, 2015. This file is part of Sortix. @@ -54,11 +54,7 @@ typedef __ino_t ino_t; #include #endif -#ifndef NULL -#define __need_NULL -#include -#endif - +#if __USE_SORTIX #define DT_UNKNOWN __DT_UNKNOWN #define DT_BLK __DT_BLK #define DT_CHR __DT_CHR @@ -67,14 +63,16 @@ typedef __ino_t ino_t; #define DT_LNK __DT_LNK #define DT_REG __DT_REG #define DT_SOCK __DT_SOCK +#endif +#if __USE_SORTIX #define IFTODT(x) __IFTODT(x) #define DTTOIF(x) __DTTOIF(x) +#endif -struct kernel_dirent +struct dirent { size_t d_reclen; - size_t d_nextoff; size_t d_namlen; ino_t d_ino; dev_t d_dev; @@ -82,13 +80,6 @@ struct kernel_dirent __extension__ char d_name[]; }; -static __inline struct kernel_dirent* kernel_dirent_next(struct kernel_dirent* ent) -{ - if ( !ent->d_nextoff ) - return NULL; - return (struct kernel_dirent*) ((uint8_t*) ent + ent->d_nextoff); -} - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/kernel/include/sortix/kernel/descriptor.h b/kernel/include/sortix/kernel/descriptor.h index fd42d3a2..7a674105 100644 --- a/kernel/include/sortix/kernel/descriptor.h +++ b/kernel/include/sortix/kernel/descriptor.h @@ -34,12 +34,12 @@ #include #include +struct dirent; struct stat; struct statvfs; struct termios; struct wincurpos; struct winsize; -struct kernel_dirent; namespace Sortix { @@ -75,8 +75,7 @@ public: int utimens(ioctx_t* ctx, const struct timespec* atime, const struct timespec* ctime, const struct timespec* mtime); int isatty(ioctx_t* ctx); - ssize_t readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, size_t size, - size_t maxcount); + ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, size_t size); Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode = 0); int mkdir(ioctx_t* ctx, const char* filename, mode_t mode); diff --git a/kernel/include/sortix/kernel/inode.h b/kernel/include/sortix/kernel/inode.h index 6c35af06..c0922a7c 100644 --- a/kernel/include/sortix/kernel/inode.h +++ b/kernel/include/sortix/kernel/inode.h @@ -34,12 +34,12 @@ #include +struct dirent; struct stat; struct statvfs; struct termios; struct wincurpos; struct winsize; -struct kernel_dirent; namespace Sortix { @@ -76,8 +76,8 @@ public: const struct timespec* ctime, const struct timespec* mtime) = 0; virtual int isatty(ioctx_t* ctx) = 0; - virtual ssize_t readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, - size_t size, off_t start, size_t maxcount) = 0; + virtual ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, + size_t size, off_t start) = 0; virtual Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode) = 0; virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode) = 0; @@ -171,8 +171,8 @@ public: const struct timespec* ctime, const struct timespec* mtime); virtual int isatty(ioctx_t* ctx); - virtual ssize_t readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, - size_t size, off_t start, size_t maxcount); + virtual ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, + size_t size, off_t start); virtual Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode); virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode); diff --git a/kernel/include/sortix/kernel/syscall.h b/kernel/include/sortix/kernel/syscall.h index 2314b86d..b5dddd46 100644 --- a/kernel/include/sortix/kernel/syscall.h +++ b/kernel/include/sortix/kernel/syscall.h @@ -129,7 +129,7 @@ ssize_t sys_pwritev(int, const struct iovec*, int, off_t); int sys_raise(int); uint64_t sys_rdmsr(uint32_t); ssize_t sys_read(int, void*, size_t); -ssize_t sys_readdirents(int, struct kernel_dirent*, size_t); +ssize_t sys_readdirents(int, struct dirent*, size_t); ssize_t sys_readlinkat(int, const char*, char*, size_t); ssize_t sys_readv(int, const struct iovec*, int); ssize_t sys_recv(int, void*, size_t, int); diff --git a/kernel/include/sortix/kernel/vnode.h b/kernel/include/sortix/kernel/vnode.h index 80b14571..8770e693 100644 --- a/kernel/include/sortix/kernel/vnode.h +++ b/kernel/include/sortix/kernel/vnode.h @@ -33,12 +33,12 @@ #include +struct dirent; struct stat; struct statvfs; struct termios; struct wincurpos; struct winsize; -struct kernel_dirent; namespace Sortix { @@ -72,8 +72,8 @@ public: int utimens(ioctx_t* ctx, const struct timespec* atime, const struct timespec* ctime, const struct timespec* mtime); int isatty(ioctx_t* ctx); - ssize_t readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, - size_t size, off_t start, size_t maxcount); + ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, size_t size, + off_t start); Ref open(ioctx_t* ctx, const char* filename, int flags, mode_t mode); int mkdir(ioctx_t* ctx, const char* filename, mode_t mode); int unlink(ioctx_t* ctx, const char* filename); diff --git a/kernel/initrd.cpp b/kernel/initrd.cpp index 5db2e2b7..d32de797 100644 --- a/kernel/initrd.cpp +++ b/kernel/initrd.cpp @@ -383,11 +383,11 @@ bool ExtractFromPhysicalInto(addr_t physaddr, size_t size, Ref desc) union { - struct kernel_dirent dirent; - uint8_t dirent_data[sizeof(struct kernel_dirent) + sizeof(uintmax_t) * 3]; + struct dirent dirent; + uint8_t dirent_data[sizeof(struct dirent) + sizeof(uintmax_t) * 3]; }; - while ( 0 < ctx.links->readdirents(&ctx.ioctx, &dirent, sizeof(dirent_data), 1) && + while ( 0 < ctx.links->readdirents(&ctx.ioctx, &dirent, sizeof(dirent_data)) && ((const char*) dirent.d_name)[0] ) { if ( ((const char*) dirent.d_name)[0] == '.' ) diff --git a/kernel/inode.cpp b/kernel/inode.cpp index b1f2d24d..885e5073 100644 --- a/kernel/inode.cpp +++ b/kernel/inode.cpp @@ -202,9 +202,9 @@ int AbstractInode::isatty(ioctx_t* /*ctx*/) } ssize_t AbstractInode::readdirents(ioctx_t* /*ctx*/, - struct kernel_dirent* /*dirent*/, - size_t /*size*/, off_t /*start*/, - size_t /*maxcount*/) + struct dirent* /*dirent*/, + size_t /*size*/, + off_t /*start*/) { if ( inode_type == INODE_TYPE_DIR ) return errno = EBADF, -1; diff --git a/kernel/io.cpp b/kernel/io.cpp index 43cc8689..47a548f5 100644 --- a/kernel/io.cpp +++ b/kernel/io.cpp @@ -382,16 +382,15 @@ int sys_ioctl(int fd, int cmd, uintptr_t arg) } } -ssize_t sys_readdirents(int fd, struct kernel_dirent* dirent, size_t size) +ssize_t sys_readdirents(int fd, struct dirent* dirent, size_t size) { - if ( size < sizeof(kernel_dirent) ) { errno = EINVAL; return -1; } if ( SSIZE_MAX < size ) size = SSIZE_MAX; Ref desc = CurrentProcess()->GetDescriptor(fd); if ( !desc ) return -1; ioctx_t ctx; SetupUserIOCtx(&ctx); - return desc->readdirents(&ctx, dirent, size, 1 /*maxcount*/); + return desc->readdirents(&ctx, dirent, size); } int sys_fchdir(int fd) diff --git a/kernel/vnode.cpp b/kernel/vnode.cpp index 733b657b..2eea3b3a 100644 --- a/kernel/vnode.cpp +++ b/kernel/vnode.cpp @@ -281,10 +281,10 @@ int Vnode::isatty(ioctx_t* ctx) return inode->isatty(ctx); } -ssize_t Vnode::readdirents(ioctx_t* ctx, struct kernel_dirent* dirent, - size_t size, off_t start, size_t count) +ssize_t Vnode::readdirents(ioctx_t* ctx, struct dirent* dirent, + size_t size, off_t start) { - return inode->readdirents(ctx, dirent, size, start, count); + return inode->readdirents(ctx, dirent, size, start); } int Vnode::mkdir(ioctx_t* ctx, const char* filename, mode_t mode) diff --git a/libc/Makefile b/libc/Makefile index 9186bb29..252f472d 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -36,16 +36,7 @@ ctype/tolower.o \ ctype/toupper.o \ dirent/alphasort.o \ dirent/alphasort_r.o \ -dirent/closedir.o \ -dirent/dclearerr.o \ -dirent/deof.o \ -dirent/derror.o \ dirent/dirfd.o \ -dirent/dnewdir.o \ -dirent/dregister.o \ -dirent/dunregister.o \ -dirent/readdir.o \ -dirent/rewinddir.o \ dirent/versionsort.o \ dirent/versionsort_r.o \ errno/errno.o \ @@ -330,9 +321,12 @@ $(CPUDIR)/fork.o \ $(CPUDIR)/setjmp.o \ $(CPUDIR)/signal.o \ $(CPUDIR)/syscall.o \ +dirent/closedir.o \ dirent/dscandir_r.o \ dirent/fdopendir.o \ dirent/opendir.o \ +dirent/readdir.o \ +dirent/rewinddir.o \ dirent/scandir.o \ dlfcn/dlfcn.o \ err/err.o \ diff --git a/libc/dirent/closedir.cpp b/libc/dirent/closedir.cpp index 52c31a6b..fad1dcc3 100644 --- a/libc/dirent/closedir.cpp +++ b/libc/dirent/closedir.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2014, 2015. This file is part of the Sortix C Library. @@ -23,15 +23,13 @@ *******************************************************************************/ #include -#include #include +#include extern "C" int closedir(DIR* dir) { - int result = dir->close_func ? dir->close_func(dir->user) : 0; - dunregister(dir); + close(dir->fd); free(dir->entry); - if ( dir->free_func ) - dir->free_func(dir); - return result; + free(dir); + return 0; } diff --git a/libc/dirent/dclearerr.cpp b/libc/dirent/dclearerr.cpp deleted file mode 100644 index 76b3c1dc..00000000 --- a/libc/dirent/dclearerr.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. - - This file is part of the Sortix C Library. - - The Sortix C Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or (at your - option) any later version. - - The Sortix C Library is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with the Sortix C Library. If not, see . - - dirent/dclearerr.cpp - Clears the error flag from a directory stream. - -*******************************************************************************/ - -#include -#include - -extern "C" void dclearerr(DIR* dir) -{ - dir->flags &= ~_DIR_ERROR; -} diff --git a/libc/dirent/deof.cpp b/libc/dirent/deof.cpp deleted file mode 100644 index 26c552de..00000000 --- a/libc/dirent/deof.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. - - This file is part of the Sortix C Library. - - The Sortix C Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or (at your - option) any later version. - - The Sortix C Library is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with the Sortix C Library. If not, see . - - dirent/deof.cpp - Returns the end-of-file flag of a directory stream. - -*******************************************************************************/ - -#include -#include - -extern "C" int deof(DIR* dir) -{ - return dir->flags & _DIR_EOF; -} diff --git a/libc/dirent/derror.cpp b/libc/dirent/derror.cpp deleted file mode 100644 index ac51b482..00000000 --- a/libc/dirent/derror.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. - - This file is part of the Sortix C Library. - - The Sortix C Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or (at your - option) any later version. - - The Sortix C Library is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with the Sortix C Library. If not, see . - - dirent/derror.cpp - Returns the error flag of a directory stream. - -*******************************************************************************/ - -#include -#include - -extern "C" int derror(DIR* dir) -{ - return dir->flags & _DIR_ERROR; -} diff --git a/libc/dirent/dirfd.cpp b/libc/dirent/dirfd.cpp index dcc4dc04..68a5b3b4 100644 --- a/libc/dirent/dirfd.cpp +++ b/libc/dirent/dirfd.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2014, 2015. This file is part of the Sortix C Library. @@ -23,12 +23,9 @@ *******************************************************************************/ #include -#include #include extern "C" int dirfd(DIR* dir) { - if ( !dir->fd_func ) - return errno = EBADF, 0; - return dir->fd_func(dir->user); + return dir->fd; } diff --git a/libc/dirent/dnewdir.cpp b/libc/dirent/dnewdir.cpp deleted file mode 100644 index c7946ce0..00000000 --- a/libc/dirent/dnewdir.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. - - This file is part of the Sortix C Library. - - The Sortix C Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or (at your - option) any later version. - - The Sortix C Library is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with the Sortix C Library. If not, see . - - dirent/dnewdir.cpp - Allocates and registers a new directory stream structure. - -*******************************************************************************/ - -#include -#include -#include -#include - -static void dfreedir(DIR* dir) -{ - free(dir); -} - -extern "C" DIR* dnewdir(void) -{ - DIR* dir = (DIR*) calloc(sizeof(DIR), 1); - if ( !dir ) - return NULL; - dir->flags = 0; - dir->free_func = dfreedir; - dir->closedir_indirect = closedir; - dregister(dir); - return dir; -} diff --git a/libc/dirent/dregister.cpp b/libc/dirent/dregister.cpp deleted file mode 100644 index a16d8195..00000000 --- a/libc/dirent/dregister.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. - - This file is part of the Sortix C Library. - - The Sortix C Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or (at your - option) any later version. - - The Sortix C Library is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with the Sortix C Library. If not, see . - - dirent/dregister.cpp - Registers an directory stream for later automatic closing. - -*******************************************************************************/ - -#include -#include - -extern "C" void dregister(DIR* dir) -{ - pthread_mutex_lock(&__first_dir_lock); - dir->flags |= _DIR_REGISTERED; - if ( (dir->next = __first_dir) ) - dir->next->prev = dir; - __first_dir = dir; - pthread_mutex_unlock(&__first_dir_lock); -} diff --git a/libc/dirent/dunregister.cpp b/libc/dirent/dunregister.cpp deleted file mode 100644 index 1f037f31..00000000 --- a/libc/dirent/dunregister.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. - - This file is part of the Sortix C Library. - - The Sortix C Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or (at your - option) any later version. - - The Sortix C Library is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with the Sortix C Library. If not, see . - - dirent/dunregister.cpp - Unregisters an directory stream for later automatic closing. - -*******************************************************************************/ - -#include -#include - -extern "C" void dunregister(DIR* dir) -{ - if ( !(dir->flags & _DIR_REGISTERED) ) - return; - pthread_mutex_lock(&__first_dir_lock); - if ( !dir->prev ) - __first_dir = dir->next; - if ( dir->prev ) - dir->prev->next = dir->next; - if ( dir->next ) - dir->next->prev = dir->prev; - dir->flags &= ~_DIR_REGISTERED; - pthread_mutex_unlock(&__first_dir_lock); -} diff --git a/libc/dirent/fdopendir.cpp b/libc/dirent/fdopendir.cpp index 11e215ba..7c5012bb 100644 --- a/libc/dirent/fdopendir.cpp +++ b/libc/dirent/fdopendir.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2014, 2015. This file is part of the Sortix C Library. @@ -22,129 +22,20 @@ *******************************************************************************/ -#include - -#include #include #include -#include #include -#include -#include #include -#include -#include - -typedef struct fddir_sortix_struct -{ - struct kernel_dirent* dirent; - struct kernel_dirent* current; - size_t direntsize; - int fd; -} fddir_sortix_t; - -static int fddir_sortix_readents(fddir_sortix_t* info) -{ - if ( !info->dirent ) - { - // Allocate a buffer of at least sizeof(kernel_dirent). - info->direntsize = sizeof(struct kernel_dirent) + 4UL; - info->dirent = (struct kernel_dirent*) malloc(info->direntsize); - if ( !info->dirent ) - return -1; - } - - int saved_errno = errno; - if ( readdirents(info->fd, info->dirent, info->direntsize) < 0 ) - { - if ( errno != ERANGE ) - return -1; - errno = saved_errno; - size_t newdirentsize = sizeof(struct kernel_dirent) + info->dirent->d_namlen + 1; - if ( newdirentsize < info->direntsize ) - newdirentsize *= 2; - struct kernel_dirent* newdirent = (struct kernel_dirent*) malloc(newdirentsize); - if ( !newdirent ) - return -1; - free(info->dirent); - info->dirent = newdirent; - info->direntsize = newdirentsize; - return fddir_sortix_readents(info); - } - - return 0; -} - -static int fddir_sortix_read(void* user, struct dirent* dirent, size_t* size) -{ - fddir_sortix_t* info = (fddir_sortix_t*) user; - if ( !info->current ) - { - if ( fddir_sortix_readents(info) ) - return -1; - info->current = info->dirent; - } - - size_t provided = (user) ? *size : 0; - size_t needed = sizeof(struct dirent) + info->current->d_namlen + 1; - *size = needed; - if ( provided < needed ) - return 1; - - dirent->d_reclen = needed; - dirent->d_namlen = info->current->d_namlen; - dirent->d_ino = info->current->d_ino; - dirent->d_dev = info->current->d_dev; - dirent->d_type = info->current->d_type; - strcpy(dirent->d_name, info->current->d_name); - - info->current = kernel_dirent_next(info->current); - - return 0; -} - -static int fddir_sortix_rewind(void* user) -{ - fddir_sortix_t* info = (fddir_sortix_t*) user; - return lseek(info->fd, 0, SEEK_SET); -} - -static int fddir_sortix_fd(void* user) -{ - fddir_sortix_t* info = (fddir_sortix_t*) user; - return info->fd; -} - -static int fddir_sortix_close(void* user) -{ - fddir_sortix_t* info = (fddir_sortix_t*) user; - int result = close(info->fd); - free(info->dirent); - free(info); - return result; -} extern "C" DIR* fdopendir(int fd) { - fddir_sortix_t* info = (fddir_sortix_t*) calloc(sizeof(fddir_sortix_t), 1); - if ( !info ) - return NULL; - - DIR* dir = dnewdir(); - if ( !dir ) - return free(info), (DIR*) NULL; - int old_dflags = fcntl(fd, F_GETFD); - if ( 0 <= old_dflags ) + if ( 0 <= old_dflags && !(old_dflags & FD_CLOEXEC) ) fcntl(fd, F_SETFD, old_dflags | FD_CLOEXEC); - - info->fd = fd; - - dir->read_func = fddir_sortix_read; - dir->rewind_func = fddir_sortix_rewind; - dir->fd_func = fddir_sortix_fd; - dir->close_func = fddir_sortix_close; - dir->user = (void*) info; - + // TODO: Potentially reopen as O_EXEC when the kernel requires that. + DIR* dir = (DIR*) calloc(sizeof(DIR), 1); + if ( !dir ) + return NULL; + dir->fd = fd; return dir; } diff --git a/libc/dirent/opendir.cpp b/libc/dirent/opendir.cpp index 0758f53b..026bb4e2 100644 --- a/libc/dirent/opendir.cpp +++ b/libc/dirent/opendir.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2014, 2015. This file is part of the Sortix C Library. @@ -24,16 +24,17 @@ #include #include -#include +#include #include extern "C" DIR* opendir(const char* path) { - int fd = open(path, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + int fd = open(path, O_SEARCH | O_DIRECTORY | O_CLOEXEC); if ( fd < 0 ) return NULL; - DIR* dir = fdopendir(fd); + DIR* dir = (DIR*) calloc(sizeof(DIR), 1); if ( !dir ) return close(fd), (DIR*) NULL; + dir->fd = fd; return dir; } diff --git a/libc/dirent/readdir.cpp b/libc/dirent/readdir.cpp index c402d1b9..ac24fb16 100644 --- a/libc/dirent/readdir.cpp +++ b/libc/dirent/readdir.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2014, 2015. This file is part of the Sortix C Library. @@ -22,38 +22,34 @@ *******************************************************************************/ +#include + #include -#include #include -#include #include extern "C" struct dirent* readdir(DIR* dir) { int old_errno = errno; - - if ( !dir->read_func ) - return dir->flags |= _DIR_ERROR, errno = EBADF, (struct dirent*) NULL; - - size_t size = dir->entrysize; - int status; - while ( 0 < (status = dir->read_func(dir->user, dir->entry, &size)) ) + struct dirent fallback; + struct dirent* entry = dir->entry ? dir->entry : &fallback; + size_t size = dir->entry ? dir->size : sizeof(fallback); + ssize_t amount; + while ( (amount = readdirents(dir->fd, entry, size)) < 0 ) { - struct dirent* biggerdir = (struct dirent*) malloc(size); - if ( !biggerdir ) - return dir->flags |= _DIR_ERROR, (struct dirent*) NULL; + if ( errno != ERANGE ) + return NULL; + errno = old_errno; + size_t needed = entry->d_reclen; free(dir->entry); - dir->entry = biggerdir; - dir->entrysize = size; + dir->entry = NULL; + struct dirent* new_dirent = (struct dirent*) malloc(needed); + if ( !new_dirent ) + return NULL; + entry = dir->entry = new_dirent; + size = dir->size = needed; } - - if ( status < 0 ) - return dir->flags |= _DIR_ERROR, (struct dirent*) NULL; - - dir->flags &= ~_DIR_ERROR; - - if ( !dir->entry->d_name[0] ) - return dir->flags |= _DIR_EOF, errno = old_errno, (struct dirent*) NULL; - + if ( amount == 0 ) + return NULL; return dir->entry; } diff --git a/libc/dirent/rewinddir.cpp b/libc/dirent/rewinddir.cpp index e61c6f1c..c3265657 100644 --- a/libc/dirent/rewinddir.cpp +++ b/libc/dirent/rewinddir.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2014. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2014, 2015. This file is part of the Sortix C Library. @@ -23,11 +23,9 @@ *******************************************************************************/ #include -#include +#include extern "C" void rewinddir(DIR* dir) { - if ( dir->rewind_func ) - dir->rewind_func(dir->user); - dir->flags &= ~_DIR_EOF; + lseek(dir->fd, 0, SEEK_SET); } diff --git a/libc/include/DIR.h b/libc/include/DIR.h index 473ee720..c71fafa4 100644 --- a/libc/include/DIR.h +++ b/libc/include/DIR.h @@ -54,26 +54,11 @@ typedef struct __DIR DIR; struct __DIR { - void* user; - int (*read_func)(void* user, struct dirent* dirent, size_t* size); - int (*rewind_func)(void* user); - int (*fd_func)(void* user); - int (*close_func)(void* user); - void (*free_func)(DIR* dir); - /* Application writers shouldn't use anything beyond this point. */ - int (*closedir_indirect)(DIR*); - DIR* prev; - DIR* next; struct dirent* entry; - size_t entrysize; - int flags; + size_t size; + int fd; }; -#if defined(__is_sortix_libc) -extern DIR* __first_dir; -extern __pthread_mutex_t __first_dir_lock; -#endif - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/libc/include/dirent.h b/libc/include/dirent.h index 2ef49b75..6e59e7b4 100644 --- a/libc/include/dirent.h +++ b/libc/include/dirent.h @@ -29,67 +29,25 @@ #include -#include +#include #if defined(__is_sortix_libc) #include #endif -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __dev_t_defined -#define __dev_t_defined -typedef __dev_t dev_t; -#endif - -#ifndef __ino_t_defined -#define __ino_t_defined -typedef __ino_t ino_t; -#endif - -#ifndef __size_t_defined -#define __size_t_defined -#define __need_size_t -#include -#endif - #ifndef __DIR_defined #define __DIR_defined typedef struct __DIR DIR; #endif -#if __USE_SORTIX -#define DT_UNKNOWN __DT_UNKNOWN -#define DT_BLK __DT_BLK -#define DT_CHR __DT_CHR -#define DT_DIR __DT_DIR -#define DT_FIFO __DT_FIFO -#define DT_LNK __DT_LNK -#define DT_REG __DT_REG -#define DT_SOCK __DT_SOCK +#ifdef __cplusplus +extern "C" { #endif -#if __USE_SORTIX -#define IFTODT(x) __IFTODT(x) -#define DTTOIF(x) __DTTOIF(x) -#endif - -struct dirent -{ - size_t d_reclen; - size_t d_namlen; - ino_t d_ino; - dev_t d_dev; - unsigned char d_type; - __extension__ char d_name[]; -}; - -int closedir(DIR* dir); -DIR* opendir(const char* path); -struct dirent* readdir(DIR* dir); -void rewinddir(DIR* dir); +int closedir(DIR*); +DIR* opendir(const char*); +struct dirent* readdir(DIR*); +void rewinddir(DIR*); #if __USE_SORTIX || __USE_XOPEN /* TODO: seekdir */ @@ -104,8 +62,8 @@ void rewinddir(DIR* dir); /* Functions from POSIX 2008. */ #if __USE_SORTIX || 200809L <= __USE_POSIX int alphasort(const struct dirent**, const struct dirent**); -int dirfd(DIR* dir); -DIR* fdopendir(int fd); +int dirfd(DIR*); +DIR* fdopendir(int); int scandir(const char*, struct dirent***, int (*)(const struct dirent*), int (*)(const struct dirent**, const struct dirent**)); #endif @@ -118,17 +76,11 @@ int versionsort(const struct dirent**, const struct dirent**); /* Functions that are Sortix extensions. */ #if __USE_SORTIX int alphasort_r(const struct dirent**, const struct dirent**, void*); -void dclearerr(DIR* dir); -int deof(DIR* dif); -int derror(DIR* dir); -DIR* dnewdir(void); -void dregister(DIR* dir); int dscandir_r(DIR*, struct dirent***, int (*)(const struct dirent*, void*), void*, int (*)(const struct dirent**, const struct dirent**, void*), void*); -void dunregister(DIR* dir); int versionsort_r(const struct dirent**, const struct dirent**, void*); #endif diff --git a/libc/include/sys/readdirents.h b/libc/include/sys/readdirents.h index 0797fbf8..502ee20f 100644 --- a/libc/include/sys/readdirents.h +++ b/libc/include/sys/readdirents.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2015. This file is part of the Sortix C Library. @@ -29,22 +29,24 @@ #include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - #ifndef __size_t_defined #define __size_t_defined #define __need_size_t #include #endif -ssize_t readdirents(int fd, struct kernel_dirent* dirent, size_t size); +#ifndef __ssize_t_defined +#define __ssize_t_defined +typedef __ssize_t ssize_t; +#endif + +struct dirent; + +#ifdef __cplusplus +extern "C" { +#endif + +ssize_t readdirents(int, struct dirent*, size_t); #ifdef __cplusplus } /* extern "C" */ diff --git a/libc/stdlib/exit.cpp b/libc/stdlib/exit.cpp index 11bb7461..e014081a 100644 --- a/libc/stdlib/exit.cpp +++ b/libc/stdlib/exit.cpp @@ -60,11 +60,8 @@ extern "C" void exit(int status) __exit_handler_stack = __exit_handler_stack->next; } - pthread_mutex_lock(&__first_dir_lock); pthread_mutex_lock(&__first_file_lock); - while ( __first_dir ) - __first_dir->closedir_indirect(__first_dir); for ( FILE* fp = __first_file; fp; fp = fp->next ) { flockfile(fp); diff --git a/libc/sys/readdirents/readdirents.cpp b/libc/sys/readdirents/readdirents.cpp index 748d440f..6a54aeed 100644 --- a/libc/sys/readdirents/readdirents.cpp +++ b/libc/sys/readdirents/readdirents.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2015. This file is part of the Sortix C Library. @@ -18,16 +18,16 @@ along with the Sortix C Library. If not, see . sys/readdirents/readdirents.cpp - Reads entries from a directory file descriptor. + Reads directory entries from a directory file descriptor. *******************************************************************************/ #include #include -DEFN_SYSCALL4(ssize_t, sys_readdirents, SYSCALL_READDIRENTS, int, struct kernel_dirent*, size_t, size_t); +DEFN_SYSCALL3(ssize_t, sys_readdirents, SYSCALL_READDIRENTS, int, struct dirent*, size_t); -extern "C" ssize_t readdirents(int fd, struct kernel_dirent* dirent, size_t size) +extern "C" ssize_t readdirents(int fd, struct dirent* dirent, size_t size) { - return sys_readdirents(fd, dirent, size, 1); + return sys_readdirents(fd, dirent, size); } diff --git a/utils/chmod.cpp b/utils/chmod.cpp index c357ec5c..df199898 100644 --- a/utils/chmod.cpp +++ b/utils/chmod.cpp @@ -272,7 +272,8 @@ static bool do_chmod_directory(int fd, joiner = ""; bool success = true; - while ( struct dirent* entry = readdir(dir) ) + struct dirent* entry; + while ( (errno = 0, entry = readdir(dir)) ) { if ( !strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") ) continue; @@ -291,7 +292,7 @@ static bool do_chmod_directory(int fd, free(entry_path); } - if ( derror(dir) ) + if ( errno != 0 ) { error(0, errno, "reading directory: `%s'", path); closedir(dir); diff --git a/utils/du.cpp b/utils/du.cpp index 888feb86..b5c65efe 100644 --- a/utils/du.cpp +++ b/utils/du.cpp @@ -223,7 +223,8 @@ bool disk_usage_file_at(int relfd, } bool success = true; - while ( struct dirent* entry = readdir(dir) ) + struct dirent* entry; + while ( (errno = 0, entry = readdir(dir)) ) { if ( !strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") ) continue; @@ -249,14 +250,12 @@ bool disk_usage_file_at(int relfd, if ( num_bytes_ptr ) *num_bytes_ptr = num_bytes; -#if defined(__sortix__) - if ( derror(dir) && errno != ENOTDIR ) + if ( errno && errno != ENOTDIR ) { error(0, errno, "reading directory `%s'", path); closedir(dir); return false; } -#endif if ( print_if_dir ) print_disk_usage(num_bytes, block_size, flags, path);