4c85ec073b550d3e994475da3c5449ad879ef7ca
[occt.git] / src / OSD / OSD_Process.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 #ifndef _WIN32
16
17 #include <OSD_Environment.hxx>
18 #include <OSD_OSDError.hxx>
19 #include <OSD_Path.hxx>
20 #include <OSD_Process.hxx>
21 #include <OSD_WhoAmI.hxx>
22 #include <Quantity_Date.hxx>
23 #include <TCollection_AsciiString.hxx>
24
25 const OSD_WhoAmI Iam = OSD_WProcess;
26
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <sys/param.h>
30 #include <sys/time.h>
31 #include <pwd.h>       // For command getpwuid
32 #include <unistd.h>
33
34 OSD_Process::OSD_Process(){
35 }
36
37
38 Standard_Integer OSD_Process::Spawn (const TCollection_AsciiString& cmd,
39                          const Standard_Boolean /*ShowWindow*/)
40 {
41  return system(cmd.ToCString());
42 }
43
44
45 void OSD_Process::TerminalType(TCollection_AsciiString& Name){
46 TCollection_AsciiString which="TERM";
47 OSD_Environment term (which,"");
48
49  term.Value();
50  which = term.Value();
51  Name = term.Name();
52 }
53
54
55 // Get date of system date
56
57 Quantity_Date  OSD_Process::SystemDate(){
58 Quantity_Date result;
59 Standard_Integer month=0,day=0,year=0,hh=0,mn=0,ss=0;
60 struct tm transfert;
61 struct timeval tval;
62 struct timezone tzone;
63 int status;
64
65  status = gettimeofday( &tval, &tzone );
66  if (status == -1) myError.SetValue (errno, Iam, "GetSystem");
67  else {
68   memcpy(&transfert, localtime((time_t *)&tval.tv_sec), sizeof(struct
69 tm));
70   month = transfert.tm_mon + 1;  // Add to January (month #1)
71   day   = transfert.tm_mday;
72   year  = transfert.tm_year;
73   hh    = transfert.tm_hour;
74   mn    = transfert.tm_min ;
75   ss    = transfert.tm_sec ;
76 }
77
78  result.SetValues ( month, day, year+1900, hh, mn, ss);
79  return (result);
80 }
81
82
83 Standard_Integer OSD_Process::ProcessId(){
84  return (getpid());
85 }
86
87 TCollection_AsciiString OSD_Process::UserName()
88 {
89   struct passwd *anInfos = getpwuid (getuid());
90   return TCollection_AsciiString (anInfos ? anInfos->pw_name : "");
91 }
92
93 Standard_Boolean OSD_Process::IsSuperUser (){
94   if (getuid()) {
95     return Standard_False;
96   }
97   else {
98     return Standard_True;
99   }
100 }
101
102
103 OSD_Path OSD_Process::CurrentDirectory(){
104 char cwd[MAXPATHLEN+1] ;
105 OSD_Path result;
106 TCollection_AsciiString Name;
107
108  if (!getcwd(cwd,MAXPATHLEN+1))
109    myError.SetValue (errno, Iam, "Where");
110  else {
111    Name = cwd;
112
113 //   JPT : August,20 1993. This code has been replaced by #ifdef ... #endif
114 //   position = Name.SearchFromEnd(".");
115 //   if (position != -1){
116 //     Ext = Name;
117 //     Ext.Remove(1,position);
118 //     Name.Remove( position,Ext.Length()+1);
119 //   }
120 //   result.SetValues("","","","","",Name,Ext);
121 //   End
122
123 #if defined(vax) || defined(__vms)
124    Standard_Integer iDisk = Name.Search(":");
125    if (iDisk){
126      TCollection_AsciiString Disk;
127      TCollection_AsciiString Directory;
128      Disk = Name.SubString(1,iDisk-1);
129      Directory = Name.SubString(iDisk+1,Name.Length());
130      result.SetValues("","","",Disk,Directory,"","");
131    }
132 #else
133    Name += TCollection_AsciiString("/");
134    result = OSD_Path(Name);
135    //      result.SetValues("","","","",Name,"","");
136 #endif
137
138  }
139 return (result);
140 }
141
142
143 void OSD_Process::SetCurrentDirectory(const OSD_Path& where){
144 TCollection_AsciiString Name;
145 int status;
146
147  where.SystemName(Name);
148
149  status = chdir (Name.ToCString());
150  if (status == -1) myError.SetValue(errno, Iam, "Move to directory");
151 }
152
153
154 void OSD_Process::Reset(){
155  myError.Reset();
156 }
157
158 Standard_Boolean OSD_Process::Failed()const{
159  return( myError.Failed());
160 }
161
162 void OSD_Process::Perror() {
163  myError.Perror();
164 }
165
166
167 Standard_Integer OSD_Process::Error()const{
168  return( myError.Error());
169 }
170
171 #else
172
173 //------------------------------------------------------------------------
174 //-------------------  WNT Sources of OSD_Path ---------------------------
175 //------------------------------------------------------------------------
176
177 //it is important to undefine NOUSER and enforce including <windows.h> before
178 //Standard_Macro.hxx defines it and includes <windows.h> causing compilation errors
179 #ifdef NOUSER
180 #undef NOUSER /* we need SW_HIDE from windows.h */
181 #endif
182 #include <windows.h>
183
184 #include <OSD_Process.hxx>
185
186 #include <OSD_Path.hxx>
187 #include <Quantity_Date.hxx>
188 #include <Standard_PExtCharacter.hxx>
189 #include <TCollection_ExtendedString.hxx>
190
191 #include <OSD_WNT_1.hxx>
192 #include <LMCONS.H> // for UNLEN - maximum user name length GetUserName()
193
194 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
195
196 // =======================================================================
197 // function : OSD_Process
198 // purpose  :
199 // =======================================================================
200 OSD_Process::OSD_Process()
201 {
202   //
203 }
204
205 // =======================================================================
206 // function : Spawn
207 // purpose  :
208 // =======================================================================
209 Standard_Integer OSD_Process::Spawn (const TCollection_AsciiString& theCmd,
210                                                        const Standard_Boolean theToShowWindow)
211 {
212 #ifndef OCCT_UWP
213   STARTUPINFOW aStartupInfo;
214   ZeroMemory (&aStartupInfo, sizeof(STARTUPINFO));
215   aStartupInfo.cb = sizeof(STARTUPINFO);
216   if (!theToShowWindow)
217   {
218     aStartupInfo.dwFlags     = STARTF_USESHOWWINDOW;
219     aStartupInfo.wShowWindow = SW_HIDE;
220   }
221
222   DWORD aRes = 0;
223   TCollection_ExtendedString aCmdWide (theCmd);
224   wchar_t* aCmdWidePtr = const_cast<wchar_t*>(aCmdWide.ToWideString()); // CreateProcessW() can modify content of this string
225   PROCESS_INFORMATION aProcessInfo;
226   if (!CreateProcessW (NULL, aCmdWidePtr, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &aStartupInfo, &aProcessInfo))
227   {
228     _osd_wnt_set_error (myError, OSD_WProcess);
229     aRes = myError.Error();
230   }
231   else
232   {
233     CloseHandle (aProcessInfo.hThread);
234     WaitForSingleObject (aProcessInfo.hProcess, INFINITE);
235     GetExitCodeProcess  (aProcessInfo.hProcess, &aRes);
236     CloseHandle (aProcessInfo.hProcess);
237   }
238
239   return aRes;
240 #else
241   (void )theCmd;
242   (void )theToShowWindow;
243   return 0;
244 #endif
245 }
246
247 void OSD_Process :: TerminalType ( TCollection_AsciiString& Name ) {
248
249  Name = "WIN32 console";
250
251 }  // end OSD_Process :: TerminalType
252
253 Quantity_Date OSD_Process :: SystemDate () {
254
255  Quantity_Date retVal;
256  SYSTEMTIME    st;
257
258  GetLocalTime ( &st );
259
260  retVal.SetValues (
261          st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds
262         );
263
264  return retVal;
265
266 }  // end OSD_Process :: SystemDate
267
268 // =======================================================================
269 // function : UserName
270 // purpose  :
271 // =======================================================================
272 TCollection_AsciiString OSD_Process::UserName()
273 {
274 #ifndef OCCT_UWP
275   wchar_t aUserName[UNLEN + 1];
276   DWORD aNameSize = UNLEN + 1;
277   TCollection_AsciiString retVal;
278   if (!GetUserNameW (aUserName, &aNameSize))
279   {
280     _osd_wnt_set_error(myError, OSD_WProcess);
281     return TCollection_AsciiString();
282   }
283   return TCollection_AsciiString (aUserName);
284 #else
285   return TCollection_AsciiString();
286 #endif
287 }
288
289 Standard_Boolean OSD_Process :: IsSuperUser () {
290 #ifndef OCCT_UWP
291  Standard_Boolean retVal = FALSE;
292  PSID             pSIDadmin;
293  HANDLE           hProcessToken = INVALID_HANDLE_VALUE;
294  PTOKEN_GROUPS    pTKgroups = NULL;
295
296  if (  !OpenProcessToken (
297          GetCurrentProcess (),
298          TOKEN_QUERY, &hProcessToken
299         ) ||
300         (  pTKgroups = ( PTOKEN_GROUPS )GetTokenInformationEx (
301                                          hProcessToken, TokenGroups
302                                         )
303         ) == NULL
304  )
305
306   _osd_wnt_set_error ( myError, OSD_WProcess );
307
308  else {
309  
310   pSIDadmin = AdminSid ();
311
312   for ( int i = 0; i < ( int )pTKgroups -> GroupCount; ++i )
313
314    if (  EqualSid ( pTKgroups -> Groups[ i ].Sid, pSIDadmin )  ) {
315    
316     retVal = TRUE;
317     break;
318    
319    }  // end if
320  
321  }  // end else
322
323  if ( hProcessToken != INVALID_HANDLE_VALUE ) CloseHandle ( hProcessToken );
324  if ( pTKgroups     != NULL                 ) FreeTokenInformation ( pTKgroups );
325
326  return retVal;
327 #else
328  return FALSE;
329 #endif
330 }  // end OSD_Process :: IsSuperUser
331
332 // =======================================================================
333 // function : ProcessId
334 // purpose  :
335 // =======================================================================
336 Standard_Integer OSD_Process::ProcessId()
337 {
338   return (Standard_Integer )GetCurrentProcessId();
339 }
340
341 // =======================================================================
342 // function : CurrentDirectory
343 // purpose  :
344 // =======================================================================
345 OSD_Path OSD_Process::CurrentDirectory()
346 {
347   OSD_Path anCurrentDirectory;
348 #ifndef OCCT_UWP
349   const DWORD aBuffLen = GetCurrentDirectoryW (0, NULL);
350   if (aBuffLen > 0)
351   {
352     wchar_t* aBuff = new wchar_t[aBuffLen + 1];
353     GetCurrentDirectoryW (aBuffLen, aBuff);
354     aBuff[aBuffLen] = L'\0';
355     const TCollection_AsciiString aPath (aBuff);
356     delete[] aBuff;
357
358     anCurrentDirectory = OSD_Path (aPath);
359   }
360   else
361   {
362     _osd_wnt_set_error (myError, OSD_WProcess);
363   }
364 #endif
365   return anCurrentDirectory;
366 }
367
368 void OSD_Process :: SetCurrentDirectory ( const OSD_Path& where ) {
369
370  TCollection_AsciiString path;
371
372  where.SystemName ( path );
373  TCollection_ExtendedString pathW(path);
374
375  if (!::SetCurrentDirectoryW (pathW.ToWideString()))
376
377   _osd_wnt_set_error ( myError, OSD_WProcess );
378
379 }  // end OSD_Process :: SetCurrentDirectory
380
381 Standard_Boolean OSD_Process :: Failed () const {
382
383  return myError.Failed ();
384
385 }  // end OSD_Process :: Failed
386
387 void OSD_Process :: Reset () {
388
389  myError.Reset ();
390
391 }  // end OSD_Process :: Reset
392
393 void OSD_Process :: Perror () {
394
395  myError.Perror ();
396
397 }  // end OSD_Process :: Perror
398
399 Standard_Integer OSD_Process :: Error () const {
400
401  return myError.Error ();
402
403 }  // end OSD_Process :: Error
404
405 #endif