Пример #1
0
/*===========================================================================*
 *				do_shmdt		     		     *
 *===========================================================================*/
int do_shmdt(message *m)
{
	vir_bytes addr;
	phys_bytes vm_id;
	int i;

	addr = (vir_bytes) m->m_lc_ipc_shmdt.addr;

	if ((vm_id = vm_getphys(who_e, (void *) addr)) == 0)
		return EINVAL;

	for (i = 0; i < shm_list_nr; i++) {
		if (shm_list[i].vm_id == vm_id) {
			struct shm_struct *shm = &shm_list[i];

			shm->shmid_ds.shm_atime = time(NULL);
			shm->shmid_ds.shm_lpid = getnpid(who_e);
			/* nattch is updated lazily */

			vm_unmap(who_e, (void *) addr);
			break;
		}
	}
	if (i == shm_list_nr)
		printf("IPC: do_shmdt impossible error! could not find id %lu to unmap\n",
			vm_id);

	update_refcount_and_destroy();

	return OK;
}
Пример #2
0
/*===========================================================================*
 *				do_shmdt		     		     *
 *===========================================================================*/
PUBLIC int do_shmdt(message *m)
{
	vir_bytes addr;
	phys_bytes paddr;
	int i;

	addr = m->SHMDT_ADDR;

	if ((paddr = vm_getphys(who_e, (void *) addr)) == 0)
		return EINVAL;

	for (i = 0; i < shm_list_nr; i++) {
		if (shm_list[i].phys == paddr) {
			struct shm_struct *shm = &shm_list[i];

			shm->shmid_ds.shm_atime = time(NULL);
			shm->shmid_ds.shm_lpid = getnpid(who_e);
			/* nattch is updated lazily */

			vm_unmap(who_e, (void *) addr);
			break;
		}
	}
	if (i == shm_list_nr)
		fprintf(stderr, "IPC: do_shmdt impossible error!\n");

	update_refcount_and_destroy();

	return OK;
}
Пример #3
0
PUBLIC int main(int argc, char *argv[])
{
	message m;

	/* SEF local startup. */
	env_setargs(argc, argv);
	sef_local_startup();

	while (TRUE) {
		int r;
		int i;

		if ((r = sef_receive(ANY, &m)) != OK)
			printf("sef_receive failed %d.\n", r);
		who_e = m.m_source;
		call_type = m.m_type;

		if(verbose)
			printf("IPC: get %d from %d\n", call_type, who_e);

		if (call_type & NOTIFY_MESSAGE) {
			switch (who_e) {
			case PM_PROC_NR:
				/* PM sends a notify() on shutdown,
				 * checkout if there are still IPC keys,
				 * give warning messages.
				 */
				if (!is_sem_nil() || !is_shm_nil())
					printf("IPC: exit with un-clean states.\n");
				break;
			case VM_PROC_NR:
				/* currently, only semaphore needs such information. */
				sem_process_vm_notify();
				break;
			default:
				printf("IPC: ignoring notify() from %d\n",
					who_e);
				break;
			}
			continue;
		}

		/* dispatch messages */
		for (i = 0; i < SIZE(ipc_calls); i++) {
			if (ipc_calls[i].type == call_type) {
				int result;

				result = ipc_calls[i].func(&m);

				if (ipc_calls[i].reply)
					break;

				m.m_type = result;

				if(verbose && result != OK)
					printf("IPC: error for %d: %d\n",
						call_type, result);

				if ((r = sendnb(who_e, &m)) != OK)
					printf("IPC send error %d.\n", r);
				break;
			}
		}

		if (i == SIZE(ipc_calls)) {
			/* warn and then ignore */
			printf("IPC unknown call type: %d from %d.\n",
				call_type, who_e);
		}
		update_refcount_and_destroy();
	}

	/* no way to get here */
	return -1;
}
Пример #4
0
/*===========================================================================*
 *				do_shmctl		     		     *
 *===========================================================================*/
