sysfile.inc 6.5 KB

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