sysfile.inc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  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. All these functions can set InOutRes on errors
  14. ****************************************************************************}
  15. PROCEDURE NW2PASErr (Err : LONGINT);
  16. BEGIN
  17. if Err = 0 then { Else it will go through all the cases }
  18. exit;
  19. case Err of
  20. Sys_ENFILE,
  21. Sys_EMFILE : Inoutres:=4;
  22. Sys_ENOENT : Inoutres:=2;
  23. Sys_EBADF : Inoutres:=6;
  24. Sys_ENOMEM,
  25. Sys_EFAULT : Inoutres:=217;
  26. Sys_EINVAL : Inoutres:=218;
  27. Sys_EPIPE,
  28. Sys_EINTR,
  29. Sys_EIO,
  30. Sys_EAGAIN,
  31. Sys_ENOSPC : Inoutres:=101;
  32. Sys_ENAMETOOLONG,
  33. Sys_ELOOP,
  34. Sys_ENOTDIR : Inoutres:=3;
  35. Sys_EROFS,
  36. Sys_EEXIST,
  37. Sys_EACCES : Inoutres:=5;
  38. Sys_EBUSY : Inoutres:=162;
  39. end;
  40. END;
  41. FUNCTION errno : LONGINT;
  42. BEGIN
  43. errno := __get_errno_ptr^;
  44. END;
  45. PROCEDURE Errno2Inoutres;
  46. BEGIN
  47. NW2PASErr (errno);
  48. END;
  49. PROCEDURE SetFileError (VAR Err : LONGINT);
  50. BEGIN
  51. IF Err >= 0 THEN
  52. InOutRes := 0
  53. ELSE
  54. BEGIN
  55. Err := errno;
  56. NW2PASErr (Err);
  57. Err := 0;
  58. END;
  59. END;
  60. { close a file from the handle value }
  61. procedure do_close(handle : thandle);
  62. VAR res : LONGINT;
  63. begin
  64. res := _close (handle);
  65. IF res <> 0 THEN
  66. SetFileError (res)
  67. ELSE
  68. InOutRes := 0;
  69. end;
  70. procedure do_erase(p : pchar; pchangeable: boolean);
  71. VAR res : LONGINT;
  72. begin
  73. res := _unlink (p);
  74. IF Res < 0 THEN
  75. SetFileError (res)
  76. ELSE
  77. InOutRes := 0;
  78. end;
  79. procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
  80. VAR res : LONGINT;
  81. begin
  82. res := _rename (p1,p2);
  83. IF Res < 0 THEN
  84. SetFileError (res)
  85. ELSE
  86. InOutRes := 0
  87. end;
  88. function do_write(h:thandle;addr:pointer;len : longint) : longint;
  89. VAR res : LONGINT;
  90. begin
  91. res := _write (h,addr,len);
  92. IF res > 0 THEN
  93. InOutRes := 0
  94. ELSE
  95. SetFileError (res);
  96. do_write := res;
  97. end;
  98. function do_read(h:thandle;addr:pointer;len : longint) : longint;
  99. VAR res : LONGINT;
  100. begin
  101. res := _read (h,addr,len);
  102. IF res > 0 THEN
  103. InOutRes := 0
  104. ELSE
  105. SetFileError (res);
  106. do_read := res;
  107. end;
  108. function do_filepos(handle : thandle) : longint;
  109. VAR res : LONGINT;
  110. begin
  111. InOutRes:=1;
  112. res := _tell (handle);
  113. IF res < 0 THEN
  114. SetFileError (res)
  115. ELSE
  116. InOutRes := 0;
  117. do_filepos := res;
  118. end;
  119. CONST SEEK_SET = 0; // Seek from beginning of file.
  120. SEEK_CUR = 1; // Seek from current position.
  121. SEEK_END = 2; // Seek from end of file.
  122. procedure do_seek(handle:thandle;pos : longint);
  123. VAR res : LONGINT;
  124. begin
  125. res := _lseek (handle,pos, SEEK_SET);
  126. IF res >= 0 THEN
  127. InOutRes := 0
  128. ELSE
  129. SetFileError (res);
  130. end;
  131. function do_seekend(handle:thandle):longint;
  132. VAR res : LONGINT;
  133. begin
  134. res := _lseek (handle,0, SEEK_END);
  135. IF res >= 0 THEN
  136. InOutRes := 0
  137. ELSE
  138. SetFileError (res);
  139. do_seekend := res;
  140. end;
  141. function do_filesize(handle : thandle) : longint;
  142. VAR res : LONGINT;
  143. begin
  144. res := _filelength (handle);
  145. IF res < 0 THEN
  146. BEGIN
  147. SetFileError (Res);
  148. do_filesize := -1;
  149. END ELSE
  150. BEGIN
  151. InOutRes := 0;
  152. do_filesize := res;
  153. END;
  154. end;
  155. { truncate at a given position }
  156. procedure do_truncate (handle:thandle;pos:longint);
  157. VAR res : LONGINT;
  158. begin
  159. res := _chsize (handle,pos);
  160. IF res <> 0 THEN
  161. SetFileError (res)
  162. ELSE
  163. InOutRes := 0;
  164. end;
  165. // mostly stolen from syslinux
  166. procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
  167. {
  168. filerec and textrec have both handle and mode as the first items so
  169. they could use the same routine for opening/creating.
  170. when (flags and $10) the file will be append
  171. when (flags and $100) the file will be truncate/rewritten
  172. when (flags and $1000) there is no check for close (needed for textfiles)
  173. }
  174. var
  175. oflags : longint;
  176. Begin
  177. { close first if opened }
  178. if ((flags and $10000)=0) then
  179. begin
  180. case FileRec(f).mode of
  181. fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle);
  182. fmclosed : ;
  183. else
  184. begin
  185. inoutres:=102; {not assigned}
  186. exit;
  187. end;
  188. end;
  189. end;
  190. { reset file Handle }
  191. FileRec(f).Handle:=UnusedHandle;
  192. { We do the conversion of filemodes here, concentrated on 1 place }
  193. case (flags and 3) of
  194. 0 : begin
  195. oflags := O_RDONLY;
  196. filerec(f).mode := fminput;
  197. end;
  198. 1 : begin
  199. oflags := O_WRONLY;
  200. filerec(f).mode := fmoutput;
  201. end;
  202. 2 : begin
  203. oflags := O_RDWR;
  204. filerec(f).mode := fminout;
  205. end;
  206. end;
  207. if (flags and $1000)=$1000 then
  208. oflags:=oflags or (O_CREAT or O_TRUNC)
  209. else
  210. if (flags and $100)=$100 then
  211. oflags:=oflags or (O_APPEND);
  212. { empty name is special }
  213. if p[0]=#0 then
  214. begin
  215. case FileRec(f).mode of
  216. fminput :
  217. FileRec(f).Handle:=StdInputHandle;
  218. fminout, { this is set by rewrite }
  219. fmoutput :
  220. FileRec(f).Handle:=StdOutputHandle;
  221. fmappend :
  222. begin
  223. FileRec(f).Handle:=StdOutputHandle;
  224. FileRec(f).mode:=fmoutput; {fool fmappend}
  225. end;
  226. end;
  227. exit;
  228. end;
  229. { real open call }
  230. FileRec(f).Handle := _open(p,oflags,438);
  231. //WriteLn ('_open (',p,') returned ',ErrNo, 'Handle: ',FileRec(f).Handle);
  232. // errno does not seem to be set on succsess ??
  233. IF FileRec(f).Handle < 0 THEN
  234. if (ErrNo=Sys_EROFS) and ((OFlags and O_RDWR)<>0) then
  235. begin // i.e. for cd-rom
  236. Oflags:=Oflags and not(O_RDWR);
  237. FileRec(f).Handle := _open(p,oflags,438);
  238. end;
  239. IF FileRec(f).Handle < 0 THEN
  240. begin
  241. Errno2Inoutres;
  242. FileRec(f).mode:=fmclosed;
  243. end
  244. ELSE
  245. InOutRes := 0;
  246. End;
  247. function do_isdevice(handle:THandle):boolean;
  248. begin
  249. do_isdevice := (_isatty (handle) > 0);
  250. end;