41 #include "blocxx/BLOCXX_config.h"
68 using namespace BLOCXX_NAMESPACE;
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
213 #ifdef BLOCXX_NETWARE
214 #define MAXSYMLINKS 20
219 #include <sys/stat.h>
220 #include <sys/types.h>
228 namespace BLOCXX_NAMESPACE
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);
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);
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);