dos.pp 25 KB

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