ipc.pp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2004 by the Free Pascal development team
  4. This file implements IPC calls calls for Linu/FreeBSD
  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 ipc;
  12. interface
  13. Uses
  14. {$ifdef FPC_USE_LIBCX}
  15. initc,
  16. {$endif}
  17. BaseUnix,UnixType;
  18. {$i osdefs.inc} { Compile time defines }
  19. { ----------------------------------------------------------------------
  20. General IPC stuff
  21. ----------------------------------------------------------------------}
  22. //Var
  23. // IPCError : longint;
  24. {$packrecords c}
  25. Type
  26. {$IFDEF FreeBSD}
  27. TKey = clong;
  28. {$ELSE}
  29. TKey = cint;
  30. {$ENDIF}
  31. key_t = TKey;
  32. Const
  33. { IPC flags for get calls }
  34. {$if defined(FreeBSD) or defined(NetBSD) or defined(OpenBSD)} // BSD_VISIBLE
  35. IPC_R = 4 shl 6;
  36. IPC_W = 2 shl 6;
  37. IPC_M = 2 shl 12;
  38. {$endif}
  39. {$ifdef Darwin}
  40. IPC_R = 4 shl 6;
  41. IPC_W = 2 shl 6;
  42. IPC_M = 1 shl 12;
  43. {$endif}
  44. IPC_CREAT = 1 shl 9; { create if key is nonexistent }
  45. IPC_EXCL = 2 shl 9; { fail if key exists }
  46. IPC_NOWAIT = 4 shl 9; { return error on wait }
  47. {$if defined(FreeBSD) or defined(Darwin) or defined(Linux) or defined(OpenBSD)}
  48. IPC_PRIVATE : TKey = 0;
  49. {$endif}
  50. { Actions for ctl calls }
  51. IPC_RMID = 0; { remove resource }
  52. IPC_SET = 1; { set ipc_perm options }
  53. IPC_STAT = 2; { get ipc_perm options }
  54. {$ifndef Darwin}
  55. IPC_INFO = 3; { see ipcs }
  56. {$endif}
  57. type
  58. PIPC_Perm = ^TIPC_Perm;
  59. {$ifdef darwin }
  60. {$packrecords 4}
  61. { This is also the strcut for FreeBSD up to version 7
  62. renamed ipc_perm_old in /usr/include/sys/ipc.h in version 8 and after }
  63. TIPC_Perm = record
  64. cuid : cushort; { creator user id }
  65. cgid : cushort; { creator group id }
  66. uid : cushort; { user id }
  67. gid : cushort; { group id }
  68. mode : cushort; { r/w permission }
  69. seq : cushort; { sequence # (to generate unique msg/sem/shm id) }
  70. key : key_t; { user specified msg/sem/shm key }
  71. End;
  72. {$packrecords c}
  73. {$else }
  74. {$if defined(NetBSD) or defined(OpenBSD) or defined(FreeBSD) }
  75. TIPC_Perm = record
  76. cuid : uid_t; { creator user id }
  77. cgid : gid_t; { creator group id }
  78. uid : uid_t; { user id }
  79. gid : gid_t; { group id }
  80. mode : mode_t; { r/w permission }
  81. seq : cushort; { sequence # (to generate unique msg/sem/shm id) }
  82. key : key_t; { user specified msg/sem/shm key }
  83. End;
  84. {$else } // linux
  85. {$ifdef cpu32}
  86. {$ifndef linux_ipc64}
  87. {$define linux_ipc32}
  88. {$endif}
  89. {$endif}
  90. {$if not defined(linux_ipc32) and not defined(FPC_USE_LIBC)}
  91. TIPC_Perm = record
  92. key : TKey;
  93. uid : kernel_uid_t;
  94. gid : kernel_gid_t;
  95. cuid : kernel_uid_t;
  96. cgid : kernel_gid_t;
  97. mode : kernel_mode_t;
  98. {$if sizeof(kernel_mode_t) < 4}
  99. __pad1 : array[1..4-sizeof(mode_t)];
  100. {$endif}
  101. {$ifdef cpupowerpc}
  102. seq : cuint;
  103. {$else}
  104. seq : cushort;
  105. {$endif}
  106. __pad2 : cushort;
  107. __unused1 : culong;
  108. __unused2 : culong;
  109. End;
  110. {$else not(linux_ipc32) and not(FPC_USE_LIBC)}
  111. TIPC_Perm = record
  112. key : TKey;
  113. uid : kernel_uid_t;
  114. gid : kernel_gid_t;
  115. cuid : kernel_uid_t;
  116. cgid : kernel_gid_t;
  117. mode : kernel_mode_t;
  118. seq : cushort;
  119. End;
  120. {$endif not(linux_ipc32) and not(FPC_USE_LIBC)}
  121. {$endif not netbsd}
  122. {$endif not others}
  123. { Function to generate a IPC key. }
  124. Function ftok (Path : pchar; ID : cint) : TKey; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'ftok'; {$endif}
  125. { ----------------------------------------------------------------------
  126. Sys V Shared memory stuff
  127. ----------------------------------------------------------------------}
  128. Type
  129. PShmid_DS = ^TShmid_ds;
  130. {$if defined(FreeBSD) or defined(OpenBSD) or defined (NetBSD) }
  131. TShmid_ds = record
  132. shm_perm : TIPC_Perm;
  133. shm_segsz : cint;
  134. shm_lpid : pid_t;
  135. shm_cpid : pid_t;
  136. shm_nattch : cshort;
  137. shm_atime : time_t;
  138. shm_dtime : time_t;
  139. shm_ctime : time_t;
  140. shm_internal : pointer;
  141. end;
  142. {$endif}
  143. {$ifdef Darwin}
  144. {$packrecords 4}
  145. TShmid_ds = record
  146. shm_perm : TIPC_Perm;
  147. shm_segsz : size_t;
  148. shm_lpid : pid_t;
  149. shm_cpid : pid_t;
  150. shm_nattch : cushort; // typedef unsigned short shmatt_t
  151. shm_atime : time_t;
  152. shm_dtime : time_t;
  153. shm_ctime : time_t;
  154. shm_internal : pointer;
  155. end;
  156. {$packrecords c}
  157. {$endif}
  158. {$ifdef Linux}
  159. {$ifdef cpux86_64}
  160. TShmid_ds = record
  161. shm_perm : TIPC_Perm;
  162. shm_segsz : size_t;
  163. shm_atime : time_t;
  164. shm_dtime : time_t;
  165. shm_ctime : time_t;
  166. shm_cpid : pid_t;
  167. shm_lpid : pid_t;
  168. shm_nattch : culong;
  169. __unused4 : culong;
  170. __unused5 : culong;
  171. end;
  172. {$else cpux86_64}
  173. TShmid_ds = record
  174. shm_perm : TIPC_Perm;
  175. shm_segsz : cint;
  176. shm_atime : time_t;
  177. shm_dtime : time_t;
  178. shm_ctime : time_t;
  179. shm_cpid : ipc_pid_t;
  180. shm_lpid : ipc_pid_t;
  181. shm_nattch : word;
  182. shm_npages : word;
  183. shm_pages : pointer;
  184. attaches : pointer;
  185. end;
  186. {$endif cpux86_64}
  187. {$endif}
  188. const
  189. {$ifdef Linux}
  190. SHM_R = 4 shl 6;
  191. SHM_W = 2 shl 6;
  192. {$else}
  193. SHM_R = IPC_R;
  194. SHM_W = IPC_W;
  195. {$endif}
  196. SHM_RDONLY = 1 shl 12;
  197. SHM_RND = 2 shl 12;
  198. {$ifdef Linux}
  199. SHM_REMAP = 4 shl 12;
  200. {$endif}
  201. {$ifdef Darwin}
  202. SHMLBA = 4096;
  203. {$endif}
  204. SHM_LOCK = 11;
  205. SHM_UNLOCK = 12;
  206. {$ifdef FreeBSD} // ipcs shmctl commands
  207. SHM_STAT = 13;
  208. SHM_INFO = 14;
  209. {$endif}
  210. type // the shm*info kind is "kernel" only.
  211. PSHMinfo = ^TSHMinfo;
  212. TSHMinfo = record // comment under FreeBSD/Darwin: do we really need this?
  213. shmmax : cint;
  214. shmmin : cint;
  215. shmmni : cint;
  216. shmseg : cint;
  217. shmall : cint;
  218. end;
  219. {$if defined(FreeBSD) or defined(OpenBSD) or defined(Linux)}
  220. PSHM_info = ^TSHM_info;
  221. TSHM_info = record
  222. used_ids : cint;
  223. shm_tot,
  224. shm_rss,
  225. shm_swp,
  226. swap_attempts,
  227. swap_successes : culong;
  228. end;
  229. {$endif}
  230. Function shmget(key: Tkey; size:size_t; flag:cint):cint; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'shmget'; {$endif}
  231. Function shmat (shmid:cint; shmaddr:pointer; shmflg:cint):pointer; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'shmat'; {$endif}
  232. Function shmdt (shmaddr:pointer):cint; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'shmdt'; {$endif}
  233. Function shmctl(shmid:cint; cmd:cint; buf: pshmid_ds): cint; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'shmctl'; {$endif}
  234. { ----------------------------------------------------------------------
  235. Message queue stuff
  236. ----------------------------------------------------------------------}
  237. const
  238. MSG_NOERROR = 1 shl 12;
  239. {$ifdef Linux}
  240. MSG_EXCEPT = 2 shl 12;
  241. MSGMNI = 128;
  242. MSGMAX = 4056;
  243. MSGMNB = 16384;
  244. {$endif}
  245. type
  246. msglen_t = culong;
  247. msgqnum_t= culong;
  248. {$ifdef Darwin}
  249. user_msglen_t = culonglong;
  250. user_msgqnum_t= culonglong;
  251. {$endif}
  252. PMSG = ^TMSG;
  253. TMSG = record
  254. {$ifndef FreeBSD} // opague in FreeBSD
  255. {$ifdef Darwin}
  256. msg_next : PMSG;
  257. msg_type : clong;
  258. msg_ts : cushort;
  259. mac_label : pointer;
  260. {$else}
  261. msg_next : PMSG;
  262. msg_type : Longint;
  263. msg_spot : PChar;
  264. msg_stime : Longint;
  265. msg_ts : Integer;
  266. {$endif}
  267. {$endif}
  268. end;
  269. type
  270. {$ifdef Linux}
  271. PMSQid_ds = ^TMSQid_ds;
  272. TMSQid_ds = record
  273. msg_perm : TIPC_perm;
  274. msg_first : PMsg;
  275. msg_last : PMsg;
  276. msg_stime : time_t;
  277. msg_rtime : time_t;
  278. msg_ctime : time_t;
  279. msg_cbytes : word;
  280. msg_qnum : word;
  281. msg_qbytes : word;
  282. msg_lspid : ipc_pid_t;
  283. msg_lrpid : ipc_pid_t;
  284. end;
  285. {$else}
  286. {$ifdef Darwin}
  287. {$packrecords 4}
  288. PMSQid_ds = ^TMSQid_ds;
  289. TMSQid_ds = record
  290. msg_perm : TIPC_perm;
  291. msg_first : cint32;
  292. msg_last : cint32;
  293. msg_cbytes : msglen_t;
  294. msg_qnum : msgqnum_t;
  295. msg_qbytes : msglen_t;
  296. msg_lspid : pid_t;
  297. msg_lrpid : pid_t;
  298. msg_stime : time_t;
  299. msg_pad1 : cint32;
  300. msg_rtime : time_t;
  301. msg_pad2 : cint32;
  302. msg_ctime : time_t;
  303. msg_pad3 : cint32;
  304. msg_pad4 : array [0..3] of cint32;
  305. end;
  306. {$packrecords c}
  307. {$else}
  308. PMSQid_ds = ^TMSQid_ds;
  309. TMSQid_ds = record
  310. msg_perm : TIPC_perm;
  311. msg_first : PMsg;
  312. msg_last : PMsg;
  313. msg_cbytes : msglen_t;
  314. msg_qnum : msgqnum_t;
  315. msg_qbytes : msglen_t;
  316. msg_lspid : pid_t;
  317. msg_lrpid : pid_t;
  318. msg_stime : time_t;
  319. msg_pad1 : clong;
  320. msg_rtime : time_t;
  321. msg_pad2 : clong;
  322. msg_ctime : time_t;
  323. msg_pad3 : clong;
  324. msg_pad4 : array [0..3] of clong;
  325. end;
  326. {$endif}
  327. {$endif}
  328. PMSGbuf = ^TMSGbuf;
  329. TMSGbuf = record // called mymsg on freebsd and SVID manual
  330. mtype : clong;
  331. mtext : array[0..0] of char;
  332. end;
  333. {$ifdef linux}
  334. PMSGinfo = ^TMSGinfo;
  335. TMSGinfo = record
  336. msgpool : cint;
  337. msgmap : cint;
  338. msgmax : cint;
  339. msgmnb : cint;
  340. msgmni : cint;
  341. msgssz : cint;
  342. msgtql : cint;
  343. msgseg : cushort;
  344. end;
  345. {$else}
  346. PMSGinfo = ^TMSGinfo;
  347. TMSGinfo = record
  348. msgmax,
  349. msgmni,
  350. msgmnb,
  351. msgtql,
  352. msgssz,
  353. msgseg : cint;
  354. end;
  355. {$endif}
  356. Function msgget(key: TKey; msgflg:cint):cint; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'msgget'; {$endif}
  357. Function msgsnd(msqid:cint; msgp: PMSGBuf; msgsz: size_t; msgflg:cint): cint; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'msgsnd'; {$endif}
  358. Function msgrcv(msqid:cint; msgp: PMSGBuf; msgsz: size_t; msgtyp:clong; msgflg:cint): {$ifdef Darwin}ssize_t;{$else}cint;{$endif} {$ifdef FPC_USE_LIBC} cdecl; external clib name 'msgrcv'; {$endif}
  359. Function msgctl(msqid:cint; cmd: cint; buf: PMSQid_ds): cint; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'msgctl'; {$endif}
  360. { ----------------------------------------------------------------------
  361. Semaphores stuff
  362. ----------------------------------------------------------------------}
  363. const
  364. {$ifdef Linux} // renamed to many name clashes
  365. SEM_UNDO = $1000;
  366. SEM_GETPID = 11;
  367. SEM_GETVAL = 12;
  368. SEM_GETALL = 13;
  369. SEM_GETNCNT = 14;
  370. SEM_GETZCNT = 15;
  371. SEM_SETVAL = 16;
  372. SEM_SETALL = 17;
  373. SEM_SEMMNI = 128;
  374. SEM_SEMMSL = 32;
  375. SEM_SEMMNS = (SEM_SEMMNI * SEM_SEMMSL);
  376. SEM_SEMOPM = 32;
  377. SEM_SEMVMX = 32767;
  378. {$else}
  379. SEM_UNDO = 1 shl 12;
  380. MAX_SOPS = 5;
  381. SEM_GETNCNT = 3; { Return the value of sempid {READ} }
  382. SEM_GETPID = 4; { Return the value of semval {READ} }
  383. SEM_GETVAL = 5; { Return semvals into arg.array {READ} }
  384. SEM_GETALL = 6; { Return the value of semzcnt {READ} }
  385. SEM_GETZCNT = 7; { Set the value of semval to arg.val {ALTER} }
  386. SEM_SETVAL = 8; { Set semvals from arg.array {ALTER} }
  387. SEM_SETALL = 9;
  388. { Permissions }
  389. SEM_A = 2 shl 6; { alter permission }
  390. SEM_R = 4 shl 6; { read permission }
  391. {$endif}
  392. type
  393. {$ifdef Linux}
  394. {$ifndef linux_ipc32}
  395. PSEMid_ds = ^TSEMid_ds;
  396. TSEMid_ds = record
  397. sem_perm : tipc_perm;
  398. sem_otime : time_t; // kernel
  399. unused1 : culong;
  400. sem_ctime : time_t;
  401. unused2 : culong;
  402. sem_nsems : culong;
  403. unused3 : culong;
  404. unused4 : culong;
  405. end;
  406. {$else not linux_ipc32}
  407. PSEMid_ds = ^TSEMid_ds;
  408. TSEMid_ds = record
  409. sem_perm : tipc_perm;
  410. sem_otime : time_t; // kernel
  411. sem_ctime : time_t;
  412. sem_base : pointer;
  413. sem_pending : pointer;
  414. sem_pending_last : pointer;
  415. undo : pointer;
  416. sem_nsems : cushort;
  417. end;
  418. {$endif not linux_ipc32}
  419. {$else Linux}
  420. {$ifdef Darwin}
  421. PSEM = ^TSEM;
  422. TSEM = record
  423. semval : cushort;
  424. sempid : pid_t;
  425. semncnt : cushort;
  426. semzcnt : cushort;
  427. end;
  428. {$packrecords 4}
  429. PSEMid_ds = ^TSEMid_ds;
  430. TSEMid_ds = record
  431. sem_perm : tipc_perm;
  432. sem_base : cint32;
  433. sem_nsems : cushort;
  434. sem_otime : time_t;
  435. sem_pad1 : cint32;
  436. sem_ctime : time_t;
  437. sem_pad2 : cint32;
  438. sem_pad3 : array[0..3] of cint32;
  439. end;
  440. {$packrecords c}
  441. {$else}
  442. PSEM = ^TSEM;
  443. TSEM = record end; // opague
  444. PSEMid_ds = ^TSEMid_ds;
  445. TSEMid_ds = record
  446. sem_perm : tipc_perm;
  447. sem_base : PSEM;
  448. sem_nsems : cushort;
  449. sem_otime : time_t;
  450. sem_pad1 : cint;
  451. sem_ctime : time_t;
  452. sem_pad2 : cint;
  453. sem_pad3 : array[0..3] of cint;
  454. end;
  455. {$endif}
  456. {$endif}
  457. PSEMbuf = ^TSEMbuf;
  458. TSEMbuf = record
  459. sem_num : cushort;
  460. sem_op : cshort;
  461. sem_flg : cshort;
  462. end;
  463. PSEMinfo = ^TSEMinfo;
  464. TSEMinfo = record
  465. semmap : cint;
  466. semmni : cint;
  467. semmns : cint;
  468. semmnu : cint;
  469. semmsl : cint;
  470. semopm : cint;
  471. semume : cint;
  472. semusz : cint;
  473. semvmx : cint;
  474. semaem : cint;
  475. end;
  476. { internal mode bits}
  477. {$ifdef FreeBSD}
  478. Const
  479. SEM_ALLOC = 1 shl 9;
  480. SEM_DEST = 2 shl 9;
  481. {$endif}
  482. Type
  483. PSEMun = ^TSEMun;
  484. TSEMun = record
  485. case cint of
  486. 0 : ( val : cint );
  487. 1 : ( buf : PSEMid_ds );
  488. 2 : ( arr : PWord ); // ^ushort
  489. {$ifdef linux}
  490. 3 : ( padbuf : PSeminfo );
  491. 4 : ( padpad : pointer );
  492. {$endif}
  493. end;
  494. Function semget(key:Tkey; nsems:cint; semflg:cint): cint; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'semget'; {$endif}
  495. Function semop(semid:cint; sops: psembuf; nsops: cuint): cint; {$ifdef FPC_USE_LIBC} cdecl; external clib name 'semop'; {$endif}
  496. Function semctl(semid:cint; semnum:cint; cmd:cint; var arg: tsemun): cint;
  497. {$ifdef linux}
  498. Function semtimedop(semid:cint; sops: psembuf; nsops: cuint; timeOut: ptimespec): cint; {$ifdef FPC_USE_LIBC} cdecl; external name 'semtimedop'; platform; {$else} platform; {$endif}
  499. {$endif}
  500. implementation
  501. {$ifndef FPC_USE_LIBC}
  502. uses Syscall;
  503. {$endif ndef FPC_USE_LIBC}
  504. {$ifndef FPC_USE_LIBC}
  505. {$ifdef Linux}
  506. {$if defined(cpux86_64) or defined(NO_SYSCALL_IPC)}
  507. {$i ipcsys.inc}
  508. {$else}
  509. {$i ipccall.inc}
  510. {$endif}
  511. {$endif}
  512. {$ifdef BSD}
  513. {$i ipcbsd.inc}
  514. {$endif}
  515. {$else ndef FPC_USE_LIBC}
  516. Function real_semctl(semid:cint; semnum:cint; cmd:cint): cint; {$ifdef FPC_USE_LIBC} cdecl; varargs; external clib name 'semctl'; {$endif}
  517. Function semctl(semid:cint; semnum:cint; cmd:cint; var arg: tsemun): cint;
  518. begin
  519. semctl := real_semctl(semid,semnum,cmd,pointer(arg));
  520. end;
  521. {$endif}
  522. end.