sysfile.inc 5.3 KB

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