sysfile.inc 5.2 KB

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