ipc.pp 13 KB

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