sysfile.inc 7.8 KB

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