mqd_t do_mq_open()
{
	size_t name_size = sizeof(char) * MAX_NAME_SIZE;
	char *name = (char *)malloc(name_size);
	sys_datacopy(who_e, (vir_bytes)m_in.m7_p1, SELF, (vir_bytes)name, name_size);
	int open_flag = m_in.m7_i1;
	int blocking_flag = m_in.m7_i2;
	int max_mess = m_in.m7_i3;
	int grp_id = m_in.m7_i4;
	uid_t my_uid = mproc[who_p].mp_realuid;

	int grp_index = array_search(groups_ids, MAX_ADMINS, grp_id);

	if (grp_index < 0) {
		printf("Error: queue Group not found in the group list\n");
		return FAIL;
	}

	int grp_policy = groups_attr[grp_index]->grouptype;

	int uid_index = array_search(groups_attr[grp_index]->sendingusers, MAX_ADMINS, my_uid);

	if(uid_index < 0) {
		uid_index = array_search(groups_attr[grp_index]->receivingusers, MAX_ADMINS, my_uid);
	}

	/*              public                  ||             secure               */
	if ((grp_policy != 0 && uid_index >= 0) || (grp_policy == 0 && uid_index < 0)) { 
		if (my_uid != groups_attr[grp_index]->creator || my_uid != 0) { 
			printf("Error: user not allowed to open the queue\n");
			return FAIL;
		}
	} 

	// printf("do_mq_open: printing of variables\n");
	// printf("      name           %s\n", name);
	// printf("      open_flag      %d\n", open_flag);
	// printf("      blocking_flag  %d\n", blocking_flag);
	// printf("      max_mess       %d\n", max_mess);

	if (curr_num_queues == MAX_QUEUES)
	{
		printf("Maximum number of queues have already been opened.\n");
		return FAIL;
	}

	pid_t calling_proc = mproc[who_p].mp_pid;

	if (calling_proc < 1)
	{
		printf("Unable to acquire the calling process's PID.\n");
		return FAIL;
	}

	if (open_flag != O_RDONLY && open_flag != O_WRONLY && open_flag != O_RDWR)
	{
		printf("The open flag must either be O_RDONLY, O_WRONLY, or O_RDWR.\n");
		return FAIL;
	}


	// printf("do_mq_open: name of queue: %s\n", name);
	int i;
	for (i = 0; i < curr_num_queues; i++)
	{
		if (strcmp(queues[i].attr->name, name) == 0)
		{
			if (open_flag == O_RDONLY)
			{
				int success = addproc(queues[i].receiver_pids, calling_proc);
				if (success == FAIL)
					return FAIL;
			}
			else if (open_flag == O_WRONLY)
			{
				int success = addproc(queues[i].sender_pids, calling_proc);
				if (success == FAIL)
					return FAIL;
			}
			else
			{
				int success = addproc(queues[i].sender_pids, calling_proc);
				if (success == FAIL)
					return FAIL;
				success = addproc(queues[i].receiver_pids, calling_proc);
				if (success == FAIL)
				{
					deleteproc(queues[i].sender_pids, calling_proc);
					return FAIL;
				}
			}
			return i;
		}
	}

	queues_mask[curr_num_queues++] = 1;

	// printf("do_mq_open: curr_num_queues %d\n", curr_num_req);

	mq_t *new_queue = malloc(sizeof(mq_t));
	new_queue->attr = malloc(sizeof(mq_attr_t));
	new_queue->attr->name = (char *)name;
	new_queue->attr->send_blocking = blocking_flag;
	new_queue->attr->receive_blocking = blocking_flag;
	new_queue->attr->max_message_size = MAX_MESSAGE_SIZE;
	new_queue->attr->grp_id = grp_id;

	printf("do_mq_open: new_queue->attr->grp_id = %d\n", new_queue->attr->grp_id);

	if (max_mess)
	{
		new_queue->attr->max_messages = max_mess;
		
	}
	else
	{
		new_queue->attr->max_messages = MAX_MESSAGES;
	}

	new_queue->curr_num_messages_total = 0;
	new_queue->sender_pids = malloc(sizeof(SIZE_INT * MAX_PROCESSES));
	new_queue->receiver_pids = malloc(sizeof(SIZE_INT * MAX_PROCESSES));
	new_queue->queue_high = malloc(sizeof(queue_t));
	new_queue->queue_norm = malloc(sizeof(queue_t));
	new_queue->queue_low = malloc(sizeof(queue_t));

	int num_messages = new_queue->attr->max_messages;
	int size_messages = new_queue->attr->max_message_size;

	// TODO: go back and fix this size of
	new_queue->queue_high->messages = malloc(sizeof(message_t) * num_messages * size_messages);
	new_queue->queue_norm->messages = malloc(sizeof(message_t) * num_messages * size_messages);
	new_queue->queue_low->messages = malloc(sizeof(message_t) * num_messages * size_messages);

	init_queue(new_queue->queue_high, num_messages);
	init_queue(new_queue->queue_norm, num_messages);
	init_queue(new_queue->queue_low, num_messages);

	queues[curr_num_queues - 1] = *new_queue;

	return curr_num_queues - 1;
	
}
Exemple #2
0
static void
sysrfork(void)
{
	u32int flags;
	int rc, i;
	Process *p;
	Segment *s, *t;
	Fd *old;
	
	flags = arg(0);
	if(systrace)
		fprint(2, "rfork(%#o)\n", flags);
	if((flags & (RFFDG | RFCFDG)) == (RFFDG | RFCFDG) ||
	   (flags & (RFNAMEG | RFCNAMEG)) == (RFNAMEG | RFCNAMEG) ||
	   (flags & (RFENVG | RFCENVG)) == (RFENVG | RFCENVG)) {
		P->R[0] = -1;
		cherrstr("bad arg in syscall");
		return;
	}
	if((flags & RFPROC) == 0) {
		if(flags & RFFDG) {
			old = P->fd;
			P->fd = copyfd(P->fd);
			fddecref(old);
		}
		if(flags & RFCFDG) {
			old = P->fd;
			P->fd = newfd();
			fddecref(old);
		}
		P->R[0] = noteerr(rfork(flags), 0);
		return;
	}
	incref(&nproc);
	p = emallocz(sizeof(Process));
	memcpy(p, P, sizeof(Process));
	for(i = 0; i < SEGNUM; i++) {
		s = p->S[i];
		if(s == nil)
			continue;
		if((flags & RFMEM) == 0 && i != SEGTEXT || i == SEGSTACK) {
			t = emallocz(sizeof(Segment));
			incref(t);
			t->size = s->size;
			t->start = s->start;
			t->dref = emalloc(sizeof(Ref) + s->size);
			memset(t->dref, 0, sizeof(Ref));
			incref(t->dref);
			t->data = t->dref + 1;
			memcpy(t->data, s->data, s->size);
			p->S[i] = t;
		} else {
			incref(s->dref);
			incref(s);
		}
	}
	
	if(flags & RFFDG)
		p->fd = copyfd(P->fd);
	else if(flags & RFCFDG)
		p->fd = newfd();
	else
		incref(P->fd);

	incref(P->path);
	rc = rfork(RFMEM | flags);
	if(rc < 0) /* this should NEVER happen */
		sysfatal("rfork failed wtf: %r");
	if(rc == 0) {
		P = p;
		atexit(cleanup);
		P->pid = getpid();
		inittos();
		addproc(P);
	}
	P->R[0] = rc;
}