PUBLIC int do_shmctl(message *m)
{
	int id = m->SHMCTL_ID;
	int cmd = m->SHMCTL_CMD;
	struct shmid_ds *ds = (struct shmid_ds *)m->SHMCTL_BUF;
	struct shmid_ds tmp_ds;
	struct shm_struct *shm;
	struct shminfo sinfo;
	struct shm_info s_info;
	uid_t uid;
	int r, i;

	if (cmd == IPC_STAT)
		update_refcount_and_destroy();

	if ((cmd == IPC_STAT ||
		cmd == IPC_SET ||
		cmd == IPC_RMID) &&
		!(shm = shm_find_id(id)))
		return EINVAL;

	switch (cmd) {
	case IPC_STAT:
		if (!ds)
			return EFAULT;
		/* check whether it has read permission */
		if (!check_perm(&shm->shmid_ds.shm_perm, who_e, 0444))
			return EACCES;
		r = sys_datacopy(SELF_E, (vir_bytes)&shm->shmid_ds,
			who_e, (vir_bytes)ds, sizeof(struct shmid_ds));
		if (r != OK)
			return EFAULT;
		break;
	case IPC_SET:
		uid = getnuid(who_e);
		if (uid != shm->shmid_ds.shm_perm.cuid &&
			uid != shm->shmid_ds.shm_perm.uid &&
			uid != 0)
			return EPERM;
		r = sys_datacopy(who_e, (vir_bytes)ds,
			SELF_E, (vir_bytes)&tmp_ds, sizeof(struct shmid_ds));
		if (r != OK)
			return EFAULT;
		shm->shmid_ds.shm_perm.uid = tmp_ds.shm_perm.uid;
		shm->shmid_ds.shm_perm.gid = tmp_ds.shm_perm.gid;
		shm->shmid_ds.shm_perm.mode &= ~0777;
		shm->shmid_ds.shm_perm.mode |= tmp_ds.shm_perm.mode & 0666;
		shm->shmid_ds.shm_ctime = time(NULL);
		break;
	case IPC_RMID:
		uid = getnuid(who_e);
		if (uid != shm->shmid_ds.shm_perm.cuid &&
			uid != shm->shmid_ds.shm_perm.uid &&
			uid != 0)
			return EPERM;
		shm->shmid_ds.shm_perm.mode |= SHM_DEST;
		/* destroy if possible */
		update_refcount_and_destroy();
		break;
	case IPC_INFO:
		if (!ds)
			return EFAULT;
		sinfo.shmmax = (unsigned long) -1;
		sinfo.shmmin = 1;
		sinfo.shmmni = MAX_SHM_NR;
		sinfo.shmseg = (unsigned long) -1;
		sinfo.shmall = (unsigned long) -1;
		r = sys_datacopy(SELF_E, (vir_bytes)&sinfo,
			who_e, (vir_bytes)ds, sizeof(struct shminfo));
		if (r != OK)
			return EFAULT;
		m->SHMCTL_RET = shm_list_nr - 1;
		if (m->SHMCTL_RET < 0)
			m->SHMCTL_RET = 0;
		break;
	case SHM_INFO:
		if (!ds)
			return EFAULT;
		s_info.used_ids = shm_list_nr;
		s_info.shm_tot = 0;
		for (i = 0; i < shm_list_nr; i++)
			s_info.shm_tot +=
				shm_list[i].shmid_ds.shm_segsz/I386_PAGE_SIZE;
		s_info.shm_rss = s_info.shm_tot;
		s_info.shm_swp = 0;
		s_info.swap_attempts = 0;
		s_info.swap_successes = 0;
		r = sys_datacopy(SELF_E, (vir_bytes)&s_info,
			who_e, (vir_bytes)ds, sizeof(struct shm_info));
		if (r != OK)
			return EFAULT;
		m->SHMCTL_RET = shm_list_nr - 1;
		if (m->SHMCTL_RET < 0)
			m->SHMCTL_RET = 0;
		break;
	case SHM_STAT:
		if (id < 0 || id >= shm_list_nr)
			return EINVAL;
		shm = &shm_list[id];
		r = sys_datacopy(SELF_E, (vir_bytes)&shm->shmid_ds,
			who_e, (vir_bytes)ds, sizeof(struct shmid_ds));
		if (r != OK)
			return EFAULT;
		m->SHMCTL_RET = shm->id;
		break;
	default:
		return EINVAL;
	}
	return OK;
}
Пример #5
0
PUBLIC int main(int argc, char *argv[])
{
	message m;

	/* SEF local startup. */
	env_setargs(argc, argv);
	sef_local_startup();

	while (TRUE) {
		int r;
		int i;

		if ((r = sef_receive(ANY, &m)) != OK)
			printf("sef_receive failed %d.\n", r);
		who_e = m.m_source;
		call_type = m.m_type;

		if(verbose)
			printf("IPC: get %d from %d\n", call_type, who_e);

		if (call_type & NOTIFY_MESSAGE) {
			switch (who_e) {
			case VM_PROC_NR:
				/* currently, only semaphore needs such information. */
				sem_process_vm_notify();
				break;
			default:
				printf("IPC: ignoring notify() from %d\n",
					who_e);
				break;
			}
			continue;
		}

		/* dispatch messages */
		for (i = 0; i < SIZE(ipc_calls); i++) {
			/* If any process does an IPC call,
			 * we have to know about it exiting.
			 * Tell VM to watch it for us.
			 */
			if(vm_watch_exit(m.m_source) != OK) {
				printf("IPC: watch failed on %d\n", m.m_source);
			}

			if (ipc_calls[i].type == call_type) {
				int result;

				result = ipc_calls[i].func(&m);

				if (ipc_calls[i].reply)
					break;

				m.m_type = result;

				if(verbose && result != OK)
					printf("IPC: error for %d: %d\n",
						call_type, result);

				if ((r = sendnb(who_e, &m)) != OK)
					printf("IPC send error %d.\n", r);
				break;
			}
		}

		if (i == SIZE(ipc_calls)) {
			/* warn and then ignore */
			printf("IPC unknown call type: %d from %d.\n",
				call_type, who_e);
		}
		update_refcount_and_destroy();
	}

	/* no way to get here */
	return -1;
}