32 #ifndef _QORE_QORE_QD_PRIVATE_H 34 #define _QORE_QORE_QD_PRIVATE_H 44 #include <sys/types.h> 48 static int mkdir(
const char *path, mode_t mode) {
53 class qore_qd_private {
59 DLLLOCAL
static bool is_dir_sep(
const std::string& str) {
60 for (std::string::size_type i = 0, e = str.size(); i < e; ++i) {
62 if (str[i] !=
'\\' && str[i] !=
'/')
65 if (str[i] != QORE_DIR_SEP)
72 DLLLOCAL
static std::string::size_type get_first_non_dir_sep(
const std::string& str, std::string::size_type pos = 0) {
73 for (std::string::size_type i = pos, e = str.size(); i < e; ++i) {
75 if (str[i] !=
'\\' && str[i] !=
'/')
78 if (str[i] != QORE_DIR_SEP)
82 return std::string::npos;
85 DLLLOCAL
static std::string::size_type get_first_dir_sep(
const std::string& str, std::string::size_type pos = 0) {
86 for (std::string::size_type i = pos, e = str.size(); i < e; ++i) {
88 if (str[i] ==
'\\' || str[i] ==
'/')
91 if (str[i] == QORE_DIR_SEP)
95 return std::string::npos;
99 DLLLOCAL
static void tokenize(
const std::string& str,
name_vec_t& tokens) {
101 if (is_dir_sep(str)) {
102 tokens.push_back(QORE_DIR_SEP_STR);
107 std::string::size_type lastPos = get_first_non_dir_sep(str, 0);
109 std::string::size_type pos = get_first_dir_sep(str, lastPos);
111 while (std::string::npos != pos || std::string::npos != lastPos) {
113 tokens.push_back(str.substr(lastPos, pos - lastPos));
115 lastPos = get_first_non_dir_sep(str, pos);
117 pos = get_first_dir_sep(str, lastPos);
124 DLLLOCAL
static int verifyDirectory(
const std::string &dir) {
126 dptr = opendir(dir.c_str());
137 DLLLOCAL std::string getPathIntern(
const char *sub)
const {
138 if (!dirname.empty())
139 return dirname + QORE_DIR_SEP_STR + std::string(sub);
140 return std::string(sub);
147 DLLLOCAL
int checkPathIntern()
const {
148 return dirname.empty() ? -1 : verifyDirectory(dirname);
159 char *cwd = (
char*)malloc(
sizeof(
char)*QORE_PATH_MAX);
164 ON_BLOCK_EXIT(free, cwd);
166 if (getcwd(cwd, (
size_t)QORE_PATH_MAX))
170 DLLLOCAL qore_qd_private(
ExceptionSink *xsink,
const qore_qd_private &old) {
173 dirname = old.dirname;
181 DLLLOCAL std::string getPath(
const char *sub)
const {
184 return getPathIntern(sub);
187 DLLLOCAL
int checkPath()
const {
190 return checkPathIntern();
199 if (ndir[0] ==
'.') {
200 const char* p = ndir + 1;
202 while (*p && (*p ==
'\\' || *p ==
'/'))
204 while (*p && *p == QORE_DIR_SEP)
216 if (dirname.empty()) {
217 xsink->
raiseException(
"DIR-CHDIR-ERROR",
"cannot change to relative directory because no current directory is set");
221 ds = dirname + QORE_DIR_SEP + std::string(ndir);
226 ds = normalizePath(ds);
231 return checkPathIntern();
234 DLLLOCAL
int mkdir(
const char *subdir,
int mode,
ExceptionSink *xsink)
const {
238 std::string path = getPathIntern(subdir);
239 if (::mkdir(path.c_str(), mode)) {
240 xsink->
raiseErrnoException(
"DIR-MKDIR-FAILURE", errno,
"error creating directory '%s'", path.c_str());
246 DLLLOCAL
int rmdir(
const char *subdir,
ExceptionSink *xsink)
const {
250 std::string path = getPathIntern(subdir);
251 if (::rmdir(path.c_str())) {
252 xsink->
raiseErrnoException(
"DIR-RMDIR-FAILURE", errno,
"error removing directory '%s'", path.c_str());
264 if (dirname.empty()) {
265 xsink->
raiseException(
"DIR-CREATE-ERROR",
"cannot create directory; no directory is set");
271 bool unc = (dirname[0] ==
'/' || dirname[0] ==
'\\')
272 && (dirname[1] ==
'/' || dirname[1] ==
'\\')
273 && (dirname[2] !=
'/' && dirname[2] !=
'\\');
278 tokenize(dirname, dirs);
282 name_vec_t::iterator it;
291 for (it = dirs.begin(); it < dirs.end(); it++) {
293 if (it == dirs.begin() && abs)
297 path += QORE_DIR_SEP_STR + (*it);
300 if (unc && cnt < 2) {
305 if (verifyDirectory(path)) {
306 if (::mkdir(path.c_str(), mode)) {
307 xsink->
raiseErrnoException(
"DIR-CREATE-FAILURE", errno,
"cannot mkdir '%s'", path.c_str());
320 if (dirname.empty()) {
321 xsink->
raiseException(
"DIR-CHMOD-ERROR",
"cannot change directory mode; no directory is set");
325 if (::chmod(dirname.c_str(), mode)) {
326 xsink->
raiseErrnoException(
"DIR-CHMOD-FAILURE", errno,
"error in Dir::chmod() on '%s'", dirname.c_str());
334 DLLLOCAL
int chown(uid_t uid, gid_t gid,
ExceptionSink *xsink)
const {
337 if (dirname.empty()) {
338 xsink->
raiseException(
"DIR-CHOWN-ERROR",
"cannot change directory ownership; no directory is set");
342 if (::chown(dirname.c_str(), uid, gid)) {
343 xsink->
raiseErrnoException(
"DIR-CHOWN-FAILURE", errno,
"error in Dir::chown() on '%s'", dirname.c_str());
354 if (dirname.empty()) {
355 xsink->
raiseException(
"DIR-STAT-ERROR",
"cannot stat; no directory is set");
360 if (::stat(dirname.c_str(), &sbuf)) {
361 xsink->
raiseErrnoException(
"DIR-STAT-FAILURE", errno,
"stat() call failed on '%s'", dirname.c_str());
365 return stat_to_list(sbuf);
370 #ifdef Q_HAVE_STATVFS 374 if (dirname.empty()) {
375 xsink->
raiseException(
"DIR-STATVFS-ERROR",
"cannot execute File::statvfs(); no directory is set");
379 hashdecl statvfs vfs;
380 if (::statvfs(dirname.c_str(), &vfs)) {
381 xsink->
raiseErrnoException(
"DIR-STATVFS-FAILURE", errno,
"statvfs() call failed on '%s'", dirname.c_str());
385 return statvfs_to_hash(vfs);
394 DLLLOCAL
static int lstat(
const char* str,
struct stat& buf,
ExceptionSink *xsink) {
395 int rc = ::lstat(str, &buf);
404 DLLLOCAL
static int stat(
const char* str,
struct stat& buf,
ExceptionSink *xsink) {
405 int rc = ::stat(str, &buf);
414 DLLLOCAL
static const std::string normalizePath(
const std::string& odir) {
417 bool unc = (odir[0] ==
'/' || odir[0] ==
'\\')
418 && (odir[1] ==
'/' || odir[1] ==
'\\')
419 && (odir[2] !=
'/' && odir[2] !=
'\\');
424 tokenize(odir, ptoken);
427 for (name_vec_t::iterator it = ptoken.begin(), et = ptoken.end(); it != et; ++it) {
429 if (d ==
"." || d ==
"")
432 if (d ==
".." && !dirs.empty())
446 for (name_vec_t::iterator it = dirs.begin(), et = dirs.end(); it != et; ++it) {
448 if (it == dirs.begin() && abs)
452 ret += QORE_DIR_SEP_STR + (*it);
DLLEXPORT void outOfMemory()
intended to be used to handle out of memory errors FIXME: not yet fully implemented ...
defines string encoding functions in Qore
Definition: QoreEncoding.h:83
This is the hash or associative list container type in Qore, dynamically allocated only...
Definition: QoreHashNode.h:50
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
DLLEXPORT AbstractQoreNode * raiseErrnoException(const char *err, int en, const char *fmt,...)
appends a Qore-language exception to the list and appends the result of strerror(errno) to the descri...
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:81
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:128
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
std::vector< std::string > name_vec_t
vector of parameter names for parameter lists
Definition: common.h:257
DLLEXPORT bool q_absolute_path_windows(const char *path)
returns true if the given string is an absolute path on Windows systems
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:47
DLLEXPORT bool q_absolute_path(const char *path)
returns true if the given string is an absolute path on the current platform