sysutils.pp 13 KB

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