15db71995Sopenharmony_ci/*
25db71995Sopenharmony_ci
35db71995Sopenharmony_ci    Implementation of POSIX directory browsing functions and types for Win32.
45db71995Sopenharmony_ci
55db71995Sopenharmony_ci    Author:  Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
65db71995Sopenharmony_ci    History: Created March 1997. Updated June 2003 and July 2012.
75db71995Sopenharmony_ci    Rights:  See end of file.
85db71995Sopenharmony_ci
95db71995Sopenharmony_ci*/
105db71995Sopenharmony_ci#include "dirent_on_windows.h"
115db71995Sopenharmony_ci
125db71995Sopenharmony_ci#include <errno.h>
135db71995Sopenharmony_ci#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
145db71995Sopenharmony_ci#include <stdlib.h>
155db71995Sopenharmony_ci#include <string.h>
165db71995Sopenharmony_ci
175db71995Sopenharmony_ci#include "allocation.h"
185db71995Sopenharmony_ci
195db71995Sopenharmony_ci#if defined(__cplusplus)
205db71995Sopenharmony_ciextern "C" {
215db71995Sopenharmony_ci#endif
225db71995Sopenharmony_ci
235db71995Sopenharmony_citypedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */
245db71995Sopenharmony_ci
255db71995Sopenharmony_cistruct DIR {
265db71995Sopenharmony_ci    handle_type handle; /* -1 for failed rewind */
275db71995Sopenharmony_ci    struct _finddata_t info;
285db71995Sopenharmony_ci    struct dirent result; /* d_name null iff first time */
295db71995Sopenharmony_ci    char *name;           /* null-terminated char string */
305db71995Sopenharmony_ci};
315db71995Sopenharmony_ci
325db71995Sopenharmony_ciDIR *opendir(const VkAllocationCallbacks *pAllocator, const char *name) {
335db71995Sopenharmony_ci    DIR *dir = 0;
345db71995Sopenharmony_ci
355db71995Sopenharmony_ci    if (name && name[0]) {
365db71995Sopenharmony_ci        size_t base_length = strlen(name);
375db71995Sopenharmony_ci        const char *all = /* search pattern must end with suitable wildcard */
385db71995Sopenharmony_ci            strchr("/\\", name[base_length - 1]) ? "*" : "/*";
395db71995Sopenharmony_ci        size_t full_length = base_length + strlen(all) + 1;
405db71995Sopenharmony_ci
415db71995Sopenharmony_ci        if ((dir = (DIR *)loader_alloc(pAllocator, sizeof *dir, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)) != 0 &&
425db71995Sopenharmony_ci            (dir->name = (char *)loader_calloc(pAllocator, full_length, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)) != 0) {
435db71995Sopenharmony_ci            loader_strncpy(dir->name, full_length, name, base_length);
445db71995Sopenharmony_ci            loader_strncat(dir->name, full_length, all, strlen(all));
455db71995Sopenharmony_ci
465db71995Sopenharmony_ci            if ((dir->handle = (handle_type)_findfirst(dir->name, &dir->info)) != -1) {
475db71995Sopenharmony_ci                dir->result.d_name = 0;
485db71995Sopenharmony_ci            } else /* rollback */
495db71995Sopenharmony_ci            {
505db71995Sopenharmony_ci                loader_free(pAllocator, dir->name);
515db71995Sopenharmony_ci                loader_free(pAllocator, dir);
525db71995Sopenharmony_ci                dir = 0;
535db71995Sopenharmony_ci            }
545db71995Sopenharmony_ci        } else /* rollback */
555db71995Sopenharmony_ci        {
565db71995Sopenharmony_ci            loader_free(pAllocator, dir);
575db71995Sopenharmony_ci            dir = 0;
585db71995Sopenharmony_ci            errno = ENOMEM;
595db71995Sopenharmony_ci        }
605db71995Sopenharmony_ci    } else {
615db71995Sopenharmony_ci        errno = EINVAL;
625db71995Sopenharmony_ci    }
635db71995Sopenharmony_ci
645db71995Sopenharmony_ci    return dir;
655db71995Sopenharmony_ci}
665db71995Sopenharmony_ci
675db71995Sopenharmony_ciint closedir(const VkAllocationCallbacks *pAllocator, DIR *dir) {
685db71995Sopenharmony_ci    int result = -1;
695db71995Sopenharmony_ci
705db71995Sopenharmony_ci    if (dir) {
715db71995Sopenharmony_ci        if (dir->handle != -1) {
725db71995Sopenharmony_ci            result = _findclose(dir->handle);
735db71995Sopenharmony_ci        }
745db71995Sopenharmony_ci
755db71995Sopenharmony_ci        loader_free(pAllocator, dir->name);
765db71995Sopenharmony_ci        loader_free(pAllocator, dir);
775db71995Sopenharmony_ci    }
785db71995Sopenharmony_ci
795db71995Sopenharmony_ci    if (result == -1) /* map all errors to EBADF */
805db71995Sopenharmony_ci    {
815db71995Sopenharmony_ci        errno = EBADF;
825db71995Sopenharmony_ci    }
835db71995Sopenharmony_ci
845db71995Sopenharmony_ci    return result;
855db71995Sopenharmony_ci}
865db71995Sopenharmony_ci
875db71995Sopenharmony_cistruct dirent *readdir(DIR *dir) {
885db71995Sopenharmony_ci    struct dirent *result = 0;
895db71995Sopenharmony_ci
905db71995Sopenharmony_ci    if (dir && dir->handle != -1) {
915db71995Sopenharmony_ci        if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) {
925db71995Sopenharmony_ci            result = &dir->result;
935db71995Sopenharmony_ci            result->d_name = dir->info.name;
945db71995Sopenharmony_ci        }
955db71995Sopenharmony_ci    } else {
965db71995Sopenharmony_ci        errno = EBADF;
975db71995Sopenharmony_ci    }
985db71995Sopenharmony_ci
995db71995Sopenharmony_ci    return result;
1005db71995Sopenharmony_ci}
1015db71995Sopenharmony_ci
1025db71995Sopenharmony_civoid rewinddir(DIR *dir) {
1035db71995Sopenharmony_ci    if (dir && dir->handle != -1) {
1045db71995Sopenharmony_ci        _findclose(dir->handle);
1055db71995Sopenharmony_ci        dir->handle = (handle_type)_findfirst(dir->name, &dir->info);
1065db71995Sopenharmony_ci        dir->result.d_name = 0;
1075db71995Sopenharmony_ci    } else {
1085db71995Sopenharmony_ci        errno = EBADF;
1095db71995Sopenharmony_ci    }
1105db71995Sopenharmony_ci}
1115db71995Sopenharmony_ci
1125db71995Sopenharmony_ci#if defined(__cplusplus)
1135db71995Sopenharmony_ci}
1145db71995Sopenharmony_ci#endif
1155db71995Sopenharmony_ci
1165db71995Sopenharmony_ci/*
1175db71995Sopenharmony_ci
1185db71995Sopenharmony_ci    Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
1195db71995Sopenharmony_ci    Copyright (c) 2015 The Khronos Group Inc.
1205db71995Sopenharmony_ci    Copyright (c) 2015 Valve Corporation
1215db71995Sopenharmony_ci    Copyright (c) 2015 LunarG, Inc.
1225db71995Sopenharmony_ci    Permission to use, copy, modify, and distribute this software and its
1235db71995Sopenharmony_ci    documentation for any purpose is hereby granted without fee, provided
1245db71995Sopenharmony_ci    that this copyright and permissions notice appear in all copies and
1255db71995Sopenharmony_ci    derivatives.
1265db71995Sopenharmony_ci
1275db71995Sopenharmony_ci    This software is supplied "as is" without express or implied warranty.
1285db71995Sopenharmony_ci
1295db71995Sopenharmony_ci    But that said, if there are any problems please get in touch.
1305db71995Sopenharmony_ci
1315db71995Sopenharmony_ci*/
132