src/jdk.packager/share/native/library/common/FilePath.cpp
branchJDK-8200758-branch
changeset 56982 e094d5483bd6
parent 56854 aedce3eaaf17
child 56993 3629eb24e9ac
equal deleted inserted replaced
56963:eaca4369b068 56982:e094d5483bd6
    28 #include <algorithm>
    28 #include <algorithm>
    29 #include <list>
    29 #include <list>
    30 
    30 
    31 #ifdef WINDOWS
    31 #ifdef WINDOWS
    32 #include <ShellAPI.h>
    32 #include <ShellAPI.h>
    33 #endif //WINDOWS
    33 #endif // WINDOWS
    34 
    34 
    35 #ifdef POSIX
    35 #ifdef POSIX
    36 #include <sys/stat.h>
    36 #include <sys/stat.h>
    37 #endif //POSIX
    37 #endif // POSIX
    38 
    38 
    39 
    39 
    40 bool FilePath::FileExists(const TString FileName) {
    40 bool FilePath::FileExists(const TString FileName) {
    41     bool result = false;
    41     bool result = false;
    42 #ifdef WINDOWS
    42 #ifdef WINDOWS
    52             result = true;
    52             result = true;
    53         }
    53         }
    54 
    54 
    55         FindClose(handle);
    55         FindClose(handle);
    56     }
    56     }
    57 #endif //WINDOWS
    57 #endif // WINDOWS
    58 #ifdef POSIX
    58 #ifdef POSIX
    59     struct stat buf;
    59     struct stat buf;
    60 
    60 
    61     if ((stat(StringToFileSystemString(FileName), &buf) == 0) && (S_ISREG(buf.st_mode) != 0)) {
    61     if ((stat(StringToFileSystemString(FileName), &buf) == 0) &&
       
    62             (S_ISREG(buf.st_mode) != 0)) {
    62         result = true;
    63         result = true;
    63     }
    64     }
    64 #endif //POSIX
    65 #endif // POSIX
    65     return result;
    66     return result;
    66 }
    67 }
    67 
    68 
    68 bool FilePath::DirectoryExists(const TString DirectoryName) {
    69 bool FilePath::DirectoryExists(const TString DirectoryName) {
    69     bool result = false;
    70     bool result = false;
    77             result = true;
    78             result = true;
    78         }
    79         }
    79 
    80 
    80         FindClose(handle);
    81         FindClose(handle);
    81     }
    82     }
    82 #endif //WINDOWS
    83 #endif // WINDOWS
    83 #ifdef POSIX
    84 #ifdef POSIX
    84     struct stat buf;
    85     struct stat buf;
    85 
    86 
    86     if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) && (S_ISDIR(buf.st_mode) != 0)) {
    87     if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) &&
       
    88             (S_ISDIR(buf.st_mode) != 0)) {
    87         result = true;
    89         result = true;
    88     }
    90     }
    89 #endif //POSIX
    91 #endif // POSIX
    90     return result;
    92     return result;
    91 }
    93 }
    92 
    94 
    93 #ifdef WINDOWS
    95 #ifdef WINDOWS
    94 std::string GetLastErrorAsString() {
    96 std::string GetLastErrorAsString() {
    95     //Get the error message, if any.
    97     // Get the error message, if any.
    96     DWORD errorMessageID = ::GetLastError();
    98     DWORD errorMessageID = ::GetLastError();
    97 
    99 
    98     if (errorMessageID == 0) {
   100     if (errorMessageID == 0) {
    99         return "No error message has been recorded";
   101         return "No error message has been recorded";
   100     }
   102     }
   101 
   103 
   102     LPSTR messageBuffer = NULL;
   104     LPSTR messageBuffer = NULL;
   103     size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
   105     size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
   104                                  NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
   106             | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
       
   107             NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL,
       
   108             SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
   105 
   109 
   106     std::string message(messageBuffer, size);
   110     std::string message(messageBuffer, size);
   107 
   111 
   108     // Free the buffer.
   112     // Free the buffer.
   109     LocalFree(messageBuffer);
   113     LocalFree(messageBuffer);
   110 
   114 
   111     return message;
   115     return message;
   112 }
   116 }
   113 #endif //WINDOWS
   117 #endif // WINDOWS
   114 
   118 
   115 bool FilePath::DeleteFile(const TString FileName) {
   119 bool FilePath::DeleteFile(const TString FileName) {
   116     bool result = false;
   120     bool result = false;
   117 
   121 
   118     if (FileExists(FileName) == true) {
   122     if (FileExists(FileName) == true) {
   123         if (attributes.Contains(faReadOnly) == true) {
   127         if (attributes.Contains(faReadOnly) == true) {
   124             attributes.Remove(faReadOnly);
   128             attributes.Remove(faReadOnly);
   125         }
   129         }
   126 
   130 
   127         result = ::DeleteFile(lFileName.data()) == TRUE;
   131         result = ::DeleteFile(lFileName.data()) == TRUE;
   128 #endif //WINDOWS
   132 #endif // WINDOWS
   129 #ifdef POSIX
   133 #ifdef POSIX
   130         if (unlink(StringToFileSystemString(FileName)) == 0) {
   134         if (unlink(StringToFileSystemString(FileName)) == 0) {
   131             result = true;
   135             result = true;
   132         }
   136         }
   133 #endif //POSIX
   137 #endif // POSIX
   134     }
   138     }
   135 
   139 
   136     return result;
   140     return result;
   137 }
   141 }
   138 
   142 
   143 #ifdef WINDOWS
   147 #ifdef WINDOWS
   144         SHFILEOPSTRUCTW fos = {0};
   148         SHFILEOPSTRUCTW fos = {0};
   145         TString directoryName = FixPathForPlatform(DirectoryName);
   149         TString directoryName = FixPathForPlatform(DirectoryName);
   146         DynamicBuffer<TCHAR> lDirectoryName(directoryName.size() + 2);
   150         DynamicBuffer<TCHAR> lDirectoryName(directoryName.size() + 2);
   147         memcpy(lDirectoryName.GetData(), directoryName.data(), (directoryName.size() + 2) * sizeof(TCHAR));
   151         memcpy(lDirectoryName.GetData(), directoryName.data(), (directoryName.size() + 2) * sizeof(TCHAR));
   148         lDirectoryName[directoryName.size() + 1] = NULL; // Double null terminate for SHFileOperation.
   152         lDirectoryName[directoryName.size() + 1] = NULL;
       
   153         // Double null terminate for SHFileOperation.
   149 
   154 
   150         // Delete the folder and everything inside.
   155         // Delete the folder and everything inside.
   151         fos.wFunc = FO_DELETE;
   156         fos.wFunc = FO_DELETE;
   152         fos.pFrom = lDirectoryName.GetData();
   157         fos.pFrom = lDirectoryName.GetData();
   153         fos.fFlags = FOF_NO_UI;
   158         fos.fFlags = FOF_NO_UI;
   154         result = SHFileOperation(&fos) == 0;
   159         result = SHFileOperation(&fos) == 0;
   155 #endif //WINDOWS
   160 #endif // WINDOWS
   156 #ifdef POSIX
   161 #ifdef POSIX
   157         if (unlink(StringToFileSystemString(DirectoryName)) == 0) {
   162         if (unlink(StringToFileSystemString(DirectoryName)) == 0) {
   158             result = true;
   163             result = true;
   159         }
   164         }
   160 #endif //POSIX
   165 #endif // POSIX
   161     }
   166     }
   162 
   167 
   163     return result;
   168     return result;
   164 }
   169 }
   165 
   170 
   166 TString FilePath::IncludeTrailingSeparater(const TString value) {
   171 TString FilePath::IncludeTrailingSeparator(const TString value) {
   167     TString result = value;
   172     TString result = value;
   168 
   173 
   169     if (value.size() > 0) {
   174     if (value.size() > 0) {
   170         TString::iterator i = result.end();
   175         TString::iterator i = result.end();
   171         i--;
   176         i--;
   176     }
   181     }
   177 
   182 
   178     return result;
   183     return result;
   179 }
   184 }
   180 
   185 
   181 TString FilePath::IncludeTrailingSeparater(const char* value) {
   186 TString FilePath::IncludeTrailingSeparator(const char* value) {
   182     TString lvalue = PlatformString(value).toString();
   187     TString lvalue = PlatformString(value).toString();
   183     return IncludeTrailingSeparater(lvalue);
   188     return IncludeTrailingSeparator(lvalue);
   184 }
   189 }
   185 
   190 
   186 TString FilePath::IncludeTrailingSeparater(const wchar_t* value) {
   191 TString FilePath::IncludeTrailingSeparator(const wchar_t* value) {
   187     TString lvalue = PlatformString(value).toString();
   192     TString lvalue = PlatformString(value).toString();
   188     return IncludeTrailingSeparater(lvalue);
   193     return IncludeTrailingSeparator(lvalue);
   189 }
   194 }
   190 
   195 
   191 TString FilePath::ExtractFilePath(TString Path) {
   196 TString FilePath::ExtractFilePath(TString Path) {
   192 #ifdef WINDOWS
   197 #ifdef WINDOWS
   193     TString result;
   198     TString result;
   194     size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
   199     size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
   195     if (slash != TString::npos)
   200     if (slash != TString::npos)
   196         result = Path.substr(0, slash);
   201         result = Path.substr(0, slash);
   197     return result;
   202     return result;
   198 #endif //WINDOWS
   203 #endif // WINDOWS
   199 #ifdef POSIX
   204 #ifdef POSIX
   200     return dirname(StringToFileSystemString(Path));
   205     return dirname(StringToFileSystemString(Path));
   201 #endif //POSIX
   206 #endif // POSIX
   202 }
   207 }
   203 
   208 
   204 TString FilePath::ExtractFileExt(TString Path) {
   209 TString FilePath::ExtractFileExt(TString Path) {
   205     TString result;
   210     TString result;
   206     size_t dot = Path.find_last_of('.');
   211     size_t dot = Path.find_last_of('.');
   219     size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
   224     size_t slash = Path.find_last_of(TRAILING_PATHSEPARATOR);
   220     if (slash != TString::npos)
   225     if (slash != TString::npos)
   221         result = Path.substr(slash + 1, Path.size() - slash - 1);
   226         result = Path.substr(slash + 1, Path.size() - slash - 1);
   222 
   227 
   223     return result;
   228     return result;
   224 #endif // WINDOWS
   229 #endif //  WINDOWS
   225 #ifdef POSIX
   230 #ifdef POSIX
   226     return basename(StringToFileSystemString(Path));
   231     return basename(StringToFileSystemString(Path));
   227 #endif //POSIX
   232 #endif // POSIX
   228 }
   233 }
   229 
   234 
   230 TString FilePath::ChangeFileExt(TString Path, TString Extension) {
   235 TString FilePath::ChangeFileExt(TString Path, TString Extension) {
   231     TString result;
   236     TString result;
   232     size_t dot = Path.find_last_of('.');
   237     size_t dot = Path.find_last_of('.');
   242     return result;
   247     return result;
   243 }
   248 }
   244 
   249 
   245 TString FilePath::FixPathForPlatform(TString Path) {
   250 TString FilePath::FixPathForPlatform(TString Path) {
   246     TString result = Path;
   251     TString result = Path;
   247     std::replace(result.begin(), result.end(), BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR);
   252     std::replace(result.begin(), result.end(),
       
   253             BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR);
   248 #ifdef WINDOWS
   254 #ifdef WINDOWS
   249     // The maximum path that does not require long path prefix. On Windows the
   255     // The maximum path that does not require long path prefix. On Windows the
   250     // maximum path is 260 minus 1 (NUL) but for directories it is 260 minus
   256     // maximum path is 260 minus 1 (NUL) but for directories it is 260 minus
   251     // 12 minus 1 (to allow for the creation of a 8.3 file in the directory).
   257     // 12 minus 1 (to allow for the creation of a 8.3 file in the directory).
   252     const int maxPath = 247;
   258     const int maxPath = 247;
   266     return result;
   272     return result;
   267 }
   273 }
   268 
   274 
   269 TString FilePath::FixPathSeparatorForPlatform(TString Path) {
   275 TString FilePath::FixPathSeparatorForPlatform(TString Path) {
   270     TString result = Path;
   276     TString result = Path;
   271     std::replace(result.begin(), result.end(), BAD_PATH_SEPARATOR, PATH_SEPARATOR);
   277     std::replace(result.begin(), result.end(),
       
   278             BAD_PATH_SEPARATOR, PATH_SEPARATOR);
   272     return result;
   279     return result;
   273 }
   280 }
   274 
   281 
   275 TString FilePath::PathSeparator() {
   282 TString FilePath::PathSeparator() {
   276     TString result;
   283     TString result;
   287     while (lpath.empty() == false && DirectoryExists(lpath) == false) {
   294     while (lpath.empty() == false && DirectoryExists(lpath) == false) {
   288         paths.push_front(lpath);
   295         paths.push_front(lpath);
   289         lpath = ExtractFilePath(lpath);
   296         lpath = ExtractFilePath(lpath);
   290     }
   297     }
   291 
   298 
   292     for (std::list<TString>::iterator iterator = paths.begin(); iterator != paths.end(); iterator++) {
   299     for (std::list<TString>::iterator iterator = paths.begin();
       
   300             iterator != paths.end(); iterator++) {
   293         lpath = *iterator;
   301         lpath = *iterator;
   294 
   302 
   295 #ifdef WINDOWS
   303 #ifdef WINDOWS
   296         if (_wmkdir(lpath.data()) == 0) {
   304         if (_wmkdir(lpath.data()) == 0) {
   297 #endif // WINDOWS
   305 #endif // WINDOWS
   299         mode_t mode = S_IRWXU;
   307         mode_t mode = S_IRWXU;
   300         if (!ownerOnly) {
   308         if (!ownerOnly) {
   301             mode |= S_IRWXG | S_IROTH | S_IXOTH;
   309             mode |= S_IRWXG | S_IROTH | S_IXOTH;
   302         }
   310         }
   303         if (mkdir(StringToFileSystemString(lpath), mode) == 0) {
   311         if (mkdir(StringToFileSystemString(lpath), mode) == 0) {
   304 #endif //POSIX
   312 #endif // POSIX
   305             result = true;
   313             result = true;
   306         }
   314         }
   307         else {
   315         else {
   308             result = false;
   316             result = false;
   309             break;
   317             break;
   321     }
   329     }
   322     chmod(FileName.data(), mode);
   330     chmod(FileName.data(), mode);
   323 #endif // POSIX
   331 #endif // POSIX
   324 }
   332 }
   325 
   333 
   326 //--------------------------------------------------------------------------------------------------
   334 //----------------------------------------------------------------------------
   327 
   335 
   328 #include <algorithm>
   336 #include <algorithm>
   329 
   337 
   330 FileAttributes::FileAttributes(const TString FileName, bool FollowLink) {
   338 FileAttributes::FileAttributes(const TString FileName, bool FollowLink) {
   331     FFileName = FileName;
   339     FFileName = FileName;
   337     bool result = false;
   345     bool result = false;
   338 
   346 
   339 #ifdef WINDOWS
   347 #ifdef WINDOWS
   340     DWORD attributes = 0;
   348     DWORD attributes = 0;
   341 
   349 
   342     for (std::vector<FileAttribute>::const_iterator iterator = FAttributes.begin();
   350     for (std::vector<FileAttribute>::const_iterator iterator =
   343          iterator != FAttributes.end(); iterator++) {
   351             FAttributes.begin();
       
   352         iterator != FAttributes.end(); iterator++) {
   344         switch (*iterator) {
   353         switch (*iterator) {
   345             case faArchive: {
   354             case faArchive: {
   346                 attributes = attributes & FILE_ATTRIBUTE_ARCHIVE;
   355                 attributes = attributes & FILE_ATTRIBUTE_ARCHIVE;
   347                 break;
   356                 break;
   348             }
   357             }
   364             }
   373             }
   365             case faHidden: {
   374             case faHidden: {
   366                 attributes = attributes & FILE_ATTRIBUTE_HIDDEN;
   375                 attributes = attributes & FILE_ATTRIBUTE_HIDDEN;
   367                 break;
   376                 break;
   368             }
   377             }
   369 //            case faIntegrityStream: {
       
   370 //                attributes = attributes & FILE_ATTRIBUTE_INTEGRITY_STREAM;
       
   371 //                break;
       
   372 //            }
       
   373             case faNormal: {
   378             case faNormal: {
   374                 attributes = attributes & FILE_ATTRIBUTE_NORMAL;
   379                 attributes = attributes & FILE_ATTRIBUTE_NORMAL;
   375                 break;
   380                 break;
   376             }
   381             }
   377             case faNotContentIndexed: {
   382             case faNotContentIndexed: {
   378                 attributes = attributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
   383                 attributes = attributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
   379                 break;
   384                 break;
   380             }
   385             }
   381 //            case faNoScrubData: {
       
   382 //                attributes = attributes & FILE_ATTRIBUTE_NO_SCRUB_DATA;
       
   383 //                break;
       
   384 //            }
       
   385             case faOffline: {
   386             case faOffline: {
   386                 attributes = attributes & FILE_ATTRIBUTE_OFFLINE;
   387                 attributes = attributes & FILE_ATTRIBUTE_OFFLINE;
   387                 break;
   388                 break;
   388             }
   389             }
   389             case faSystem: {
   390             case faSystem: {
   418     }
   419     }
   419 #endif // WINDOWS
   420 #endif // WINDOWS
   420 #ifdef POSIX
   421 #ifdef POSIX
   421     mode_t attributes = 0;
   422     mode_t attributes = 0;
   422 
   423 
   423     for (std::vector<FileAttribute>::const_iterator iterator = FAttributes.begin();
   424     for (std::vector<FileAttribute>::const_iterator iterator =
   424          iterator != FAttributes.end(); iterator++) {
   425             FAttributes.begin();
       
   426         iterator != FAttributes.end(); iterator++) {
   425         switch (*iterator) {
   427         switch (*iterator) {
   426             case faBlockSpecial: {
   428             case faBlockSpecial: {
   427                 attributes |= S_IFBLK;
   429                 attributes |= S_IFBLK;
   428                 break;
   430                 break;
   429             }
   431             }
   514     }
   516     }
   515 
   517 
   516     if (chmod(FFileName.data(), attributes) == 0) {
   518     if (chmod(FFileName.data(), attributes) == 0) {
   517         result = true;
   519         result = true;
   518     }
   520     }
   519 #endif //POSIX
   521 #endif // POSIX
   520 
   522 
   521     return result;
   523     return result;
   522 }
   524 }
   523 
   525 
   524 #define S_ISRUSR(m)    (((m) & S_IRWXU) == S_IRUSR)
   526 #define S_ISRUSR(m)    (((m) & S_IRWXU) == S_IRUSR)
   540     DWORD attributes = ::GetFileAttributes(FFileName.data());
   542     DWORD attributes = ::GetFileAttributes(FFileName.data());
   541 
   543 
   542     if (attributes != INVALID_FILE_ATTRIBUTES) {
   544     if (attributes != INVALID_FILE_ATTRIBUTES) {
   543         result = true;
   545         result = true;
   544 
   546 
   545         if (attributes | FILE_ATTRIBUTE_ARCHIVE) { FAttributes.push_back(faArchive); }
   547         if (attributes | FILE_ATTRIBUTE_ARCHIVE) {
   546         if (attributes | FILE_ATTRIBUTE_COMPRESSED) { FAttributes.push_back(faCompressed); }
   548             FAttributes.push_back(faArchive);
   547         if (attributes | FILE_ATTRIBUTE_DEVICE) { FAttributes.push_back(faDevice); }
   549         }
   548         if (attributes | FILE_ATTRIBUTE_DIRECTORY) { FAttributes.push_back(faDirectory); }
   550         if (attributes | FILE_ATTRIBUTE_COMPRESSED) {
   549         if (attributes | FILE_ATTRIBUTE_ENCRYPTED) { FAttributes.push_back(faEncrypted); }
   551             FAttributes.push_back(faCompressed);
   550         if (attributes | FILE_ATTRIBUTE_HIDDEN) { FAttributes.push_back(faHidden); }
   552         }
   551         //if (attributes | FILE_ATTRIBUTE_INTEGRITY_STREAM) { FAttributes.push_back(faIntegrityStream); }
   553         if (attributes | FILE_ATTRIBUTE_DEVICE) {
   552         if (attributes | FILE_ATTRIBUTE_NORMAL) { FAttributes.push_back(faNormal); }
   554             FAttributes.push_back(faDevice);
   553         if (attributes | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) { FAttributes.push_back(faNotContentIndexed); }
   555         }
   554         //if (attributes | FILE_ATTRIBUTE_NO_SCRUB_DATA) { FAttributes.push_back(faNoScrubData); }
   556         if (attributes | FILE_ATTRIBUTE_DIRECTORY) {
   555         if (attributes | FILE_ATTRIBUTE_SYSTEM) { FAttributes.push_back(faSystem); }
   557             FAttributes.push_back(faDirectory);
   556         if (attributes | FILE_ATTRIBUTE_OFFLINE) { FAttributes.push_back(faOffline); }
   558         }
   557         if (attributes | FILE_ATTRIBUTE_REPARSE_POINT) { FAttributes.push_back(faSymbolicLink); }
   559         if (attributes | FILE_ATTRIBUTE_ENCRYPTED) {
   558         if (attributes | FILE_ATTRIBUTE_SPARSE_FILE) { FAttributes.push_back(faSparceFile); }
   560             FAttributes.push_back(faEncrypted);
   559         if (attributes | FILE_ATTRIBUTE_READONLY ) { FAttributes.push_back(faReadOnly); }
   561         }
   560         if (attributes | FILE_ATTRIBUTE_TEMPORARY) { FAttributes.push_back(faTemporary); }
   562         if (attributes | FILE_ATTRIBUTE_HIDDEN) {
   561         if (attributes | FILE_ATTRIBUTE_VIRTUAL) { FAttributes.push_back(faVirtual); }
   563             FAttributes.push_back(faHidden);
       
   564         }
       
   565         // if (attributes | FILE_ATTRIBUTE_INTEGRITY_STREAM) {
       
   566         //     FAttributes.push_back(faIntegrityStream);
       
   567         // }
       
   568         if (attributes | FILE_ATTRIBUTE_NORMAL) {
       
   569             FAttributes.push_back(faNormal);
       
   570         }
       
   571         if (attributes | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) {
       
   572             FAttributes.push_back(faNotContentIndexed);
       
   573         }
       
   574         // if (attributes | FILE_ATTRIBUTE_NO_SCRUB_DATA) {
       
   575         //     FAttributes.push_back(faNoScrubData);
       
   576         // }
       
   577         if (attributes | FILE_ATTRIBUTE_SYSTEM) {
       
   578             FAttributes.push_back(faSystem);
       
   579         }
       
   580         if (attributes | FILE_ATTRIBUTE_OFFLINE) {
       
   581             FAttributes.push_back(faOffline);
       
   582         }
       
   583         if (attributes | FILE_ATTRIBUTE_REPARSE_POINT) {
       
   584             FAttributes.push_back(faSymbolicLink);
       
   585         }
       
   586         if (attributes | FILE_ATTRIBUTE_SPARSE_FILE) {
       
   587             FAttributes.push_back(faSparceFile);
       
   588         }
       
   589         if (attributes | FILE_ATTRIBUTE_READONLY ) {
       
   590             FAttributes.push_back(faReadOnly);
       
   591         }
       
   592         if (attributes | FILE_ATTRIBUTE_TEMPORARY) {
       
   593             FAttributes.push_back(faTemporary);
       
   594         }
       
   595         if (attributes | FILE_ATTRIBUTE_VIRTUAL) {
       
   596             FAttributes.push_back(faVirtual);
       
   597         }
   562     }
   598     }
   563 #endif // WINDOWS
   599 #endif // WINDOWS
   564 #ifdef POSIX
   600 #ifdef POSIX
   565     struct stat status;
   601     struct stat status;
   566 
   602 
   567     if (stat(StringToFileSystemString(FFileName), &status) == 0) {
   603     if (stat(StringToFileSystemString(FFileName), &status) == 0) {
   568         result = true;
   604         result = true;
   569 
   605 
   570         if (S_ISBLK(status.st_mode) != 0) { FAttributes.push_back(faBlockSpecial); }
   606         if (S_ISBLK(status.st_mode) != 0) {
   571         if (S_ISCHR(status.st_mode) != 0) { FAttributes.push_back(faCharacterSpecial); }
   607             FAttributes.push_back(faBlockSpecial);
   572         if (S_ISFIFO(status.st_mode) != 0) { FAttributes.push_back(faFIFOSpecial); }
   608         }
   573         if (S_ISREG(status.st_mode) != 0) { FAttributes.push_back(faNormal); }
   609         if (S_ISCHR(status.st_mode) != 0) {
   574         if (S_ISDIR(status.st_mode) != 0) { FAttributes.push_back(faDirectory); }
   610             FAttributes.push_back(faCharacterSpecial);
   575         if (S_ISLNK(status.st_mode) != 0) { FAttributes.push_back(faSymbolicLink); }
   611         }
   576         if (S_ISSOCK(status.st_mode) != 0) { FAttributes.push_back(faSocket); }
   612         if (S_ISFIFO(status.st_mode) != 0) {
       
   613             FAttributes.push_back(faFIFOSpecial);
       
   614         }
       
   615         if (S_ISREG(status.st_mode) != 0) {
       
   616             FAttributes.push_back(faNormal);
       
   617         }
       
   618         if (S_ISDIR(status.st_mode) != 0) {
       
   619             FAttributes.push_back(faDirectory);
       
   620         }
       
   621         if (S_ISLNK(status.st_mode) != 0) {
       
   622             FAttributes.push_back(faSymbolicLink);
       
   623         }
       
   624         if (S_ISSOCK(status.st_mode) != 0) {
       
   625             FAttributes.push_back(faSocket);
       
   626         }
   577 
   627 
   578         // Owner
   628         // Owner
   579         if (S_ISRUSR(status.st_mode) != 0) {
   629         if (S_ISRUSR(status.st_mode) != 0) {
   580             if (S_ISWUSR(status.st_mode) != 0) { FAttributes.push_back(faReadWrite); }
   630             if (S_ISWUSR(status.st_mode) != 0) {
   581             else { FAttributes.push_back(faReadOnly); }
   631                 FAttributes.push_back(faReadWrite);
   582         }
   632             } else {
   583         else if (S_ISWUSR(status.st_mode) != 0) { FAttributes.push_back(faWriteOnly); }
   633                 FAttributes.push_back(faReadOnly);
   584 
   634             }
   585         if (S_ISXUSR(status.st_mode) != 0) { FAttributes.push_back(faExecute); }
   635         } else if (S_ISWUSR(status.st_mode) != 0) {
       
   636             FAttributes.push_back(faWriteOnly);
       
   637         }
       
   638 
       
   639         if (S_ISXUSR(status.st_mode) != 0) {
       
   640             FAttributes.push_back(faExecute);
       
   641         }
   586 
   642 
   587         // Group
   643         // Group
   588         if (S_ISRGRP(status.st_mode) != 0) {
   644         if (S_ISRGRP(status.st_mode) != 0) {
   589             if (S_ISWGRP(status.st_mode) != 0) { FAttributes.push_back(faGroupReadWrite); }
   645             if (S_ISWGRP(status.st_mode) != 0) {
   590             else { FAttributes.push_back(faGroupReadOnly); }
   646                 FAttributes.push_back(faGroupReadWrite);
   591         }
   647             } else {
   592         else if (S_ISWGRP(status.st_mode) != 0) { FAttributes.push_back(faGroupWriteOnly); }
   648                 FAttributes.push_back(faGroupReadOnly);
   593 
   649             }
   594         if (S_ISXGRP(status.st_mode) != 0) { FAttributes.push_back(faGroupExecute); }
   650         } else if (S_ISWGRP(status.st_mode) != 0) {
       
   651             FAttributes.push_back(faGroupWriteOnly);
       
   652         }
       
   653 
       
   654         if (S_ISXGRP(status.st_mode) != 0) {
       
   655             FAttributes.push_back(faGroupExecute);
       
   656         }
   595 
   657 
   596 
   658 
   597         // Others
   659         // Others
   598         if (S_ISROTH(status.st_mode) != 0) {
   660         if (S_ISROTH(status.st_mode) != 0) {
   599             if (S_ISWOTH(status.st_mode) != 0) { FAttributes.push_back(faOthersReadWrite); }
   661             if (S_ISWOTH(status.st_mode) != 0) {
   600             else { FAttributes.push_back(faOthersReadOnly); }
   662                 FAttributes.push_back(faOthersReadWrite);
   601         }
   663             } else {
   602         else if (S_ISWOTH(status.st_mode) != 0) { FAttributes.push_back(faOthersWriteOnly); }
   664                 FAttributes.push_back(faOthersReadOnly);
   603 
   665             }
   604         if (S_ISXOTH(status.st_mode) != 0) { FAttributes.push_back(faOthersExecute); }
   666         }
       
   667         else if (S_ISWOTH(status.st_mode) != 0) {
       
   668             FAttributes.push_back(faOthersWriteOnly);
       
   669         }
       
   670 
       
   671         if (S_ISXOTH(status.st_mode) != 0) {
       
   672             FAttributes.push_back(faOthersExecute);
       
   673         }
   605 
   674 
   606         if (FFileName.size() > 0 && FFileName[0] == '.') {
   675         if (FFileName.size() > 0 && FFileName[0] == '.') {
   607             FAttributes.push_back(faHidden);
   676             FAttributes.push_back(faHidden);
   608         }
   677         }
   609     }
   678     }
   610 #endif //POSIX
   679 #endif // POSIX
   611 
   680 
   612     return result;
   681     return result;
   613 }
   682 }
   614 
   683 
   615 bool FileAttributes::Valid(const FileAttribute Value) {
   684 bool FileAttributes::Valid(const FileAttribute Value) {
   631 
   700 
   632         case faOthersReadWrite:
   701         case faOthersReadWrite:
   633         case faOthersWriteOnly:
   702         case faOthersWriteOnly:
   634         case faOthersReadOnly:
   703         case faOthersReadOnly:
   635         case faOthersExecute:
   704         case faOthersExecute:
   636 #endif //POSIX
   705 #endif // POSIX
   637 
   706 
   638         case faReadOnly: {
   707         case faReadOnly: {
   639             result = true;
   708             result = true;
   640             break;
   709             break;
   641         }
   710         }
   651 #ifdef POSIX
   720 #ifdef POSIX
   652         if ((Value == faReadOnly && Contains(faWriteOnly) == true) ||
   721         if ((Value == faReadOnly && Contains(faWriteOnly) == true) ||
   653             (Value == faWriteOnly && Contains(faReadOnly) == true)) {
   722             (Value == faWriteOnly && Contains(faReadOnly) == true)) {
   654             Value = faReadWrite;
   723             Value = faReadWrite;
   655         }
   724         }
   656 #endif //POSIX
   725 #endif // POSIX
   657 
   726 
   658         FAttributes.push_back(Value);
   727         FAttributes.push_back(Value);
   659         WriteAttributes();
   728         WriteAttributes();
   660     }
   729     }
   661 }
   730 }
   662 
   731 
   663 bool FileAttributes::Contains(FileAttribute Value) {
   732 bool FileAttributes::Contains(FileAttribute Value) {
   664     bool result = false;
   733     bool result = false;
   665 
   734 
   666     std::vector<FileAttribute>::const_iterator iterator = std::find(FAttributes.begin(), FAttributes.end(), Value);
   735     std::vector<FileAttribute>::const_iterator iterator =
       
   736             std::find(FAttributes.begin(), FAttributes.end(), Value);
   667 
   737 
   668     if (iterator != FAttributes.end()) {
   738     if (iterator != FAttributes.end()) {
   669         result = true;
   739         result = true;
   670     }
   740     }
   671 
   741 
   681         }
   751         }
   682         else if (Value == faWriteOnly && Contains(faReadWrite) == true) {
   752         else if (Value == faWriteOnly && Contains(faReadWrite) == true) {
   683             Append(faReadOnly);
   753             Append(faReadOnly);
   684             Remove(faReadWrite);
   754             Remove(faReadWrite);
   685         }
   755         }
   686 #endif //POSIX
   756 #endif // POSIX
   687 
   757 
   688         std::vector<FileAttribute>::iterator iterator = std::find(FAttributes.begin(), FAttributes.end(), Value);
   758         std::vector<FileAttribute>::iterator iterator =
       
   759             std::find(FAttributes.begin(), FAttributes.end(), Value);
   689 
   760 
   690         if (iterator != FAttributes.end()) {
   761         if (iterator != FAttributes.end()) {
   691             FAttributes.erase(iterator);
   762             FAttributes.erase(iterator);
   692             WriteAttributes();
   763             WriteAttributes();
   693         }
   764         }