ded

Dramatic EDitor
Index Commits Files Refs README LICENSE
src/minirent.h (3692B)
   1 // Copyright 2021 Alexey Kutepov <reximkut@gmail.com>
   2 //
   3 // Permission is hereby granted, free of charge, to any person obtaining
   4 // a copy of this software and associated documentation files (the
   5 // "Software"), to deal in the Software without restriction, including
   6 // without limitation the rights to use, copy, modify, merge, publish,
   7 // distribute, sublicense, and/or sell copies of the Software, and to
   8 // permit persons to whom the Software is furnished to do so, subject to
   9 // the following conditions:
  10 //
  11 // The above copyright notice and this permission notice shall be
  12 // included in all copies or substantial portions of the Software.
  13 //
  14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21 //
  22 // ============================================================
  23 //
  24 // minirent — 0.0.1 — A subset of dirent interface for Windows.
  25 //
  26 // https://github.com/tsoding/minirent
  27 //
  28 // ============================================================
  29 //
  30 // ChangeLog (https://semver.org/ is implied)
  31 //
  32 //    0.0.1 First Official Release
  33 
  34 #ifndef MINIRENT_H_
  35 #define MINIRENT_H_
  36 
  37 #define WIN32_LEAN_AND_MEAN
  38 #include "windows.h"
  39 
  40 struct dirent
  41 {
  42     char d_name[MAX_PATH+1];
  43 };
  44 
  45 typedef struct DIR DIR;
  46 
  47 DIR *opendir(const char *dirpath);
  48 struct dirent *readdir(DIR *dirp);
  49 int closedir(DIR *dirp);
  50 
  51 #endif  // MINIRENT_H_
  52 
  53 #ifdef MINIRENT_IMPLEMENTATION
  54 
  55 struct DIR
  56 {
  57     HANDLE hFind;
  58     WIN32_FIND_DATA data;
  59     struct dirent *dirent;
  60 };
  61 
  62 DIR *opendir(const char *dirpath)
  63 {
  64     assert(dirpath);
  65 
  66     char buffer[MAX_PATH];
  67     snprintf(buffer, MAX_PATH, "%s\\*", dirpath);
  68 
  69     DIR *dir = (DIR*)calloc(1, sizeof(DIR));
  70 
  71     dir->hFind = FindFirstFile(buffer, &dir->data);
  72     if (dir->hFind == INVALID_HANDLE_VALUE) {
  73         // TODO: opendir should set errno accordingly on FindFirstFile fail
  74         // https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror
  75         errno = ENOSYS;
  76         goto fail;
  77     }
  78 
  79     return dir;
  80 
  81 fail:
  82     if (dir) {
  83         free(dir);
  84     }
  85 
  86     return NULL;
  87 }
  88 
  89 struct dirent *readdir(DIR *dirp)
  90 {
  91     assert(dirp);
  92 
  93     if (dirp->dirent == NULL) {
  94         dirp->dirent = (struct dirent*)calloc(1, sizeof(struct dirent));
  95     } else {
  96         if(!FindNextFile(dirp->hFind, &dirp->data)) {
  97             if (GetLastError() != ERROR_NO_MORE_FILES) {
  98                 // TODO: readdir should set errno accordingly on FindNextFile fail
  99                 // https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror
 100                 errno = ENOSYS;
 101             }
 102 
 103             return NULL;
 104         }
 105     }
 106 
 107     memset(dirp->dirent->d_name, 0, sizeof(dirp->dirent->d_name));
 108 
 109     strncpy(
 110         dirp->dirent->d_name,
 111         dirp->data.cFileName,
 112         sizeof(dirp->dirent->d_name) - 1);
 113 
 114     return dirp->dirent;
 115 }
 116 
 117 int closedir(DIR *dirp)
 118 {
 119     assert(dirp);
 120 
 121     if(!FindClose(dirp->hFind)) {
 122         // TODO: closedir should set errno accordingly on FindClose fail
 123         // https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror
 124         errno = ENOSYS;
 125         return -1;
 126     }
 127 
 128     if (dirp->dirent) {
 129         free(dirp->dirent);
 130     }
 131     free(dirp);
 132 
 133     return 0;
 134 }
 135 
 136 #endif  // MINIRENT_IMPLEMENTATION