sysutils.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2001 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Sysutils unit for POSIX compliant systems
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit sysutils;
  14. interface
  15. {$MODE objfpc}
  16. { force ansistrings }
  17. {$H+}
  18. { Include platform independent interface part }
  19. {$i sysutilh.inc}
  20. { Platform dependent calls }
  21. Procedure AddDisk(const path:string);
  22. implementation
  23. uses
  24. sysconst,dos,posix;
  25. { Include platform independent implementation part }
  26. {$i sysutils.inc}
  27. {****************************************************************************
  28. File Functions
  29. ****************************************************************************}
  30. {$I-}
  31. const
  32. { read/write permission for everyone }
  33. MODE_OPEN = S_IWUSR OR S_IRUSR OR
  34. S_IWGRP OR S_IRGRP OR
  35. S_IWOTH OR S_IROTH;
  36. Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
  37. Var Flags : cint;
  38. FileHandle : cint;
  39. { lock: flock;}
  40. BEGIN
  41. Flags:=0;
  42. Case (Mode and 3) of
  43. fmOpenRead : Flags:=Flags or O_RDONLY;
  44. fmOpenWrite : Flags:=Flags or O_WRONLY;
  45. fmOpenReadWrite : Flags:=Flags or O_RDWR;
  46. end;
  47. FileHandle:=sys_Open (pchar(FileName),Flags,MODE_OPEN);
  48. if (ErrNo=Sys_EROFS) and ((Flags and O_RDWR)<>0) then
  49. begin
  50. Flags:=Flags and not(O_RDWR);
  51. FileHandle:=sys_open(pchar(FileName),Flags,MODE_OPEN);
  52. end;
  53. FileOpen := longint(FileHandle);
  54. (*
  55. { if there was an error, then don't do anything }
  56. if FileHandle = -1 then
  57. exit;
  58. { now check if the file can actually be used }
  59. { by verifying the locks on the file }
  60. lock.l_whence := SEEK_SET;
  61. lock.l_start := 0; { from start of file }
  62. lock.l_len := 0; { to END of file }
  63. if sys_fcntl(FileHandle, F_GETLK, @lock)<>-1 then
  64. begin
  65. { if another process has created a lock on this file }
  66. { exclusive lock? }
  67. if (lock.l_type = F_WRLCK) then
  68. begin
  69. { close and exit }
  70. sys_close(FileHandle);
  71. FileOpen := -1;
  72. exit;
  73. end;
  74. { shared lock? }
  75. if (lock.l_type = F_RDLK) and
  76. ((Flags = O_RDWR) or Flags = O_WRONLY)) then
  77. begin
  78. { close and exit }
  79. sys_close(FileHandle);
  80. FileOpen := -1;
  81. exit;
  82. end;
  83. end;
  84. { now actually set the lock: }
  85. { only the following are simulated with sysutils : }
  86. { - fmShareDenywrite (get exclusive lock) }
  87. { - fmShareExclusive (get exclusive lock) }
  88. if ((Mode and fmShareDenyWrite)<>0) or
  89. ((Mode and fmShareExclusive)<>0) then
  90. begin
  91. lock.l_whence := SEEK_SET;
  92. lock.l_start := 0; { from stat of file }
  93. lock.l_len := 0; { to END of file }
  94. lock.l_type := F_WRLCK; { exclusive lock }
  95. if sys_fcntl(FileHandle, F_SETLK, @lock)=-1 then
  96. begin
  97. sys_close(FileHandel);
  98. FileOpen := -1;
  99. exit;
  100. end;
  101. end;
  102. *)
  103. end;
  104. Function FileCreate (Const FileName : String) : Longint;
  105. begin
  106. FileCreate:=sys_Open(pchar(FileName),O_RDWR or O_CREAT or O_TRUNC,MODE_OPEN);
  107. end;
  108. Function FileRead (Handle : Longint; Var Buffer; Count : longint) : Longint;
  109. begin
  110. repeat
  111. FileRead:=sys_read(Handle,pchar(@Buffer),Count);
  112. until ErrNo<>Sys_EINTR;
  113. If FileRead = -1 then
  114. FileRead := 0;
  115. end;
  116. Function FileWrite (Handle : Longint; const Buffer; Count : Longint) : Longint;
  117. begin
  118. repeat
  119. FileWrite:=sys_write(Handle,pchar(@Buffer),Count);
  120. until ErrNo<>Sys_EINTR;
  121. if FileWrite = -1 then
  122. FileWrite := 0;
  123. end;
  124. Function FileSeek (Handle,FOffset,Origin : Longint) : Longint;
  125. var
  126. whence : cint;
  127. begin
  128. FileSeek := -1;
  129. case Origin of
  130. { from beginning of file }
  131. 0 : whence := SEEK_SET;
  132. { from current position }
  133. 1 : whence := SEEK_CUR;
  134. { from end of file }
  135. 2 : whence := SEEK_END;
  136. else
  137. exit;
  138. end;
  139. FileSeek := sys_lseek(Handle,FOffset,whence);
  140. if errno <> 0 then
  141. FileSeek := -1;
  142. end;
  143. Procedure FileClose (Handle : Longint);
  144. begin
  145. sys_close(Handle);
  146. end;
  147. Function FileTruncate (Handle,Size: Longint) : boolean;
  148. begin
  149. if sys_ftruncate(Handle,Size)=0 then
  150. FileTruncate := true
  151. else
  152. FileTruncate := false;
  153. end;
  154. Function FileAge (Const FileName : String): Longint;
  155. var F: file;
  156. Time: longint;
  157. begin
  158. Assign(F,FileName);
  159. Reset(F,1);
  160. dos.GetFTime(F,Time);
  161. Close(F);
  162. FileAge := Time;
  163. end;
  164. Function FileExists (Const FileName : String) : Boolean;
  165. Var Info : Stat;
  166. begin
  167. if sys_stat(pchar(filename),Info)<>0 then
  168. FileExists := false
  169. else
  170. FileExists := true;
  171. end;
  172. Function UNIXToWinAttr (FN : Pchar; Const Info : Stat) : Longint;
  173. begin
  174. Result:=faArchive;
  175. If S_ISDIR(Info.st_mode) then
  176. Result:=Result or faDirectory ;
  177. If (FN[0]='.') and (not (FN[1] in [#0,'.'])) then
  178. Result:=Result or faHidden;
  179. if (info.st_mode and S_IWUSR)=0 then
  180. Result:=Result or fareadonly;
  181. If S_ISREG(Info.st_Mode) Then
  182. Result:=Result or faSysFile;
  183. end;
  184. type
  185. PDOSSearchRec = ^SearchRec;
  186. Function FindFirst (Const Path : String; Attr : Longint; Var Rslt : TSearchRec) : Longint;
  187. Const
  188. faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
  189. var
  190. p : pDOSSearchRec;
  191. dosattr: word;
  192. begin
  193. dosattr:=0;
  194. if Attr and faHidden <> 0 then
  195. dosattr := dosattr or Hidden;
  196. if Attr and faSysFile <> 0 then
  197. dosattr := dosattr or SysFile;
  198. if Attr and favolumeID <> 0 then
  199. dosattr := dosattr or VolumeID;
  200. if Attr and faDirectory <> 0 then
  201. dosattr := dosattr or faDirectory;
  202. New(p);
  203. Rslt.FindHandle := THandle(p);
  204. dos.FindFirst(path,dosattr,p^);
  205. if DosError <> 0 then
  206. begin
  207. FindFirst := -1;
  208. end
  209. else
  210. begin
  211. Rslt.Name := p^.Name;
  212. Rslt.Time := p^.Time;
  213. Rslt.Attr := p^.Attr;
  214. Rslt.ExcludeAttr := not p^.Attr;
  215. Rslt.Size := p^.Size;
  216. FindFirst := 0;
  217. end;
  218. end;
  219. Function FindNext (Var Rslt : TSearchRec) : Longint;
  220. var
  221. p : pDOSSearchRec;
  222. begin
  223. p:= PDOsSearchRec(Rslt.FindHandle);
  224. if not assigned(p) then
  225. begin
  226. FindNext := -1;
  227. exit;
  228. end;
  229. Dos.FindNext(p^);
  230. if DosError <> 0 then
  231. begin
  232. FindNext := -1;
  233. end
  234. else
  235. begin
  236. Rslt.Name := p^.Name;
  237. Rslt.Time := p^.Time;
  238. Rslt.Attr := p^.Attr;
  239. Rslt.ExcludeAttr := not p^.Attr;
  240. Rslt.Size := p^.Size;
  241. FindNext := 0;
  242. end;
  243. end;
  244. Procedure FindClose (Var F : TSearchrec);
  245. Var
  246. p : PDOSSearchRec;
  247. begin
  248. p:=PDOSSearchRec(f.FindHandle);
  249. if not assigned(p) then
  250. exit;
  251. Dos.FindClose(p^);
  252. if assigned(p) then
  253. Dispose(p);
  254. f.FindHandle := THandle(nil);
  255. end;
  256. Function FileGetDate (Handle : Longint) : Longint;
  257. Var Info : Stat;
  258. begin
  259. If sys_FStat(Handle,Info)<>0 then
  260. Result:=-1
  261. else
  262. Result:=Info.st_mtime;
  263. end;
  264. Function FileSetDate (Handle,Age : Longint) : Longint;
  265. begin
  266. // Impossible under unix from FileHandle !!
  267. FileSetDate:=-1;
  268. end;
  269. Function FileGetAttr (Const FileName : String) : Longint;
  270. Var Info : Stat;
  271. begin
  272. If sys_stat (pchar(FileName),Info)<>0 then
  273. Result:=-1
  274. Else
  275. Result:=UNIXToWinAttr(Pchar(FileName),Info);
  276. end;
  277. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  278. begin
  279. Result:=-1;
  280. end;
  281. Function DeleteFile (Const FileName : String) : Boolean;
  282. begin
  283. if sys_unlink(pchar(FileName))=0 then
  284. DeleteFile := true
  285. else
  286. DeleteFile := false;
  287. end;
  288. Function RenameFile (Const OldName, NewName : String) : Boolean;
  289. begin
  290. { you can directly typecast and ansistring to a pchar }
  291. if sys_rename(pchar(OldName),pchar(NewName))=0 then
  292. RenameFile := TRUE
  293. else
  294. RenameFile := FALSE;
  295. end;
  296. {****************************************************************************
  297. Disk Functions
  298. ****************************************************************************}
  299. {
  300. The Diskfree and Disksize functions need a file on the specified drive, since this
  301. is required for the statfs system call.
  302. These filenames are set in drivestr[0..26], and have been preset to :
  303. 0 - '.' (default drive - hence current dir is ok.)
  304. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  305. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  306. 3 - '/' (C: equivalent of dos is the root partition)
  307. 4..26 (can be set by you're own applications)
  308. ! Use AddDisk() to Add new drives !
  309. They both return -1 when a failure occurs.
  310. }
  311. Const
  312. FixDriveStr : array[0..3] of pchar=(
  313. '.',
  314. '/fd0/.',
  315. '/fd1/.',
  316. '/.'
  317. );
  318. var
  319. Drives : byte;
  320. DriveStr : array[4..26] of pchar;
  321. Procedure AddDisk(const path:string);
  322. begin
  323. if not (DriveStr[Drives]=nil) then
  324. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  325. GetMem(DriveStr[Drives],length(Path)+1);
  326. StrPCopy(DriveStr[Drives],path);
  327. inc(Drives);
  328. if Drives>26 then
  329. Drives:=4;
  330. end;
  331. Function DiskFree(Drive: Byte): int64;
  332. Begin
  333. DiskFree := dos.diskFree(Drive);
  334. End;
  335. Function DiskSize(Drive: Byte): int64;
  336. Begin
  337. DiskSize := dos.DiskSize(Drive);
  338. End;
  339. Function GetCurrentDir : String;
  340. begin
  341. GetDir (0,Result);
  342. end;
  343. Function SetCurrentDir (Const NewDir : String) : Boolean;
  344. begin
  345. ChDir(NewDir);
  346. result := (IOResult = 0);
  347. end;
  348. Function CreateDir (Const NewDir : String) : Boolean;
  349. begin
  350. MkDir(NewDir);
  351. result := (IOResult = 0);
  352. end;
  353. Function RemoveDir (Const Dir : String) : Boolean;
  354. begin
  355. RmDir(Dir);
  356. result := (IOResult = 0);
  357. end;
  358. Function DirectoryExists(const Directory: string): Boolean;
  359. var
  360. Info : Stat;
  361. l: cint;
  362. begin
  363. l:=sys_Stat(pchar(Directory),Info);
  364. if l<>0 then
  365. Result:=S_ISDIR(info.st_mode)
  366. else
  367. Result := false;
  368. end;
  369. {****************************************************************************
  370. Misc Functions
  371. ****************************************************************************}
  372. procedure Beep;
  373. begin
  374. end;
  375. {****************************************************************************
  376. Locale Functions
  377. ****************************************************************************}
  378. Procedure GetLocalTime(var SystemTime: TSystemTime);
  379. var
  380. dayOfWeek: word;
  381. begin
  382. dos.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second,SystemTime.Millisecond);
  383. dos.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day, DayOfWeek);
  384. end ;
  385. Procedure InitAnsi;
  386. Var
  387. i : longint;
  388. begin
  389. { Fill table entries 0 to 127 }
  390. for i := 0 to 96 do
  391. UpperCaseTable[i] := chr(i);
  392. for i := 97 to 122 do
  393. UpperCaseTable[i] := chr(i - 32);
  394. for i := 123 to 191 do
  395. UpperCaseTable[i] := chr(i);
  396. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  397. for i := 0 to 64 do
  398. LowerCaseTable[i] := chr(i);
  399. for i := 65 to 90 do
  400. LowerCaseTable[i] := chr(i + 32);
  401. for i := 91 to 191 do
  402. LowerCaseTable[i] := chr(i);
  403. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  404. end;
  405. Procedure InitInternational;
  406. begin
  407. InitAnsi;
  408. end;
  409. function SysErrorMessage(ErrorCode: Integer): String;
  410. begin
  411. { Result:=StrError(ErrorCode);}
  412. end;
  413. {****************************************************************************
  414. OS utility functions
  415. ****************************************************************************}
  416. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  417. begin
  418. Result:=Dos.Getenv(shortstring(EnvVar));
  419. end;
  420. Function GetEnvironmentVariableCount : Integer;
  421. begin
  422. // Bad bad bad...
  423. Result:=Dos.EnvCount;
  424. // Result:=FPCCountEnvVar(EnvP);
  425. end;
  426. Function GetEnvironmentString(Index : Integer) : String;
  427. begin
  428. // Bad bad bad...
  429. Result:=Dos.EnvStr(Index);
  430. // Result:=FPCGetEnvStrFromP(Envp,Index);
  431. end;
  432. {****************************************************************************
  433. Initialization code
  434. ****************************************************************************}
  435. Initialization
  436. InitExceptions; { Initialize exceptions. OS independent }
  437. InitInternational; { Initialize internationalization settings }
  438. Finalization
  439. DoneExceptions;
  440. end.
  441. {
  442. $Log$
  443. Revision 1.10 2004-12-11 11:32:44 michael
  444. + Added GetEnvironmentVariableCount and GetEnvironmentString calls
  445. Revision 1.9 2003/11/26 20:00:19 florian
  446. * error handling for Variants improved
  447. Revision 1.8 2003/10/25 23:43:59 hajny
  448. * THandle in sysutils common using System.THandle
  449. Revision 1.7 2003/10/09 20:13:19 florian
  450. * more type alias updates as suggested by DarekM
  451. Revision 1.6 2003/04/01 15:57:41 peter
  452. * made THandle platform dependent and unique type
  453. Revision 1.5 2003/03/29 15:36:58 hajny
  454. * DirectoryExists merged from the fixes branch
  455. Revision 1.4 2003/03/29 15:16:26 hajny
  456. * dummy DirectoryExists added
  457. Revision 1.3 2002/09/07 16:01:26 peter
  458. * old logs removed and tabs fixed
  459. Revision 1.2 2002/08/10 13:42:36 marco
  460. * Fixes Posix dir copied to devel branch
  461. Revision 1.1.2.5 2002/04/28 07:28:43 carl
  462. * some cleanup
  463. Revision 1.1.2.4 2002/03/03 08:47:37 carl
  464. + FindFirst / FindNext implemented
  465. Revision 1.1.2.3 2002/01/22 07:41:11 michael
  466. + Fixed FileSearch bug in Win32 and made FIleSearch platform independent
  467. }