41#include "blocxx/BLOCXX_config.h"
71 static unsigned long MapPosixPermissionsMask( PACCESS_ALLOWED_ACE pAce,
int PermissionMask )
74 pAce->Mask |= ((PermissionMask & S_IROTH) == S_IROTH) ? BLOCXX_WIN32_ACCESSMASK_GENERIC_READ : 0;
75 pAce->Mask |= ((PermissionMask & S_IWOTH) == S_IWOTH) ? BLOCXX_WIN32_ACCESSMASK_GENERIC_WRITE : 0;
76 pAce->Mask |= ((PermissionMask & S_IXOTH) == S_IXOTH) ? BLOCXX_WIN32_ACCESSMASK_GENERIC_EXEC : 0;
86 static int posix_chmod(
const char* path,
int mode)
88 int result, nLenghtNeeded;
89 PSID ppOwnerSid = NULL, ppGroupSid = NULL, pSecurityDescriptor = NULL;
91 if ( (result = GetNamedSecurityInfo( (LPTSTR)path,
93 DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
98 &pSecurityDescriptor) ) )
106 for (
unsigned short aceIdx = 0; aceIdx < pAcl->AceCount; aceIdx++)
109 if (!::GetAce(pAcl, aceIdx, (
void**)&pAce))
113 switch( pAce->AceType )
115 case ACCESS_ALLOWED_ACE_TYPE:
117 PACCESS_ALLOWED_ACE pAllowedAce = (PACCESS_ALLOWED_ACE) pAce;
118 unsigned long sNameLen, sDNameLen = sNameLen = MAX_PATH;
119 char sName[MAX_PATH] = {0}, sDName[MAX_PATH] = {0};
122 if ( !::LookupAccountSid( NULL, &(pAllowedAce->SidStart), sName, &sNameLen, sDName, &sDNameLen, &eUse) )
127 if ( EqualSid( ppOwnerSid, &pAllowedAce->SidStart ) || (eUse == SidTypeWellKnownGroup && !strcmp(sName,
"CREATOR OWNER")) )
130 int hundreds = mode / 100;
131 MapPosixPermissionsMask( pAllowedAce, (hundreds - (hundreds/10)*10) );
134 if ( EqualSid( ppGroupSid, &pAllowedAce->SidStart ) || eUse == WinCreatorGroupSid )
137 int decimals = mode / 10;
138 MapPosixPermissionsMask( pAllowedAce, (decimals - (decimals/10)*10) );
142 MapPosixPermissionsMask( pAllowedAce, (mode - (mode/10)*10) );
146 case ACCESS_DENIED_ACE_TYPE:
152 DeleteAce(pAcl, aceIdx);
162 result = SetNamedSecurityInfo((LPTSTR)path,
164 PROTECTED_DACL_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
170 if (pSecurityDescriptor) LocalFree((HLOCAL)pSecurityDescriptor);
176 static int posix_mkdir(
const char* path,
int mode)
179 if ( result = _mkdir(path) )
return result;
185 return ((mode!=-1) ? result = posix_chmod(path, mode) : result);
189 #define _ACCESS ::_access
193 #define _CHDIR _chdir
194 #define _MKDIR(a,b) posix_mkdir((a), (b))
195 #define _RMDIR _rmdir
196 #define _UNLINK _unlink
200 #ifdef BLOCXX_HAVE_UNISTD_H
203 #ifdef BLOCXX_HAVE_DIRENT_H
207 #define _ACCESS ::access
209 #define _MKDIR(a,b) mkdir((a),(b))
211 #define _UNLINK unlink
214#define MAXSYMLINKS 20
220#include <sys/types.h>
250 return ::chown(filename.
c_str(), userId, gid_t(-1));
263 HANDLE fh = ::CreateFile(path.
c_str(), GENERIC_READ | GENERIC_WRITE,
264 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
265 FILE_ATTRIBUTE_NORMAL, NULL);
267 return (fh != INVALID_HANDLE_VALUE) ?
File(fh) :
File();
269 return File(::open(path.
c_str(), O_RDWR));
282 HANDLE fh = ::CreateFile(path.
c_str(), GENERIC_READ | GENERIC_WRITE,
283 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
284 FILE_ATTRIBUTE_NORMAL, NULL);
285 return (fh != INVALID_HANDLE_VALUE) ?
File(fh) :
File();
287 int fd = ::open(path.
c_str(), O_CREAT | O_EXCL | O_TRUNC | O_RDWR, 0660);
306 HANDLE fh = ::CreateFile(path.
c_str(), GENERIC_READ | GENERIC_WRITE,
307 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
308 FILE_ATTRIBUTE_NORMAL, NULL);
309 return (fh != INVALID_HANDLE_VALUE) ?
File(fh) :
File();
311 return File(::open(path.
c_str(), O_RDWR | O_CREAT, 0660));
327 HANDLE fh = ::CreateFile(path.
c_str(), FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | STANDARD_RIGHTS_WRITE | SYNCHRONIZE,
328 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS,
329 FILE_ATTRIBUTE_NORMAL, NULL);
330 return (fh != INVALID_HANDLE_VALUE) ?
File(fh) :
File();
332 return File(::open(path.
c_str(), O_WRONLY | O_APPEND | O_CREAT, 0660));
356 const char* envtmp = ::getenv(
"TMPDIR");
370 sfname = (dir.
endsWith(
'/')) ? dir : dir+
"/";
373 sfname +=
"blocxxtmpfileXXXXXX";
374 size_t len = sfname.
length();
379 int hdl = mkstemp(filename.
get());
384 filePath = filename.
get();
400 const char* envtmp = ::getenv(
"TMPDIR");
414 sfname = (dir.
endsWith(
'/')) ? dir : dir+
"/";
417 sfname +=
"blocxxtmpfileXXXXXX";
418 size_t len = sfname.
length();
422 int hdl = mkstemp(filename.
get());
429 if (::unlink(filename.
get()) != 0)
452 char envtmp[MAX_PATH];
453 rc = ::GetTempPath(MAX_PATH, envtmp);
467 sfname = (dir.
endsWith(
'/')) ? dir : dir+
"/";
470 char szTempName[MAX_PATH];
472 rc = ::GetTempFileName(sfname.
c_str(),
482 size_t len = sfname.
length();
489 GENERIC_READ | GENERIC_WRITE,
493 FILE_ATTRIBUTE_NORMAL,
495 if (hdl == INVALID_HANDLE_VALUE)
500 filePath = filename.get();
516 char envtmp[MAX_PATH];
517 rc = ::GetTempPath(MAX_PATH, envtmp);
531 sfname = (dir.
endsWith(
'/')) ? dir : dir+
"/";
534 char szTempName[MAX_PATH];
536 rc = ::GetTempFileName(sfname.
c_str(),
546 size_t len = sfname.
length();
553 GENERIC_READ | GENERIC_WRITE,
557 FILE_ATTRIBUTE_NORMAL,
559 if (hdl == INVALID_HANDLE_VALUE)
565 if (::unlink(filename.get()) != 0)
629 if (lstat(path.
c_str(), &st) != 0)
633 return S_ISLNK(st.st_mode);
646 if (_stat(path.
c_str(), &st) != 0)
650 return ((st.st_mode & _S_IFDIR) != 0);
653 if (stat(path.
c_str(), &st) != 0)
657 return S_ISDIR(st.st_mode);
690 if (_stat(path.
c_str(), &st) != 0)
696 if (stat(path.
c_str(), &st) != 0)
733 static Mutex readdirGuard;
737 struct _finddata_t dentry;
747 if ((hFile = _findfirst( _path.
c_str(), &dentry)) == -1L)
752 while (_findnext(hFile, &dentry) == 0)
759 struct dirent* dentry(0);
760 if ((dp = opendir(path.
c_str())) == NULL)
765 while ((dentry = readdir(dp)) != NULL)
776 const String& newFileName)
782 return ::rename(oldFileName.
c_str(), newFileName.
c_str()) == 0;
794 OVERLAPPED ov = { 0, 0, 0, 0, NULL };
795 OVERLAPPED *pov = NULL;
798 ov.Offset = (DWORD) offset;
800 if (ov.Offset != offset)
808 size_t cc = (size_t)-1;
809 if(::ReadFile(hdl, bfr, (DWORD)numberOfBytes, &bytesRead, pov))
811 cc = (size_t)bytesRead;
818 ::off_t offset2 =
static_cast< ::off_t
>(offset);
820 if (offset2 != offset)
825 ::lseek(hdl, offset2, SEEK_SET);
827 return ::read(hdl, bfr, numberOfBytes);
840 OVERLAPPED ov = { 0, 0, 0, 0, NULL };
841 OVERLAPPED *pov = NULL;
844 ov.Offset = (DWORD) offset;
846 if (ov.Offset != offset)
854 size_t cc = (size_t)-1;
855 if(::WriteFile(hdl, bfr, (DWORD)numberOfBytes, &bytesWritten, pov))
857 cc = (size_t)bytesWritten;
864 ::off_t offset2 =
static_cast< ::off_t
>(offset);
866 if (offset2 != offset)
870 ::lseek(hdl, offset2, SEEK_SET);
872 return ::write(hdl, bfr, numberOfBytes);
888 case SEEK_END: moveMethod = FILE_END;
break;
889 case SEEK_CUR: moveMethod = FILE_CURRENT;
break;
890 default: moveMethod = FILE_BEGIN;
break;
894 li.QuadPart = offset;
895 li.LowPart = SetFilePointer(hdl, li.LowPart, &li.HighPart, moveMethod);
897 if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
904 ::off_t offset2 =
static_cast< ::off_t
>(offset);
906 if (offset2 != offset)
910 return ::lseek(hdl, offset2, whence);
924 li.LowPart = SetFilePointer(hdl, li.LowPart, &li.HighPart, FILE_CURRENT);
926 if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
933 return ::lseek(hdl, 0, SEEK_CUR);
947 int rc = ::fstat(fh, &st);
955 LARGE_INTEGER FileSize;
956 BOOL rc = GetFileSizeEx(fh, &FileSize);
962 UInt64 tmp = FileSize.QuadPart;
976 ::SetFilePointer(hdl, 0L, NULL, FILE_BEGIN);
978 ::lseek(hdl, 0, SEEK_SET);
990 return (::CloseHandle(hdl)) ? 0 : -1;
1004 return (::FlushFileBuffers(hdl)) ? 0 : -1;
1006 return ::fsync(hdl);
1016 std::ifstream in(filename.
c_str());
1050 rc = ::readlink(path.
c_str(), &buf[0], buf.size());
1059 else if (
static_cast<unsigned>(rc) == buf.size())
1061 buf.resize(buf.size() * 2);
1066 buf.push_back(
'\0');
1087 char c, *bfr, *pname;
1088 const char *pathcstr;
1091 pathcstr = path.
c_str();
1092 while (*pathcstr ==
'/' || *pathcstr ==
'\\')
1099 if(pathcstr != path.
c_str())
1104 cc = GetFullPathName(path.
c_str(), 1, &c, &pname);
1110 cc = GetFullPathName(path.
c_str(), cc, bfr, &pname);
1139 if (filename.
length() == 0)
1143 size_t lastSlash = filename.
length() - 1;
1144 while (lastSlash > 0
1167 return filename.
substring(0, lastSlash);
1177 if (filename.
length() == 0)
1181 size_t end = filename.
length() -1;
1191 if (end == filename.
length() -1)
1219 p = ::getcwd(&buf[0], buf.size());
1224 buf.resize(buf.size() * 2);
1225 }
while (p == 0 && errno == ERANGE);
#define BLOCXX_DEFINE_EXCEPTION_WITH_ID(NAME)
Define a new exception class named <NAME>Exception that derives from Exception.
#define BLOCXX_THROW(exType, msg)
Throw an exception using FILE and LINE.
#define BLOCXX_THROW_ERRNO(exType)
Throw an exception using FILE, LINE, errno and strerror(errno)
#define BLOCXX_THROW_ERRNO_MSG(exType, msg)
Throw an exception using FILE, LINE, errno and strerror(errno)
#define BLOCXX_GLOBAL_MUTEX_INIT()
#define BLOCXX_GLOBAL_PTR_INIT
This macro is provided to abstract the details of GlobalPtr.
#define BLOCXX_GLOBAL_STRING_INIT(str)
#define BLOCXX_LOG_ERROR(logger, message)
Log message to logger with the Error level.
#define BLOCXX_FILENAME_SEPARATOR
#define BLOCXX_FILENAME_SEPARATOR_C
void append(const T &x)
Append an element to the end of the Array.
void clear()
Remove all items from the Array.
The AutoPtrVec class provides a simple class for smart pointers to a dynamically allocated array of o...
The purpose of the File class is to provide an abstraction layer over the platform dependant function...
This class can be used to store a global pointer.
This class can be used to store a global variable that is lazily initialized in a thread safe manner.
This String class is an abstract data type that represents as NULL terminated string of characters.
const char * c_str() const
String & erase()
Delete all the characters of the string.
String substring(size_t beginIndex, size_t length=npos) const
Create another String object that is comprised of a substring of this String object.
StringArray tokenize(const char *delims=" \n\r\t\v", EReturnDelimitersFlag returnDelimitersAsTokens=E_DISCARD_DELIMITERS, EEmptyTokenReturnFlag returnEmptyTokens=E_SKIP_EMPTY_TOKENS) const
Tokenize this String object using the given delimeters.
bool startsWith(const char *arg, EIgnoreCaseFlag ignoreCase=E_CASE_SENSITIVE) const
Determine if this String object starts with a given substring.
size_t lastIndexOf(char ch, size_t fromIndex=npos) const
Find the last occurence of a character in this String object.
bool endsWith(const char *arg, EIgnoreCaseFlag ignoreCase=E_CASE_SENSITIVE) const
Determine if this String object ends with given C string.
BLOCXX_COMMON_API String basename(const String &filename)
Take a string that contains a pathname, and return a string that is the filename with the path remove...
BLOCXX_COMMON_API String realPath(const String &path)
BLOCXX_COMMON_API std::pair< ESecurity, String > security(String const &path, UserId uid)
BLOCXX_COMMON_API String dirname(const String &filename)
Take a string that contains a pathname, and return a string that is a pathname of the parent director...
BLOCXX_COMMON_API String getCurrentWorkingDirectory()
Get the process's current working directory.
BLOCXX_COMMON_API int changeFileOwner(const String &filename, const UserId &userId)
Change the given file ownership.
GlobalString COMPONENT_NAME
BLOCXX_COMMON_API void rewind(const FileHandle &hdl)
Position the file pointer associated with the given file handle to the beginning of the file.
BLOCXX_COMMON_API File createFile(const String &path)
Create the file for the given name.
BLOCXX_COMMON_API File openForAppendOrCreateFile(const String &path)
Opens the file for the given name to append data or create if it does not exist.
BLOCXX_COMMON_API size_t read(const FileHandle &hdl, void *bfr, size_t numberOfBytes, Int64 offset=-1L)
Read data from file.
BLOCXX_COMMON_API bool canRead(const String &path)
BLOCXX_COMMON_API bool isLink(const String &path)
Tests if a file is a symbolic link.
BLOCXX_COMMON_API bool exists(const String &path)
BLOCXX_COMMON_API bool removeFile(const String &path)
Remove the given file.
BLOCXX_COMMON_API bool getFileSize(const String &path, Int64 &size)
Get the size of the file in bytes.
BLOCXX_COMMON_API bool getDirectoryContents(const String &path, StringArray &dirEntries)
Get the names of the files (and directories) in the given directory.
BLOCXX_COMMON_API File createAutoDeleteTempFile(const String &dir=String())
Create a tempororary file that will be removed when the returned File object is closed.
BLOCXX_COMMON_API String readSymbolicLink(const String &path)
Read the value of a symbolic link.
BLOCXX_COMMON_API Int64 seek(const FileHandle &hdl, Int64 offset, int whence)
Seek to a given offset within the file.
BLOCXX_COMMON_API int close(const FileHandle &hdl)
Close file handle.
BLOCXX_COMMON_API size_t write(FileHandle hdl, const void *bfr, size_t numberOfBytes, Int64 offset=-1L)
Write data to a file.
BLOCXX_COMMON_API bool renameFile(const String &oldFileName, const String &newFileName)
Rename the given file to the new name.
BLOCXX_COMMON_API bool isExecutable(const String &path)
Tests if a file is executable.
BLOCXX_COMMON_API bool canWrite(const String &path)
BLOCXX_COMMON_API File openOrCreateFile(const String &path)
Opens or creates the file for the given name.
FileSystemMockObject_t g_fileSystemMockObject
BLOCXX_COMMON_API File createTempFile(String &filePath, const String &dir=String())
Create a tempororary file in an optional directory.
BLOCXX_COMMON_API Int64 tell(const FileHandle &hdl)
BLOCXX_COMMON_API UInt64 fileSize(FileHandle fh)
Get the size of a file from the file handle.
BLOCXX_COMMON_API bool isDirectory(const String &path)
BLOCXX_COMMON_API int flush(FileHandle &hdl)
Flush any buffered data to the file if buffering supported.
BLOCXX_COMMON_API StringArray getFileLines(const String &filename)
Read and return the lines of a test file.
GlobalPtr< FileSystemMockObject, NullFactory > FileSystemMockObject_t
BLOCXX_COMMON_API bool changeDirectory(const String &path)
Change to the given directory.
BLOCXX_COMMON_API File openFile(const String &path)
Open a file for read/write and return an File object that can be used for reading and writing.
BLOCXX_COMMON_API String getFileContents(const String &filename)
Read and return the contents of a text file.
BLOCXX_COMMON_API bool removeDirectory(const String &path)
Remove the given directory.
BLOCXX_COMMON_API bool makeDirectory(const String &path, int mode=0777)
Create a directory.
char * strcpy_check(char *dst, std::size_t dstsize, char const *src)
PROMISE: copies the first n = min(strlen(src), dstsize - 1) chars of the C-string src to dst and appe...