sysutils.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. Sysutils unit for netware
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit sysutils;
  13. interface
  14. {$MODE objfpc}
  15. {$MODESWITCH OUT}
  16. {$IFDEF UNICODERTL}
  17. {$MODESWITCH UNICODESTRINGS}
  18. {$ELSE}
  19. {$H+}
  20. {$ENDIF}
  21. {$modeswitch typehelpers}
  22. {$modeswitch advancedrecords}
  23. uses DOS;
  24. {$I nwsys.inc}
  25. {$I errno.inc}
  26. {$DEFINE HAS_SLEEP}
  27. {$DEFINE HAS_OSERROR}
  28. { used OS file system APIs use ansistring }
  29. {$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  30. { OS has an ansistring/single byte environment variable API }
  31. {$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
  32. {$DEFINE executeprocuni} (* Only 1 byte version of ExecuteProcess is provided by the OS *)
  33. TYPE
  34. TNetwareFindData =
  35. RECORD
  36. DirP : PNWDirEnt; { used for opendir }
  37. EntryP: PNWDirEnt; { and readdir }
  38. Magic : WORD; { to avoid abends with uninitialized TSearchRec }
  39. END;
  40. { Include platform independent interface part }
  41. {$i sysutilh.inc}
  42. { additional NetWare file flags}
  43. CONST
  44. faSHARE = $00000080; { Sharable file }
  45. faNO_SUBALLOC = $00000800; { Don't sub alloc. this file }
  46. faTRANS = $00001000; { Transactional file (TTS usable) }
  47. faREADAUD = $00004000; { Read audit }
  48. faWRITAUD = $00008000; { Write audit }
  49. faIMMPURG = $00010000; { Immediate purge }
  50. faNORENAM = $00020000; { Rename inhibit }
  51. faNODELET = $00040000; { Delete inhibit }
  52. faNOCOPY = $00080000; { Copy inhibit }
  53. faFILE_MIGRATED = $00400000; { File has been migrated }
  54. faDONT_MIGRATE = $00800000; { Don't migrate this file }
  55. faIMMEDIATE_COMPRESS = $02000000; { Compress this file immediately }
  56. faFILE_COMPRESSED = $04000000; { File is compressed }
  57. faDONT_COMPRESS = $08000000; { Don't compress this file }
  58. faCANT_COMPRESS = $20000000; { Can't compress this file }
  59. faATTR_ARCHIVE = $40000000; { Entry has had an EA modified, }
  60. { an ownerID changed, or trustee }
  61. { info changed, etc. }
  62. implementation
  63. uses
  64. sysconst;
  65. {$define FPC_FEXPAND_DRIVES}
  66. {$define FPC_FEXPAND_VOLUMES}
  67. {$define FPC_FEXPAND_NO_DEFAULT_PATHS}
  68. { Include platform independent implementation part }
  69. {$i sysutils.inc}
  70. {****************************************************************************
  71. File Functions
  72. ****************************************************************************}
  73. Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : THandle;
  74. VAR NWOpenFlags : longint;
  75. SystemFileName: RawByteString;
  76. begin
  77. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  78. NWOpenFlags:=0;
  79. Case (Mode and 3) of
  80. 0 : NWOpenFlags:=NWOpenFlags or O_RDONLY;
  81. 1 : NWOpenFlags:=NWOpenFlags or O_WRONLY;
  82. 2 : NWOpenFlags:=NWOpenFlags or O_RDWR;
  83. end;
  84. FileOpen := _open (PAnsiChar(SystemFileName),NWOpenFlags,0);
  85. //!! We need to set locking based on Mode !!
  86. end;
  87. Function FileCreate (Const FileName : RawByteString) : THandle;
  88. VAR SystemFileName: RawByteString;
  89. begin
  90. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  91. FileCreate:=_open(PAnsiChar(SystemFileName),O_RdWr or O_Creat or O_Trunc,0);
  92. end;
  93. Function FileCreate (Const FileName : RawByteString; Rights:longint) : THandle;
  94. begin
  95. FileCreate:=FileCreate (FileName);
  96. end;
  97. Function FileCreate (Const FileName : RawByteString; ShareMode: Longint; Rights:longint) : THandle;
  98. begin
  99. FileCreate:=FileCreate (FileName);
  100. end;
  101. Function FileRead (Handle : THandle; Out Buffer; Count : longint) : longint;
  102. begin
  103. FileRead:=_read (Handle,@Buffer,Count);
  104. end;
  105. Function FileWrite (Handle : THandle; const Buffer; Count : Longint) : longint;
  106. begin
  107. FileWrite:=_write (Handle,@Buffer,Count);
  108. end;
  109. Function FileSeek (Handle : THandle; FOffset,Origin : Longint) : Longint;
  110. begin
  111. FileSeek:=_lseek (Handle,FOffset,Origin);
  112. end;
  113. Function FileSeek (Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
  114. begin
  115. {$warning need to add 64bit FileSeek }
  116. FileSeek:=FileSeek(Handle,Longint(FOffset),Longint(Origin));
  117. end;
  118. Procedure FileClose (Handle : THandle);
  119. begin
  120. _close(Handle);
  121. end;
  122. Function FileTruncate (Handle : THandle; Size: Int64) : boolean;
  123. begin
  124. if Size > high (longint) then
  125. FileTruncate := false
  126. {$WARNING Possible support for 64-bit FS to be checked!}
  127. else
  128. FileTruncate:=(_chsize(Handle,Size) = 0);
  129. end;
  130. Function FileAge (Const FileName : RawByteString): Int64;
  131. var Handle: longint;
  132. begin
  133. Handle := FileOpen(FileName, 0);
  134. if Handle <> -1 then
  135. begin
  136. result := FileGetDate(Handle);
  137. FileClose(Handle);
  138. end
  139. else
  140. result := -1;
  141. end;
  142. Function FileLock (Handle,FOffset,FLen : Longint) : Longint;
  143. begin
  144. FileLock := _lock (Handle,FOffset,FLen);
  145. end;
  146. Function FileLock (Handle : Longint; FOffset,FLen : Int64) : Longint;
  147. begin
  148. {$warning need to add 64bit FileLock call }
  149. FileLock := FileLock (Handle, longint(FOffset),longint(FLen));
  150. end;
  151. Function FileUnlock (Handle,FOffset,FLen : Longint) : Longint;
  152. begin
  153. FileUnlock := _unlock (Handle,FOffset,FLen);
  154. end;
  155. Function FileUnlock (Handle : Longint; FOffset,FLen : Int64) : Longint;
  156. begin
  157. {$warning need to add 64bit FileUnlock call }
  158. FileUnlock := FileUnlock (Handle, longint(FOffset),longint(FLen));
  159. end;
  160. Function FileAge (Const FileName : String): Int64;
  161. VAR Info : NWStatBufT;
  162. PTM : PNWTM;
  163. begin
  164. If _stat (PAnsiChar(FileName),Info) <> 0 then
  165. exit(-1)
  166. else
  167. begin
  168. PTM := _localtime (Info.st_mtime);
  169. IF PTM = NIL THEN
  170. exit(-1)
  171. else
  172. WITH PTM^ DO
  173. Result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  174. end;
  175. end;
  176. function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
  177. begin
  178. Result := False;
  179. end;
  180. Function FileExists (Const FileName : RawByteString; FollowLink : Boolean) : Boolean;
  181. VAR Info : NWStatBufT;
  182. SystemFileName: RawByteString;
  183. begin
  184. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  185. FileExists:=(_stat(PAnsiChar(SystemFileName),Info) = 0);
  186. end;
  187. Function DirectoryExists (Const Directory : RawByteString; FollowLink : Boolean) : Boolean;
  188. Var
  189. Dir : RawByteString;
  190. drive : byte;
  191. FADir, StoredIORes : longint;
  192. begin
  193. Dir:=Directory;
  194. if (length(dir)=2) and (dir[2]=':') and
  195. ((dir[1] in ['A'..'Z']) or (dir[1] in ['a'..'z'])) then
  196. begin
  197. { We want to test GetCurDir }
  198. if dir[1] in ['A'..'Z'] then
  199. drive:=ord(dir[1])-ord('A')+1
  200. else
  201. drive:=ord(dir[1])-ord('a')+1;
  202. {$push}
  203. {$I-}
  204. StoredIORes:=InOutRes;
  205. InOutRes:=0;
  206. GetDir(drive,dir);
  207. if InOutRes <> 0 then
  208. begin
  209. InOutRes:=StoredIORes;
  210. result:=false;
  211. exit;
  212. end;
  213. end;
  214. {$pop}
  215. if (Length (Dir) > 1) and
  216. (Dir [Length (Dir)] in AllowDirectorySeparators) and
  217. (* Do not remove '\' after ':' (root directory of a drive)
  218. or in '\\' (invalid path, possibly broken UNC path). *)
  219. not (Dir [Length (Dir) - 1] in (AllowDriveSeparators + AllowDirectorySeparators)) then
  220. dir:=copy(dir,1,length(dir)-1);
  221. (* FileGetAttr returns -1 on error *)
  222. FADir := FileGetAttr (Dir);
  223. Result := (FADir <> -1) and
  224. ((FADir and faDirectory) = faDirectory);
  225. end;
  226. PROCEDURE find_setfields (VAR f : TAbstractSearchRec; VAR Name : RawByteString);
  227. VAR T : Dos.DateTime;
  228. BEGIN
  229. WITH F DO
  230. BEGIN
  231. IF FindData.Magic = $AD01 THEN
  232. BEGIN
  233. {attr := FindData.EntryP^.d_attr AND $FF;} // lowest 8 bit -> same as dos
  234. attr := FindData.EntryP^.d_attr; { return complete netware attributes }
  235. UnpackTime(FindData.EntryP^.d_time + (LONGINT (FindData.EntryP^.d_date) SHL 16), T);
  236. time := DateTimeToFileDate(EncodeDate(T.Year,T.Month,T.day)+EncodeTime(T.Hour,T.Min,T.Sec,0));
  237. size := FindData.EntryP^.d_size;
  238. name := FindData.EntryP^.d_nameDOS;
  239. SetCodePage(name, DefaultFileSystemCodePage, false);
  240. END ELSE
  241. BEGIN
  242. name := '';
  243. END;
  244. END;
  245. END;
  246. Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
  247. var
  248. SystemEncodedPath: RawByteString;
  249. begin
  250. IF path = '' then
  251. exit (18);
  252. SystemEncodedPath := ToSingleByteFileSystemEncodedFileName(Path);
  253. Rslt.FindData.DirP := _opendir (PAnsiChar(SystemEncodedPath));
  254. IF Rslt.FindData.DirP = NIL THEN
  255. exit (18);
  256. IF attr <> faAnyFile THEN
  257. _SetReaddirAttribute (Rslt.FindData.DirP, attr);
  258. Rslt.FindData.Magic := $AD01;
  259. Rslt.FindData.EntryP := _readdir (Rslt.FindData.DirP);
  260. if Rslt.FindData.EntryP = nil then
  261. begin
  262. _closedir (Rslt.FindData.DirP);
  263. Rslt.FindData.DirP := NIL;
  264. result := 18;
  265. end else
  266. begin
  267. find_setfields (Rslt,Name);
  268. result := 0;
  269. end;
  270. end;
  271. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
  272. begin
  273. IF Rslt.FindData.Magic <> $AD01 THEN
  274. exit (18);
  275. Rslt.FindData.EntryP := _readdir (Rslt.FindData.DirP);
  276. IF Rslt.FindData.EntryP = NIL THEN
  277. exit (18);
  278. find_setfields (Rslt,Name);
  279. result := 0;
  280. end;
  281. Procedure InternalFindClose (var Handle: THandle; var FindData: TFindData);
  282. begin
  283. IF FindData.Magic = $AD01 THEN
  284. BEGIN
  285. IF FindData.DirP <> NIL THEN
  286. _closedir (FindData.DirP);
  287. FindData.Magic := 0;
  288. FindData.DirP := NIL;
  289. FindData.EntryP := NIL;
  290. END;
  291. end;
  292. Function FileGetDate (Handle : THandle) : Int64;
  293. Var Info : NWStatBufT;
  294. PTM : PNWTM;
  295. begin
  296. If _fstat(Handle,Info) <> 0 then
  297. Result:=-1
  298. else
  299. begin
  300. PTM := _localtime (Info.st_mtime);
  301. IF PTM = NIL THEN
  302. exit(-1)
  303. else
  304. WITH PTM^ DO
  305. Result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  306. end;
  307. end;
  308. Function FileSetDate (Handle : THandle; Age : Int64) : Longint;
  309. begin
  310. { i think its impossible under netware from FileHandle. I dident found a way to get the
  311. complete pathname of a filehandle, that would be needed for ChangeDirectoryEntry }
  312. FileSetDate:=-1;
  313. ConsolePrintf ('warning: fpc sysutils.FileSetDate not implemented'#13#10,0);
  314. {$warning FileSetDate not implemented (i think is impossible) }
  315. end;
  316. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  317. Var Info : NWStatBufT;
  318. SystemFileName: RawByteString;
  319. begin
  320. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  321. If _stat (PAnsiChar(SystemFileName),Info) <> 0 then
  322. Result:=-1
  323. Else
  324. Result := Info.st_attr AND $FFFF;
  325. end;
  326. Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
  327. VAR MS : NWModifyStructure;
  328. SystemFileName: RawByteString;
  329. begin
  330. { The Attr parameter is not used! }
  331. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  332. FillChar (MS, SIZEOF (MS), 0);
  333. if _ChangeDirectoryEntry (PAnsiChar (SystemFilename), MS, MFileAtrributesBit, 0) <> 0 then
  334. result := -1
  335. else
  336. result := 0;
  337. end;
  338. Function DeleteFile (Const FileName : RawByteString) : Boolean;
  339. var
  340. SystemFileName: RawByteString;
  341. begin
  342. SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
  343. Result:= (_UnLink (PAnsiChar(SystemFileName)) = 0);
  344. end;
  345. Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
  346. var
  347. OldSystemFileName, NewSystemFileName: RawByteString;
  348. begin
  349. OldSystemFileName:=ToSingleByteFileSystemEncodedFileName(OldName);
  350. NewSystemFileName:=ToSingleByteFileSystemEncodedFileName(NewName);
  351. RenameFile:=(_rename(PAnsiChar(OldSystemFileName),PAnsiChar(NewSystemFileName)) = 0);
  352. end;
  353. {****************************************************************************
  354. Disk Functions
  355. ****************************************************************************}
  356. {
  357. The Diskfree and Disksize functions need a file on the specified drive, since this
  358. is required for the statfs system call.
  359. These filenames are set in drivestr[0..26], and have been preset to :
  360. 0 - '.' (default drive - hence current dir is ok.)
  361. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  362. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  363. 3 - '/' (C: equivalent of dos is the root partition)
  364. 4..26 (can be set by you're own applications)
  365. ! Use AddDisk() to Add new drives !
  366. They both return -1 when a failure occurs.
  367. }
  368. Const
  369. FixDriveStr : array[0..3] of PAnsiChar=(
  370. '.',
  371. 'a:.',
  372. 'b:.',
  373. 'sys:/'
  374. );
  375. var
  376. Drives : byte;
  377. DriveStr : array[4..26] of PAnsiChar;
  378. Procedure AddDisk(const path:string);
  379. begin
  380. if not (DriveStr[Drives]=nil) then
  381. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  382. GetMem(DriveStr[Drives],length(Path)+1);
  383. StrPCopy(DriveStr[Drives],path);
  384. inc(Drives);
  385. if Drives>26 then
  386. Drives:=4;
  387. end;
  388. Function DiskFree(Drive: Byte): int64;
  389. //var fs : statfs;
  390. Begin
  391. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and fsstat(StrPas(fixdrivestr[drive]),fs)) or
  392. ((not (drivestr[Drive]=nil)) and fsstat(StrPas(drivestr[drive]),fs)) then
  393. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  394. else
  395. Diskfree:=-1;}
  396. DiskFree := -1;
  397. ConsolePrintf ('warning: fpc sysutils.diskfree not implemented'#13#10,0);
  398. {$warning DiskFree not implemented (does it make sense ?) }
  399. End;
  400. Function DiskSize(Drive: Byte): int64;
  401. //var fs : statfs;
  402. Begin
  403. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and fsstat(StrPas(fixdrivestr[drive]),fs)) or
  404. ((not (drivestr[Drive]=nil)) and fsstat(StrPas(drivestr[drive]),fs)) then
  405. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  406. else
  407. DiskSize:=-1;}
  408. DiskSize := -1;
  409. ConsolePrintf ('warning: fpc sysutils.disksize not implemented'#13#10,0);
  410. {$warning DiskSize not implemented (does it make sense ?) }
  411. End;
  412. function DirectoryExists (const Directory: string; FollowLink : Boolean): boolean;
  413. var
  414. Info : NWStatBufT;
  415. SystemFileName: RawByteString;
  416. begin
  417. SystemFileName:=ToSingleByteFileSystemEncodedFileName(Directory);
  418. If _stat (PAnsiChar(SystemFileName),Info) <> 0 then
  419. exit(false)
  420. else
  421. Exit ((Info.st_attr and faDirectory) <> 0);
  422. end;
  423. {****************************************************************************
  424. Misc Functions
  425. ****************************************************************************}
  426. procedure SysBeep;
  427. begin
  428. _RingTheBell;
  429. end;
  430. {****************************************************************************
  431. Locale Functions
  432. ****************************************************************************}
  433. Procedure GetLocalTime(var SystemTime: TSystemTime);
  434. var xx : word;
  435. begin
  436. Dos.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second, xx);
  437. Dos.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day, xx);
  438. SystemTime.MilliSecond := 0;
  439. end;
  440. Procedure InitAnsi;
  441. Var i : longint;
  442. begin
  443. { Fill table entries 0 to 127 }
  444. for i := 0 to 96 do
  445. UpperCaseTable[i] := chr(i);
  446. for i := 97 to 122 do
  447. UpperCaseTable[i] := chr(i - 32);
  448. for i := 123 to 191 do
  449. UpperCaseTable[i] := chr(i);
  450. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  451. for i := 0 to 64 do
  452. LowerCaseTable[i] := chr(i);
  453. for i := 65 to 90 do
  454. LowerCaseTable[i] := chr(i + 32);
  455. for i := 91 to 191 do
  456. LowerCaseTable[i] := chr(i);
  457. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  458. end;
  459. Procedure InitInternational;
  460. begin
  461. InitInternationalGeneric;
  462. InitAnsi;
  463. end;
  464. function SysErrorMessage(ErrorCode: Integer): String;
  465. begin
  466. Result:=''; // StrError(ErrorCode);
  467. end;
  468. {****************************************************************************
  469. OS utility functions
  470. ****************************************************************************}
  471. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  472. begin
  473. Result:=_getenv(PAnsiChar(EnvVar));
  474. end;
  475. Function GetEnvironmentVariableCount : Integer;
  476. begin
  477. // Result:=FPCCountEnvVar(EnvP);
  478. Result:=0;
  479. end;
  480. Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
  481. begin
  482. // Result:=FPCGetEnvStrFromP(Envp,Index);
  483. Result:='';
  484. end;
  485. function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
  486. var
  487. e : EOSError;
  488. CommandLine: RawByteString;
  489. begin
  490. dos.exec(path,comline);
  491. if (Dos.DosError <> 0) then
  492. begin
  493. if ComLine <> '' then
  494. CommandLine := Path + ' ' + ComLine
  495. else
  496. CommandLine := Path;
  497. e:=EOSError.CreateFmt(SExecuteProcessFailed,[CommandLine,Dos.DosError]);
  498. e.ErrorCode:=Dos.DosError;
  499. raise e;
  500. end;
  501. Result := DosExitCode;
  502. end;
  503. function ExecuteProcess (const Path: RawByteString;
  504. const ComLine: array of RawByteString;Flags:TExecuteFlags=[]): integer;
  505. var
  506. CommandLine: RawByteString;
  507. I: integer;
  508. begin
  509. Commandline := '';
  510. for I := 0 to High (ComLine) do
  511. if Pos (' ', ComLine [I]) <> 0 then
  512. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  513. else
  514. CommandLine := CommandLine + ' ' + Comline [I];
  515. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  516. end;
  517. procedure Sleep(milliseconds: Cardinal);
  518. begin
  519. _delay (milliseconds);
  520. end;
  521. Function GetLastOSError : Integer;
  522. begin
  523. Result:=Integer(__get_errno_ptr^);
  524. end;
  525. {****************************************************************************
  526. Initialization code
  527. ****************************************************************************}
  528. Initialization
  529. InitExceptions; { Initialize exceptions. OS independent }
  530. InitInternational; { Initialize internationalization settings }
  531. OnBeep:=@SysBeep;
  532. Finalization
  533. FreeTerminateProcs;
  534. DoneExceptions;
  535. end.