sysfile.inc 4.9 KB

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