sysfile.inc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Main OS dependant body of the system unit, loosely modelled
  4. after POSIX. *BSD version (Linux version is near identical)
  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. Procedure Do_Close(Handle:thandle);
  12. var
  13. res: cint;
  14. Begin
  15. repeat
  16. res:=Fpclose(cint(Handle));
  17. until (res<>-1) or (geterrno<>ESysEINTR);
  18. End;
  19. Procedure Do_Erase(p : RawByteString);
  20. var
  21. fileinfo : stat;
  22. Begin
  23. { verify if the filename is actually a directory }
  24. { if so return error and do nothing, as defined }
  25. { by POSIX }
  26. if Fpstat(pchar(P),fileinfo)<0 then
  27. begin
  28. Errno2Inoutres;
  29. exit;
  30. end;
  31. if FpS_ISDIR(fileinfo.st_mode) then
  32. begin
  33. InOutRes := 2;
  34. exit;
  35. end;
  36. if Fpunlink(pchar(p))<0 then
  37. Errno2Inoutres
  38. Else
  39. InOutRes:=0;
  40. End;
  41. {$IFDEF FPC_UNICODE_RTL}
  42. Procedure Do_Erase(S : UnicodeString);
  43. var
  44. R : RawByteString;
  45. Begin
  46. R:=ToSingleByteFileSystemEncodedFileName(S);
  47. Do_Erase(R);
  48. end;
  49. {$endif}
  50. { truncate at a given position }
  51. procedure do_truncate (handle:thandle;fpos:longint);
  52. begin
  53. { should be simulated in cases where it is not }
  54. { available. }
  55. If Fpftruncate(handle,fpos)<0 Then
  56. Errno2Inoutres
  57. Else
  58. InOutRes:=0;
  59. end;
  60. Procedure Do_Rename(Src : RawByteString; Dest : RawByteString);
  61. Var
  62. S : RawbyteString;
  63. Begin
  64. S:=ToSingleByteFileSystemEncodedFileName(Src);
  65. If Fprename(Pchar(S),Pchar(Dest))<0 Then
  66. Errno2Inoutres
  67. Else
  68. InOutRes:=0;
  69. End;
  70. {$IFDEF FPC_UNICODE_RTL}
  71. Procedure Do_Rename(Src,Dest : UnicodeString);
  72. Var
  73. sdest,ssrc : RawbyteString;
  74. Begin
  75. SDest:=ToSingleByteFileSystemEncodedFileName(Dest);
  76. SSrc:=ToSingleByteFileSystemEncodedFileName(Src);
  77. Do_Rename(SSrc,SDest);
  78. end;
  79. {$endif}
  80. Function Do_Write(Handle:thandle;Addr:Pointer;Len:Longint):longint;
  81. var j : cint;
  82. Begin
  83. repeat
  84. Do_Write:=Fpwrite(Handle,addr,len);
  85. j:=geterrno;
  86. until (do_write<>-1) or ((j<>ESysEINTR) and (j<>ESysEAgain));
  87. If Do_Write<0 Then
  88. Begin
  89. Errno2InOutRes;
  90. Do_Write:=0;
  91. End
  92. else
  93. InOutRes:=0;
  94. End;
  95. Function Do_Read(Handle:thandle;Addr:Pointer;Len:Longint):Longint;
  96. var j:cint;
  97. Begin
  98. repeat
  99. Do_Read:=Fpread(Handle,addr,len);
  100. j:=geterrno;
  101. until (do_read<>-1) or ((j<>ESysEINTR) and (j<>ESysEAgain));
  102. If Do_Read<0 Then
  103. Begin
  104. Errno2InOutRes;
  105. Do_Read:=0;
  106. End
  107. else
  108. InOutRes:=0;
  109. End;
  110. function Do_FilePos(Handle: thandle):Int64;
  111. Begin
  112. do_FilePos:=Fplseek(Handle, 0, SEEK_CUR);
  113. If Do_FilePos<0 Then
  114. Errno2InOutRes
  115. else
  116. InOutRes:=0;
  117. End;
  118. Procedure Do_Seek(Handle:thandle;Pos:Int64);
  119. Begin
  120. If Fplseek(Handle, pos, SEEK_SET)<0 Then
  121. Errno2Inoutres
  122. Else
  123. InOutRes:=0;
  124. End;
  125. Function Do_SeekEnd(Handle:thandle):Int64;
  126. begin
  127. Do_SeekEnd:=Fplseek(Handle,0,SEEK_END);
  128. If Do_SeekEnd<0 Then
  129. Errno2Inoutres
  130. Else
  131. InOutRes:=0;
  132. end;
  133. Function Do_FileSize(Handle:thandle):Int64;
  134. var
  135. Info : Stat;
  136. Ret : Longint;
  137. Begin
  138. Ret:=Fpfstat(handle,info);
  139. If Ret=0 Then
  140. Do_FileSize:=Info.st_size
  141. else
  142. Do_FileSize:=0;
  143. If Ret<0 Then
  144. Errno2InOutRes
  145. Else
  146. InOutRes:=0;
  147. End;
  148. Procedure Do_Open(var f; const s : RawByteString;flags:longint);
  149. {
  150. FileRec and textrec have both Handle and mode as the first items so
  151. they could use the same routine for opening/creating.
  152. when (flags and $100) the file will be append
  153. when (flags and $1000) the file will be truncate/rewritten
  154. when (flags and $10000) there is no check for close (needed for textfiles)
  155. }
  156. const
  157. { read/write permission for everyone }
  158. MODE_OPEN = S_IWUSR OR S_IRUSR OR
  159. S_IWGRP OR S_IRGRP OR
  160. S_IWOTH OR S_IROTH;
  161. var
  162. oflags : cint;
  163. p : pchar;
  164. Begin
  165. p:=pchar(S);
  166. {}
  167. { close first if opened }
  168. if ((flags and $10000)=0) then
  169. begin
  170. case FileRec(f).mode of
  171. fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle);
  172. fmclosed : ;
  173. else
  174. begin
  175. inoutres:=102; {not assigned}
  176. exit;
  177. end;
  178. end;
  179. end;
  180. { reset file Handle }
  181. FileRec(f).Handle:=UnusedHandle;
  182. { We do the conversion of filemodes here, concentrated on 1 place }
  183. case (flags and 3) of
  184. 0 : begin
  185. oflags :=O_RDONLY;
  186. FileRec(f).mode:=fminput;
  187. end;
  188. 1 : begin
  189. oflags :=O_WRONLY;
  190. FileRec(f).mode:=fmoutput;
  191. end;
  192. 2 : begin
  193. oflags :=O_RDWR;
  194. FileRec(f).mode:=fminout;
  195. end;
  196. end;
  197. if (flags and $1000)=$1000 then
  198. oflags:=oflags or (O_CREAT or O_TRUNC)
  199. else
  200. if (flags and $100)=$100 then
  201. oflags:=oflags or (O_APPEND);
  202. { empty name is special }
  203. if (P=Nil) or (P[0]=#0) then
  204. begin
  205. case FileRec(f).mode of
  206. fminput :
  207. FileRec(f).Handle:=StdInputHandle;
  208. fminout, { this is set by rewrite }
  209. fmoutput :
  210. FileRec(f).Handle:=StdOutputHandle;
  211. fmappend :
  212. begin
  213. FileRec(f).Handle:=StdOutputHandle;
  214. FileRec(f).mode:=fmoutput; {fool fmappend}
  215. end;
  216. end;
  217. exit;
  218. end;
  219. { real open call }
  220. repeat
  221. FileRec(f).Handle:=Fpopen(P,oflags,MODE_OPEN);
  222. until (FileRec(f).Handle<>-1) or (geterrno<>ESysEINTR);
  223. if (FileRec(f).Handle<0) and
  224. (getErrNo=ESysEROFS) and ((OFlags and O_RDWR)<>0) then
  225. begin
  226. Oflags:=Oflags and not(O_RDWR);
  227. repeat
  228. FileRec(f).Handle:=Fpopen(P,oflags,MODE_OPEN);
  229. until (FileRec(f).Handle<>-1) or (geterrno<>ESysEINTR);
  230. end;
  231. If Filerec(f).Handle<0 Then
  232. Errno2Inoutres
  233. else
  234. InOutRes:=0;
  235. End;
  236. {$IFDEF FPC_UNICODE_RTL}
  237. Procedure Do_Open(var f; const s : UnicodeString;flags:longint);
  238. Var
  239. R : RawByteString;
  240. begin
  241. R:=ToSingleByteFileSystemEncodedFileName(S);
  242. Do_open(F,R,Flags);
  243. end;
  244. {$ENDIF}