blob: 985fb6a1a765fc3cb84dddb3872a2253812dfd28 [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*/
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070010#include <dirent_on_windows.h>
11#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
Jon Ashburn23d36b12016-02-02 17:47:28 -070039 if ((dir = (DIR *)loader_tls_heap_alloc(sizeof *dir)) != 0 &&
40 (dir->name = (char *)loader_tls_heap_alloc(base_length +
41 strlen(all) + 1)) != 0) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070042 strcat(strcpy(dir->name, name), all);
43
Jon Ashburn23d36b12016-02-02 17:47:28 -070044 if ((dir->handle =
45 (handle_type)_findfirst(dir->name, &dir->info)) != -1) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070046 dir->result.d_name = 0;
Jon Ashburn23d36b12016-02-02 17:47:28 -070047 } else /* rollback */
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070048 {
Jon Ashburn87d6aa92015-08-28 15:19:27 -060049 loader_tls_heap_free(dir->name);
50 loader_tls_heap_free(dir);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070051 dir = 0;
52 }
Jon Ashburn23d36b12016-02-02 17:47:28 -070053 } else /* rollback */
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070054 {
Jon Ashburn87d6aa92015-08-28 15:19:27 -060055 loader_tls_heap_free(dir);
Jon Ashburn23d36b12016-02-02 17:47:28 -070056 dir = 0;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070057 errno = ENOMEM;
58 }
Jon Ashburn23d36b12016-02-02 17:47:28 -070059 } else {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070060 errno = EINVAL;
61 }
62
63 return dir;
64}
65
Jon Ashburn23d36b12016-02-02 17:47:28 -070066int closedir(DIR *dir) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070067 int result = -1;
68
Jon Ashburn23d36b12016-02-02 17:47:28 -070069 if (dir) {
70 if (dir->handle != -1) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070071 result = _findclose(dir->handle);
72 }
73
Mike Stroyan56118752015-10-06 10:16:47 -060074 loader_tls_heap_free(dir->name);
75 loader_tls_heap_free(dir);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070076 }
77
Jon Ashburn23d36b12016-02-02 17:47:28 -070078 if (result == -1) /* map all errors to EBADF */
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070079 {
80 errno = EBADF;
81 }
82
83 return result;
84}
85
Jon Ashburn23d36b12016-02-02 17:47:28 -070086struct dirent *readdir(DIR *dir) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070087 struct dirent *result = 0;
88
Jon Ashburn23d36b12016-02-02 17:47:28 -070089 if (dir && dir->handle != -1) {
90 if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) {
91 result = &dir->result;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070092 result->d_name = dir->info.name;
93 }
Jon Ashburn23d36b12016-02-02 17:47:28 -070094 } else {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070095 errno = EBADF;
96 }
97
98 return result;
99}
100
Jon Ashburn23d36b12016-02-02 17:47:28 -0700101void rewinddir(DIR *dir) {
102 if (dir && dir->handle != -1) {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700103 _findclose(dir->handle);
Jon Ashburn23d36b12016-02-02 17:47:28 -0700104 dir->handle = (handle_type)_findfirst(dir->name, &dir->info);
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700105 dir->result.d_name = 0;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700106 } else {
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700107 errno = EBADF;
108 }
109}
110
111#ifdef __cplusplus
112}
113#endif
114
115/*
116
117 Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700118 Copyright (c) 2015 The Khronos Group Inc.
119 Copyright (c) 2015 Valve Corporation
120 Copyright (c) 2015 LunarG, Inc.
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700121 Permission to use, copy, modify, and distribute this software and its
122 documentation for any purpose is hereby granted without fee, provided
123 that this copyright and permissions notice appear in all copies and
124 derivatives.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700125
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700126 This software is supplied "as is" without express or implied warranty.
127
128 But that said, if there are any problems please get in touch.
129
130*/