sysutils.pp 13 KB

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