sysunix.inc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  6. This is the core of the system unit *nix systems (now FreeBSD
  7. and Unix).
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. { These things are set in the makefile, }
  15. { But you can override them here.}
  16. { If you use an aout system, set the conditional AOUT}
  17. { $Define AOUT}
  18. {$I system.inc}
  19. { used in syscall to report errors.}
  20. var
  21. Errno : longint;
  22. { Include constant and type definitions }
  23. {$i errno.inc } { Error numbers }
  24. {$i sysnr.inc } { System call numbers }
  25. {$i sysconst.inc } { Miscellaneous constants }
  26. {$i systypes.inc } { Types needed for system calls }
  27. { Read actual system call definitions. }
  28. {$i signal.inc}
  29. {$i syscalls.inc }
  30. {*****************************************************************************
  31. Misc. System Dependent Functions
  32. *****************************************************************************}
  33. {$ifdef I386}
  34. { this should be defined in i386 directory !! PM }
  35. const
  36. fpucw : word = $1332;
  37. FPU_Invalid = 1;
  38. FPU_Denormal = 2;
  39. FPU_DivisionByZero = 4;
  40. FPU_Overflow = 8;
  41. FPU_Underflow = $10;
  42. FPU_StackUnderflow = $20;
  43. FPU_StackOverflow = $40;
  44. {$endif I386}
  45. Procedure ResetFPU;
  46. begin
  47. {$ifdef I386}
  48. asm
  49. fninit
  50. fldcw fpucw
  51. end;
  52. {$endif I386}
  53. end;
  54. procedure prthaltproc;external name '_haltproc';
  55. Procedure System_exit;
  56. Begin
  57. prthaltproc;
  58. End;
  59. Function ParamCount: Longint;
  60. Begin
  61. Paramcount:=argc-1;
  62. End;
  63. Function ParamStr(l: Longint): String;
  64. var
  65. link,
  66. hs : string;
  67. i : longint;
  68. begin
  69. if l=0 then
  70. begin
  71. str(sys_getpid,hs);
  72. {$ifdef FreeBSD}
  73. hs:='/proc/'+hs+'/file'#0;
  74. {$else}
  75. hs:='/proc/'+hs+'/exe'#0;
  76. {$endif}
  77. i:=Sys_readlink(@hs[1],@link[1],high(link));
  78. { it must also be an absolute filename, linux 2.0 points to a memory
  79. location so this will skip that }
  80. if (i>0) and (link[1]='/') then
  81. begin
  82. link[0]:=chr(i);
  83. paramstr:=link;
  84. end
  85. else
  86. paramstr:=strpas(argv[0]);
  87. end
  88. else
  89. if (l>0) and (l<argc) then
  90. paramstr:=strpas(argv[l])
  91. else
  92. paramstr:='';
  93. end;
  94. Procedure Randomize;
  95. Begin
  96. randseed:=sys_time;
  97. End;
  98. {*****************************************************************************
  99. Heap Management
  100. *****************************************************************************}
  101. var
  102. _HEAP : pointer;external name 'HEAP';
  103. _HEAPSIZE : longint;external name 'HEAPSIZE';
  104. function getheapstart:pointer;assembler;
  105. {$undef fpc_getheapstart_ok}
  106. {$ifdef i386}
  107. {$define fpc_getheapstart_ok}
  108. asm
  109. leal _HEAP,%eax
  110. end ['EAX'];
  111. {$endif i386}
  112. {$ifdef m68k}
  113. {$define fpc_getheapstart_ok}
  114. asm
  115. lea.l _HEAP,a0
  116. move.l a0,d0
  117. end['A0','D0'];
  118. {$endif m68k}
  119. {$ifdef powerpc}
  120. {$define fpc_getheapstart_ok}
  121. asm
  122. lis r3,HEAP@ha
  123. la r3,HEAP@l(r3)
  124. end['R3'];
  125. {$endif powerpc}
  126. {$ifndef fpc_getheapstart_ok}
  127. asm
  128. end;
  129. {$error Getheapstart code is not implemented }
  130. {$endif not fpc_getheapstart_ok}
  131. function getheapsize:longint;assembler;
  132. {$undef fpc_getheapsize_ok}
  133. {$ifdef i386}
  134. {$define fpc_getheapsize_ok}
  135. asm
  136. movl _HEAPSIZE,%eax
  137. end ['EAX'];
  138. {$endif i386}
  139. {$ifdef m68k}
  140. {$define fpc_getheapsize_ok}
  141. asm
  142. move.l _HEAPSIZE,d0
  143. end ['D0'];
  144. {$endif m68k}
  145. {$ifdef powerpc}
  146. {$define fpc_getheapsize_ok}
  147. asm
  148. lis r9,HEAPSIZE@ha
  149. lwz r3,HEAPSIZE@l(r9)
  150. end ['R0','R9'];
  151. {$endif powerpc}
  152. {$ifndef fpc_getheapsize_ok}
  153. asm
  154. end;
  155. {$error Getheapsize code is not implemented }
  156. {$endif not fpc_getheapsize_ok}
  157. Function sbrk(size : longint) : Longint;
  158. begin
  159. sbrk:=Sys_mmap(0,Size,3,MAP_PRIVATE+MAP_ANONYMOUS,-1,0);
  160. if sbrk<>-1 then
  161. errno:=0;
  162. {! It must be -1, not 0 as before, see heap.inc. Should be in sysmmap?}
  163. end;
  164. { include standard heap management }
  165. {$I heap.inc}
  166. {*****************************************************************************
  167. Low Level File Routines
  168. *****************************************************************************}
  169. {
  170. The lowlevel file functions should take care of setting the InOutRes to the
  171. correct value if an error has occured, else leave it untouched
  172. }
  173. Procedure Errno2Inoutres;
  174. {
  175. Convert ErrNo error to the correct Inoutres value
  176. }
  177. begin
  178. if ErrNo=0 then { Else it will go through all the cases }
  179. exit;
  180. If errno<0 then Errno:=-errno;
  181. case ErrNo of
  182. Sys_ENFILE,
  183. Sys_EMFILE : Inoutres:=4;
  184. Sys_ENOENT : Inoutres:=2;
  185. Sys_EBADF : Inoutres:=6;
  186. Sys_ENOMEM,
  187. Sys_EFAULT : Inoutres:=217;
  188. Sys_EINVAL : Inoutres:=218;
  189. Sys_EPIPE,
  190. Sys_EINTR,
  191. Sys_EIO,
  192. Sys_EAGAIN,
  193. Sys_ENOSPC : Inoutres:=101;
  194. Sys_ENAMETOOLONG,
  195. Sys_ELOOP,
  196. Sys_ENOTDIR : Inoutres:=3;
  197. Sys_EROFS,
  198. Sys_EEXIST,
  199. Sys_EISDIR,
  200. Sys_ENOTEMPTY,
  201. Sys_EACCES : Inoutres:=5;
  202. Sys_ETXTBSY : Inoutres:=162;
  203. else
  204. InOutRes := Integer(Errno);
  205. end;
  206. end;
  207. Procedure Do_Close(Handle:Longint);
  208. Begin
  209. sys_close(Handle);
  210. {Errno2Inoutres;}
  211. End;
  212. Procedure Do_Erase(p:pchar);
  213. {$ifdef BSD}
  214. var FileInfo : Stat;
  215. {$endif}
  216. Begin
  217. {$ifdef BSD} {or POSIX}
  218. { verify if the filename is actually a directory }
  219. { if so return error and do nothing, as defined }
  220. { by POSIX }
  221. if sys_stat(p,fileinfo)<0 then
  222. begin
  223. Errno2Inoutres;
  224. exit;
  225. end;
  226. {$ifdef BSD}
  227. if (fileinfo.mode and STAT_IFMT)=STAT_IFDIR then
  228. {$else}
  229. if s_ISDIR(fileinfo.st_mode) then
  230. {$endif}
  231. begin
  232. InOutRes := 2;
  233. exit;
  234. end;
  235. {$endif}
  236. sys_unlink(p);
  237. Errno2Inoutres;
  238. {$ifdef Linux}
  239. { tp compatible result }
  240. if (Errno=Sys_EISDIR) then
  241. InOutRes:=2;
  242. {$endif}
  243. End;
  244. Procedure Do_Rename(p1,p2:pchar);
  245. Begin
  246. sys_rename(p1,p2);
  247. Errno2Inoutres;
  248. End;
  249. Function Do_Write(Handle,Addr,Len:Longint):longint;
  250. Begin
  251. repeat
  252. Do_Write:=sys_write(Handle,pchar(addr),len);
  253. until ErrNo<>Sys_EINTR;
  254. Errno2Inoutres;
  255. if Do_Write<0 then
  256. Do_Write:=0;
  257. End;
  258. Function Do_Read(Handle,Addr,Len:Longint):Longint;
  259. Begin
  260. repeat
  261. Do_Read:=sys_read(Handle,pchar(addr),len);
  262. until ErrNo<>Sys_EINTR;
  263. Errno2Inoutres;
  264. if Do_Read<0 then
  265. Do_Read:=0;
  266. End;
  267. Function Do_FilePos(Handle: Longint): Longint;
  268. Begin
  269. Do_FilePos:=sys_lseek(Handle, 0, Seek_Cur);
  270. Errno2Inoutres;
  271. End;
  272. Procedure Do_Seek(Handle,Pos:Longint);
  273. Begin
  274. sys_lseek(Handle, pos, Seek_set);
  275. errno2inoutres;
  276. End;
  277. Function Do_SeekEnd(Handle:Longint): Longint;
  278. begin
  279. Do_SeekEnd:=sys_lseek(Handle,0,Seek_End);
  280. errno2inoutres;
  281. end;
  282. Function Do_FileSize(Handle:Longint): Longint;
  283. var
  284. Info : Stat;
  285. Begin
  286. if sys_fstat(handle,info)=0 then
  287. Do_FileSize:=Info.Size
  288. else
  289. Do_FileSize:=0;
  290. Errno2Inoutres;
  291. End;
  292. Procedure Do_Truncate(Handle,fPos:longint);
  293. begin
  294. sys_ftruncate(handle,fpos);
  295. Errno2Inoutres;
  296. end;
  297. Procedure Do_Open(var f;p:pchar;flags:longint);
  298. {
  299. FileRec and textrec have both Handle and mode as the first items so
  300. they could use the same routine for opening/creating.
  301. when (flags and $100) the file will be append
  302. when (flags and $1000) the file will be truncate/rewritten
  303. when (flags and $10000) there is no check for close (needed for textfiles)
  304. }
  305. var
  306. oflags : longint;
  307. Begin
  308. { close first if opened }
  309. if ((flags and $10000)=0) then
  310. begin
  311. case FileRec(f).mode of
  312. fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle);
  313. fmclosed : ;
  314. else
  315. begin
  316. inoutres:=102; {not assigned}
  317. exit;
  318. end;
  319. end;
  320. end;
  321. { reset file Handle }
  322. FileRec(f).Handle:=UnusedHandle;
  323. { We do the conversion of filemodes here, concentrated on 1 place }
  324. case (flags and 3) of
  325. 0 : begin
  326. oflags :=Open_RDONLY;
  327. FileRec(f).mode:=fminput;
  328. end;
  329. 1 : begin
  330. oflags :=Open_WRONLY;
  331. FileRec(f).mode:=fmoutput;
  332. end;
  333. 2 : begin
  334. oflags :=Open_RDWR;
  335. FileRec(f).mode:=fminout;
  336. end;
  337. end;
  338. if (flags and $1000)=$1000 then
  339. oflags:=oflags or (Open_CREAT or Open_TRUNC)
  340. else
  341. if (flags and $100)=$100 then
  342. oflags:=oflags or (Open_APPEND);
  343. { empty name is special }
  344. if p[0]=#0 then
  345. begin
  346. case FileRec(f).mode of
  347. fminput :
  348. FileRec(f).Handle:=StdInputHandle;
  349. fminout, { this is set by rewrite }
  350. fmoutput :
  351. FileRec(f).Handle:=StdOutputHandle;
  352. fmappend :
  353. begin
  354. FileRec(f).Handle:=StdOutputHandle;
  355. FileRec(f).mode:=fmoutput; {fool fmappend}
  356. end;
  357. end;
  358. exit;
  359. end;
  360. { real open call }
  361. FileRec(f).Handle:=sys_open(p,oflags,438);
  362. if (ErrNo=Sys_EROFS) and ((OFlags and Open_RDWR)<>0) then
  363. begin
  364. Oflags:=Oflags and not(Open_RDWR);
  365. FileRec(f).Handle:=sys_open(p,oflags,438);
  366. end;
  367. Errno2Inoutres;
  368. End;
  369. Function Do_IsDevice(Handle:Longint):boolean;
  370. {
  371. Interface to Unix ioctl call.
  372. Performs various operations on the filedescriptor Handle.
  373. Ndx describes the operation to perform.
  374. Data points to data needed for the Ndx function. The structure of this
  375. data is function-dependent.
  376. }
  377. var
  378. Data : array[0..255] of byte; {Large enough for termios info}
  379. begin
  380. Do_IsDevice:=(sys_ioctl(handle,IOCTL_TCGETS,@data)<>-1);
  381. end;
  382. {*****************************************************************************
  383. UnTyped File Handling
  384. *****************************************************************************}
  385. {$i file.inc}
  386. {*****************************************************************************
  387. Typed File Handling
  388. *****************************************************************************}
  389. {$i typefile.inc}
  390. {*****************************************************************************
  391. Text File Handling
  392. *****************************************************************************}
  393. {$DEFINE SHORT_LINEBREAK}
  394. {$DEFINE EXTENDED_EOF}
  395. {$i text.inc}
  396. {*****************************************************************************
  397. Directory Handling
  398. *****************************************************************************}
  399. Procedure MkDir(Const s: String);[IOCheck];
  400. Var
  401. Buffer: Array[0..255] of Char;
  402. Begin
  403. If (s='') or (InOutRes <> 0) then
  404. exit;
  405. Move(s[1], Buffer, Length(s));
  406. Buffer[Length(s)] := #0;
  407. sys_mkdir(@buffer, 511);
  408. Errno2Inoutres;
  409. End;
  410. Procedure RmDir(Const s: String);[IOCheck];
  411. Var
  412. Buffer: Array[0..255] of Char;
  413. Begin
  414. if (s ='.') then
  415. InOutRes := 16;
  416. If (s='') or (InOutRes <> 0) then
  417. exit;
  418. Move(s[1], Buffer, Length(s));
  419. Buffer[Length(s)] := #0;
  420. sys_rmdir(@buffer);
  421. {$ifdef BSD}
  422. if (Errno=Sys_EINVAL) Then
  423. InOutRes:=5
  424. Else
  425. {$endif}
  426. Errno2Inoutres;
  427. End;
  428. Procedure ChDir(Const s: String);[IOCheck];
  429. Var
  430. Buffer: Array[0..255] of Char;
  431. Begin
  432. If (s='') or (InOutRes <> 0) then
  433. exit;
  434. Move(s[1], Buffer, Length(s));
  435. Buffer[Length(s)] := #0;
  436. sys_chdir(@buffer);
  437. Errno2Inoutres;
  438. { file not exists is path not found under tp7 }
  439. if InOutRes=2 then
  440. InOutRes:=3;
  441. End;
  442. procedure GetDir (DriveNr: byte; var Dir: ShortString);
  443. var
  444. thisdir : stat;
  445. rootino,
  446. thisino,
  447. dotdotino : longint;
  448. rootdev,
  449. thisdev,
  450. dotdotdev : dev_t;
  451. thedir,dummy : string[255];
  452. dirstream : pdir;
  453. d : pdirent;
  454. mountpoint,validdir : boolean;
  455. predot : string[255];
  456. begin
  457. drivenr:=0;
  458. dir:='';
  459. thedir:='/'#0;
  460. if sys_stat(@thedir[1],thisdir)<0 then
  461. exit;
  462. rootino:=thisdir.ino;
  463. rootdev:=thisdir.dev;
  464. thedir:='.'#0;
  465. if sys_stat(@thedir[1],thisdir)<0 then
  466. exit;
  467. thisino:=thisdir.ino;
  468. thisdev:=thisdir.dev;
  469. { Now we can uniquely identify the current and root dir }
  470. thedir:='';
  471. predot:='';
  472. while not ((thisino=rootino) and (thisdev=rootdev)) do
  473. begin
  474. { Are we on a mount point ? }
  475. dummy:=predot+'..'#0;
  476. if sys_stat(@dummy[1],thisdir)<0 then
  477. exit;
  478. dotdotino:=thisdir.ino;
  479. dotdotdev:=thisdir.dev;
  480. mountpoint:=(thisdev<>dotdotdev);
  481. { Now, Try to find the name of this dir in the previous one }
  482. dirstream:=opendir (@dummy[1]);
  483. if dirstream=nil then
  484. exit;
  485. repeat
  486. d:=sys_readdir (dirstream);
  487. validdir:=false;
  488. if (d<>nil) and
  489. (not ((d^.name[0]='.') and ((d^.name[1]=#0) or ((d^.name[1]='.')
  490. and (d^.name[2]=#0))))) and
  491. (mountpoint or (d^.ino=thisino)) then
  492. begin
  493. dummy:=predot+'../'+strpas(@(d^.name[0]))+#0;
  494. validdir:=not (sys_stat (@(dummy[1]),thisdir)<0);
  495. end
  496. else
  497. validdir:=false;
  498. until (d=nil) or
  499. ((validdir) and (thisdir.dev=thisdev) and (thisdir.ino=thisino) );
  500. { At this point, d.name contains the name of the current dir}
  501. if (d<>nil) then
  502. thedir:='/'+strpas(@(d^.name[0]))+thedir;
  503. { closedir also makes d invalid }
  504. if (closedir(dirstream)<0) or (d=nil) then
  505. exit;
  506. thisdev:=dotdotdev;
  507. thisino:=dotdotino;
  508. predot:=predot+'../';
  509. end;
  510. { Now rootino=thisino and rootdev=thisdev so we've reached / }
  511. dir:=thedir
  512. end;
  513. {$ifdef Unix}
  514. {*****************************************************************************
  515. Thread Handling
  516. *****************************************************************************}
  517. { include threading stuff, this is os independend part }
  518. {$I thread.inc}
  519. {$endif Unix}
  520. {*****************************************************************************
  521. SystemUnit Initialization
  522. *****************************************************************************}
  523. {$ifdef BSD}
  524. procedure SignalToRunerror(Sig: longint; SigContext: SigContextRec;someptr:pointer); cdecl;
  525. {$else}
  526. {$ifdef Solaris}
  527. procedure SignalToRunerror(Sig: longint; SigContext: SigContextRec;someptr:pointer); cdecl;
  528. {$else}
  529. procedure SignalToRunerror(Sig: longint; SigContext: SigContextRec); cdecl;
  530. {$endif}
  531. {$ENDIF}
  532. var
  533. res,fpustate : word;
  534. begin
  535. res:=0;
  536. case sig of
  537. SIGFPE :
  538. begin
  539. { this is not allways necessary but I don't know yet
  540. how to tell if it is or not PM }
  541. {$ifdef I386}
  542. fpustate:=0;
  543. res:=200;
  544. {$ifndef FreeBSD}
  545. if assigned(SigContext.fpstate) then
  546. fpuState:=SigContext.fpstate^.sw;
  547. {$else}
  548. fpustate:=SigContext.en_sw;
  549. {$ifdef SYSTEM_DEBUG}
  550. writeln('xx:',sigcontext.en_tw,' ',sigcontext.en_cw);
  551. {$endif SYSTEM_DEBUG}
  552. {$endif}
  553. {$ifdef SYSTEM_DEBUG}
  554. Writeln(stderr,'FpuState = ',FpuState);
  555. {$endif SYSTEM_DEBUG}
  556. if (FpuState and $7f) <> 0 then
  557. begin
  558. { first check te more precise options }
  559. if (FpuState and FPU_DivisionByZero)<>0 then
  560. res:=200
  561. else if (FpuState and FPU_Overflow)<>0 then
  562. res:=205
  563. else if (FpuState and FPU_Underflow)<>0 then
  564. res:=206
  565. else if (FpuState and FPU_Denormal)<>0 then
  566. res:=216
  567. else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow))<>0 then
  568. res:=207
  569. else if (FpuState and FPU_Invalid)<>0 then
  570. res:=216
  571. else
  572. res:=207; {'Coprocessor Error'}
  573. end;
  574. {$endif I386}
  575. ResetFPU;
  576. end;
  577. SIGILL,
  578. SIGBUS,
  579. SIGSEGV :
  580. res:=216;
  581. end;
  582. { give runtime error at the position where the signal was raised }
  583. if res<>0 then
  584. begin
  585. {$ifdef I386}
  586. {$ifdef FreeBSD}
  587. HandleErrorAddrFrame(res,SigContext.sc_eip,SigContext.sc_ebp);
  588. {$else}
  589. HandleErrorAddrFrame(res,SigContext.eip,SigContext.ebp);
  590. {$endif}
  591. {$else}
  592. HandleError(res);
  593. {$endif}
  594. end;
  595. end;
  596. Procedure InstallSignals;
  597. const
  598. {$Ifndef BSD}
  599. {$ifdef solaris}
  600. act: SigActionRec =(sa_flags:SA_SIGINFO;Handler:(sa:@signaltorunerror;sa_mask:0);
  601. {$else}
  602. act: SigActionRec = (handler:(Sa:@SignalToRunError);sa_mask:0;sa_flags:0;
  603. Sa_restorer: NIL);
  604. {$endif}
  605. {$ELSE}
  606. act: SigActionRec = (handler:(Sa:@SignalToRunError);sa_flags:SA_SIGINFO;
  607. sa_mask:0);
  608. {$endif}
  609. oldact: PSigActionRec = Nil; {Probably not necessary anymore, now
  610. VAR is removed}
  611. begin
  612. ResetFPU;
  613. SigAction(SIGFPE,@act,oldact);
  614. {$ifndef Solaris}
  615. SigAction(SIGSEGV,@act,oldact);
  616. SigAction(SIGBUS,@act,oldact);
  617. SigAction(SIGILL,@act,oldact);
  618. {$endif}
  619. end;
  620. procedure SetupCmdLine;
  621. var
  622. bufsize,
  623. len,j,
  624. size,i : longint;
  625. found : boolean;
  626. buf : array[0..1026] of char;
  627. procedure AddBuf;
  628. begin
  629. reallocmem(cmdline,size+bufsize);
  630. move(buf,cmdline[size],bufsize);
  631. inc(size,bufsize);
  632. bufsize:=0;
  633. end;
  634. begin
  635. size:=0;
  636. bufsize:=0;
  637. i:=0;
  638. while (i<argc) do
  639. begin
  640. len:=strlen(argv[i]);
  641. if len>sizeof(buf)-2 then
  642. len:=sizeof(buf)-2;
  643. found:=false;
  644. for j:=1 to len do
  645. if argv[i][j]=' ' then
  646. begin
  647. found:=true;
  648. break;
  649. end;
  650. if bufsize+len>=sizeof(buf)-2 then
  651. AddBuf;
  652. if found then
  653. begin
  654. buf[bufsize]:='"';
  655. inc(bufsize);
  656. end;
  657. move(argv[i]^,buf[bufsize],len);
  658. inc(bufsize,len);
  659. if found then
  660. begin
  661. buf[bufsize]:='"';
  662. inc(bufsize);
  663. end;
  664. if i<argc then
  665. buf[bufsize]:=' '
  666. else
  667. buf[bufsize]:=#0;
  668. inc(bufsize);
  669. inc(i);
  670. end;
  671. AddBuf;
  672. end;
  673. Begin
  674. IsConsole := TRUE;
  675. IsLibrary := FALSE;
  676. StackBottom := Sptr - StackLength;
  677. { Set up signals handlers }
  678. InstallSignals;
  679. { Setup heap }
  680. InitHeap;
  681. InitExceptions;
  682. { Arguments }
  683. SetupCmdLine;
  684. { Setup stdin, stdout and stderr }
  685. OpenStdIO(Input,fmInput,StdInputHandle);
  686. OpenStdIO(Output,fmOutput,StdOutputHandle);
  687. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  688. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  689. { Reset IO Error }
  690. InOutRes:=0;
  691. End.
  692. {
  693. $Log$
  694. Revision 1.28 2002-09-02 19:46:37 florian
  695. * fixed line breaks
  696. Revision 1.27 2002/08/31 21:29:57 florian
  697. * several PC related fixes
  698. Revision 1.26 2002/08/13 18:11:08 florian
  699. * heap stuff for powerpc fixed
  700. Revision 1.25 2002/08/03 20:05:13 florian
  701. + ppc implementation of heap functions added
  702. Revision 1.24 2002/07/29 21:28:17 florian
  703. * several fixes to get further with linux/ppc system unit compilation
  704. Revision 1.23 2002/07/28 20:43:49 florian
  705. * several fixes for linux/powerpc
  706. * several fixes to MT
  707. Revision 1.22 2002/05/31 13:37:24 marco
  708. * more Renamefest
  709. Revision 1.21 2002/04/21 15:55:00 carl
  710. + initialize some global variables
  711. Revision 1.20 2002/04/12 17:43:28 carl
  712. + generic stack checking
  713. Revision 1.19 2002/03/11 19:10:33 peter
  714. * Regenerated with updated fpcmake
  715. Revision 1.18 2001/10/14 13:33:21 peter
  716. * start of thread support for linux
  717. Revision 1.17 2001/09/30 21:10:20 peter
  718. * erase(directory) returns now 2 to be tp compatible
  719. Revision 1.16 2001/08/05 12:24:20 peter
  720. * m68k merges
  721. Revision 1.15 2001/07/16 19:51:36 marco
  722. * A small note, copied from the Solaris patch. Do_close needs errnotoiores?
  723. Revision 1.14 2001/07/15 11:57:16 peter
  724. * merged m68k updates
  725. Revision 1.13 2001/07/13 22:05:09 peter
  726. * cygwin updates
  727. Revision 1.12 2001/06/02 19:24:49 peter
  728. * chdir rte 2 mapped to 3
  729. Revision 1.11 2001/06/02 00:31:31 peter
  730. * merge unix updates from the 1.0 branch, mostly related to the
  731. solaris target
  732. Revision 1.10 2001/04/23 20:33:31 peter
  733. * also install sig handlers for sigill,sigbus
  734. Revision 1.9 2001/04/13 22:39:05 peter
  735. * removed warning
  736. Revision 1.8 2001/04/12 17:53:43 peter
  737. * fixed usage of already release memory in getdir
  738. Revision 1.7 2001/03/21 21:08:20 hajny
  739. * GetDir fixed
  740. Revision 1.6 2001/03/16 20:09:58 hajny
  741. * universal FExpand
  742. Revision 1.5 2001/02/20 21:31:12 peter
  743. * chdir,mkdir,rmdir with empty string fixed
  744. Revision 1.4 2000/12/17 14:00:57 peter
  745. * removed debug writelns
  746. Revision 1.3 2000/10/09 16:35:51 marco
  747. * Fixed the first (of many) ioctls that make building the IDE hard.
  748. Revision 1.2 2000/09/18 13:14:51 marco
  749. * Global Linux +bsd to (rtl/freebsd rtl/unix rtl/linux structure)
  750. Revision 1.6 2000/09/11 13:48:08 marco
  751. * FreeBSD support and removal of old sighandler
  752. Revision 1.5 2000/08/13 08:43:45 peter
  753. * don't check for directory in do_open (merged)
  754. Revision 1.4 2000/08/05 18:33:51 peter
  755. * paramstr(0) fix for linux 2.0 kernels (merged)
  756. Revision 1.3 2000/07/14 10:33:10 michael
  757. + Conditionals fixed
  758. Revision 1.2 2000/07/13 11:33:49 michael
  759. + removed logs
  760. }