sysfile.inc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2001 by Free Pascal development team
  4. Low leve file functions
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************
  12. Low Level File Routines
  13. ****************************************************************************}
  14. procedure allowslash(p:Pchar);
  15. {Allow slash as backslash.}
  16. var i:longint;
  17. begin
  18. for i:=0 to strlen(p) do
  19. if p[i]='/' then p[i]:='\';
  20. end;
  21. procedure do_close(h:thandle);
  22. begin
  23. { Only three standard handles under real OS/2 }
  24. if h>2 then
  25. begin
  26. InOutRes:=DosClose(h);
  27. end;
  28. {$ifdef IODEBUG}
  29. writeln('do_close: handle=', H, ', InOutRes=', InOutRes);
  30. {$endif}
  31. end;
  32. procedure do_erase(p:Pchar);
  33. begin
  34. allowslash(p);
  35. inoutres:=DosDelete(p);
  36. end;
  37. procedure do_rename(p1,p2:Pchar);
  38. begin
  39. allowslash(p1);
  40. allowslash(p2);
  41. inoutres:=DosMove(p1, p2);
  42. end;
  43. function do_read(h:thandle;addr:pointer;len:longint):longint;
  44. Var
  45. T: cardinal;
  46. begin
  47. {$ifdef IODEBUG}
  48. write('do_read: handle=', h, ', addr=', ptrint(addr), ', length=', len);
  49. {$endif}
  50. InOutRes:=DosRead(H, Addr, Len, T);
  51. do_read:= longint (T);
  52. {$ifdef IODEBUG}
  53. writeln(', actual_len=', t, ', InOutRes=', InOutRes);
  54. {$endif}
  55. end;
  56. function do_write(h:thandle;addr:pointer;len:longint) : longint;
  57. Var
  58. T: cardinal;
  59. begin
  60. {$ifdef IODEBUG}
  61. write('do_write: handle=', h, ', addr=', ptrint(addr), ', length=', len);
  62. {$endif}
  63. InOutRes:=DosWrite(H, Addr, Len, T);
  64. do_write:= longint (T);
  65. {$ifdef IODEBUG}
  66. writeln(', actual_len=', t, ', InOutRes=', InOutRes);
  67. {$endif}
  68. end;
  69. function Do_FilePos (Handle: THandle): int64;
  70. var
  71. PosActual: int64;
  72. begin
  73. InOutRes := DosSetFilePtrL (Handle, 0, 1, PosActual);
  74. Do_FilePos := PosActual;
  75. {$ifdef IODEBUG}
  76. writeln('do_filepos: handle=', Handle, ', actual_pos=', PosActual, ', InOutRes=', InOutRes);
  77. {$endif}
  78. end;
  79. procedure Do_Seek (Handle: THandle; Pos: int64);
  80. var
  81. PosActual: int64;
  82. begin
  83. InOutRes:=DosSetFilePtrL(Handle, Pos, 0 {ZeroBased}, PosActual);
  84. {$ifdef IODEBUG}
  85. writeln('do_seek: handle=', Handle, ', pos=', pos, ', actual_pos=', PosActual, ', InOutRes=', InOutRes);
  86. {$endif}
  87. end;
  88. function Do_SeekEnd (Handle: THandle): int64;
  89. var
  90. PosActual: int64;
  91. begin
  92. InOutRes := DosSetFilePtrL (Handle, 0, 2 {EndBased}, PosActual);
  93. Do_SeekEnd := PosActual;
  94. {$ifdef IODEBUG}
  95. writeln('do_seekend: handle=', Handle, ', actual_pos=', PosActual, ', InOutRes=', InOutRes);
  96. {$endif}
  97. end;
  98. function Do_FileSize (Handle: THandle): int64;
  99. var
  100. AktFilePos: int64;
  101. begin
  102. AktFilePos := Do_FilePos (Handle);
  103. Do_FileSize := Do_SeekEnd (Handle);
  104. Do_Seek (Handle, AktFilePos);
  105. end;
  106. procedure Do_Truncate (Handle: THandle; Pos: int64);
  107. begin
  108. InOutRes := DosSetFileSizeL (Handle, Pos);
  109. Do_SeekEnd (Handle);
  110. end;
  111. const
  112. FileHandleCount: cardinal = 20;
  113. function Increase_File_Handle_Count: boolean;
  114. var Err: word;
  115. L1: longint;
  116. L2: cardinal;
  117. begin
  118. L1 := 10;
  119. if DosSetRelMaxFH (L1, L2) <> 0 then
  120. Increase_File_Handle_Count := false
  121. else
  122. if L2 > FileHandleCount then
  123. begin
  124. FileHandleCount := L2;
  125. Increase_File_Handle_Count := true;
  126. end
  127. else
  128. Increase_File_Handle_Count := false;
  129. end;
  130. procedure do_open(var f;p:pchar;flags:longint);
  131. {
  132. filerec and textrec have both handle and mode as the first items so
  133. they could use the same routine for opening/creating.
  134. when (flags and $100) the file will be append
  135. when (flags and $1000) the file will be truncate/rewritten
  136. when (flags and $10000) there is no check for close (needed for textfiles)
  137. }
  138. var
  139. Action, Attrib, OpenFlags, FM: Cardinal;
  140. begin
  141. // convert unix slashes to normal slashes
  142. allowslash(p);
  143. // close first if opened
  144. if ((flags and $10000)=0) then
  145. begin
  146. case filerec(f).mode of
  147. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  148. fmclosed:;
  149. else
  150. begin
  151. inoutres:=102; {not assigned}
  152. exit;
  153. end;
  154. end;
  155. end;
  156. // reset file handle
  157. filerec(f).handle := UnusedHandle;
  158. Attrib:=0;
  159. OpenFlags:=0;
  160. // convert filesharing
  161. FM := Flags and $FF and not (8);
  162. (* DenyNone if sharing not specified. *)
  163. if FM and 112 = 0 then
  164. FM := FM or 64;
  165. // convert filemode to filerec modes and access mode
  166. case (FM and 3) of
  167. 0: filerec(f).mode:=fminput;
  168. 1: filerec(f).mode:=fmoutput;
  169. 2: filerec(f).mode:=fminout;
  170. end;
  171. if (flags and $1000)<>0 then
  172. OpenFlags:=OpenFlags or 2 {doOverwrite} or 16 {doCreate} // Create/overwrite
  173. else
  174. OpenFlags:=OpenFlags or 1 {doOpen}; // Open existing
  175. // Handle Std I/O
  176. if p[0]=#0 then
  177. begin
  178. case FileRec(f).mode of
  179. fminput :
  180. FileRec(f).Handle:=StdInputHandle;
  181. fminout, // this is set by rewrite
  182. fmoutput :
  183. FileRec(f).Handle:=StdOutputHandle;
  184. fmappend :
  185. begin
  186. FileRec(f).Handle:=StdOutputHandle;
  187. FileRec(f).mode:=fmoutput; // fool fmappend
  188. end;
  189. end;
  190. exit;
  191. end;
  192. Attrib:=32 {faArchive};
  193. InOutRes:=DosOpenL(p, FileRec(F).Handle, Action, 0, Attrib, OpenFlags, FM, nil);
  194. // If too many open files try to set more file handles and open again
  195. if (InOutRes = 4) then
  196. if Increase_File_Handle_Count then
  197. InOutRes:=DosOpenL(p, FileRec(F).Handle, Action, 0, Attrib, OpenFlags, FM, nil);
  198. If InOutRes<>0 then FileRec(F).Handle:=UnusedHandle;
  199. // If Handle created -> make some things
  200. if (FileRec(F).Handle <> UnusedHandle) then
  201. begin
  202. // Move to end of file for Append command
  203. if ((Flags and $100) <> 0) then
  204. begin
  205. do_seekend(FileRec(F).Handle);
  206. FileRec(F).Mode := fmOutput;
  207. end;
  208. end;
  209. {$ifdef IODEBUG}
  210. writeln('do_open,', filerec(f).handle, ',', filerec(f).name, ',', filerec(f).mode, ', InOutRes=', InOutRes);
  211. {$endif}
  212. end;
  213. function do_isdevice (Handle: THandle): boolean;
  214. var
  215. HT, Attr: cardinal;
  216. begin
  217. do_isdevice:=false;
  218. If DosQueryHType(Handle, HT, Attr)<>0 then exit;
  219. if ht=1 then do_isdevice:=true;
  220. end;
  221. {$ASMMODE ATT}