sysfile.inc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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): longint;
  70. var
  71. PosActual: cardinal;
  72. begin
  73. InOutRes:=DosSetFilePtr(Handle, 0, 1, PosActual);
  74. do_filepos:=longint (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:longint);
  80. var
  81. PosActual: cardinal;
  82. begin
  83. InOutRes:=DosSetFilePtr(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):longint;
  89. var
  90. PosActual: cardinal;
  91. begin
  92. InOutRes:=DosSetFilePtr(Handle, 0, 2 {EndBased}, PosActual);
  93. do_seekend:=longint (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):longint;
  99. var aktfilepos: cardinal;
  100. begin
  101. aktfilepos:=do_filepos(handle);
  102. do_filesize:=do_seekend(handle);
  103. do_seek(handle,aktfilepos);
  104. end;
  105. procedure do_truncate(handle:thandle;pos:longint);
  106. begin
  107. InOutRes:=DosSetFileSize(Handle, Pos);
  108. do_seekend(handle);
  109. end;
  110. const
  111. FileHandleCount: cardinal = 20;
  112. function Increase_File_Handle_Count: boolean;
  113. var Err: word;
  114. L1: longint;
  115. L2: cardinal;
  116. begin
  117. L1 := 10;
  118. if DosSetRelMaxFH (L1, L2) <> 0 then
  119. Increase_File_Handle_Count := false
  120. else
  121. if L2 > FileHandleCount then
  122. begin
  123. FileHandleCount := L2;
  124. Increase_File_Handle_Count := true;
  125. end
  126. else
  127. Increase_File_Handle_Count := false;
  128. end;
  129. procedure do_open(var f;p:pchar;flags:longint);
  130. {
  131. filerec and textrec have both handle and mode as the first items so
  132. they could use the same routine for opening/creating.
  133. when (flags and $100) the file will be append
  134. when (flags and $1000) the file will be truncate/rewritten
  135. when (flags and $10000) there is no check for close (needed for textfiles)
  136. }
  137. var
  138. Action, Attrib, OpenFlags, FM: Cardinal;
  139. begin
  140. // convert unix slashes to normal slashes
  141. allowslash(p);
  142. // close first if opened
  143. if ((flags and $10000)=0) then
  144. begin
  145. case filerec(f).mode of
  146. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  147. fmclosed:;
  148. else
  149. begin
  150. inoutres:=102; {not assigned}
  151. exit;
  152. end;
  153. end;
  154. end;
  155. // reset file handle
  156. filerec(f).handle := UnusedHandle;
  157. Attrib:=0;
  158. OpenFlags:=0;
  159. // convert filesharing
  160. FM := Flags and $FF and not (8);
  161. (* DenyNone if sharing not specified. *)
  162. if FM and 112 = 0 then
  163. FM := FM or 64;
  164. // convert filemode to filerec modes and access mode
  165. case (FM and 3) of
  166. 0: filerec(f).mode:=fminput;
  167. 1: filerec(f).mode:=fmoutput;
  168. 2: filerec(f).mode:=fminout;
  169. end;
  170. if (flags and $1000)<>0 then
  171. OpenFlags:=OpenFlags or 2 {doOverwrite} or 16 {doCreate} // Create/overwrite
  172. else
  173. OpenFlags:=OpenFlags or 1 {doOpen}; // Open existing
  174. // Handle Std I/O
  175. if p[0]=#0 then
  176. begin
  177. case FileRec(f).mode of
  178. fminput :
  179. FileRec(f).Handle:=StdInputHandle;
  180. fminout, // this is set by rewrite
  181. fmoutput :
  182. FileRec(f).Handle:=StdOutputHandle;
  183. fmappend :
  184. begin
  185. FileRec(f).Handle:=StdOutputHandle;
  186. FileRec(f).mode:=fmoutput; // fool fmappend
  187. end;
  188. end;
  189. exit;
  190. end;
  191. Attrib:=32 {faArchive};
  192. InOutRes:=DosOpen(p, FileRec(F).Handle, Action, 0, Attrib, OpenFlags, FM, nil);
  193. // If too many open files try to set more file handles and open again
  194. if (InOutRes = 4) then
  195. if Increase_File_Handle_Count then
  196. InOutRes:=DosOpen(p, FileRec(F).Handle, Action, 0, Attrib, OpenFlags, FM, nil);
  197. If InOutRes<>0 then FileRec(F).Handle:=UnusedHandle;
  198. // If Handle created -> make some things
  199. if (FileRec(F).Handle <> UnusedHandle) then
  200. begin
  201. // Move to end of file for Append command
  202. if ((Flags and $100) <> 0) then
  203. begin
  204. do_seekend(FileRec(F).Handle);
  205. FileRec(F).Mode := fmOutput;
  206. end;
  207. end;
  208. {$ifdef IODEBUG}
  209. writeln('do_open,', filerec(f).handle, ',', filerec(f).name, ',', filerec(f).mode, ', InOutRes=', InOutRes);
  210. {$endif}
  211. end;
  212. function do_isdevice (Handle: THandle): boolean;
  213. var
  214. HT, Attr: cardinal;
  215. begin
  216. do_isdevice:=false;
  217. If DosQueryHType(Handle, HT, Attr)<>0 then exit;
  218. if ht=1 then do_isdevice:=true;
  219. end;
  220. {$ASMMODE ATT}