dos.pp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2017 by the Free Pascal development team.
  4. DOS unit for BP7 compatible RTL, Atari implementation
  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. unit dos;
  12. interface
  13. type
  14. SearchRec = record
  15. { Replacement for Fill }
  16. IFD: Pointer;
  17. Fill: Array[1..17] of Byte; {future use}
  18. {End of replacement for fill}
  19. Attr : BYTE; {attribute of found file}
  20. Time : LongInt; {last modify date of found file}
  21. Size : LongInt; {file size of found file}
  22. Name : String[255]; {name of found file}
  23. end;
  24. {$i dosh.inc}
  25. implementation
  26. {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
  27. {$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
  28. {$i dos.inc}
  29. {$i gemdos.inc}
  30. procedure Error2DosError(errno: longint);
  31. begin
  32. case errno of
  33. EFILNF: DosError:=2; // File not found
  34. EPTHNF: DosError:=3; // Directory (folder/path) not found
  35. EACCDN: DosError:=5; // Access denied
  36. EIHNDL: DosError:=6; // Invalid file handle
  37. ENSMEM: DosError:=8; // Insufficient memory
  38. ENMFIL: DosError:=18; // No more files can be opened
  39. else
  40. DosError:=errno;
  41. end;
  42. end;
  43. function DosVersion: Word;
  44. begin
  45. DosVersion:=0;
  46. end;
  47. function WeekDay (y,m,d:longint):longint;
  48. {
  49. Calculates th day of the week. returns -1 on error
  50. }
  51. var
  52. u,v : longint;
  53. begin
  54. if (m<1) or (m>12) or (y<1600) or (y>4000) or
  55. (d<1) or (d>30+((m+ord(m>7)) and 1)-ord(m=2)) or
  56. ((m*d=58) and (((y mod 4>0) or (y mod 100=0)) and (y mod 400>0))) then
  57. WeekDay:=-1
  58. else
  59. begin
  60. u:=m;
  61. v:=y;
  62. if m<3 then
  63. begin
  64. inc(u,12);
  65. dec(v);
  66. end;
  67. WeekDay:=(d+2*u+((3*(u+1)) div 5)+v+(v div 4)-(v div 100)+(v div 400)+1) mod 7;
  68. end;
  69. end;
  70. procedure GetDate(Var Year, Month, MDay, WDay: Word);
  71. var
  72. TOSDate: LongInt;
  73. D: DateTime;
  74. begin
  75. TOSDate:=gemdos_tgetdate shl 16;
  76. { the time values will be invalid here,
  77. but it doesn't matter, we want the date }
  78. UnpackTime(TOSDate,D);
  79. Year:=D.Year;
  80. Month:=D.Month;
  81. MDay:=D.Day;
  82. WDay:=WeekDay(Year,Month,MDay);
  83. end;
  84. procedure SetDate(Year, Month, Day: Word);
  85. var
  86. D: DateTime;
  87. TOSDate: LongInt;
  88. begin
  89. D.Year:=Year;
  90. D.Month:=Month;
  91. D.Day:=Day;
  92. PackTime(D,TOSDate);
  93. gemdos_tsetdate(hi(TOSDate));
  94. end;
  95. procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
  96. var
  97. TOSTime: LongInt;
  98. T: DateTime;
  99. begin
  100. TOSTime:=gemdos_tgettime;
  101. { the date values will be invalid here,
  102. but it doesn't matter, we want the time }
  103. UnpackTime(TOSTime,T);
  104. Hour:=T.Hour;
  105. Minute:=T.Min;
  106. Second:=T.Sec;
  107. Sec100:=0;
  108. end;
  109. procedure SetTime(Hour, Minute, Second, Sec100: Word);
  110. var
  111. T: DateTime;
  112. TOSTime: LongInt;
  113. begin
  114. T.Hour:=Hour;
  115. T.Min:=Minute;
  116. T.Sec:=Second;
  117. PackTime(T,TOSTime);
  118. gemdos_tsettime(lo(TOSTime));
  119. end;
  120. procedure Exec(const Path: PathStr; const ComLine: ComStr);
  121. var
  122. dosResult: LongInt;
  123. tmpPath: String;
  124. begin
  125. tmpPath:=Path+#0;
  126. DoDirSeparators(tmpPath);
  127. { the zero offset for cmdline is actually correct here. pexec() expects
  128. pascal formatted string for cmdline, so length in first byte }
  129. dosResult:=gemdos_pexec(0,PChar(@tmpPath[1]),@ComLine[0],nil);
  130. if dosResult < 0 then
  131. Error2DosError(dosResult);
  132. end;
  133. function DiskSize(Drive: Byte): Int64;
  134. var
  135. dosResult: longint;
  136. di: TDISKINFO;
  137. begin
  138. DiskSize := -1;
  139. dosResult:=gemdos_dfree(@di,drive);
  140. if dosResult < 0 then
  141. exit;
  142. DiskSize:=di.b_total * di.b_secsiz * di.b_clsiz;
  143. end;
  144. function DiskFree(Drive: Byte): Int64;
  145. var
  146. dosResult: longint;
  147. di: TDISKINFO;
  148. begin
  149. DiskFree := -1;
  150. dosResult:=gemdos_dfree(@di,drive);
  151. if dosResult < 0 then
  152. exit;
  153. DiskFree:=di.b_free * di.b_secsiz * di.b_clsiz;
  154. end;
  155. type
  156. PInternalFindData = ^TInternalFindData;
  157. TInternalFindData = record
  158. dta_original: pointer;
  159. dta_search: TDTA;
  160. end;
  161. procedure FindFirst(const Path: PathStr; Attr: Word; Var f: SearchRec);
  162. var
  163. p: PathStr;
  164. r: RawByteString;
  165. dosResult: LongInt;
  166. IFD: PInternalFindData;
  167. begin
  168. p:=Path;
  169. DoDirSeparators(p);
  170. r:=p;
  171. new(IFD);
  172. IFD^.dta_original:=gemdos_getdta;
  173. gemdos_setdta(@IFD^.dta_search);
  174. f.IFD:=IFD;
  175. dosResult:=gemdos_fsfirst(pchar(r), Attr and AnyFile);
  176. if dosResult < 0 then
  177. begin
  178. Error2DosError(dosResult);
  179. FindClose(f);
  180. exit;
  181. end;
  182. DosError:=0;
  183. with IFD^.dta_search do
  184. begin
  185. f.name:=d_fname;
  186. f.time:=(d_date shl 16) + d_time;
  187. f.size:=d_length;
  188. f.attr:=d_attrib;
  189. end;
  190. end;
  191. procedure FindNext(Var f: SearchRec);
  192. var
  193. IFD: PInternalFindData;
  194. dosResult: LongInt;
  195. begin
  196. IFD:=f.IFD;
  197. if not assigned(IFD) then
  198. begin
  199. DosError:=6;
  200. exit;
  201. end;
  202. dosResult:=gemdos_fsnext;
  203. if dosResult < 0 then
  204. begin
  205. Error2DosError(dosResult);
  206. exit;
  207. end;
  208. DosError:=0;
  209. with IFD^.dta_search do
  210. begin
  211. f.name:=d_fname;
  212. f.time:=(d_date shl 16) + d_time;
  213. f.size:=d_length;
  214. f.attr:=d_attrib;
  215. end;
  216. end;
  217. procedure FindClose(Var f: SearchRec);
  218. var
  219. IFD: PInternalFindData;
  220. begin
  221. IFD:=f.IFD;
  222. if not assigned(IFD) then
  223. exit;
  224. gemdos_setdta(IFD^.dta_original);
  225. dispose(IFD);
  226. f.IFD:=nil;
  227. end;
  228. function FSearch(path: PathStr; dirlist: String) : PathStr;
  229. var
  230. p1 : longint;
  231. s : searchrec;
  232. newdir : pathstr;
  233. begin
  234. { No wildcards allowed in these things }
  235. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  236. begin
  237. fsearch:='';
  238. exit;
  239. end;
  240. { check if the file specified exists }
  241. findfirst(path,anyfile and not(directory),s);
  242. if doserror=0 then
  243. begin
  244. findclose(s);
  245. fsearch:=path;
  246. exit;
  247. end;
  248. findclose(s);
  249. { allow slash as backslash }
  250. DoDirSeparators(dirlist);
  251. repeat
  252. p1:=pos(';',dirlist);
  253. if p1<>0 then
  254. begin
  255. newdir:=copy(dirlist,1,p1-1);
  256. delete(dirlist,1,p1);
  257. end
  258. else
  259. begin
  260. newdir:=dirlist;
  261. dirlist:='';
  262. end;
  263. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  264. newdir:=newdir+'\';
  265. findfirst(newdir+path,anyfile and not(directory),s);
  266. if doserror=0 then
  267. newdir:=newdir+path
  268. else
  269. newdir:='';
  270. findclose(s);
  271. until (dirlist='') or (newdir<>'');
  272. fsearch:=newdir;
  273. end;
  274. procedure GetFAttr(var f; var Attr : word);
  275. var
  276. dosResult: LongInt;
  277. path: PChar;
  278. {$ifndef FPC_ANSI_TEXTFILEREC}
  279. r: rawbytestring;
  280. {$endif not FPC_ANSI_TEXTFILEREC}
  281. begin
  282. {$ifdef FPC_ANSI_TEXTFILEREC}
  283. path:=@filerec(f).Name;
  284. {$else}
  285. r:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
  286. path:=pchar(r);
  287. {$endif}
  288. Attr:=0;
  289. dosResult:=gemdos_fattrib(path,0,0);
  290. if dosResult < 0 then
  291. Error2DosError(dosResult)
  292. else
  293. Attr:=word(dosResult);
  294. end;
  295. procedure GetFTime(var f; var Time : longint);
  296. var
  297. td: TDOSTIME;
  298. begin
  299. gemdos_fdatime(@td,TextRec(f).Handle,0);
  300. Time:=(td.date shl 16) + td.time;
  301. end;
  302. procedure SetFAttr(var f; attr : word);
  303. var
  304. dosResult: LongInt;
  305. path: PChar;
  306. {$ifndef FPC_ANSI_TEXTFILEREC}
  307. r: rawbytestring;
  308. {$endif not FPC_ANSI_TEXTFILEREC}
  309. begin
  310. {$ifdef FPC_ANSI_TEXTFILEREC}
  311. path:=@filerec(f).Name;
  312. {$else}
  313. r:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
  314. path:=pchar(r);
  315. {$endif}
  316. dosResult:=gemdos_fattrib(pchar(@FileRec(f).name),1,Attr);
  317. if dosResult < 0 then
  318. Error2DosError(dosResult)
  319. end;
  320. procedure SetFTime(var f; time : longint);
  321. var
  322. td: TDOSTIME;
  323. begin
  324. td.date:=Hi(Time);
  325. td.time:=Lo(Time);
  326. gemdos_fdatime(@td,TextRec(f).Handle,1);
  327. end;
  328. function EnvCount: Longint;
  329. begin
  330. EnvCount:=0;
  331. end;
  332. function EnvStr(Index: LongInt): String;
  333. begin
  334. EnvStr:='';
  335. end;
  336. function GetEnv(envvar : String): String;
  337. begin
  338. GetEnv:='';
  339. end;
  340. end.