mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Simplify directory reading.
This commit is contained in:
parent
56085108b6
commit
2e4b15daed
34 changed files with 139 additions and 590 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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> 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> 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)
|
||||
|
|
|
@ -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<Inode> open(ioctx_t* ctx, const char* filename, int flags,
|
||||
mode_t mode);
|
||||
virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode);
|
||||
|
|
|
@ -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<Inode> 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;
|
||||
|
|
|
@ -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 <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define __need_NULL
|
||||
#include <stddef.h>
|
||||
#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
|
||||
|
|
|
@ -34,12 +34,12 @@
|
|||
#include <sortix/kernel/kthread.h>
|
||||
#include <sortix/kernel/refcount.h>
|
||||
|
||||
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<Descriptor> open(ioctx_t* ctx, const char* filename, int flags,
|
||||
mode_t mode = 0);
|
||||
int mkdir(ioctx_t* ctx, const char* filename, mode_t mode);
|
||||
|
|
|
@ -34,12 +34,12 @@
|
|||
|
||||
#include <sortix/kernel/refcount.h>
|
||||
|
||||
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<Inode> 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<Inode> open(ioctx_t* ctx, const char* filename, int flags,
|
||||
mode_t mode);
|
||||
virtual int mkdir(ioctx_t* ctx, const char* filename, mode_t mode);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
|
||||
#include <sortix/kernel/refcount.h>
|
||||
|
||||
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<Vnode> 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);
|
||||
|
|
|
@ -383,11 +383,11 @@ bool ExtractFromPhysicalInto(addr_t physaddr, size_t size, Ref<Descriptor> 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] == '.' )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<Descriptor> 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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 <dirent.h>
|
||||
#include <DIR.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dirent/dclearerr.cpp
|
||||
Clears the error flag from a directory stream.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <DIR.h>
|
||||
|
||||
extern "C" void dclearerr(DIR* dir)
|
||||
{
|
||||
dir->flags &= ~_DIR_ERROR;
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dirent/deof.cpp
|
||||
Returns the end-of-file flag of a directory stream.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <DIR.h>
|
||||
|
||||
extern "C" int deof(DIR* dir)
|
||||
{
|
||||
return dir->flags & _DIR_EOF;
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dirent/derror.cpp
|
||||
Returns the error flag of a directory stream.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <DIR.h>
|
||||
|
||||
extern "C" int derror(DIR* dir)
|
||||
{
|
||||
return dir->flags & _DIR_ERROR;
|
||||
}
|
|
@ -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 <dirent.h>
|
||||
#include <DIR.h>
|
||||
#include <errno.h>
|
||||
|
||||
extern "C" int dirfd(DIR* dir)
|
||||
{
|
||||
if ( !dir->fd_func )
|
||||
return errno = EBADF, 0;
|
||||
return dir->fd_func(dir->user);
|
||||
return dir->fd;
|
||||
}
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dirent/dnewdir.cpp
|
||||
Allocates and registers a new directory stream structure.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <DIR.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dirent/dregister.cpp
|
||||
Registers an directory stream for later automatic closing.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
|
||||
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);
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
dirent/dunregister.cpp
|
||||
Unregisters an directory stream for later automatic closing.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
|
||||
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);
|
||||
}
|
|
@ -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 <sys/readdirents.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <DIR.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 <sys/readdirents.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <DIR.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 <dirent.h>
|
||||
#include <DIR.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -29,67 +29,25 @@
|
|||
|
||||
#include <sys/__/types.h>
|
||||
|
||||
#include <sortix/__/dirent.h>
|
||||
#include <sortix/dirent.h>
|
||||
|
||||
#if defined(__is_sortix_libc)
|
||||
#include <DIR.h>
|
||||
#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 <stddef.h>
|
||||
#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
|
||||
|
||||
|
|
|
@ -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 <sys/__/types.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sortix/dirent.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __size_t_defined
|
||||
#define __size_t_defined
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
#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" */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
sys/readdirents/readdirents.cpp
|
||||
Reads entries from a directory file descriptor.
|
||||
Reads directory entries from a directory file descriptor.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <sys/readdirents.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue