sysfile.inc 7.7 KB

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