ipc.pp 14 KB

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