ibcs2_ipc.c revision 331722
1/*-
2 * Copyright (c) 1995 Scott Bartram
3 * Copyright (c) 1995 Steven Wallace
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. The name of the author may not be used to endorse or promote products
12 *    derived from this software without specific prior written permission
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD: stable/11/sys/i386/ibcs2/ibcs2_ipc.c 331722 2018-03-29 02:50:57Z eadler $");
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/limits.h>
32#include <sys/msg.h>
33#include <sys/sem.h>
34#include <sys/shm.h>
35#include <sys/syscallsubr.h>
36#include <sys/sysproto.h>
37
38#include <i386/ibcs2/ibcs2_types.h>
39#include <i386/ibcs2/ibcs2_signal.h>
40#include <i386/ibcs2/ibcs2_proto.h>
41#include <i386/ibcs2/ibcs2_util.h>
42#include <i386/ibcs2/ibcs2_ipc.h>
43
44#define IBCS2_IPC_RMID	0
45#define IBCS2_IPC_SET	1
46#define IBCS2_IPC_STAT	2
47#define IBCS2_SETVAL	8
48
49
50
51static void cvt_msqid2imsqid(struct msqid_ds *, struct ibcs2_msqid_ds *);
52static void cvt_imsqid2msqid(struct ibcs2_msqid_ds *, struct msqid_ds *);
53#ifdef unused
54static void cvt_sem2isem(struct sem *, struct ibcs2_sem *);
55static void cvt_isem2sem(struct ibcs2_sem *, struct sem *);
56#endif
57static void cvt_semid2isemid(struct semid_ds *, struct ibcs2_semid_ds *);
58static void cvt_isemid2semid(struct ibcs2_semid_ds *, struct semid_ds *);
59static void cvt_shmid2ishmid(struct shmid_ds *, struct ibcs2_shmid_ds *);
60static void cvt_ishmid2shmid(struct ibcs2_shmid_ds *, struct shmid_ds *);
61static void cvt_perm2iperm(struct ipc_perm *, struct ibcs2_ipc_perm *);
62static void cvt_iperm2perm(struct ibcs2_ipc_perm *, struct ipc_perm *);
63
64
65/*
66 * iBCS2 msgsys call
67 */
68
69static void
70cvt_msqid2imsqid(bp, ibp)
71struct msqid_ds *bp;
72struct ibcs2_msqid_ds *ibp;
73{
74	cvt_perm2iperm(&bp->msg_perm, &ibp->msg_perm);
75	ibp->msg_first = bp->msg_first;
76	ibp->msg_last = bp->msg_last;
77	ibp->msg_cbytes = (u_short)bp->msg_cbytes;
78	ibp->msg_qnum = (u_short)bp->msg_qnum;
79	ibp->msg_qbytes = (u_short)bp->msg_qbytes;
80	ibp->msg_lspid = (u_short)bp->msg_lspid;
81	ibp->msg_lrpid = (u_short)bp->msg_lrpid;
82	ibp->msg_stime = bp->msg_stime;
83	ibp->msg_rtime = bp->msg_rtime;
84	ibp->msg_ctime = bp->msg_ctime;
85	return;
86}
87
88static void
89cvt_imsqid2msqid(ibp, bp)
90struct ibcs2_msqid_ds *ibp;
91struct msqid_ds *bp;
92{
93	cvt_iperm2perm(&ibp->msg_perm, &bp->msg_perm);
94	bp->msg_first = ibp->msg_first;
95	bp->msg_last = ibp->msg_last;
96	bp->msg_cbytes = ibp->msg_cbytes;
97	bp->msg_qnum = ibp->msg_qnum;
98	bp->msg_qbytes = ibp->msg_qbytes;
99	bp->msg_lspid = ibp->msg_lspid;
100	bp->msg_lrpid = ibp->msg_lrpid;
101	bp->msg_stime = ibp->msg_stime;
102	bp->msg_rtime = ibp->msg_rtime;
103	bp->msg_ctime = ibp->msg_ctime;
104	return;
105}
106
107struct ibcs2_msgget_args {
108	int what;
109	ibcs2_key_t key;
110	int msgflg;
111};
112
113static int
114ibcs2_msgget(struct thread *td, void *v)
115{
116	struct ibcs2_msgget_args *uap = v;
117	struct msgget_args ap;
118
119	ap.key = uap->key;
120	ap.msgflg = uap->msgflg;
121	return sys_msgget(td, &ap);
122}
123
124struct ibcs2_msgctl_args {
125	int what;
126	int msqid;
127	int cmd;
128	struct ibcs2_msqid_ds *buf;
129};
130
131static int
132ibcs2_msgctl(struct thread *td, void *v)
133{
134	struct ibcs2_msgctl_args *uap = v;
135	struct ibcs2_msqid_ds is;
136	struct msqid_ds bs;
137	int error;
138
139	switch (uap->cmd) {
140	case IBCS2_IPC_STAT:
141		error = kern_msgctl(td, uap->msqid, IPC_STAT, &bs);
142		if (!error) {
143			cvt_msqid2imsqid(&bs, &is);
144			error = copyout(&is, uap->buf, sizeof(is));
145		}
146		return (error);
147	case IBCS2_IPC_SET:
148		error = copyin(uap->buf, &is, sizeof(is));
149		if (error)
150			return (error);
151		cvt_imsqid2msqid(&is, &bs);
152		return (kern_msgctl(td, uap->msqid, IPC_SET, &bs));
153	case IBCS2_IPC_RMID:
154		return (kern_msgctl(td, uap->msqid, IPC_RMID, NULL));
155	}
156	return (EINVAL);
157}
158
159struct ibcs2_msgrcv_args {
160	int what;
161	int msqid;
162	void *msgp;
163	size_t msgsz;
164	long msgtyp;
165	int msgflg;
166};
167
168static int
169ibcs2_msgrcv(struct thread *td, void *v)
170{
171	struct ibcs2_msgrcv_args *uap = v;
172	struct msgrcv_args ap;
173
174	ap.msqid = uap->msqid;
175	ap.msgp = uap->msgp;
176	ap.msgsz = uap->msgsz;
177	ap.msgtyp = uap->msgtyp;
178	ap.msgflg = uap->msgflg;
179	return (sys_msgrcv(td, &ap));
180}
181
182struct ibcs2_msgsnd_args {
183	int what;
184	int msqid;
185	void *msgp;
186	size_t msgsz;
187	int msgflg;
188};
189
190static int
191ibcs2_msgsnd(struct thread *td, void *v)
192{
193	struct ibcs2_msgsnd_args *uap = v;
194	struct msgsnd_args ap;
195
196	ap.msqid = uap->msqid;
197	ap.msgp = uap->msgp;
198	ap.msgsz = uap->msgsz;
199	ap.msgflg = uap->msgflg;
200	return (sys_msgsnd(td, &ap));
201}
202
203int
204ibcs2_msgsys(td, uap)
205	struct thread *td;
206	struct ibcs2_msgsys_args *uap;
207{
208	switch (uap->which) {
209	case 0:
210		return (ibcs2_msgget(td, uap));
211	case 1:
212		return (ibcs2_msgctl(td, uap));
213	case 2:
214		return (ibcs2_msgrcv(td, uap));
215	case 3:
216		return (ibcs2_msgsnd(td, uap));
217	default:
218		return (EINVAL);
219	}
220}
221
222/*
223 * iBCS2 semsys call
224 */
225#ifdef unused
226static void
227cvt_sem2isem(bp, ibp)
228struct sem *bp;
229struct ibcs2_sem *ibp;
230{
231	ibp->semval = bp->semval;
232	ibp->sempid = bp->sempid;
233	ibp->semncnt = bp->semncnt;
234	ibp->semzcnt = bp->semzcnt;
235	return;
236}
237
238static void
239cvt_isem2sem(ibp, bp)
240struct ibcs2_sem *ibp;
241struct sem *bp;
242{
243	bp->semval = ibp->semval;
244	bp->sempid = ibp->sempid;
245	bp->semncnt = ibp->semncnt;
246	bp->semzcnt = ibp->semzcnt;
247	return;
248}
249#endif
250
251static void
252cvt_iperm2perm(ipp, pp)
253struct ibcs2_ipc_perm *ipp;
254struct ipc_perm *pp;
255{
256	pp->uid = ipp->uid;
257	pp->gid = ipp->gid;
258	pp->cuid = ipp->cuid;
259	pp->cgid = ipp->cgid;
260	pp->mode = ipp->mode;
261	pp->seq = ipp->seq;
262	pp->key = ipp->key;
263}
264
265static void
266cvt_perm2iperm(pp, ipp)
267struct ipc_perm *pp;
268struct ibcs2_ipc_perm *ipp;
269{
270	ipp->uid = pp->uid;
271	ipp->gid = pp->gid;
272	ipp->cuid = pp->cuid;
273	ipp->cgid = pp->cgid;
274	ipp->mode = pp->mode;
275	ipp->seq = pp->seq;
276	ipp->key = pp->key;
277}
278
279static void
280cvt_semid2isemid(bp, ibp)
281struct semid_ds *bp;
282struct ibcs2_semid_ds *ibp;
283{
284	cvt_perm2iperm(&bp->sem_perm, &ibp->sem_perm);
285	ibp->sem_base = (struct ibcs2_sem *)bp->sem_base;
286	ibp->sem_nsems = bp->sem_nsems;
287	ibp->sem_otime = bp->sem_otime;
288	ibp->sem_ctime = bp->sem_ctime;
289	return;
290}
291
292static void
293cvt_isemid2semid(ibp, bp)
294struct ibcs2_semid_ds *ibp;
295struct semid_ds *bp;
296{
297	cvt_iperm2perm(&ibp->sem_perm, &bp->sem_perm);
298	bp->sem_base = (struct sem *)ibp->sem_base;
299	bp->sem_nsems = ibp->sem_nsems;
300	bp->sem_otime = ibp->sem_otime;
301	bp->sem_ctime = ibp->sem_ctime;
302	return;
303}
304
305struct ibcs2_semctl_args {
306	int what;
307	int semid;
308	int semnum;
309	int cmd;
310	union semun arg;
311};
312
313static int
314ibcs2_semctl(struct thread *td, void *v)
315{
316	struct ibcs2_semctl_args *uap = v;
317	struct ibcs2_semid_ds is;
318	struct semid_ds bs;
319	union semun semun;
320	register_t rval;
321	int error;
322
323	switch(uap->cmd) {
324	case IBCS2_IPC_STAT:
325		semun.buf = &bs;
326		error = kern_semctl(td, uap->semid, uap->semnum, IPC_STAT,
327		    &semun, &rval);
328		if (error)
329			return (error);
330		cvt_semid2isemid(&bs, &is);
331		error = copyout(&is, uap->arg.buf, sizeof(is));
332		if (error == 0)
333			td->td_retval[0] = rval;
334		return (error);
335
336	case IBCS2_IPC_SET:
337		error = copyin(uap->arg.buf, &is, sizeof(is));
338		if (error)
339			return (error);
340		cvt_isemid2semid(&is, &bs);
341		semun.buf = &bs;
342		return (kern_semctl(td, uap->semid, uap->semnum, IPC_SET,
343		    &semun, td->td_retval));
344	}
345
346	return (kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &uap->arg,
347	    td->td_retval));
348}
349
350struct ibcs2_semget_args {
351	int what;
352	ibcs2_key_t key;
353	int nsems;
354	int semflg;
355};
356
357static int
358ibcs2_semget(struct thread *td, void *v)
359{
360	struct ibcs2_semget_args *uap = v;
361	struct semget_args ap;
362
363	ap.key = uap->key;
364	ap.nsems = uap->nsems;
365	ap.semflg = uap->semflg;
366	return (sys_semget(td, &ap));
367}
368
369struct ibcs2_semop_args {
370	int what;
371	int semid;
372	struct sembuf *sops;
373	size_t nsops;
374};
375
376static int
377ibcs2_semop(struct thread *td, void *v)
378{
379	struct ibcs2_semop_args *uap = v;
380	struct semop_args ap;
381
382	ap.semid = uap->semid;
383	ap.sops = uap->sops;
384	ap.nsops = uap->nsops;
385	return (sys_semop(td, &ap));
386}
387
388int
389ibcs2_semsys(td, uap)
390	struct thread *td;
391	struct ibcs2_semsys_args *uap;
392{
393
394	switch (uap->which) {
395	case 0:
396		return (ibcs2_semctl(td, uap));
397	case 1:
398		return (ibcs2_semget(td, uap));
399	case 2:
400		return (ibcs2_semop(td, uap));
401	}
402	return (EINVAL);
403}
404
405
406/*
407 * iBCS2 shmsys call
408 */
409
410static void
411cvt_shmid2ishmid(bp, ibp)
412struct shmid_ds *bp;
413struct ibcs2_shmid_ds *ibp;
414{
415	cvt_perm2iperm(&bp->shm_perm, &ibp->shm_perm);
416	ibp->shm_segsz = bp->shm_segsz;
417	ibp->shm_lpid = bp->shm_lpid;
418	ibp->shm_cpid = bp->shm_cpid;
419	if (bp->shm_nattch > SHRT_MAX)
420		ibp->shm_nattch = SHRT_MAX;
421	else
422		ibp->shm_nattch = bp->shm_nattch;
423	ibp->shm_cnattch = 0;			/* ignored anyway */
424	ibp->shm_atime = bp->shm_atime;
425	ibp->shm_dtime = bp->shm_dtime;
426	ibp->shm_ctime = bp->shm_ctime;
427	return;
428}
429
430static void
431cvt_ishmid2shmid(ibp, bp)
432struct ibcs2_shmid_ds *ibp;
433struct shmid_ds *bp;
434{
435	cvt_iperm2perm(&ibp->shm_perm, &bp->shm_perm);
436	bp->shm_segsz = ibp->shm_segsz;
437	bp->shm_lpid = ibp->shm_lpid;
438	bp->shm_cpid = ibp->shm_cpid;
439	bp->shm_nattch = ibp->shm_nattch;
440	bp->shm_atime = ibp->shm_atime;
441	bp->shm_dtime = ibp->shm_dtime;
442	bp->shm_ctime = ibp->shm_ctime;
443	return;
444}
445
446struct ibcs2_shmat_args {
447	int what;
448	int shmid;
449	const void *shmaddr;
450	int shmflg;
451};
452
453static int
454ibcs2_shmat(struct thread *td, void *v)
455{
456	struct ibcs2_shmat_args *uap = v;
457	struct shmat_args ap;
458
459	ap.shmid = uap->shmid;
460	ap.shmaddr = uap->shmaddr;
461	ap.shmflg = uap->shmflg;
462	return (sys_shmat(td, &ap));
463}
464
465struct ibcs2_shmctl_args {
466	int what;
467	int shmid;
468	int cmd;
469	struct ibcs2_shmid_ds *buf;
470};
471
472static int
473ibcs2_shmctl(struct thread *td, void *v)
474{
475	struct ibcs2_shmctl_args *uap = v;
476	struct ibcs2_shmid_ds is;
477	struct shmid_ds bs;
478	int error;
479
480	switch(uap->cmd) {
481	case IBCS2_IPC_STAT:
482		error = kern_shmctl(td, uap->shmid, IPC_STAT, &bs, NULL);
483		if (error)
484			return (error);
485		cvt_shmid2ishmid(&bs, &is);
486		return (copyout(&is, uap->buf, sizeof(is)));
487
488	case IBCS2_IPC_SET:
489		error = copyin(uap->buf, &is, sizeof(is));
490		if (error)
491			return (error);
492		cvt_ishmid2shmid(&is, &bs);
493		return (kern_shmctl(td, uap->shmid, IPC_SET, &bs, NULL));
494
495	case IPC_INFO:
496	case SHM_INFO:
497	case SHM_STAT:
498		/* XXX: */
499		return (EINVAL);
500	}
501
502	return (kern_shmctl(td, uap->shmid, uap->cmd, NULL, NULL));
503}
504
505struct ibcs2_shmdt_args {
506	int what;
507	const void *shmaddr;
508};
509
510static int
511ibcs2_shmdt(struct thread *td, void *v)
512{
513	struct ibcs2_shmdt_args *uap = v;
514	struct shmdt_args ap;
515
516	ap.shmaddr = uap->shmaddr;
517	return (sys_shmdt(td, &ap));
518}
519
520struct ibcs2_shmget_args {
521	int what;
522	ibcs2_key_t key;
523	size_t size;
524	int shmflg;
525};
526
527static int
528ibcs2_shmget(struct thread *td, void *v)
529{
530	struct ibcs2_shmget_args *uap = v;
531	struct shmget_args ap;
532
533	ap.key = uap->key;
534	ap.size = uap->size;
535	ap.shmflg = uap->shmflg;
536	return (sys_shmget(td, &ap));
537}
538
539int
540ibcs2_shmsys(td, uap)
541	struct thread *td;
542	struct ibcs2_shmsys_args *uap;
543{
544
545	switch (uap->which) {
546	case 0:
547		return (ibcs2_shmat(td, uap));
548	case 1:
549		return (ibcs2_shmctl(td, uap));
550	case 2:
551		return (ibcs2_shmdt(td, uap));
552	case 3:
553		return (ibcs2_shmget(td, uap));
554	}
555	return (EINVAL);
556}
557
558MODULE_DEPEND(ibcs2, sysvmsg, 1, 1, 1);
559MODULE_DEPEND(ibcs2, sysvsem, 1, 1, 1);
560MODULE_DEPEND(ibcs2, sysvshm, 1, 1, 1);
561