Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
0
/*===========================================================================*
 *				do_shmget		     		     *
 *===========================================================================*/
PUBLIC int do_shmget(message *m)
{
	struct shm_struct *shm;
	long key, size, old_size;
	int flag;
	int id;

	key = m->SHMGET_KEY;
	old_size = size = m->SHMGET_SIZE;
	flag = m->SHMGET_FLAG;

	if ((shm = shm_find_key(key))) {
		if (!check_perm(&shm->shmid_ds.shm_perm, who_e, flag))
			return EACCES;
		if ((flag & IPC_CREAT) && (flag & IPC_EXCL))
			return EEXIST;
		if (size && shm->shmid_ds.shm_segsz < size)
			return EINVAL;
		id = shm->id;
	} else { /* no key found */
		if (!(flag & IPC_CREAT))
			return ENOENT;
		if (size <= 0)
			return EINVAL;
		/* round up to a multiple of PAGE_SIZE */
		if (size % I386_PAGE_SIZE)
			size += I386_PAGE_SIZE - size % I386_PAGE_SIZE;
		if (size <= 0)
			return EINVAL;

		if (shm_list_nr == MAX_SHM_NR)
			return ENOMEM;
		/* TODO: shmmni should be changed... */
		if (identifier == SHMMNI)
			return ENOSPC;
		shm = &shm_list[shm_list_nr];
		memset(shm, 0, sizeof(struct shm_struct));
		shm->page = (vir_bytes) mmap(0, size,
					PROT_READ|PROT_WRITE,
					MAP_CONTIG|MAP_PREALLOC|MAP_ANON|MAP_SHARED,
					-1, 0);
		if (shm->page == (vir_bytes) MAP_FAILED)
			return ENOMEM;
		shm->phys = vm_getphys(SELF_E, (void *) shm->page);
		memset((void *)shm->page, 0, size);

		shm->shmid_ds.shm_perm.cuid =
			shm->shmid_ds.shm_perm.uid = getnuid(who_e);
		shm->shmid_ds.shm_perm.cgid =
			shm->shmid_ds.shm_perm.gid = getngid(who_e);
		shm->shmid_ds.shm_perm.mode = flag & 0777;
		shm->shmid_ds.shm_segsz = old_size;
		shm->shmid_ds.shm_atime = 0;
		shm->shmid_ds.shm_dtime = 0;
		shm->shmid_ds.shm_ctime = time(NULL);
		shm->shmid_ds.shm_cpid = getnpid(who_e);
		shm->shmid_ds.shm_lpid = 0;
		shm->shmid_ds.shm_nattch = 0;
		shm->id = id = identifier++;
		shm->key = key;

		shm_list_nr++;
	}

	m->SHMGET_RETID = id;
	return OK;
}