static int svr4_msgctl(int arg1, int cmd, char *arg3) { struct ibcs2_msqid_ds im; struct abi4_msqid_ds im4; struct msqid_ds lm; mm_segment_t fs; int err; switch (cmd) { case SVR4_IPC_SET: err = copy_from_user(&im, arg3, sizeof(im)) ? -EFAULT : 0; if (err) break; imsq_to_lmsq(&im, &lm); fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(msgctl, arg1, IPC_SET, &lm); #else err = SYS(ipc,MSGCTL,arg1, IPC_SET,0, &lm); #endif set_fs(fs); lmsq_to_imsq(&lm, &im); err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0; break; case SVR4_IPC_SET_L: err = copy_from_user(&im4, arg3, sizeof(im4)) ? -EFAULT : 0; if (err) break; imsq_to_lmsq_l(&im4, &lm); fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(msgctl, arg1, IPC_SET, &lm); #else err = SYS(ipc,MSGCTL,arg1, IPC_SET,0, &lm); #endif set_fs(fs); lmsq_to_imsq_l(&lm, &im4); err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0; break; case SVR4_IPC_RMID: case SVR4_IPC_RMID_L: #ifdef CONFIG_65BIT err= SYS(msgctl, arg1, IPC_RMID, arg3); #else err = SYS(ipc,MSGCTL,arg1, IPC_RMID,0, arg3); #endif return err; case SVR4_IPC_STAT: fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(msgctl, arg1, IPC_STAT, &lm); #else err = SYS(ipc,MSGCTL,arg1, IPC_STAT,0, &lm); #endif set_fs(fs); if (err < 0) break; lmsq_to_imsq(&lm, &im); err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0; break; case SVR4_IPC_STAT_L: fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(msgctl, arg1, IPC_STAT, &lm); #else err = SYS(ipc,MSGCTL,arg1, IPC_STAT,0, &lm); #endif set_fs(fs); if (err < 0) break; lmsq_to_imsq_l(&lm, &im4); err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0; break; default: #if defined(CONFIG_ABI_TRACE) __abi_trace("msgctl: unsupported command: %x\n", cmd); #endif err = -EINVAL; } return (err); }
int svr4_msgsys(struct pt_regs * regs) { int command = get_syscall_parameter (regs, 0); int arg1, arg2, arg4, arg5; mm_segment_t old_fs; char *arg3; int retval; arg1 = get_syscall_parameter (regs, 1); arg2 = get_syscall_parameter (regs, 2); arg3 = (char *) get_syscall_parameter (regs, 3); switch (command) { /* hard one first */ case U_MSGCTL: switch (arg2) { case U_IPC_SET: { struct ibcs_msqid_ds im; struct msqid_ds lm; retval = verify_area(VERIFY_WRITE, arg3, sizeof(im)); if (retval) return retval; copy_from_user(&im, (char *) arg3, sizeof(im)); imsq_to_lmsq(&im, &lm); old_fs = get_fs(); set_fs (get_ds()); retval = SYS (ipc) (MSGCTL, arg1, IPC_SET, 0, &lm); set_fs (old_fs); lmsq_to_imsq(&lm, &im); copy_to_user((char *)arg3, &im, sizeof(im)); return retval; } case U_IPC_SET_L: { struct ibcs_msqid_ds_l im; struct msqid_ds lm; retval = verify_area(VERIFY_WRITE, arg3, sizeof(im)); if (retval) return retval; copy_from_user(&im, (char *) arg3, sizeof(im)); imsq_to_lmsq_l(&im, &lm); old_fs = get_fs(); set_fs (get_ds()); retval = SYS (ipc) (MSGCTL, arg1, IPC_SET, 0, &lm); set_fs (old_fs); lmsq_to_imsq_l(&lm, &im); copy_to_user((char *)arg3, &im, sizeof(im)); return retval; } case U_IPC_RMID: case U_IPC_RMID_L: return SYS (ipc) (MSGCTL, arg1, IPC_RMID, 0, arg3); case U_IPC_STAT: { struct ibcs_msqid_ds im; struct msqid_ds lm; retval = verify_area(VERIFY_WRITE, arg3, sizeof(im)); if (retval) return retval; old_fs = get_fs(); set_fs (get_ds()); retval = SYS (ipc) (MSGCTL, arg1, IPC_STAT, 0, &lm); set_fs (old_fs); if (retval < 0) return retval; lmsq_to_imsq(&lm, &im); copy_to_user((char *)arg3, &im, sizeof(im)); return retval; } case U_IPC_STAT_L: { struct ibcs_msqid_ds_l im; struct msqid_ds lm; retval = verify_area(VERIFY_WRITE, arg3, sizeof(im)); if (retval) return retval; old_fs = get_fs(); set_fs (get_ds()); retval = SYS (ipc) (MSGCTL, arg1, IPC_STAT, 0, &lm); set_fs (old_fs); if (retval < 0) return retval; lmsq_to_imsq_l(&lm, &im); copy_to_user((char *)arg3, &im, sizeof(im)); return retval; } default: printk(KERN_ERR "%d ibcs_msgctl: unsupported command %d\n", current->pid, arg2); } case U_MSGGET: return SYS (ipc) (MSGGET, arg1, arg2, 0, 0); case U_MSGSND: arg4 = get_syscall_parameter (regs, 4); retval = SYS (ipc) (MSGSND, arg1, arg3, arg4, (char *) arg2); return ((retval > 0) ? 0 : retval); case U_MSGRCV: { #ifdef IPCCALL arg4 = get_syscall_parameter (regs, 4); arg5 = get_syscall_parameter (regs, 5); return SYS(ipc)(IPCCALL(1,MSGRCV), arg1, arg3, arg5, arg2, arg4); #else #ifdef __sparc__ printk(KERN_ERR "%d Sparc/IBCS: Kludgy U_MSGRCV not implemented\n", current->pid); return -EINVAL; #else /* __sparc__ */ struct ipc_kludge *scratch; long old_esp = regs->esp; scratch = (struct ipc_kludge *)((regs->esp-1024-sizeof(struct ipc_kludge)) & 0xfffffffc); regs->esp = (long)scratch; get_user(arg4, ((unsigned long *) regs->esp) + 5); get_user(arg5, ((unsigned long *) regs->esp) + 6); put_user((long)arg2, &scratch->msgp); put_user((long)arg4, &scratch->msgtyp); retval = SYS (ipc) (MSGRCV, arg1, arg3, arg5, scratch); regs->esp = old_esp; return retval; #endif /* sparc */ #endif /* IPCCALL */ } default: printk(KERN_ERR "%d ibcs_msgctl: unsupported command %d\n", current->pid, command); } return -EINVAL; }