sysfile.inc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2001-2005 by Free Pascal development team
  4. Low level file functions for MacOS
  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. {*****************************************************************************
  12. Low Level File Routines
  13. ****************************************************************************}
  14. function do_isdevice(handle:longint):boolean;
  15. begin
  16. do_isdevice:= (handle=StdInputHandle) or
  17. (handle=StdOutputHandle) or
  18. (handle=StdErrorHandle);
  19. end;
  20. { close a file from the handle value }
  21. procedure do_close(h : longint);
  22. var
  23. err: OSErr;
  24. {Ignore error handling, according to the other targets, which seems reasonable,
  25. because close might be used to clean up after an error.}
  26. begin
  27. {$ifdef MACOS_USE_STDCLIB}
  28. c_close(h);
  29. errno:= 0;
  30. {$else}
  31. err:= FSClose(h);
  32. // OSErr2InOutRes(err);
  33. {$endif}
  34. end;
  35. procedure do_erase(p : pchar; pchangeable: boolean);
  36. var
  37. spec: FSSpec;
  38. err: OSErr;
  39. res: Integer;
  40. begin
  41. res:= PathArgToFSSpec(p, spec);
  42. if (res = 0) then
  43. begin
  44. if not IsDirectory(spec) then
  45. begin
  46. err:= FSpDelete(spec);
  47. OSErr2InOutRes(err);
  48. end
  49. else
  50. InOutRes:= 2;
  51. end
  52. else
  53. InOutRes:=res;
  54. end;
  55. procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
  56. var
  57. s1,s2: RawByteString;
  58. begin
  59. s1:=''; { to fix warnings }
  60. s2:='';
  61. {$ifdef MACOS_USE_STDCLIB}
  62. InOutRes:= PathArgToFullPath(p1, s1);
  63. if InOutRes <> 0 then
  64. exit;
  65. InOutRes:= PathArgToFullPath(p2, s2);
  66. if InOutRes <> 0 then
  67. exit;
  68. c_rename(PChar(s1),PChar(s2));
  69. Errno2InoutRes;
  70. {$else}
  71. InOutRes:=1;
  72. {$endif}
  73. end;
  74. function do_write(h:longint;addr:pointer;len : longint) : longint;
  75. begin
  76. {$ifdef MACOS_USE_STDCLIB}
  77. do_write:= c_write(h, addr, len);
  78. Errno2InoutRes;
  79. {$else}
  80. InOutRes:=1;
  81. if FSWrite(h, len, Mac_Ptr(addr)) = noErr then
  82. InOutRes:=0;
  83. do_write:= len;
  84. {$endif}
  85. end;
  86. function do_read(h:longint;addr:pointer;len : longint) : longint;
  87. var
  88. i: Longint;
  89. begin
  90. {$ifdef MACOS_USE_STDCLIB}
  91. len:= c_read(h, addr, len);
  92. Errno2InoutRes;
  93. do_read:= len;
  94. {$else}
  95. InOutRes:=1;
  96. if FSread(h, len, Mac_Ptr(addr)) = noErr then
  97. InOutRes:=0;
  98. do_read:= len;
  99. {$endif}
  100. end;
  101. function do_filepos(handle : longint) : longint;
  102. var
  103. pos: Longint;
  104. begin
  105. {$ifdef MACOS_USE_STDCLIB}
  106. {This returns the filepos without moving it.}
  107. do_filepos := lseek(handle, 0, SEEK_CUR);
  108. Errno2InoutRes;
  109. {$else}
  110. InOutRes:=1;
  111. if GetFPos(handle, pos) = noErr then
  112. InOutRes:=0;
  113. do_filepos:= pos;
  114. {$endif}
  115. end;
  116. procedure do_seek(handle,pos : longint);
  117. begin
  118. {$ifdef MACOS_USE_STDCLIB}
  119. lseek(handle, pos, SEEK_SET);
  120. Errno2InoutRes;
  121. {$else}
  122. InOutRes:=1;
  123. if SetFPos(handle, fsFromStart, pos) = noErr then
  124. InOutRes:=0;
  125. {$endif}
  126. end;
  127. function do_seekend(handle:longint):longint;
  128. begin
  129. {$ifdef MACOS_USE_STDCLIB}
  130. do_seekend:= lseek(handle, 0, SEEK_END);
  131. Errno2InoutRes;
  132. {$else}
  133. InOutRes:=1;
  134. if SetFPos(handle, fsFromLEOF, 0) = noErr then
  135. InOutRes:=0;
  136. {TODO Resulting file position is to be returned.}
  137. {$endif}
  138. end;
  139. function do_filesize(handle : longint) : longint;
  140. var
  141. aktfilepos: Longint;
  142. begin
  143. {$ifdef MACOS_USE_STDCLIB}
  144. aktfilepos:= lseek(handle, 0, SEEK_CUR);
  145. if errno = 0 then
  146. begin
  147. do_filesize := lseek(handle, 0, SEEK_END);
  148. Errno2InOutRes; {Report the error from this operation.}
  149. lseek(handle, aktfilepos, SEEK_SET); {Always try to move back,
  150. even in presence of error.}
  151. end
  152. else
  153. Errno2InOutRes;
  154. {$else}
  155. InOutRes:=1;
  156. if GetEOF(handle, pos) = noErr then
  157. InOutRes:=0;
  158. do_filesize:= pos;
  159. {$endif}
  160. end;
  161. { truncate at a given position }
  162. procedure do_truncate (handle,pos:longint);
  163. begin
  164. {$ifdef MACOS_USE_STDCLIB}
  165. ioctl(handle, FIOSETEOF, pointer(pos));
  166. Errno2InoutRes;
  167. {$else}
  168. InOutRes:=1;
  169. do_seek(handle,pos); //TODO: Is this needed (Does the user anticipate the filemarker is at the end?)
  170. if SetEOF(handle, pos) = noErr then
  171. InOutRes:=0;
  172. {$endif}
  173. end;
  174. procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
  175. {
  176. filerec and textrec have both handle and mode as the first items so
  177. they could use the same routine for opening/creating.
  178. when (flags and $100) the file will be append
  179. when (flags and $1000) the file will be truncate/rewritten
  180. when (flags and $10000) there is no check for close (needed for textfiles)
  181. }
  182. var
  183. scriptTag: ScriptCode;
  184. refNum: Integer;
  185. err: OSErr;
  186. res: Integer;
  187. spec: FSSpec;
  188. fh: Longint;
  189. oflags : longint;
  190. fullPath: RawByteString;
  191. finderInfo: FInfo;
  192. begin
  193. { close first if opened }
  194. if ((flags and $10000)=0) then
  195. begin
  196. case filerec(f).mode of
  197. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  198. fmclosed : ;
  199. else
  200. begin
  201. {not assigned}
  202. inoutres:=102;
  203. exit;
  204. end;
  205. end;
  206. end;
  207. { reset file handle }
  208. filerec(f).handle:=UnusedHandle;
  209. {$ifdef MACOS_USE_STDCLIB}
  210. { We do the conversion of filemodes here, concentrated on 1 place }
  211. case (flags and 3) of
  212. 0 : begin
  213. oflags :=O_RDONLY;
  214. filerec(f).mode:=fminput;
  215. end;
  216. 1 : begin
  217. oflags :=O_WRONLY;
  218. filerec(f).mode:=fmoutput;
  219. end;
  220. 2 : begin
  221. oflags :=O_RDWR;
  222. filerec(f).mode:=fminout;
  223. end;
  224. end;
  225. if (flags and $1000)=$1000 then
  226. oflags:=oflags or (O_CREAT or O_TRUNC)
  227. else if (flags and $100)=$100 then
  228. oflags:=oflags or (O_APPEND);
  229. { empty name is special }
  230. if p[0]=#0 then
  231. begin
  232. case FileRec(f).mode of
  233. fminput :
  234. FileRec(f).Handle:=StdInputHandle;
  235. fminout, { this is set by rewrite }
  236. fmoutput :
  237. FileRec(f).Handle:=StdOutputHandle;
  238. fmappend :
  239. begin
  240. FileRec(f).Handle:=StdOutputHandle;
  241. FileRec(f).mode:=fmoutput; {fool fmappend}
  242. end;
  243. end;
  244. exit;
  245. end
  246. else
  247. begin
  248. InOutRes:= PathArgToFSSpec(p, spec);
  249. if (InOutRes = 0) or (InOutRes = 2) then
  250. begin
  251. err:= FSpGetFullPath(spec, fullPath, false);
  252. InOutRes:= MacOSErr2RTEerr(err);
  253. end;
  254. if InOutRes <> 0 then
  255. begin
  256. FileRec(f).mode:=fmclosed;
  257. exit;
  258. end;
  259. p:= PChar(fullPath);
  260. end;
  261. fh:= c_open(p, oflags);
  262. if (fh = -1) and (errno = Sys_EROFS) and ((oflags and O_RDWR)<>0) then
  263. begin
  264. oflags:=oflags and not(O_RDWR);
  265. fh:= c_open(p, oflags);
  266. end;
  267. Errno2InOutRes;
  268. if fh <> -1 then
  269. begin
  270. if (FileRec(f).mode = fmOutput) or
  271. (FileRec(f).mode = fmInout) or
  272. (FileRec(f).mode = fmAppend) then
  273. begin
  274. {Change of filetype and creator is always done when a file is opened
  275. for some kind of writing. This ensures overwritten Darwin files will
  276. get apropriate filetype. It must be done after file is opened,
  277. in the case the file did not previously exist.}
  278. FSpGetFInfo(spec, finderInfo);
  279. finderInfo.fdType:= defaultFileType;
  280. finderInfo.fdCreator:= defaultCreator;
  281. FSpSetFInfo(spec, finderInfo);
  282. end;
  283. filerec(f).handle:= fh;
  284. end
  285. else
  286. begin
  287. filerec(f).handle:= UnusedHandle;
  288. FileRec(f).mode:=fmclosed;
  289. end;
  290. {$else}
  291. InOutRes:=1;
  292. { reset file handle }
  293. filerec(f).handle:=UnusedHandle;
  294. res:= FSpLocationFromFullPath(StrLen(p), p, spec);
  295. if (res = noErr) or (res = fnfErr) then
  296. begin
  297. if FSpCreate(spec, defaultCreator, defaultFileType, smSystemScript) = noErr then
  298. ;
  299. if FSpOpenDF(spec, fsCurPerm, refNum) = noErr then
  300. begin
  301. filerec(f).handle:= refNum;
  302. InOutRes:=0;
  303. end;
  304. end;
  305. if (filerec(f).handle=UnusedHandle) then
  306. begin
  307. FileRec(f).mode:=fmclosed;
  308. //errno:=GetLastError;
  309. //Errno2InoutRes;
  310. end;
  311. {$endif}
  312. end;