Wed, 28 Oct 2015 17:59:34 +0100
using readdir_r instead of readdir
src/server/daemon/vfs.c | file | annotate | diff | comparison | revisions | |
src/server/daemon/vfs.h | file | annotate | diff | comparison | revisions |
--- a/src/server/daemon/vfs.c Fri Oct 23 17:28:09 2015 +0200 +++ b/src/server/daemon/vfs.c Wed Oct 28 17:59:34 2015 +0100 @@ -26,6 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#define _POSIX_PTHREAD_SEMANTIS + #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -325,6 +327,22 @@ return NULL; } + SysVFSDir *dir_data = pool ? + pool_malloc(pool, sizeof(SysVFSDir)) : malloc(sizeof(SysVFSDir)); + if(!dir_data) { + closedir(sys_dir); + return NULL; + } + long maxfilelen = fpathconf(dir_fd, _PC_NAME_MAX); + size_t entry_len = offsetof(struct dirent, d_name) + maxfilelen + 1; + dir_data->cur = pool ? + pool_malloc(pool, entry_len) : malloc(entry_len); + if(!dir_data->cur) { + closedir(sys_dir); + return NULL; + } + dir_data->dir = sys_dir; + VFSDir *dir = pool ? pool_malloc(pool, sizeof(VFSDir)) : malloc(sizeof(VFSDir)); if(!dir) { @@ -332,7 +350,7 @@ return NULL; } dir->ctx = ctx; - dir->data = sys_dir; + dir->data = dir_data; dir->fd = dir_fd; dir->io = &sys_dir_io; return dir; @@ -473,9 +491,11 @@ } int sys_dir_read(VFS_DIR dir, VFS_ENTRY *entry, int getstat) { - struct dirent *e = readdir(dir->data); - if(e) { - char *name = e->d_name; + SysVFSDir *dirdata = dir->data; + struct dirent *result = NULL; + int s = readdir_r(dirdata->dir, dirdata->cur, &result); + if(!s && result) { + char *name = result->d_name; if(!strcmp(name, ".") || !strcmp(name, "..")) { return sys_dir_read(dir, entry, getstat); } else { @@ -487,7 +507,7 @@ */ if(getstat) { // TODO: check ACLs again for new path - if(fstatat(dir->fd, e->d_name, &entry->stat, 0)) { + if(fstatat(dir->fd, result->d_name, &entry->stat, 0)) { entry->stat_errno = errno; } entry->stat_extra = NULL; @@ -501,7 +521,19 @@ } void sys_dir_close(VFS_DIR dir) { - closedir(dir->data); + SysVFSDir *dirdata = dir->data; + closedir(dirdata->dir); + + pool_handle_t *pool = dir->ctx->pool; + if(pool) { + pool_free(pool, dirdata->cur); + pool_free(pool, dirdata); + pool_free(pool, dir); + } else { + free(dirdata->cur); + free(dirdata); + free(dir); + } } int sys_mkdir(VFSContext *ctx, char *path, SysACL *sysacl) {