84 lines
1.7 KiB
C
84 lines
1.7 KiB
C
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||
|
|
||
|
/* osx_dir.h implementation for Windows.
|
||
|
*
|
||
|
* Copyright: 2022, The DoubleFourteen Code Forge
|
||
|
* Author: Lorenzo Cogotti
|
||
|
*/
|
||
|
|
||
|
#include "xconf.h"
|
||
|
#include "osx_dir.h"
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
DF_OSXLIB_API df_os_dirhn os_opendir(const char *path)
|
||
|
{
|
||
|
if (*path == '\0') { // avoid generating \* search path
|
||
|
errno = ENOENT;
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
char buf[_MAX_PATH + 2 + 1];
|
||
|
int n = snprintf(buf, sizeof(buf), "%s\\*", path);
|
||
|
if (n < 0)
|
||
|
return NULL;
|
||
|
if ((size_t) n >= sizeof(buf)) {
|
||
|
errno = ERANGE;
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
df_os_dirhn hn = malloc(sizeof(*hn));
|
||
|
if (!hn)
|
||
|
return NULL;
|
||
|
|
||
|
hn->dirh = _findfirst(buf, &hn->data);
|
||
|
if (hn->dirh == -1) {
|
||
|
free(hn);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
hn->startflag = true;
|
||
|
hn->errflag = false;
|
||
|
hn->endflag = false;
|
||
|
|
||
|
return hn;
|
||
|
}
|
||
|
|
||
|
DF_OSXLIB_API char *os_readdir(df_os_dirhn hn)
|
||
|
{
|
||
|
if (hn->startflag) {
|
||
|
// Return first item found by _findfirst()
|
||
|
hn->startflag = false;
|
||
|
return hn->data.name;
|
||
|
}
|
||
|
|
||
|
// Reset status flags and advance directory iterator
|
||
|
hn->errflag = false;
|
||
|
hn->endflag = false;
|
||
|
|
||
|
int err = errno;
|
||
|
|
||
|
if (_findnext(hn->dirh, &hn->data) == -1) {
|
||
|
if (errno == ENOENT) {
|
||
|
// End of directory, this is not an error, restore old errno
|
||
|
errno = err;
|
||
|
hn->endflag = true;
|
||
|
} else {
|
||
|
hn->errflag = true;
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return hn->data.name;
|
||
|
}
|
||
|
|
||
|
DF_OSXLIB_API void os_closedir(df_os_dirhn hn)
|
||
|
{
|
||
|
_findclose(hn->dirh);
|
||
|
free(hn);
|
||
|
}
|