dos.pp 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team.
  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. {$I os.inc}
  13. interface
  14. Uses Go32;
  15. Const
  16. {Bitmasks for CPU Flags}
  17. fcarry = $0001;
  18. fparity = $0004;
  19. fauxiliary = $0010;
  20. fzero = $0040;
  21. fsign = $0080;
  22. foverflow = $0800;
  23. {Bitmasks for file attribute}
  24. readonly = $01;
  25. hidden = $02;
  26. sysfile = $04;
  27. volumeid = $08;
  28. directory = $10;
  29. archive = $20;
  30. anyfile = $3F;
  31. {File Status}
  32. fmclosed = $D7B0;
  33. fminput = $D7B1;
  34. fmoutput = $D7B2;
  35. fminout = $D7B3;
  36. Type
  37. {$IFDEF GO32V2}
  38. { Needed for Win95 LFN Support }
  39. ComStr = String[255];
  40. PathStr = String[255];
  41. DirStr = String[255];
  42. NameStr = String[255];
  43. ExtStr = String[255];
  44. {$ELSE}
  45. comstr = string[127]; { command line string }
  46. pathstr = string[79]; { string for a file path }
  47. dirstr = string[67]; { string for a directory }
  48. namestr = string[8]; { string for a file name }
  49. extstr = string[4]; { string for an extension }
  50. {$ENDIF}
  51. {
  52. filerec.inc contains the definition of the filerec.
  53. textrec.inc contains the definition of the textrec.
  54. It is in a separate file to make it available in other units without
  55. having to use the DOS unit for it.
  56. }
  57. {$i filerec.inc}
  58. {$i textrec.inc}
  59. {$PACKRECORDS 1}
  60. DateTime = record
  61. Year,
  62. Month,
  63. Day,
  64. Hour,
  65. Min,
  66. Sec : word;
  67. End;
  68. {$IFDEF GO32V2}
  69. searchrec = record
  70. fill : array[1..21] of byte;
  71. attr : byte;
  72. time : longint;
  73. { reserved : word; not in DJGPP V2 }
  74. size : longint;
  75. name : string[12]; { the same size as declared by (DJ GNU C) }
  76. end;
  77. Registers = Go32.Registers;
  78. {$ELSE}
  79. searchrec = record
  80. fill : array[1..21] of byte;
  81. attr : byte;
  82. time : longint;
  83. reserved : word; { requires the DOS extender (DJ GNU-C) }
  84. size : longint;
  85. name : string[15]; { the same size as declared by (DJ GNU C) }
  86. end;
  87. registers = record
  88. case i : integer of
  89. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  90. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  91. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  92. end;
  93. {$endif GO32V1}
  94. {$PACKRECORDS 2}
  95. Var
  96. DosError : integer;
  97. {Interrupt}
  98. Procedure Intr(intno: byte; var regs: registers);
  99. Procedure MSDos(var regs: registers);
  100. {Info/Date/Time}
  101. Function DosVersion: Word;
  102. Procedure GetDate(var year, month, mday, wday: word);
  103. Procedure GetTime(var hour, minute, second, sec100: word);
  104. procedure SetDate(year,month,day: word);
  105. Procedure SetTime(hour,minute,second,sec100: word);
  106. Procedure UnpackTime(p: longint; var t: datetime);
  107. Procedure PackTime(var t: datetime; var p: longint);
  108. {Exec}
  109. Procedure Exec(const path: pathstr; const comline: comstr);
  110. Function DosExitCode: word;
  111. {Disk}
  112. Function DiskFree(drive: byte) : longint;
  113. Function DiskSize(drive: byte) : longint;
  114. Procedure FindFirst(const path: pathstr; attr: word; var f: searchRec);
  115. Procedure FindNext(var f: searchRec);
  116. Procedure FindClose(Var f: SearchRec);
  117. {File}
  118. Procedure GetFAttr(var f; var attr: word);
  119. Procedure GetFTime(var f; var time: longint);
  120. Function FSearch(path: pathstr; dirlist: string): pathstr;
  121. Function FExpand(const path: pathstr): pathstr;
  122. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  123. {Environment}
  124. Function EnvCount: longint;
  125. Function EnvStr(index: integer): string;
  126. Function GetEnv(envvar: string): string;
  127. {Misc}
  128. Procedure SetFAttr(var f; attr: word);
  129. Procedure SetFTime(var f; time: longint);
  130. Procedure GetCBreak(var breakvalue: boolean);
  131. Procedure SetCBreak(breakvalue: boolean);
  132. Procedure GetVerify(var verify: boolean);
  133. Procedure SetVerify(verify: boolean);
  134. {Do Nothing Functions}
  135. Procedure SwapVectors;
  136. Procedure GetIntVec(intno: byte; var vector: pointer);
  137. Procedure SetIntVec(intno: byte; vector: pointer);
  138. Procedure Keep(exitcode: word);
  139. implementation
  140. uses
  141. strings;
  142. {******************************************************************************
  143. --- Dos Interrupt ---
  144. ******************************************************************************}
  145. var
  146. dosregs : registers;
  147. procedure LoadDosError;
  148. begin
  149. if (dosregs.flags and carryflag) <> 0 then
  150. doserror:=dosregs.ax
  151. else
  152. doserror:=0;
  153. end;
  154. {$ifdef GO32V2}
  155. procedure intr(intno : byte;var regs : registers);
  156. begin
  157. realintr(intno,regs);
  158. end;
  159. {$else GO32V2}
  160. procedure intr(intno : byte;var regs : registers);
  161. begin
  162. asm
  163. .data
  164. int86:
  165. .byte 0xcd
  166. int86_vec:
  167. .byte 0x03
  168. jmp int86_retjmp
  169. .text
  170. movl 8(%ebp),%eax
  171. movb %al,int86_vec
  172. movl 10(%ebp),%eax
  173. // do not use first int
  174. addl $2,%eax
  175. movl 4(%eax),%ebx
  176. movl 8(%eax),%ecx
  177. movl 12(%eax),%edx
  178. movl 16(%eax),%ebp
  179. movl 20(%eax),%esi
  180. movl 24(%eax),%edi
  181. movl (%eax),%eax
  182. jmp int86
  183. int86_retjmp:
  184. pushf
  185. pushl %ebp
  186. pushl %eax
  187. movl %esp,%ebp
  188. // calc EBP new
  189. addl $12,%ebp
  190. movl 10(%ebp),%eax
  191. // do not use first int
  192. addl $2,%eax
  193. popl (%eax)
  194. movl %ebx,4(%eax)
  195. movl %ecx,8(%eax)
  196. movl %edx,12(%eax)
  197. // restore EBP
  198. popl %edx
  199. movl %edx,16(%eax)
  200. movl %esi,20(%eax)
  201. movl %edi,24(%eax)
  202. // ignore ES and DS
  203. popl %ebx /* flags */
  204. movl %ebx,32(%eax)
  205. // FS and GS too
  206. end;
  207. end;
  208. {$endif GO32V2}
  209. procedure msdos(var regs : registers);
  210. begin
  211. intr($21,regs);
  212. end;
  213. {******************************************************************************
  214. --- Info / Date / Time ---
  215. ******************************************************************************}
  216. function dosversion : word;
  217. begin
  218. dosregs.ax:=$3000;
  219. msdos(dosregs);
  220. dosversion:=dosregs.ax;
  221. end;
  222. procedure getdate(var year,month,mday,wday : word);
  223. begin
  224. dosregs.ax:=$2a00;
  225. msdos(dosregs);
  226. wday:=dosregs.al;
  227. year:=dosregs.cx;
  228. month:=dosregs.dh;
  229. mday:=dosregs.dl;
  230. end;
  231. procedure setdate(year,month,day : word);
  232. begin
  233. dosregs.cx:=year;
  234. dosregs.dh:=month;
  235. dosregs.dl:=day;
  236. dosregs.ah:=$2b;
  237. msdos(dosregs);
  238. LoadDosError;
  239. end;
  240. procedure gettime(var hour,minute,second,sec100 : word);
  241. begin
  242. dosregs.ah:=$2c;
  243. msdos(dosregs);
  244. hour:=dosregs.ch;
  245. minute:=dosregs.cl;
  246. second:=dosregs.dh;
  247. sec100:=dosregs.dl;
  248. end;
  249. procedure settime(hour,minute,second,sec100 : word);
  250. begin
  251. dosregs.ch:=hour;
  252. dosregs.cl:=minute;
  253. dosregs.dh:=second;
  254. dosregs.dl:=sec100;
  255. dosregs.ah:=$2d;
  256. msdos(dosregs);
  257. LoadDosError;
  258. end;
  259. Procedure packtime(var t : datetime;var p : longint);
  260. Begin
  261. p:=(t.sec shr 1)+(t.min shl 5)+(t.hour shl 11)+(t.day shl 16)+(t.month shl 21)+((t.year-1980) shl 25);
  262. End;
  263. Procedure unpacktime(p : longint;var t : datetime);
  264. Begin
  265. t.sec:=(p and 31) shl 1;
  266. t.min:=(p shr 5) and 63;
  267. t.hour:=(p shr 11) and 31;
  268. t.day:=(p shr 16) and 31;
  269. t.month:=(p shr 21) and 15;
  270. t.year:=(p shr 25)+1980;
  271. End;
  272. {******************************************************************************
  273. --- Exec ---
  274. ******************************************************************************}
  275. var
  276. lastdosexitcode : word;
  277. {$ifdef GO32V2}
  278. { this code is just the most basic part of dosexec.c from
  279. the djgpp code }
  280. procedure exec(const path : pathstr;const comline : comstr);
  281. procedure do_system(p,c : string);
  282. {
  283. Table 0931
  284. Format of EXEC parameter block for AL=00h,01h,04h:
  285. Offset Size Description
  286. 00h WORD segment of environment to copy for child process (copy caller's
  287. environment if 0000h)
  288. this does not seem to work (PM)
  289. 02h DWORD pointer to command tail to be copied into child's PSP
  290. 06h DWORD pointer to first FCB to be copied into child's PSP
  291. 0Ah DWORD pointer to second FCB to be copied into child's PSP
  292. 0Eh DWORD (AL=01h) will hold subprogram's initial SS:SP on return
  293. 12h DWORD (AL=01h) will hold entry point (CS:IP) on return
  294. INT 21 4B--
  295. }
  296. type
  297. realptr = record
  298. ofs,seg : word;
  299. end;
  300. texecblock = record
  301. envseg : word;
  302. comtail : realptr;
  303. firstFCB : realptr;
  304. secondFCB : realptr;
  305. iniStack : realptr;
  306. iniCSIP : realptr;
  307. end;
  308. var current_dos_buffer_pos : longint;
  309. function paste_to_dos(src : string) : boolean;
  310. var c : array[0..255] of char;
  311. begin
  312. paste_to_dos:=false;
  313. if current_dos_buffer_pos+length(src)+1>transfer_buffer+tb_size then
  314. RunError(217);
  315. move(src[1],c[0],length(src));
  316. c[length(src)]:=#0;
  317. seg_move(get_ds,longint(@c),dosmemselector,current_dos_buffer_pos,length(src)+1);
  318. current_dos_buffer_pos:=current_dos_buffer_pos+length(src)+1;
  319. paste_to_dos:=true;
  320. end;
  321. var
  322. i,la_env,la_p,la_c,la_e,fcb1_la,fcb2_la : longint;
  323. arg_ofs : longint;
  324. execblock : texecblock;
  325. begin
  326. la_env:=transfer_buffer;
  327. while (la_env mod 16)<>0 do inc(la_env);
  328. current_dos_buffer_pos:=la_env;
  329. for i:=1 to envcount do
  330. begin
  331. paste_to_dos(envstr(i));
  332. end;
  333. paste_to_dos(''); { adds a double zero at the end }
  334. { allow slash as backslash }
  335. for i:=1 to length(p) do
  336. if p[i]='/' then p[i]:='\';
  337. la_p:=current_dos_buffer_pos;
  338. paste_to_dos(p);
  339. la_c:=current_dos_buffer_pos;
  340. paste_to_dos(c);
  341. la_e:=current_dos_buffer_pos;
  342. fcb1_la:=la_e;
  343. la_e:=la_e+16;
  344. fcb2_la:=la_e;
  345. la_e:=la_e+16;
  346. { allocate FCB see dosexec code }
  347. dosregs.ax:=$2901;
  348. arg_ofs:=1;
  349. while (c[arg_ofs]=' ') or (c[arg_ofs]=#9) do inc(arg_ofs);
  350. dosregs.ds:=(la_c+arg_ofs) div 16;
  351. dosregs.si:=(la_c+arg_ofs) mod 16;
  352. dosregs.es:=fcb1_la div 16;
  353. dosregs.di:=fcb1_la mod 16;
  354. msdos(dosregs);
  355. repeat
  356. inc(arg_ofs);
  357. until (c[arg_ofs]=' ') or
  358. (c[arg_ofs]=#9) or
  359. (c[arg_ofs]=#13);
  360. if c[arg_ofs]<>#13 then
  361. begin
  362. inc(arg_ofs);
  363. while (c[arg_ofs]=' ') or (c[arg_ofs]=#9) do inc(arg_ofs);
  364. end;
  365. { allocate second FCB see dosexec code }
  366. dosregs.ax:=$2901;
  367. dosregs.ds:=(la_c+arg_ofs) div 16;
  368. dosregs.si:=(la_c+arg_ofs) mod 16;
  369. dosregs.es:=fcb2_la div 16;
  370. dosregs.di:=fcb2_la mod 16;
  371. msdos(dosregs);
  372. with execblock do
  373. begin
  374. envseg:=la_env div 16;
  375. comtail.seg:=la_c div 16;
  376. comtail.ofs:=la_c mod 16;
  377. firstFCB.seg:=fcb1_la div 16;
  378. firstFCB.ofs:=fcb1_la mod 16;
  379. secondFCB.seg:=fcb2_la div 16;
  380. secondFCB.ofs:=fcb2_la mod 16;
  381. end;
  382. seg_move(get_ds,longint(@execblock),dosmemselector,la_e,sizeof(texecblock));
  383. dosregs.edx:=la_p mod 16;
  384. dosregs.ds:=la_p div 16;
  385. dosregs.ebx:=la_e mod 16;
  386. dosregs.es:=la_e div 16;
  387. dosregs.ax:=$4b00;
  388. msdos(dosregs);
  389. LoadDosError;
  390. if DosError=0 then
  391. begin
  392. dosregs.ax:=$4d00;
  393. msdos(dosregs);
  394. LastDosExitCode:=DosRegs.al
  395. end
  396. else
  397. LastDosExitCode:=0;
  398. end;
  399. { var
  400. p,c : array[0..255] of char; }
  401. var c : string;
  402. begin
  403. doserror:=0;
  404. { move(path[1],p,length(path));
  405. p[length(path)]:=#0; }
  406. move(comline[0],c[1],length(comline)+1);
  407. c[length(comline)+2]:=#13;
  408. c[0]:=char(length(comline)+2);
  409. do_system(path,c);
  410. end;
  411. {$else GO32V2}
  412. procedure exec(const path : pathstr;const comline : comstr);
  413. procedure do_system(p : pchar);
  414. begin
  415. asm
  416. movl 12(%ebp),%ebx
  417. movw $0xff07,%ax
  418. int $0x21
  419. movw %ax,_LASTDOSEXITCODE
  420. end;
  421. end;
  422. var
  423. i : longint;
  424. execute : string;
  425. b : array[0..255] of char;
  426. begin
  427. doserror:=0;
  428. execute:=path+' '+comline;
  429. { allow slash as backslash for the program name only }
  430. for i:=1 to length(path) do
  431. if execute[i]='/' then execute[i]:='\';
  432. move(execute[1],b,length(execute));
  433. b[length(execute)]:=#0;
  434. do_system(b);
  435. end;
  436. {$endif GO32V2}
  437. function dosexitcode : word;
  438. begin
  439. dosexitcode:=lastdosexitcode;
  440. end;
  441. procedure getcbreak(var breakvalue : boolean);
  442. begin
  443. dosregs.ax:=$3300;
  444. msdos(dosregs);
  445. breakvalue:=dosregs.dl<>0;
  446. end;
  447. procedure setcbreak(breakvalue : boolean);
  448. begin
  449. dosregs.ax:=$3301;
  450. dosregs.dl:=ord(breakvalue);
  451. msdos(dosregs);
  452. end;
  453. procedure getverify(var verify : boolean);
  454. begin
  455. dosregs.ah:=$54;
  456. msdos(dosregs);
  457. verify:=dosregs.al<>0;
  458. end;
  459. procedure setverify(verify : boolean);
  460. begin
  461. dosregs.ah:=$2e;
  462. dosregs.al:=ord(verify);
  463. msdos(dosregs);
  464. end;
  465. {******************************************************************************
  466. --- Disk ---
  467. ******************************************************************************}
  468. function diskfree(drive : byte) : longint;
  469. begin
  470. dosregs.dl:=drive;
  471. dosregs.ah:=$36;
  472. msdos(dosregs);
  473. if dosregs.ax<>$FFFF then
  474. diskfree:=dosregs.ax*dosregs.bx*dosregs.cx
  475. else
  476. diskfree:=-1;
  477. end;
  478. function disksize(drive : byte) : longint;
  479. begin
  480. dosregs.dl:=drive;
  481. dosregs.ah:=$36;
  482. msdos(dosregs);
  483. if dosregs.ax<>$FFFF then
  484. disksize:=dosregs.ax*dosregs.cx*dosregs.dx
  485. else
  486. disksize:=-1;
  487. end;
  488. {******************************************************************************
  489. --- Findfirst FindNext ---
  490. ******************************************************************************}
  491. procedure searchrec2dossearchrec(var f : searchrec);
  492. var
  493. l,i : longint;
  494. begin
  495. l:=length(f.name);
  496. for i:=1 to 12 do
  497. f.name[i-1]:=f.name[i];
  498. f.name[l]:=#0;
  499. end;
  500. procedure dossearchrec2searchrec(var f : searchrec);
  501. var
  502. l,i : longint;
  503. begin
  504. l:=12;
  505. for i:=0 to 12 do
  506. if f.name[i]=#0 then
  507. begin
  508. l:=i;
  509. break;
  510. end;
  511. for i:=11 downto 0 do
  512. f.name[i+1]:=f.name[i];
  513. f.name[0]:=chr(l);
  514. end;
  515. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  516. {$ifdef GO32V2}
  517. procedure _findfirst(path : pchar;attr : word;var f : searchrec);
  518. var
  519. i : longint;
  520. begin
  521. { allow slash as backslash }
  522. for i:=0 to strlen(path) do
  523. if path[i]='/' then path[i]:='\';
  524. copytodos(f,sizeof(searchrec));
  525. dosregs.edx:=transfer_buffer mod 16;
  526. dosregs.ds:=transfer_buffer div 16;
  527. dosregs.ah:=$1a;
  528. msdos(dosregs);
  529. dosregs.ecx:=attr;
  530. dosregs.edx:=(transfer_buffer mod 16) + Sizeof(searchrec)+1;
  531. dosmemput(transfer_buffer div 16,
  532. (transfer_buffer mod 16) +Sizeof(searchrec)+1,path^,strlen(path)+1);
  533. dosregs.ds:=transfer_buffer div 16;
  534. dosregs.ah:=$4e;
  535. msdos(dosregs);
  536. copyfromdos(f,sizeof(searchrec));
  537. LoadDosError;
  538. end;
  539. {$else GO32V2}
  540. procedure _findfirst(path : pchar;attr : word;var f : searchrec);
  541. var
  542. i : longint;
  543. begin
  544. { allow slash as backslash }
  545. for i:=0 to strlen(path) do
  546. if path[i]='/' then path[i]:='\';
  547. asm
  548. movl 18(%ebp),%edx
  549. movb $0x1a,%ah
  550. int $0x21
  551. movl 12(%ebp),%edx
  552. movzwl 16(%ebp),%ecx
  553. movb $0x4e,%ah
  554. int $0x21
  555. jnc .LFF
  556. movw %ax,U_DOS_DOSERROR
  557. .LFF:
  558. end;
  559. end;
  560. {$endif GO32V2}
  561. var
  562. path0 : array[0..80] of char;
  563. begin
  564. { no error }
  565. doserror:=0;
  566. strpcopy(path0,path);
  567. _findfirst(path0,attr,f);
  568. dossearchrec2searchrec(f);
  569. end;
  570. procedure findnext(var f : searchRec);
  571. {$ifdef GO32V2}
  572. procedure _findnext(var f : searchrec);
  573. begin
  574. copytodos(f,sizeof(searchrec));
  575. dosregs.edx:=transfer_buffer mod 16;
  576. dosregs.ds:=transfer_buffer div 16;
  577. dosregs.ah:=$1a;
  578. msdos(dosregs);
  579. dosregs.ah:=$4f;
  580. msdos(dosregs);
  581. copyfromdos(f,sizeof(searchrec));
  582. LoadDosError;
  583. end;
  584. {$else GO32V2}
  585. procedure _findnext(var f : searchrec);
  586. begin
  587. asm
  588. movl 12(%ebp),%edx
  589. movb $0x1a,%ah
  590. int $0x21
  591. movb $0x4f,%ah
  592. int $0x21
  593. jnc .LFN
  594. movw %ax,U_DOS_DOSERROR
  595. .LFN:
  596. end;
  597. end;
  598. {$endif GO32V2}
  599. begin
  600. { no error }
  601. doserror:=0;
  602. searchrec2dossearchrec(f);
  603. _findnext(f);
  604. dossearchrec2searchrec(f);
  605. end;
  606. procedure swapvectors;
  607. {$ifdef go32v2}
  608. { uses four global symbols from v2prt0.as
  609. to be able to know the current exception state
  610. without using dpmiexcp unit }
  611. begin
  612. asm
  613. movl _exception_exit,%eax
  614. orl %eax,%eax
  615. je .Lno_excep
  616. movl _v2prt0_exceptions_on,%eax
  617. orl %eax,%eax
  618. je .Lexceptions_off
  619. movl _swap_out,%eax
  620. call *%eax
  621. jmp .Lno_excep
  622. .Lexceptions_off:
  623. movl _swap_in,%eax
  624. call *%eax
  625. .Lno_excep:
  626. end;
  627. end;
  628. {$else not go32v2}
  629. begin
  630. { only a dummy }
  631. end;
  632. {$endif go32v2}
  633. Procedure FindClose(Var f: SearchRec);
  634. begin
  635. end;
  636. {******************************************************************************
  637. --- File ---
  638. ******************************************************************************}
  639. procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
  640. var
  641. p1,i : longint;
  642. begin
  643. { allow slash as backslash }
  644. for i:=1 to length(path) do
  645. if path[i]='/' then path[i]:='\';
  646. { get drive name }
  647. p1:=pos(':',path);
  648. if p1>0 then
  649. begin
  650. dir:=path[1]+':';
  651. delete(path,1,p1);
  652. end
  653. else
  654. dir:='';
  655. { split the path and the name, there are no more path informtions }
  656. { if path contains no backslashes }
  657. while true do
  658. begin
  659. p1:=pos('\',path);
  660. if p1=0 then
  661. break;
  662. dir:=dir+copy(path,1,p1);
  663. delete(path,1,p1);
  664. end;
  665. { try to find out a extension }
  666. p1:=pos('.',path);
  667. if p1>0 then
  668. begin
  669. ext:=copy(path,p1,4);
  670. delete(path,p1,length(path)-p1+1);
  671. end
  672. else
  673. ext:='';
  674. name:=path;
  675. end;
  676. function fexpand(const path : pathstr) : pathstr;
  677. var
  678. s,pa : string[79];
  679. i,j : longint;
  680. begin
  681. getdir(0,s);
  682. pa:=upcase(path);
  683. { allow slash as backslash }
  684. for i:=1 to length(pa) do
  685. if pa[i]='/' then
  686. pa[i]:='\';
  687. if (length(pa)>1) and (pa[1] in ['A'..'Z']) and (pa[2]=':') then
  688. begin
  689. { we must get the right directory }
  690. getdir(ord(pa[1])-ord('A')+1,s);
  691. if (ord(pa[0])>2) and (pa[3]<>'\') then
  692. if pa[1]=s[1] then
  693. pa:=s+'\'+copy (pa,3,length(pa))
  694. else
  695. pa:=pa[1]+':\'+copy (pa,3,length(pa))
  696. end
  697. else
  698. if pa[1]='\' then
  699. pa:=s[1]+':'+pa
  700. else if s[0]=#3 then
  701. pa:=s+pa
  702. else
  703. pa:=s+'\'+pa;
  704. {First remove all references to '\.\'}
  705. while pos ('\.\',pa)<>0 do
  706. delete (pa,pos('\.\',pa),2);
  707. {Now remove also all references to '\..\' + of course previous dirs..}
  708. repeat
  709. i:=pos('\..\',pa);
  710. if i<>0 then j:=i-1;
  711. while (j>1) and (pa[j]<>'\') do
  712. dec (j);
  713. delete (pa,j,i-j+3);
  714. until i=0;
  715. {Remove End . and \}
  716. if (length(pa)>0) and (pa[length(pa)]='.') then
  717. dec(byte(pa[0]));
  718. if (length(pa)>0) and (pa[length(pa)]='\') then
  719. dec(byte(pa[0]));
  720. fexpand:=pa;
  721. end;
  722. Function FSearch(path: pathstr; dirlist: string): pathstr;
  723. var
  724. i,p1 : longint;
  725. s : searchrec;
  726. newdir : pathstr;
  727. begin
  728. { No wildcards allowed in these things }
  729. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  730. fsearch:=''
  731. else
  732. begin
  733. { allow slash as backslash }
  734. for i:=1 to length(dirlist) do
  735. if dirlist[i]='/' then dirlist[i]:='\';
  736. repeat
  737. p1:=pos(';',dirlist);
  738. if p1=0 then
  739. begin
  740. newdir:=copy(dirlist,1,p1-1);
  741. delete(dirlist,1,p1);
  742. end
  743. else
  744. begin
  745. newdir:=dirlist;
  746. dirlist:='';
  747. end;
  748. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  749. newdir:=newdir+'\';
  750. findfirst(newdir+path,anyfile,s);
  751. if doserror=0 then
  752. newdir:=newdir+path
  753. else
  754. newdir:='';
  755. until (dirlist='') or (newdir<>'');
  756. fsearch:=newdir;
  757. end;
  758. end;
  759. {$ifdef GO32V2}
  760. procedure getftime(var f;var time : longint);
  761. begin
  762. dosregs.bx:=textrec(f).handle;
  763. dosregs.ax:=$5700;
  764. msdos(dosregs);
  765. time:=(dosregs.dx shl 16)+dosregs.cx;
  766. doserror:=dosregs.al;
  767. end;
  768. procedure setftime(var f;time : longint);
  769. begin
  770. dosregs.bx:=textrec(f).handle;
  771. dosregs.cx:=time and $ffff;
  772. dosregs.dx:=time shr 16;
  773. dosregs.ax:=$5701;
  774. msdos(dosregs);
  775. doserror:=dosregs.al;
  776. end;
  777. procedure getfattr(var f;var attr : word);
  778. begin
  779. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  780. dosregs.ax:=$4300;
  781. dosregs.edx:=transfer_buffer and 15;
  782. dosregs.ds:=transfer_buffer shr 4;
  783. msdos(dosregs);
  784. LoadDosError;
  785. Attr:=dosregs.cx;
  786. end;
  787. procedure setfattr(var f;attr : word);
  788. begin
  789. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  790. dosregs.ax:=$4301;
  791. dosregs.edx:=transfer_buffer mod 16;
  792. dosregs.ds:=transfer_buffer div 16;
  793. dosregs.cx:=attr;
  794. msdos(dosregs);
  795. LoadDosError;
  796. end;
  797. {$else GO32V2}
  798. procedure getfattr(var f;var attr : word);
  799. var
  800. n : array[0..255] of char;
  801. r : registers;
  802. begin
  803. strpcopy(n,filerec(f).name);
  804. dosregs.ax:=$4300;
  805. dosregs.edx:=longint(@n);
  806. msdos(dosregs);
  807. LoadDosError;
  808. attr:=dosregs.cx;
  809. end;
  810. procedure setfattr(var f;attr : word);
  811. var
  812. n : array[0..255] of char;
  813. r : registers;
  814. begin
  815. strpcopy(n,filerec(f).name);
  816. dosregs.ax:=$4301;
  817. dosregs.edx:=longint(@n);
  818. dosregs.cx:=attr;
  819. msdos(dosregs);
  820. LoadDosError;
  821. end;
  822. {$endif GO32V2}
  823. {******************************************************************************
  824. --- Environment ---
  825. ******************************************************************************}
  826. function envcount : longint;
  827. var
  828. hp : ppchar;
  829. begin
  830. hp:=envp;
  831. envcount:=0;
  832. while assigned(hp^) do
  833. begin
  834. inc(envcount);
  835. hp:=hp+4;
  836. end;
  837. end;
  838. function envstr(index : integer) : string;
  839. begin
  840. if (index<=0) or (index>envcount) then
  841. begin
  842. envstr:='';
  843. exit;
  844. end;
  845. envstr:=strpas(ppchar(envp+4*(index-1))^);
  846. end;
  847. Function GetEnv(envvar: string): string;
  848. var
  849. hp : ppchar;
  850. hs : string;
  851. eqpos : longint;
  852. begin
  853. envvar:=upcase(envvar);
  854. hp:=envp;
  855. getenv:='';
  856. while assigned(hp^) do
  857. begin
  858. hs:=strpas(hp^);
  859. eqpos:=pos('=',hs);
  860. if copy(hs,1,eqpos-1)=envvar then
  861. begin
  862. getenv:=copy(hs,eqpos+1,255);
  863. exit;
  864. end;
  865. hp:=hp+4;
  866. end;
  867. end;
  868. {******************************************************************************
  869. --- Not Supported ---
  870. ******************************************************************************}
  871. Procedure keep(exitcode : word);
  872. Begin
  873. End;
  874. Procedure getintvec(intno : byte;var vector : pointer);
  875. Begin
  876. End;
  877. Procedure setintvec(intno : byte;vector : pointer);
  878. Begin
  879. End;
  880. end.
  881. {
  882. $Log$
  883. Revision 1.3 1998-05-21 19:30:47 peter
  884. * objects compiles for linux
  885. + assign(pchar), assign(char), rename(pchar), rename(char)
  886. * fixed read_text_as_array
  887. + read_text_as_pchar which was not yet in the rtl
  888. }