0032442: Application Framework - Problems of testing on MacOS arm64 platform
[occt.git] / src / OSD / OSD_Directory.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <OSD_Directory.hxx>
16
17 #include <OSD_Path.hxx>
18 #include <OSD_Protection.hxx>
19 #include <OSD_WhoAmI.hxx>
20 #include <Standard_ProgramError.hxx>
21 #include <TCollection_ExtendedString.hxx>
22 #include <NCollection_String.hxx>
23
24 #ifdef _WIN32
25   #include <OSD_WNT.hxx>
26   #include <stdio.h>
27
28   #ifndef _INC_TCHAR
29     #include <tchar.h>
30   #endif
31
32   void _osd_wnt_set_error (OSD_Error&, Standard_Integer, ... );
33 #else
34   #include <errno.h>
35   #include <stdio.h>
36   #include <sys/stat.h>
37   #include <unistd.h>
38
39   const OSD_WhoAmI Iam = OSD_WDirectory;
40 #endif
41
42 // =======================================================================
43 // function : OSD_Directory
44 // purpose  :
45 // =======================================================================
46 OSD_Directory::OSD_Directory()
47 {
48   //
49 }
50
51 // =======================================================================
52 // function : OSD_Directory
53 // purpose  :
54 // =======================================================================
55 OSD_Directory::OSD_Directory (const OSD_Path& theName)
56 : OSD_FileNode (theName)
57 {
58   //
59 }
60
61 // =======================================================================
62 // function : Build
63 // purpose  :
64 // =======================================================================
65 void OSD_Directory::Build (const OSD_Protection& theProtect)
66 {
67 #ifdef _WIN32
68   TCollection_AsciiString aDirName;
69   myPath.SystemName (aDirName);
70   if (aDirName.IsEmpty())
71   {
72     throw Standard_ProgramError ( "OSD_Directory::Build(): incorrect call - no directory name");
73   }
74
75   Standard_Boolean isOK = Exists();
76   if (!isOK)
77   {
78     // myError will be set to fail by Exists() if intermediate dirs do not exist
79     myError.Reset();
80
81     // create directory if it does not exist;
82     TCollection_ExtendedString aDirNameW (aDirName);
83     if (CreateDirectoryW (aDirNameW.ToWideString(), NULL))
84     {
85       isOK = Standard_True;
86     }
87     // if failed due to absence of intermediate directories, create them recursively
88     else if (GetLastError() == ERROR_PATH_NOT_FOUND)
89     {
90       OSD_Path aSupPath = myPath;
91       aSupPath.UpTrek();
92       aSupPath.SetName (myPath.TrekValue (myPath.TrekLength())); // incredible, but required!
93       OSD_Directory aSupDir (aSupPath);
94       aSupDir.Build (theProtect);
95       if (aSupDir.Failed())
96       {
97         myError = aSupDir.myError;
98         return;
99       }
100       isOK = (CreateDirectoryW (aDirNameW.ToWideString(), NULL) != 0);
101     }
102   }
103
104   if (isOK)
105   {
106 #ifndef OCCT_UWP
107     SetProtection (theProtect);
108 #else
109     (void)theProtect;
110 #endif
111   }
112   else
113   {
114     _osd_wnt_set_error (myError, OSD_WDirectory);
115   }
116 #else
117   errno = 0;
118   TCollection_AsciiString aBuffer;
119   mode_t anInternalProt = (mode_t )theProtect.Internal();
120   myPath.SystemName (aBuffer);
121   umask (0);
122   int aStatus = mkdir (aBuffer.ToCString(), anInternalProt);
123   if (aStatus == -1 && errno == ENOENT)
124   {
125     OSD_Path aSupPath = myPath;
126     aSupPath.UpTrek();
127     aSupPath.SetName (myPath.TrekValue (myPath.TrekLength())); // incredible, but required!
128     OSD_Directory aSupDir (aSupPath);
129     aSupDir.Build (theProtect);
130     if (aSupDir.Failed())
131     {
132       myError = aSupDir.myError;
133       return;
134     }
135     aStatus = mkdir (aBuffer.ToCString(), anInternalProt);
136   }
137   if (aStatus == -1 && errno != EEXIST)
138   {
139     char anErrMsg[2048];
140     Sprintf (anErrMsg, "OSD_Directory::Build Directory \"%.2000s\"", aBuffer.ToCString());
141     myError.SetValue (errno, Iam, anErrMsg);
142   }
143 #endif
144 }
145
146 // =======================================================================
147 // function : BuildTemporary
148 // purpose  :
149 // =======================================================================
150 OSD_Directory OSD_Directory::BuildTemporary()
151 {
152 #ifdef _WIN32
153   wchar_t* aTmpNameW = _wtmpnam (NULL);
154   if (aTmpNameW == NULL)
155   {
156     return OSD_Directory();
157   }
158
159   TCollection_AsciiString aTmpName (aTmpNameW);
160   OSD_Path aDirPath (aTmpName);
161   OSD_Directory aDir;
162   aDir.SetPath (aDirPath);
163   aDir.Build (OSD_Protection());
164   return aDir;
165 #else
166   // create a temporary directory with 0700 permissions
167   char aTmpName[] = "/tmp/CSFXXXXXX";
168   if (NULL == mkdtemp (aTmpName))
169   {
170     return OSD_Directory(); // can't create a directory
171   }
172
173   unlink (aTmpName); // destroys link but directory still exists while current process lives
174   OSD_Directory aDir;
175   aDir.SetPath (TCollection_AsciiString (aTmpName));
176   return aDir;
177 #endif
178 }