dos.pp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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. exit;
  180. end;
  181. DosError:=0;
  182. with IFD^.dta_search do
  183. begin
  184. f.name:=d_fname;
  185. f.time:=(d_date shl 16) + d_time;
  186. f.size:=d_length;
  187. f.attr:=d_attrib;
  188. end;
  189. end;
  190. procedure FindNext(Var f: SearchRec);
  191. var
  192. IFD: PInternalFindData;
  193. dosResult: LongInt;
  194. begin
  195. IFD:=f.IFD;
  196. if not assigned(IFD) then
  197. begin
  198. DosError:=6;
  199. exit;
  200. end;
  201. dosResult:=gemdos_fsnext;
  202. if dosResult < 0 then
  203. begin
  204. Error2DosError(dosResult);
  205. exit;
  206. end;
  207. DosError:=0;
  208. with IFD^.dta_search do
  209. begin
  210. f.name:=d_fname;
  211. f.time:=(d_date shl 16) + d_time;
  212. f.size:=d_length;
  213. f.attr:=d_attrib;
  214. end;
  215. end;
  216. procedure FindClose(Var f: SearchRec);
  217. var
  218. IFD: PInternalFindData;
  219. begin
  220. IFD:=f.IFD;
  221. if not assigned(IFD) then
  222. exit;
  223. gemdos_setdta(IFD^.dta_original);
  224. dispose(IFD);
  225. f.IFD:=nil;
  226. end;
  227. function FSearch(path: PathStr; dirlist: String) : PathStr;
  228. var
  229. p1 : longint;
  230. s : searchrec;
  231. newdir : pathstr;
  232. begin
  233. { No wildcards allowed in these things }
  234. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  235. begin
  236. fsearch:='';
  237. exit;
  238. end;
  239. { check if the file specified exists }
  240. findfirst(path,anyfile and not(directory),s);
  241. if doserror=0 then
  242. begin
  243. findclose(s);
  244. fsearch:=path;
  245. exit;
  246. end;
  247. findclose(s);
  248. { allow slash as backslash }
  249. DoDirSeparators(dirlist);
  250. repeat
  251. p1:=pos(';',dirlist);
  252. if p1<>0 then
  253. begin
  254. newdir:=copy(dirlist,1,p1-1);
  255. delete(dirlist,1,p1);
  256. end
  257. else
  258. begin
  259. newdir:=dirlist;
  260. dirlist:='';
  261. end;
  262. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  263. newdir:=newdir+'\';
  264. findfirst(newdir+path,anyfile and not(directory),s);
  265. if doserror=0 then
  266. newdir:=newdir+path
  267. else
  268. newdir:='';
  269. findclose(s);
  270. until (dirlist='') or (newdir<>'');
  271. fsearch:=newdir;
  272. end;
  273. procedure GetFAttr(var f; var Attr : word);
  274. var
  275. dosResult: LongInt;
  276. path: PChar;
  277. {$ifndef FPC_ANSI_TEXTFILEREC}
  278. r: rawbytestring;
  279. {$endif not FPC_ANSI_TEXTFILEREC}
  280. begin
  281. {$ifdef FPC_ANSI_TEXTFILEREC}
  282. path:=@filerec(f).Name;
  283. {$else}
  284. r:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
  285. path:=pchar(r);
  286. {$endif}
  287. Attr:=0;
  288. dosResult:=gemdos_fattrib(path,0,0);
  289. if dosResult < 0 then
  290. Error2DosError(dosResult)
  291. else
  292. Attr:=word(dosResult);
  293. end;
  294. procedure GetFTime(var f; var Time : longint);
  295. var
  296. td: TDOSTIME;
  297. begin
  298. gemdos_fdatime(@td,TextRec(f).Handle,0);
  299. Time:=(td.date shl 16) + td.time;
  300. end;
  301. procedure SetFAttr(var f; attr : word);
  302. var
  303. dosResult: LongInt;
  304. path: PChar;
  305. {$ifndef FPC_ANSI_TEXTFILEREC}
  306. r: rawbytestring;
  307. {$endif not FPC_ANSI_TEXTFILEREC}
  308. begin
  309. {$ifdef FPC_ANSI_TEXTFILEREC}
  310. path:=@filerec(f).Name;
  311. {$else}
  312. r:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
  313. path:=pchar(r);
  314. {$endif}
  315. dosResult:=gemdos_fattrib(pchar(@FileRec(f).name),1,Attr);
  316. if dosResult < 0 then
  317. Error2DosError(dosResult)
  318. end;
  319. procedure SetFTime(var f; time : longint);
  320. var
  321. td: TDOSTIME;
  322. begin
  323. td.date:=Hi(Time);
  324. td.time:=Lo(Time);
  325. gemdos_fdatime(@td,TextRec(f).Handle,1);
  326. end;
  327. function EnvCount: Longint;
  328. begin
  329. EnvCount:=0;
  330. end;
  331. function EnvStr(Index: LongInt): String;
  332. begin
  333. EnvStr:='';
  334. end;
  335. function GetEnv(envvar : String): String;
  336. begin
  337. GetEnv:='';
  338. end;
  339. end.