int _sys_msgctl(int id, int cmd, void *buf) { struct msqid_ds ubuf; msg_info_t *info; info = msg_get_by_id(id); if (!info) { syscall_errno = EINVAL; return -1; } switch (cmd) { case IPC_STAT: if (!ipc_have_permissions(&(info->info.msg_perm), IPC_PERM_READ)) { syscall_errno = EACCES; return -1; } if (!copy_kern_to_user(&(info->info), buf, sizeof(struct msqid_ds))){ syscall_errno = EFAULT; return -1; } return 0; case IPC_SET: if ((!ipc_is_creator(&(info->info.msg_perm))) && !ipc_have_permissions(&(info->info.msg_perm), IPC_PERM_WRITE)) { syscall_errno = EPERM; return -1; } if (!copy_user_to_kern(buf, &ubuf, sizeof(struct msqid_ds))){ syscall_errno = EFAULT; return -1; } info->info.msg_perm.uid = ubuf.msg_perm.uid; info->info.msg_perm.gid = ubuf.msg_perm.gid; info->info.msg_perm.mode &= ~0x1FF; info->info.msg_perm.mode |= ubuf.msg_perm.mode & 0x1FF; return 0; case IPC_RMID: if ((!ipc_is_creator(&(info->info.msg_perm))) && !ipc_have_permissions(&(info->info.msg_perm), IPC_PERM_WRITE)) { syscall_errno = EPERM; return -1; } info->del = 1; if (!info->refs) { msg_do_delete(info); } else { semaphore_add(info->rwaitsem, 999999); semaphore_add(info->swaitsem, 999999); } return 0; default: syscall_errno = EINVAL; return -1; } }
static int jack_shm_lock_registry (void) { if (semid == -1) { if (semaphore_init () < 0) return -1; } return semaphore_add (-1); }
static void jack_shm_unlock_registry (void) { semaphore_add (1); }