sysfile.inc 6.5 KB

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