1 /*- 2 * Copyright (c) 1994-1995 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software withough specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $Id: linux_ipc.c,v 1.2 1995/06/07 21:27:57 sos Exp $ 29 */ 30 31 #include <i386/linux/linux.h> 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/exec.h> 35 #include <sys/proc.h> 36 #include <sys/sem.h> 37 #include <sys/shm.h> 38 #include <sys/msg.h> 39 40 #include <vm/vm.h> 41 42 struct linux_ipc_perm { 43 linux_key_t key; 44 unsigned short uid; 45 unsigned short gid; 46 unsigned short cuid; 47 unsigned short cgid; 48 unsigned short mode; 49 unsigned short seq; 50 }; 51 52 static void 53 linux_to_bsd_ipc_perm(struct linux_ipc_perm *lpp, struct ipc_perm *bpp) 54 { 55 bpp->key = lpp->key; 56 bpp->uid = lpp->uid; 57 bpp->gid = lpp->gid; 58 bpp->cuid = lpp->cuid; 59 bpp->cgid = lpp->cgid; 60 bpp->mode = lpp->mode; 61 bpp->seq = lpp->seq; 62 } 63 64 65 static void 66 bsd_to_linux_ipc_perm(struct ipc_perm *bpp, struct linux_ipc_perm *lpp) 67 { 68 lpp->key = bpp->key; 69 lpp->uid = bpp->uid; 70 lpp->gid = bpp->gid; 71 lpp->cuid = bpp->cuid; 72 lpp->cgid = bpp->cgid; 73 lpp->mode = bpp->mode; 74 lpp->seq = bpp->seq; 75 } 76 77 struct linux_shmid_ds { 78 struct linux_ipc_perm shm_perm; 79 int shm_segsz; 80 linux_time_t shm_atime; 81 linux_time_t shm_dtime; 82 linux_time_t shm_ctime; 83 ushort shm_cpid; 84 ushort shm_lpid; 85 short shm_nattch; 86 ushort private1; 87 void *private2; 88 void *private3; 89 }; 90 91 static void 92 linux_to_bsd_shmid_ds(struct linux_shmid_ds *lsp, struct shmid_ds *bsp) 93 { 94 linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm); 95 bsp->shm_segsz = lsp->shm_segsz; 96 bsp->shm_lpid = lsp->shm_lpid; 97 bsp->shm_cpid = lsp->shm_cpid; 98 bsp->shm_nattch = lsp->shm_nattch; 99 bsp->shm_atime = lsp->shm_atime; 100 bsp->shm_dtime = lsp->shm_dtime; 101 bsp->shm_ctime = lsp->shm_ctime; 102 bsp->shm_internal = lsp->private3; /* this goes (yet) SOS */ 103 } 104 105 static void 106 bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct linux_shmid_ds *lsp) 107 { 108 bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm); 109 lsp->shm_segsz = bsp->shm_segsz; 110 lsp->shm_lpid = bsp->shm_lpid; 111 lsp->shm_cpid = bsp->shm_cpid; 112 lsp->shm_nattch = bsp->shm_nattch; 113 lsp->shm_atime = bsp->shm_atime; 114 lsp->shm_dtime = bsp->shm_dtime; 115 lsp->shm_ctime = bsp->shm_ctime; 116 lsp->private3 = bsp->shm_internal; /* this goes (yet) SOS */ 117 } 118 119 struct linux_ipc_args { 120 int what; 121 int arg1; 122 int arg2; 123 int arg3; 124 caddr_t ptr; 125 }; 126 127 int 128 linux_semop(struct proc *p, struct linux_ipc_args *args, int *retval) 129 { 130 return ENOSYS; 131 } 132 133 int 134 linux_semget(struct proc *p, struct linux_ipc_args *args, int *retval) 135 { 136 return ENOSYS; 137 } 138 139 int 140 linux_semctl(struct proc *p, struct linux_ipc_args *args, int *retval) 141 { 142 return ENOSYS; 143 } 144 145 int 146 linux_msgsnd(struct proc *p, struct linux_ipc_args *args, int *retval) 147 { 148 return ENOSYS; 149 } 150 151 int 152 linux_msgrcv(struct proc *p, struct linux_ipc_args *args, int *retval) 153 { 154 return ENOSYS; 155 } 156 157 int 158 linux_msgget(struct proc *p, struct linux_ipc_args *args, int *retval) 159 { 160 return ENOSYS; 161 } 162 163 int 164 linux_msgctl(struct proc *p, struct linux_ipc_args *args, int *retval) 165 { 166 return ENOSYS; 167 } 168 169 int 170 linux_shmat(struct proc *p, struct linux_ipc_args *args, int *retval) 171 { 172 struct shmat_args { 173 int shmid; 174 void *shmaddr; 175 int shmflg; 176 } bsd_args; 177 int error; 178 179 bsd_args.shmid = args->arg1; 180 bsd_args.shmaddr = args->ptr; 181 bsd_args.shmflg = args->arg2; 182 if ((error = shmat(p, &bsd_args, retval))) 183 return error; 184 if ((error = copyout(retval, (caddr_t)args->arg3, sizeof(int)))) 185 return error; 186 retval[0] = 0; 187 return 0; 188 } 189 190 int 191 linux_shmdt(struct proc *p, struct linux_ipc_args *args, int *retval) 192 { 193 struct shmdt_args { 194 void *shmaddr; 195 } bsd_args; 196 197 bsd_args.shmaddr = args->ptr; 198 return shmdt(p, &bsd_args, retval); 199 } 200 201 int 202 linux_shmget(struct proc *p, struct linux_ipc_args *args, int *retval) 203 { 204 struct shmget_args { 205 key_t key; 206 int size; 207 int shmflg; 208 } bsd_args; 209 210 bsd_args.key = args->arg1; 211 bsd_args.size = args->arg2; 212 bsd_args.shmflg = args->arg3; 213 return shmget(p, &bsd_args, retval); 214 } 215 216 int 217 linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval) 218 { 219 struct shmid_ds bsd_shmid; 220 struct linux_shmid_ds linux_shmid; 221 struct shmctl_args { 222 int shmid; 223 int cmd; 224 struct shmid_ds *buf; 225 } bsd_args; 226 int error; 227 228 switch (args->arg2) { 229 case LINUX_IPC_STAT: 230 bsd_args.shmid = args->arg1; 231 bsd_args.cmd = IPC_STAT; 232 bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds)); 233 if ((error = shmctl(p, &bsd_args, retval))) 234 return error; 235 if ((error = copyin((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf, 236 sizeof(struct shmid_ds)))) 237 return error; 238 bsd_to_linux_shmid_ds(&bsd_shmid, &linux_shmid); 239 return copyout((caddr_t)&linux_shmid, args->ptr, sizeof(linux_shmid)); 240 241 case LINUX_IPC_SET: 242 if ((error = copyin(args->ptr, (caddr_t)&linux_shmid, 243 sizeof(linux_shmid)))) 244 return error; 245 linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid); 246 bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds)); 247 if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf, 248 sizeof(struct shmid_ds)))) 249 return error; 250 bsd_args.shmid = args->arg1; 251 bsd_args.cmd = IPC_SET; 252 return shmctl(p, &bsd_args, retval); 253 254 case LINUX_IPC_RMID: 255 bsd_args.shmid = args->arg1; 256 bsd_args.cmd = IPC_RMID; 257 if ((error = copyin(args->ptr, (caddr_t)&linux_shmid, 258 sizeof(linux_shmid)))) 259 return error; 260 linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid); 261 bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds)); 262 if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf, 263 sizeof(struct shmid_ds)))) 264 return error; 265 return shmctl(p, &bsd_args, retval); 266 267 case LINUX_IPC_INFO: 268 case LINUX_SHM_STAT: 269 case LINUX_SHM_INFO: 270 case LINUX_SHM_LOCK: 271 case LINUX_SHM_UNLOCK: 272 default: 273 uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what); 274 return EINVAL; 275 } 276 } 277 278 int 279 linux_ipc(struct proc *p, struct linux_ipc_args *args, int *retval) 280 { 281 switch (args->what) { 282 case LINUX_SEMOP: 283 return linux_semop(p, args, retval); 284 case LINUX_SEMGET: 285 return linux_semget(p, args, retval); 286 case LINUX_SEMCTL: 287 return linux_semctl(p, args, retval); 288 case LINUX_MSGSND: 289 return linux_msgsnd(p, args, retval); 290 case LINUX_MSGRCV: 291 return linux_msgrcv(p, args, retval); 292 case LINUX_MSGGET: 293 return linux_msgget(p, args, retval); 294 case LINUX_MSGCTL: 295 return linux_msgctl(p, args, retval); 296 case LINUX_SHMAT: 297 return linux_shmat(p, args, retval); 298 case LINUX_SHMDT: 299 return linux_shmdt(p, args, retval); 300 case LINUX_SHMGET: 301 return linux_shmget(p, args, retval); 302 case LINUX_SHMCTL: 303 return linux_shmctl(p, args, retval); 304 default: 305 uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what); 306 return ENOSYS; 307 } 308 } 309