osposix.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. {
  2. $Id$
  3. Copyright (c) 2001 by Carl Eric Codere
  4. Implements roughly POSIX 1003.1 conforming interface for *BSD
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {$ifdef uselibc}
  19. {$Linklib c}
  20. { var
  21. Errno : cint; external name 'errno';}
  22. function sys_time(var tloc:time_t): time_t; cdecl; external name 'time';
  23. function sys_open(const path: pchar; flags : cint; mode: mode_t):cint; cdecl; external name 'open';
  24. function sys_close(fd : cint): cint; cdecl; external name 'close';
  25. function sys_lseek(fd : cint; offset : off_t; whence : cint): off_t; cdecl; external name 'lseek';
  26. function sys_read(fd: cint; buf: pchar; nbytes : size_t): ssize_t; cdecl; external name 'read';
  27. function sys_write(fd: cint;const buf:pchar; nbytes : size_t): ssize_t; cdecl; external name 'write';
  28. function sys_unlink(const path: pchar): cint; cdecl; external name 'unlink';
  29. function sys_rename(const old : pchar; const newpath: pchar): cint; cdecl;external name 'rename';
  30. function sys_stat(const path: pchar; var buf : stat): cint; cdecl; external name 'stat';
  31. function sys_chdir(const path : pchar): cint; cdecl; external name 'chdir';
  32. function sys_mkdir(const path : pchar; mode: mode_t):cint; cdecl; external name 'mkdir';
  33. function sys_rmdir(const path : pchar): cint; cdecl; external name 'rmdir';
  34. function sys_opendir(const dirname : pchar): pdir; cdecl; external name 'opendir';
  35. function sys_readdir(dirp : pdir) : pdirent;cdecl; external name 'readdir';
  36. function sys_closedir(dirp : pdir): cint; cdecl; external name 'closedir';
  37. procedure sys_exit(status : cint); cdecl; external name '_exit';
  38. function sys_sigaction(sig: cint; var act : sigactionrec; var oact : sigactionrec): cint; cdecl; external name 'sigaction';
  39. function sys_ftruncate(fd : cint; flength : off_t): cint; cdecl; external name 'ftruncate';
  40. function sys_rename(const old : pchar; const newpath: pchar): cint; cdecl;external name 'rename';
  41. function sys_fstat(fd : cint; var sb : stat): cint; cdecl; external name 'fstat';
  42. function sys_fork : pid_t; cdecl; external name 'fork';
  43. function sys_execve(const path : pchar; const argv : ppchar; const envp: ppchar): cint; cdecl; external name 'execve';
  44. function sys_waitpid(pid : pid_t; var stat_loc : cint; options: cint): pid_t; cdecl; external name 'waitpid';
  45. function sys_access(const pathname : pchar; amode : cint): cint; cdecl; external name 'access';
  46. // function sys_uname(var name: utsname): cint; cdecl; external name 'uname';
  47. function sys_Dup(oldd:cint):cint; cdecl; external name 'dup';
  48. function sys_Dup2(oldd:cint;newd:cint):cint; cdecl; external name 'dup2';
  49. {$else}
  50. {*****************************************************************************
  51. --- Main:The System Call Self ---
  52. *****************************************************************************}
  53. { The system designed for Linux can't be used for FreeBSD so easily, since
  54. FreeBSD pushes arguments, instead of loading them to registers.}
  55. Var ErrNo : Longint;
  56. {$I syscall.inc}
  57. {$I sysnr2.inc}
  58. // Should be moved to a FreeBSD specific unit in the future.
  59. Type
  60. timeval = packed record
  61. sec,usec:clong;
  62. end;
  63. ptimeval = ^timeval;
  64. TTimeVal = timeval;
  65. timespec = packed record
  66. tv_sec : time_t;
  67. tv_nsec : clong;
  68. end;
  69. timezone = packed record
  70. minuteswest,
  71. dsttime : cint;
  72. end;
  73. ptimezone =^timezone;
  74. TTimeZone = timezone;
  75. function sys_time(var tloc:time_t): time_t;
  76. VAR tv : timeval;
  77. tz : timezone;
  78. retval : longint;
  79. begin
  80. Retval:=do_syscall(syscall_nr_gettimeofday,longint(@tv),longint(@tz));
  81. If retval=-1 then
  82. sys_time:=-1
  83. else
  84. Begin
  85. // If Assigned(tloc) Then
  86. TLoc:=tv.sec;
  87. sys_time:=tv.sec;
  88. End;
  89. End;
  90. {*****************************************************************************
  91. --- File:File handling related calls ---
  92. *****************************************************************************}
  93. function sys_open(const path: pchar; flags : cint; mode: mode_t):cint;
  94. Begin
  95. sys_open:=do_syscall(syscall_nr_open,longint(path),longint(flags),longint(mode));
  96. End;
  97. function sys_close(fd : cint): cint;
  98. begin
  99. sys_close:=do_syscall(syscall_nr_close,fd);
  100. end;
  101. function sys_lseek(fd : cint; offset : off_t; whence : cint): off_t;
  102. {
  103. this one is special for the return value being 64-bit..
  104. hi/lo offset not yet tested.
  105. NetBSD: ok, but implicit return value in edx:eax
  106. FreeBSD: same implementation as NetBSD.
  107. }
  108. begin
  109. {ugly implicit returnvalue}
  110. do_syscall(syscall_nr___syscall,syscall_nr_lseek,0,longint(fd),0,lo(Offset),{0} hi(offset),Whence);
  111. end;
  112. function sys_read(fd: cint; buf: pchar; nbytes : size_t): ssize_t;
  113. begin
  114. sys_read:=do_syscall(syscall_nr_read,Fd,longint(buf),nbytes);
  115. end;
  116. function sys_write(fd: cint;const buf:pchar; nbytes : size_t): ssize_t;
  117. begin
  118. sys_write:=do_syscall(syscall_nr_write,Fd,longint(buf),nbytes);
  119. end;
  120. function sys_unlink(const path: pchar): cint;
  121. begin
  122. sys_unlink:=do_syscall(syscall_nr_unlink,longint(path));
  123. end;
  124. function sys_rename(const old : pchar; const newpath: pchar): cint;
  125. begin
  126. sys_rename:=do_syscall(syscall_nr_rename,longint(old),longint(newpath));
  127. end;
  128. function sys_stat(const path: pchar; var buf : stat):cint;
  129. begin
  130. sys_stat:=do_syscall(syscall_nr_stat,longint(path),longint(@buf));
  131. end;
  132. {*****************************************************************************
  133. --- Directory:Directory related calls ---
  134. *****************************************************************************}
  135. function sys_chdir(const path : pchar): cint;
  136. begin
  137. sys_chdir:=do_syscall(syscall_nr_chdir,longint(path));
  138. end;
  139. function sys_mkdir(const path : pchar; mode: mode_t):cint;
  140. begin {Mode is 16-bit on F-BSD}
  141. sys_mkdir:=do_syscall(syscall_nr_mkdir,longint(path),mode);
  142. end;
  143. function sys_rmdir(const path : pchar): cint;
  144. begin
  145. sys_rmdir:=do_syscall(syscall_nr_rmdir,longint(path));
  146. end;
  147. {$ifndef NewReaddir}
  148. const DIRBLKSIZ=1024;
  149. function sys_opendir(const dirname : pchar): pdir;
  150. var
  151. fd:longint;
  152. st:stat;
  153. ptr:pdir;
  154. begin
  155. sys_opendir:=nil;
  156. if sys_stat(dirname,st)<0 then
  157. exit;
  158. { Is it a dir ? }
  159. if not((st.st_mode and $f000)=$4000)then
  160. begin
  161. errno:=sys_enotdir;
  162. exit
  163. end;
  164. { Open it}
  165. fd:=sys_open(dirname,O_RDONLY,438);
  166. if fd<0 then
  167. Begin
  168. Errno:=-1;
  169. exit;
  170. End;
  171. new(ptr);
  172. if ptr=nil then
  173. Begin
  174. Errno:=1;
  175. exit;
  176. End;
  177. Getmem(ptr^.dd_buf,2*DIRBLKSIZ);
  178. if ptr^.dd_buf=nil then
  179. exit;
  180. ptr^.dd_fd:=fd;
  181. ptr^.dd_loc:=-1;
  182. ptr^.dd_rewind:=longint(ptr^.dd_buf);
  183. ptr^.dd_size:=0;
  184. // ptr^.dd_max:=sizeof(ptr^.dd_buf^);
  185. sys_opendir:=ptr;
  186. end;
  187. function sys_closedir(dirp : pdir): cint;
  188. begin
  189. sys_closedir:=sys_close(dirp^.dd_fd);
  190. Freemem(dirp^.dd_buf);
  191. dispose(dirp);
  192. end;
  193. function sys_readdir(dirp : pdir) : pdirent;
  194. {Different from Linux, Readdir on BSD is based on Getdents, due to the
  195. missing of the readdir syscall.
  196. Getdents requires the buffer to be larger than the blocksize.
  197. This usually the sectorsize =512 bytes, but maybe tapedrives and harddisks
  198. with blockmode have this higher?}
  199. function readbuffer:longint;
  200. var retval :longint;
  201. begin
  202. Retval:=do_syscall(syscall_nr_getdents,longint(dirp^.dd_fd),longint(@dirp^.dd_buf^),DIRBLKSIZ {sizeof(getdentsbuffer)});
  203. dirp^.dd_rewind:=longint(dirp^.dd_buf);
  204. if retval=0 then
  205. begin
  206. dirp^.dd_rewind:=0;
  207. dirp^.dd_loc:=0;
  208. end
  209. else
  210. dirP^.dd_loc:=retval;
  211. readbuffer:=retval;
  212. end;
  213. var
  214. FinalEntry : pdirent;
  215. novalid : boolean;
  216. Reclen : Longint;
  217. CurEntry : PDirent;
  218. begin
  219. if (dirp^.dd_buf=nil) or (dirp^.dd_loc=0) THEN
  220. exit(nil);
  221. if (dirp^.dd_loc=-1) OR {First readdir on this pdir. Initial fill of buffer}
  222. (dirp^.dd_rewind>=(longint(dirp^.dd_buf)+dirblksiz)) then {no more entries left?}
  223. Begin
  224. if readbuffer=0 then {succesful read?}
  225. Exit(NIL); {No more data}
  226. End;
  227. FinalEntry:=NIL;
  228. CurEntry:=nil;
  229. repeat
  230. novalid:=false;
  231. CurEntry:=pdirent(dirp^.dd_rewind);
  232. RecLen:=CurEntry^.d_reclen;
  233. if RecLen<>0 Then
  234. begin {valid direntry?}
  235. if CurEntry^.d_fileno<>0 then
  236. FinalEntry:=CurEntry;
  237. inc(dirp^.dd_rewind,Reclen);
  238. end
  239. else
  240. begin {block entirely searched or reclen=0}
  241. Novalid:=True;
  242. if dirp^.dd_loc<>0 THEN {blocks left?}
  243. if readbuffer()<>0 then {succesful read?}
  244. novalid:=false;
  245. end;
  246. until (FinalEntry<>nil) or novalid;
  247. If novalid then
  248. FinalEntry:=nil;
  249. Sys_ReadDir:=FinalEntry;
  250. end;
  251. {$endif}
  252. {*****************************************************************************
  253. --- Process:Process & program handling - related calls ---
  254. *****************************************************************************}
  255. procedure sys_exit(status : cint);
  256. begin
  257. do_syscall(syscall_nr_exit,status);
  258. end;
  259. {
  260. Change action of process upon receipt of a signal.
  261. Signum specifies the signal (all except SigKill and SigStop).
  262. If Act is non-nil, it is used to specify the new action.
  263. If OldAct is non-nil the previous action is saved there.
  264. }
  265. function sys_sigaction(sig: cint; var act : sigactionrec; var oact : sigactionrec): cint;
  266. {
  267. Change action of process upon receipt of a signal.
  268. Signum specifies the signal (all except SigKill and SigStop).
  269. If Act is non-nil, it is used to specify the new action.
  270. If OldAct is non-nil the previous action is saved there.
  271. }
  272. begin
  273. do_syscall(syscall_nr_sigaction,longint(sig),longint(@act),longint(@oact));
  274. end;
  275. (*=================== MOVED from sysunix.inc ========================*)
  276. function sys_ftruncate(fd : cint; flength : off_t): cint;
  277. { See notes lseek. This one is completely similar.
  278. }
  279. begin
  280. Do_syscall(syscall_nr___syscall,syscall_nr_ftruncate,0,fd,0,lo(flength),hi(flength));
  281. end;
  282. function sys_fstat(fd : cint; var sb : stat): cint;
  283. begin
  284. Sys_FStat:=do_SysCall(syscall_nr_fstat,fd,longint(@sb));
  285. end;
  286. {$ifdef NewReaddir}
  287. {$I readdir.inc}
  288. {$endif}
  289. function sys_fork : pid_t;
  290. {
  291. This function issues the 'fork' System call. the program is duplicated in memory
  292. and Execution continues in parent and child process.
  293. In the parent process, fork returns the PID of the child. In the child process,
  294. zero is returned.
  295. A negative value indicates that an error has occurred, the error is returned in
  296. LinuxError.
  297. }
  298. Begin
  299. sys_fork:=Do_syscall(SysCall_nr_fork);
  300. End;
  301. {
  302. function sys_execve(const path : pathstr; const argv : ppchar; const envp: ppchar): cint;
  303. }
  304. {
  305. Replaces the current program by the program specified in path,
  306. arguments in args are passed to Execve.
  307. environment specified in ep is passed on.
  308. }
  309. {
  310. Begin
  311. path:=path+#0;
  312. do_syscall(syscall_nr_Execve,longint(@path[1]),longint(Argv),longint(envp));
  313. End;
  314. }
  315. function sys_execve(const path : pchar; const argv : ppchar; const envp: ppchar): cint;
  316. {
  317. Replaces the current program by the program specified in path,
  318. arguments in args are passed to Execve.
  319. environment specified in ep is passed on.
  320. }
  321. Begin
  322. do_syscall(syscall_nr_Execve,longint(path),longint(Argv),longint(envp));
  323. End;
  324. function sys_waitpid(pid : pid_t; var stat_loc : cint; options: cint): pid_t;
  325. {
  326. Waits until a child with PID Pid exits, or returns if it is exited already.
  327. Any resources used by the child are freed.
  328. The exit status is reported in the adress referred to by Status. It should
  329. be a longint.
  330. }
  331. begin
  332. sys_WaitPID:=do_syscall(syscall_nr_WaitPID,PID,longint(Stat_loc),options,0);
  333. end;
  334. function sys_access(const pathname : pchar; amode : cint): cint;
  335. {
  336. Test users access rights on the specified file.
  337. Mode is a mask xosisting of one or more of R_OK, W_OK, X_OK, F_OK.
  338. R,W,X stand for read,write and Execute access, simultaneously.
  339. F_OK checks whether the test would be allowed on the file.
  340. i.e. It checks the search permissions in all directory components
  341. of the path.
  342. The test is done with the real user-ID, instead of the effective.
  343. If access is denied, or an error occurred, false is returned.
  344. If access is granted, true is returned.
  345. Errors other than no access,are reported in unixerror.
  346. }
  347. begin
  348. sys_Access:=do_syscall(syscall_nr_access,longint(pathname),amode);
  349. end;
  350. {
  351. function sys_access(const pathname : pathstr; amode : cint): cint;
  352. {
  353. Test users access rights on the specified file.
  354. Mode is a mask xosisting of one or more of R_OK, W_OK, X_OK, F_OK.
  355. R,W,X stand for read,write and Execute access, simultaneously.
  356. F_OK checks whether the test would be allowed on the file.
  357. i.e. It checks the search permissions in all directory components
  358. of the path.
  359. The test is done with the real user-ID, instead of the effective.
  360. If access is denied, or an error occurred, false is returned.
  361. If access is granted, true is returned.
  362. Errors other than no access,are reported in unixerror.
  363. }
  364. begin
  365. pathname:=pathname+#0;
  366. Access:=do_syscall(syscall_nr_access, longint(@pathname[1]),mode)=0;
  367. end;
  368. }
  369. function sys_Dup(oldd:cint):cint;
  370. {
  371. Copies the filedescriptor oldfile to newfile
  372. }
  373. begin
  374. sys_dup:=Do_syscall(syscall_nr_dup,oldd);
  375. end;
  376. function sys_Dup2(oldd:cint;newd:cint):cint;
  377. {
  378. Copies the filedescriptor oldfile to newfile
  379. }
  380. begin
  381. sys_dup2:=do_syscall(syscall_nr_dup2,oldd,newd);
  382. end;
  383. {$endif}
  384. function S_ISDIR(m : mode_t): boolean;
  385. begin
  386. S_ISDIR:=((m and %001111000000000000) = %100000000000000);
  387. end;
  388. function S_ISCHR(m : mode_t): boolean;
  389. begin
  390. S_ISCHR:=((m and %001111000000000000) = %10000000000000);
  391. end;
  392. function S_ISBLK(m : mode_t): boolean;
  393. begin
  394. S_ISBLK:=((m and %001111000000000000) = %110000000000000);
  395. end;
  396. function S_ISREG(m : mode_t): boolean;
  397. begin
  398. S_ISREG:=((m and %001111000000000000) = %1000000000000000);
  399. end;
  400. function S_ISFIFO(m : mode_t): boolean;
  401. begin
  402. S_ISFIFO:=((m and %001111000000000000) = %1000000000000);
  403. end;
  404. function wifexited(status : cint): cint;
  405. begin
  406. wifexited:=cint((status AND %1111111) =0);
  407. end;
  408. function wexitstatus(status : cint): cint;
  409. begin
  410. wexitstatus:=(status and %1111111) shl 8;
  411. end;
  412. function wstopsig(status : cint): cint;
  413. begin
  414. wstopsig:=(status and %1111111) shl 8;
  415. end;
  416. function wifsignaled(status : cint): cint;
  417. begin
  418. wifsignaled:=cint(((status and %1111111)<>%1111111) and ((status and %1111111)<>0));
  419. end;
  420. {
  421. $Log$
  422. Revision 1.2 2002-08-04 04:29:34 marco
  423. * More POSIX updates. Small changes to lseek and ftruncate in osposix.inc
  424. Initial versions of the type includefiles
  425. Revision 1.1 2002/08/03 19:34:19 marco
  426. * Initial *BSD versions. Seems that OpenBSD doesn't need much change,
  427. NetBSD may need some fixes to stat record and ftruncate and lseek.
  428. It is all close together, and it should be doable to have just one copy
  429. of these for *BSD.
  430. Revision 1.1.2.5 2001/12/09 03:31:50 carl
  431. + wifsignaled() added
  432. Revision 1.1.2.4 2001/12/03 03:13:30 carl
  433. * fix ftruncate prototype
  434. * fix rename prototype
  435. * change readdir / closedir prototype
  436. Revision 1.1.2.3 2001/11/30 03:50:43 carl
  437. + int -> cint
  438. + missing prototypes added
  439. Revision 1.1.2.2 2001/11/28 03:08:29 carl
  440. * int -> cint
  441. + several other stuff renamed
  442. Revision 1.1.2.1 2001/08/15 00:15:04 carl
  443. - renamed
  444. }