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());
136 DLLLOCAL std::string getPathIntern(
const char* sub)
const {
137 if (!dirname.empty())
138 return dirname + QORE_DIR_SEP_STR + std::string(sub);
139 return std::string(sub);
146 DLLLOCAL
int checkPathIntern()
const {
147 return dirname.empty() ? -1 : verifyDirectory(dirname);
158 char* cwd = (
char*)malloc(
sizeof(
char)*QORE_PATH_MAX);
163 ON_BLOCK_EXIT(free, cwd);
165 if (getcwd(cwd, (
size_t)QORE_PATH_MAX))
169 DLLLOCAL qore_qd_private(
ExceptionSink* xsink,
const qore_qd_private &old) {
172 dirname = old.dirname;
180 DLLLOCAL std::string getPath(
const char* sub)
const {
183 return getPathIntern(sub);
186 DLLLOCAL
int checkPath()
const {
189 return checkPathIntern();
193 DLLLOCAL
int chdir(
const char* ndir,
ExceptionSink* xsink =
nullptr) {
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()) {
218 xsink->
raiseException(
"DIR-CHDIR-ERROR",
"cannot change to relative directory because no current directory is set");
223 ds = dirname + QORE_DIR_SEP + std::string(ndir);
227 ds = normalizePath(ds);
232 return checkPathIntern();
235 DLLLOCAL
int mkdir(
const char* subdir,
int mode,
ExceptionSink* xsink)
const {
239 std::string path = getPathIntern(subdir);
240 if (::mkdir(path.c_str(), mode)) {
241 xsink->
raiseErrnoException(
"DIR-MKDIR-FAILURE", errno,
"error creating directory '%s'", path.c_str());
247 DLLLOCAL
int rmdir(
const char* subdir,
ExceptionSink* xsink)
const {
251 std::string path = getPathIntern(subdir);
252 if (::rmdir(path.c_str())) {
253 xsink->
raiseErrnoException(
"DIR-RMDIR-FAILURE", errno,
"error removing directory '%s'", path.c_str());
262 DLLLOCAL
int create(
int mode,
ExceptionSink* xsink =
nullptr)
const {
265 if (dirname.empty()) {
267 xsink->
raiseException(
"DIR-CREATE-ERROR",
"cannot create directory; no directory is set");
274 bool unc = (dirname[0] ==
'/' || dirname[0] ==
'\\')
275 && (dirname[1] ==
'/' || dirname[1] ==
'\\')
276 && (dirname[2] !=
'/' && dirname[2] !=
'\\');
281 tokenize(dirname, dirs);
285 name_vec_t::iterator it;
294 for (it = dirs.begin(); it < dirs.end(); it++) {
296 if (it == dirs.begin() && abs)
300 path += QORE_DIR_SEP_STR + (*it);
303 if (unc && cnt < 2) {
308 if (verifyDirectory(path)) {
309 if (::mkdir(path.c_str(), mode)) {
311 xsink->
raiseErrnoException(
"DIR-CREATE-FAILURE", errno,
"cannot mkdir '%s'", path.c_str());
325 if (dirname.empty()) {
326 xsink->
raiseException(
"DIR-CHMOD-ERROR",
"cannot change directory mode; no directory is set");
330 if (::chmod(dirname.c_str(), mode)) {
331 xsink->
raiseErrnoException(
"DIR-CHMOD-FAILURE", errno,
"error in Dir::chmod() on '%s'", dirname.c_str());
339 DLLLOCAL
int chown(uid_t uid, gid_t gid,
ExceptionSink* xsink)
const {
342 if (dirname.empty()) {
343 xsink->
raiseException(
"DIR-CHOWN-ERROR",
"cannot change directory ownership; no directory is set");
347 if (::chown(dirname.c_str(), uid, gid)) {
348 xsink->
raiseErrnoException(
"DIR-CHOWN-FAILURE", errno,
"error in Dir::chown() on '%s'", dirname.c_str());
359 if (dirname.empty()) {
360 xsink->
raiseException(
"DIR-STAT-ERROR",
"cannot stat; no directory is set");
365 if (::stat(dirname.c_str(), &sbuf)) {
366 xsink->
raiseErrnoException(
"DIR-STAT-FAILURE", errno,
"stat() call failed on '%s'", dirname.c_str());
370 return stat_to_list(sbuf);
375 #ifdef Q_HAVE_STATVFS
379 if (dirname.empty()) {
380 xsink->
raiseException(
"DIR-STATVFS-ERROR",
"cannot execute File::statvfs(); no directory is set");
384 hashdecl statvfs vfs;
385 if (::statvfs(dirname.c_str(), &vfs)) {
386 xsink->
raiseErrnoException(
"DIR-STATVFS-FAILURE", errno,
"statvfs() call failed on '%s'", dirname.c_str());
390 return statvfs_to_hash(vfs);
399 DLLLOCAL
static int lstat(
const char* str,
struct stat& buf,
ExceptionSink* xsink) {
400 int rc = ::lstat(str, &buf);
409 DLLLOCAL
static int stat(
const char* str,
struct stat& buf,
ExceptionSink* xsink) {
410 int rc = ::stat(str, &buf);
419 DLLLOCAL
static const std::string normalizePath(
const std::string& odir) {
422 bool unc = (odir[0] ==
'/' || odir[0] ==
'\\')
423 && (odir[1] ==
'/' || odir[1] ==
'\\')
424 && (odir[2] !=
'/' && odir[2] !=
'\\');
429 tokenize(odir, ptoken);
432 for (name_vec_t::iterator it = ptoken.begin(), et = ptoken.end(); it != et; ++it) {
434 if (d ==
"." || d ==
"")
437 if (d ==
".." && !dirs.empty())
451 for (name_vec_t::iterator it = dirs.begin(), et = dirs.end(); it != et; ++it) {
453 if (it == dirs.begin() && abs)
457 ret += QORE_DIR_SEP_STR + (*it);
DLLEXPORT bool q_absolute_path_windows(const char *path)
returns true if the given string is an absolute path on Windows systems
DLLEXPORT bool q_absolute_path(const char *path)
returns true if the given string is an absolute path on the current platform
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:136
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
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...
DLLEXPORT void outOfMemory()
intended to be used to handle out of memory errors
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
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
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:49
std::vector< std::string > name_vec_t
vector of parameter names for parameter lists
Definition: common.h:257