]> git.tdb.fi Git - libs/core.git/blob - source/dir.cpp
c402ec99ee2d61e95e930b07552a0437cbc2e77d
[libs/core.git] / source / dir.cpp
1 /* $Id$
2
3 This file is part of libmspfs
4 Copyright © 2006-2008  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <cstdlib>
9 #include <cerrno>
10 #include <dirent.h>
11 #include <sys/stat.h>
12 #include <msp/core/except.h>
13 #include "dir.h"
14 #include "path.h"
15 #include "stat.h"
16 #include "utils.h"
17
18 using namespace std;
19
20 namespace Msp {
21 namespace FS {
22
23 void mkdir(const Path &path, int mode)
24 {
25         int err;
26 #ifdef WIN32
27         // The win32 version of this function doesn't take the mode argument.  Go figure.
28         (void)mode;
29         err=::mkdir(path.str().c_str());
30 #else
31         err=::mkdir(path.str().c_str(), mode);
32 #endif
33
34         if(err==-1)
35                 throw SystemError("mkdir failed", errno);
36 }
37
38 /**
39 Creates a directory and any parent directories if needed.
40
41 @param   path  The path to create
42 @param   mode  Access mode for new directories
43
44 @return  0 on success, -1 on error
45 */
46 void mkpath(const Path &path, int mode)
47 {
48         Path p;
49         for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
50         {
51                 p/=*i;
52 #ifdef WIN32
53                 if(p.size()==1 && is_windows_drive(*i))
54                         continue;
55 #endif
56                 struct stat st;
57                 int err=stat(p, st);
58                 if(err==0)
59                 {
60                         if(!S_ISDIR(st.st_mode))
61                                 throw Exception("A component exists and is not a directory");
62                         continue;
63                 }
64                 else if(errno!=ENOENT)
65                         throw SystemError("stat failed", errno);
66                 else
67                         mkdir(p, mode);
68         }
69 }
70
71 void rmdir(const Path &path)
72 {
73         if(::rmdir(path.str().c_str())==-1)
74                 throw SystemError("rmdir failed", errno);
75 }
76
77 void rmdirs(const Path &path)
78 {
79         list<string> files=list_files(path);
80         for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
81         {
82                 Path p=path / *i;
83                 struct stat st=stat(p.str().c_str());
84                 if(S_ISDIR(st.st_mode))
85                         rmdirs(p);
86                 else
87                         unlink(p);
88         }
89
90         rmdir(path);
91 }
92
93 list<string> list_files(const Path &path)
94 {
95         list<string> result;
96         DIR *dir=opendir(path.str().c_str());
97         if(dir)
98         {
99                 while(dirent *de=readdir(dir))
100                 {
101                         const char *fn=de->d_name;
102                         if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0))) 
103                                 continue;
104                         result.push_back(fn);
105                 }
106                 closedir(dir);
107         }
108
109         return result;
110 }
111
112 Path getcwd()
113 {
114         char buf[1024];
115         return ::getcwd(buf, sizeof(buf));
116 }
117
118 Path get_home_dir()
119 {
120 #ifndef WIN32
121         const char *home=getenv("HOME");
122         if(home)
123                 return home;
124         return ".";
125 #else
126         return ".";
127 #endif
128 }
129
130 void chdir(const Path &path)
131 {
132         if(::chdir(path.str().c_str())==-1)
133                 throw SystemError("chdir failed", errno);
134 }
135
136 } // namespace FS
137 } // namespace Msp