blob: 16318cc70d32c2a56002e007d0719300881aa298 [file] [log] [blame]
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001/*
2
3 Implementation of POSIX directory browsing functions and types for Win32.
4
5 Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
6 History: Created March 1997. Updated June 2003 and July 2012.
7 Rights: See end of file.
8
9*/
Aaron Karp848bad42016-03-13 16:41:59 -040010#include "dirent_on_windows.h"
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070011#include <errno.h>
12#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
13#include <stdlib.h>
14#include <string.h>
Jon Ashburn480a50a2015-08-28 14:58:46 -070015#include "vk_loader_platform.h"
Jon Ashburn87d6aa92015-08-28 15:19:27 -060016#include "loader.h"
Jon Ashburn480a50a2015-08-28 14:58:46 -070017
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070018#ifdef __cplusplus
Jon Ashburn23d36b12016-02-02 17:47:28 -070019extern "C" {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070020#endif
21
22typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */
23
Jon Ashburn23d36b12016-02-02 17:47:28 -070024struct DIR {
25 handle_type handle; /* -1 for failed rewind */
26 struct _finddata_t info;
27 struct dirent result; /* d_name null iff first time */
28 char *name; /* null-terminated char string */
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070029};
30
Jon Ashburn23d36b12016-02-02 17:47:28 -070031DIR *opendir(const char *name) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070032 DIR *dir = 0;
33
Jon Ashburn23d36b12016-02-02 17:47:28 -070034 if (name && name[0]) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070035 size_t base_length = strlen(name);
36 const char *all = /* search pattern must end with suitable wildcard */
37 strchr("/\\", name[base_length - 1]) ? "*" : "/*";
38
Mark Young0ad83132016-06-30 13:02:42 -060039 if ((dir = (DIR *)loader_instance_tls_heap_alloc(sizeof *dir)) != 0 &&
Mark Lobodzinski729a8d32017-01-26 12:16:30 -070040 (dir->name = (char *)loader_instance_tls_heap_alloc(base_length + strlen(all) + 1)) != 0) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070041 strcat(strcpy(dir->name, name), all);
42
Mark Lobodzinski729a8d32017-01-26 12:16:30 -070043 if ((dir->handle = (handle_type)_findfirst(dir->name, &dir->info)) != -1) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070044 dir->result.d_name = 0;
Jon Ashburn23d36b12016-02-02 17:47:28 -070045 } else /* rollback */
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070046 {
Mark Young0ad83132016-06-30 13:02:42 -060047 loader_instance_tls_heap_free(dir->name);
48 loader_instance_tls_heap_free(dir);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070049 dir = 0;
50 }
Jon Ashburn23d36b12016-02-02 17:47:28 -070051 } else /* rollback */
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070052 {
Mark Young0ad83132016-06-30 13:02:42 -060053 loader_instance_tls_heap_free(dir);
Jon Ashburn23d36b12016-02-02 17:47:28 -070054 dir = 0;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070055 errno = ENOMEM;
56 }
Jon Ashburn23d36b12016-02-02 17:47:28 -070057 } else {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070058 errno = EINVAL;
59 }
60
61 return dir;
62}
63
Jon Ashburn23d36b12016-02-02 17:47:28 -070064int closedir(DIR *dir) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070065 int result = -1;
66
Jon Ashburn23d36b12016-02-02 17:47:28 -070067 if (dir) {
68 if (dir->handle != -1) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070069 result = _findclose(dir->handle);
70 }
71
Mark Young0ad83132016-06-30 13:02:42 -060072 loader_instance_tls_heap_free(dir->name);
73 loader_instance_tls_heap_free(dir);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070074 }
75
Jon Ashburn23d36b12016-02-02 17:47:28 -070076 if (result == -1) /* map all errors to EBADF */
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070077 {
78 errno = EBADF;
79 }
80
81 return result;
82}
83
Jon Ashburn23d36b12016-02-02 17:47:28 -070084struct dirent *readdir(DIR *dir) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070085 struct dirent *result = 0;
86
Jon Ashburn23d36b12016-02-02 17:47:28 -070087 if (dir && dir->handle != -1) {
88 if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) {
89 result = &dir->result;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070090 result->d_name = dir->info.name;
91 }
Jon Ashburn23d36b12016-02-02 17:47:28 -070092 } else {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070093 errno = EBADF;
94 }
95
96 return result;
97}
98
Jon Ashburn23d36b12016-02-02 17:47:28 -070099void rewinddir(DIR *dir) {
100 if (dir && dir->handle != -1) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700101 _findclose(dir->handle);
Jon Ashburn23d36b12016-02-02 17:47:28 -0700102 dir->handle = (handle_type)_findfirst(dir->name, &dir->info);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700103 dir->result.d_name = 0;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700104 } else {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700105 errno = EBADF;
106 }
107}
108
109#ifdef __cplusplus
110}
111#endif
112
113/*
114
115 Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700116 Copyright (c) 2015 The Khronos Group Inc.
117 Copyright (c) 2015 Valve Corporation
118 Copyright (c) 2015 LunarG, Inc.
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700119 Permission to use, copy, modify, and distribute this software and its
120 documentation for any purpose is hereby granted without fee, provided
121 that this copyright and permissions notice appear in all copies and
122 derivatives.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700123
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700124 This software is supplied "as is" without express or implied warranty.
125
126 But that said, if there are any problems please get in touch.
127
128*/