sysutils.pp 13 KB

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