Esempio n. 1
0
int
sys_shmget(struct proc *p, void *v, register_t *retval)
{
	struct sys_shmget_args /* {
		syscallarg(key_t) key;
		syscallarg(size_t) size;
		syscallarg(int) shmflg;
	} */ *uap = v;
	int segnum, mode, error;

	mode = SCARG(uap, shmflg) & ACCESSPERMS;

	if (SCARG(uap, key) != IPC_PRIVATE) {
	again:
		segnum = shm_find_segment_by_key(SCARG(uap, key));
		if (segnum >= 0)
			return (shmget_existing(p, uap, mode, segnum, retval));
		if ((SCARG(uap, shmflg) & IPC_CREAT) == 0) 
			return (ENOENT);
	}
	error = shmget_allocate_segment(p, uap, mode, retval);
	if (error == EAGAIN)
		goto again;
	return (error);
}
Esempio n. 2
0
/* Handle a shmget() request. */
int
handle_shmget(pid_t pid, struct shmget_msg *shmget_msg,
		struct cmsgcred *cred ) {
	int segnum, mode, error;
	struct shmid_ds *shmseg;
	struct shm_handle *handle;

	//if (!jail_sysvipc_allowed && td->td_cmsgcred->cr_prison != NULL)
	//	return (ENOSYS);
	mode = shmget_msg->shmflg & ACCESSPERMS;

	sysvd_print("ask for key = %ld\n", shmget_msg->key);
	shmget_msg->key = (shmget_msg->key & 0x3FFF) |
		(shmget_msg->type << 30);
	sysvd_print("ask for key = %ld\n", shmget_msg->key);

	if (shmget_msg->key != IPC_PRIVATE) {
		//again:
		segnum = shm_find_segment_by_key(shmget_msg->key);
		if (segnum >= 0) {
			error = shmget_existing(shmget_msg, mode, segnum, cred);
			//TODO if daemon is multithreading
			//if (error == EAGAIN)
			//	goto again;
			goto done;
		}
		if ((shmget_msg->shmflg & IPC_CREAT) == 0) {
			error = -ENOENT;
			goto done_err;
		}
	}
	error = shmget_allocate_segment(pid, shmget_msg, mode, cred);
	sysvd_print("allocate segment = %d\n", error);
done:
	/*
	 * Install to th client the file corresponding to the
	 * shared memory segment.
	 * client_fd is the file descriptor added in the client
	 * files table.
	 */
	shmseg = shm_find_segment_by_shmid(error);
	if (shmseg == NULL) {
		sysvd_print_err("can not find segment by shmid\n");
		return (-1);
	}

	handle = (struct shm_handle *)shmseg->shm_internal;
	if (install_fd_client(pid, handle->fd) != 0)
		error = errno;
done_err:
	return (error);

}