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; }
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; }