]> git.tdb.fi Git - libs/core.git/blob - fs/windows/dir.cpp
Check errors from CreateSemaphore
[libs/core.git] / fs / windows / dir.cpp
1 #include <windows.h>
2 #include <msp/core/mutex.h>
3 #include <msp/core/systemerror.h>
4 #include <msp/strings/regex.h>
5 #include "dir.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace FS {
11
12 void mkdir(const Path &path, int)
13 {
14         if(!CreateDirectory(path.str().c_str(), NULL))
15                 throw system_error("CreateDirectory");
16 }
17
18 void rmdir(const Path &path)
19 {
20         if(!RemoveDirectory(path.str().c_str()))
21                 throw system_error("RemoveDirectory");
22 }
23
24 vector<string> list_filtered(const Path &path, const string &filter)
25 {
26         Regex r_filter(filter);
27
28         vector<string> result;
29         WIN32_FIND_DATA entry;
30         string pattern = path.str()+"\\*";
31         HANDLE search_handle = FindFirstFileEx(pattern.c_str(), FindExInfoBasic, &entry, FindExSearchNameMatch, nullptr, 0);
32         if(search_handle==INVALID_HANDLE_VALUE)
33         {
34                 DWORD err = GetLastError();
35                 if(err==ERROR_FILE_NOT_FOUND)
36                         return result;
37                 throw system_error("FindFirstFileEx");
38         }
39
40         bool more = true;
41         for(; more; more=FindNextFile(search_handle, &entry))
42         {
43                 const char *fn = entry.cFileName;
44                 if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0)))
45                         continue;
46                 if(r_filter.match(fn))
47                         result.push_back(fn);
48         }
49
50         DWORD err = GetLastError();
51         FindClose(search_handle);
52         if(err!=ERROR_NO_MORE_FILES)
53                 throw system_error("FindNextFile");
54
55         return result;
56 }
57
58 /* Windows documentation says Get/SetCurrentDirectory use a global buffer and
59 are not thread safe. */
60 static Mutex &cwd_mutex()
61 {
62         static Mutex mutex;
63         return mutex;
64 }
65
66 Path getcwd()
67 {
68         MutexLock lock(cwd_mutex());
69
70         char buf[1024];
71         Path result;
72         DWORD len = GetCurrentDirectory(sizeof(buf), buf);
73         if(len>=sizeof(buf))
74         {
75                 vector<char> buf2(len+1);
76                 len = GetCurrentDirectory(buf2.size(), buf2.data());
77                 result = buf2.data();
78         }
79         else
80                 result = buf;
81
82         if(!len)
83                 throw system_error("GetCurrentDirectory");
84
85         return result;
86 }
87
88 void chdir(const Path &path)
89 {
90         MutexLock lock(cwd_mutex());
91         if(!SetCurrentDirectory(path.c_str()))
92                 throw system_error("SetCurrentDirectory");
93 }
94
95 } // namespace FS
96 } // namespace Msp