181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott/* 281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott Implementation of POSIX directory browsing functions and types for Win32. 481ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 581ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) 681ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott History: Created March 1997. Updated June 2003 and July 2012. 781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott Rights: See end of file. 881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 981ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott*/ 10074e0d57090165249c35a135345959e36843a5e5Aaron Karp#include "dirent_on_windows.h" 1181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott#include <errno.h> 1281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */ 1381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott#include <stdlib.h> 1481ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott#include <string.h> 156fb9a531b82cc9e3c603486f70ef9f60e617c3aaJon Ashburn#include "vk_loader_platform.h" 16413d6587475294985134aa1f9052abd697b7a4e5Jon Ashburn#include "loader.h" 176fb9a531b82cc9e3c603486f70ef9f60e617c3aaJon Ashburn 1881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott#ifdef __cplusplus 1944aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburnextern "C" { 2081ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott#endif 2181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 2281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliotttypedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */ 2381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 2444aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburnstruct DIR { 2544aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn handle_type handle; /* -1 for failed rewind */ 2644aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn struct _finddata_t info; 2744aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn struct dirent result; /* d_name null iff first time */ 2844aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn char *name; /* null-terminated char string */ 2981ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott}; 3081ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 3144aed66f451bb8cb72e233f704aa1dd68397ffbbJon AshburnDIR *opendir(const char *name) { 3281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott DIR *dir = 0; 3381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 3444aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn if (name && name[0]) { 3581ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott size_t base_length = strlen(name); 3681ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott const char *all = /* search pattern must end with suitable wildcard */ 3781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott strchr("/\\", name[base_length - 1]) ? "*" : "/*"; 3881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 3974d013a5438f47a66a77d5375d1cdeef3f0beca7Mark Young if ((dir = (DIR *)loader_instance_tls_heap_alloc(sizeof *dir)) != 0 && 4074d013a5438f47a66a77d5375d1cdeef3f0beca7Mark Young (dir->name = (char *)loader_instance_tls_heap_alloc( 4174d013a5438f47a66a77d5375d1cdeef3f0beca7Mark Young base_length + strlen(all) + 1)) != 0) { 4281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott strcat(strcpy(dir->name, name), all); 4381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 4444aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn if ((dir->handle = 4544aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn (handle_type)_findfirst(dir->name, &dir->info)) != -1) { 4681ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott dir->result.d_name = 0; 4744aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn } else /* rollback */ 4881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott { 4974d013a5438f47a66a77d5375d1cdeef3f0beca7Mark Young loader_instance_tls_heap_free(dir->name); 5074d013a5438f47a66a77d5375d1cdeef3f0beca7Mark Young loader_instance_tls_heap_free(dir); 5181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott dir = 0; 5281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 5344aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn } else /* rollback */ 5481ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott { 5574d013a5438f47a66a77d5375d1cdeef3f0beca7Mark Young loader_instance_tls_heap_free(dir); 5644aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn dir = 0; 5781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott errno = ENOMEM; 5881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 5944aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn } else { 6081ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott errno = EINVAL; 6181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 6281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 6381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott return dir; 6481ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott} 6581ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 6644aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburnint closedir(DIR *dir) { 6781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott int result = -1; 6881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 6944aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn if (dir) { 7044aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn if (dir->handle != -1) { 7181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott result = _findclose(dir->handle); 7281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 7381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 7474d013a5438f47a66a77d5375d1cdeef3f0beca7Mark Young loader_instance_tls_heap_free(dir->name); 7574d013a5438f47a66a77d5375d1cdeef3f0beca7Mark Young loader_instance_tls_heap_free(dir); 7681ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 7781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 7844aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn if (result == -1) /* map all errors to EBADF */ 7981ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott { 8081ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott errno = EBADF; 8181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 8281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 8381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott return result; 8481ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott} 8581ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 8644aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburnstruct dirent *readdir(DIR *dir) { 8781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott struct dirent *result = 0; 8881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 8944aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn if (dir && dir->handle != -1) { 9044aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) { 9144aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn result = &dir->result; 9281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott result->d_name = dir->info.name; 9381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 9444aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn } else { 9581ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott errno = EBADF; 9681ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 9781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 9881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott return result; 9981ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott} 10081ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 10144aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburnvoid rewinddir(DIR *dir) { 10244aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn if (dir && dir->handle != -1) { 10381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott _findclose(dir->handle); 10444aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn dir->handle = (handle_type)_findfirst(dir->name, &dir->info); 10581ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott dir->result.d_name = 0; 10644aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn } else { 10781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott errno = EBADF; 10881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott } 10981ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott} 11081ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 11181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott#ifdef __cplusplus 11281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott} 11381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott#endif 11481ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 11581ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott/* 11681ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 11781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. 11844aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn Copyright (c) 2015 The Khronos Group Inc. 11944aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn Copyright (c) 2015 Valve Corporation 12044aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn Copyright (c) 2015 LunarG, Inc. 12181ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott Permission to use, copy, modify, and distribute this software and its 12281ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott documentation for any purpose is hereby granted without fee, provided 12381ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott that this copyright and permissions notice appear in all copies and 12481ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott derivatives. 12544aed66f451bb8cb72e233f704aa1dd68397ffbbJon Ashburn 12681ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott This software is supplied "as is" without express or implied warranty. 12781ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 12881ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott But that said, if there are any problems please get in touch. 12981ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott 13081ac44ce34f01f6462ce61ff44b34de5c44304abIan Elliott*/ 131