Make roken build on windows
Signed-off-by: Love Hornquist Astrand <lha@h5l.org>
This commit is contained in:

committed by
Love Hornquist Astrand

parent
c4b95f7330
commit
d00f9984a5
180
lib/roken/dirent.c
Normal file
180
lib/roken/dirent.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2009, Secure Endpoints Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include<config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <io.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "dirent.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#error Only implemented for Win32
|
||||
#endif
|
||||
|
||||
struct _dirent_dirinfo {
|
||||
int magic;
|
||||
long n_entries;
|
||||
long nc_entries;
|
||||
long cursor;
|
||||
struct dirent **entries;
|
||||
};
|
||||
#define DIRINFO_MAGIC 0xf8c0639d
|
||||
#define IS_DP(p) ((p) && ((DIR *)(p))->magic == DIRINFO_MAGIC)
|
||||
|
||||
#define INITIAL_ENTRIES 16
|
||||
|
||||
ROKEN_LIB_FUNCTION DIR * ROKEN_LIB_CALL
|
||||
opendir(const char * filespec)
|
||||
{
|
||||
DIR * dp;
|
||||
struct _finddata_t fd;
|
||||
intptr_t fd_handle;
|
||||
|
||||
memset(&fd, 0, sizeof(fd));
|
||||
|
||||
fd_handle = _findfirst(filespec, &fd);
|
||||
|
||||
if (fd_handle == -1)
|
||||
return NULL;
|
||||
|
||||
dp = malloc(sizeof(*dp));
|
||||
if (dp == NULL)
|
||||
goto done;
|
||||
|
||||
memset(dp, 0, sizeof(*dp));
|
||||
dp->magic = DIRINFO_MAGIC;
|
||||
dp->cursor = 0;
|
||||
dp->n_entries = 0;
|
||||
dp->nc_entries = INITIAL_ENTRIES;
|
||||
dp->entries = calloc(dp->nc_entries, sizeof(dp->entries[0]));
|
||||
|
||||
if (dp->entries == NULL) {
|
||||
closedir(dp);
|
||||
dp = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
do {
|
||||
long len = strlen(fd.name);
|
||||
struct dirent * e;
|
||||
|
||||
if (dp->n_entries == dp->nc_entries) {
|
||||
struct dirent ** ne;
|
||||
|
||||
dp->nc_entries *= 2;
|
||||
ne = realloc(dp->entries, sizeof(dp->entries[0]) * dp->nc_entries);
|
||||
|
||||
if (ne == NULL) {
|
||||
closedir(dp);
|
||||
dp = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
dp->entries = ne;
|
||||
}
|
||||
|
||||
e = malloc(sizeof(*e) + len * sizeof(char));
|
||||
if (e == NULL) {
|
||||
closedir(dp);
|
||||
dp = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
e->d_ino = 0; /* no inodes :( */
|
||||
strcpy_s(e->d_name, len + 1, fd.name);
|
||||
|
||||
dp->entries[dp->n_entries++] = e;
|
||||
|
||||
} while (_findnext(fd_handle, &fd) == 0);
|
||||
|
||||
done:
|
||||
if (fd_handle != -1)
|
||||
_findclose(fd_handle);
|
||||
|
||||
return dp;
|
||||
}
|
||||
|
||||
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
|
||||
closedir(DIR * dp)
|
||||
{
|
||||
if (!IS_DP(dp))
|
||||
return EINVAL;
|
||||
|
||||
if (dp->entries) {
|
||||
long i;
|
||||
|
||||
for (i=0; i < dp->n_entries; i++) {
|
||||
free(dp->entries[i]);
|
||||
}
|
||||
|
||||
free(dp->entries);
|
||||
}
|
||||
|
||||
free(dp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ROKEN_LIB_FUNCTION struct dirent * ROKEN_LIB_CALL
|
||||
readdir(DIR * dp)
|
||||
{
|
||||
if (!IS_DP(dp) ||
|
||||
dp->cursor < 0 ||
|
||||
dp->cursor >= dp->n_entries)
|
||||
|
||||
return NULL;
|
||||
|
||||
return dp->entries[dp->cursor++];
|
||||
}
|
||||
|
||||
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
|
||||
rewinddir(DIR * dp)
|
||||
{
|
||||
if (IS_DP(dp))
|
||||
dp->cursor = 0;
|
||||
}
|
||||
|
||||
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
|
||||
seekdir(DIR * dp, long offset)
|
||||
{
|
||||
if (IS_DP(dp) && offset >= 0 && offset < dp->n_entries)
|
||||
dp->cursor = offset;
|
||||
}
|
||||
|
||||
ROKEN_LIB_FUNCTION long ROKEN_LIB_CALL
|
||||
telldir(DIR * dp)
|
||||
{
|
||||
return dp->cursor;
|
||||
}
|
Reference in New Issue
Block a user