void do_dup2(PCB *pcb){ int fd_old = pcb->registers[5], fd_new = pcb->registers[6]; struct File_Descriptor *new_fd_obj, *old_fd_obj, *curr_fd_obj; if(fd_old == fd_new){ syscall_return(pcb, fd_new); } if(fd_new >= 0 && fd_new < MaxFds && valid_fd(pcb, fd_old, -1)){ old_fd_obj = pcb->fd_table[fd_old]; int close = 0; curr_fd_obj = pcb->fd_table[fd_new]; new_fd_obj = new_fd(fd_new, old_fd_obj->permission); dup_fd(old_fd_obj,new_fd_obj); if(curr_fd_obj != senitel_fd){ close_fd(pcb, fd_new); } pcb->fd_table[new_fd_obj->id] = new_fd_obj; syscall_return(pcb, fd_new); }else{ syscall_return(pcb,-1*EBADF); } }
void do_dup(PCB *pcb) { int fd_old = pcb->registers[5], fd_new; struct File_Descriptor *new_fd_obj, *old_fd_obj; if(valid_fd(pcb, fd_old, -1)) { old_fd_obj = pcb->fd_table[fd_old]; fd_new = next_fd(pcb); if(fd_new > -1) { new_fd_obj = new_fd(fd_new, old_fd_obj->permission); dup_fd(old_fd_obj,new_fd_obj); pcb->fd_table[new_fd_obj->id] = new_fd_obj; } else { syscall_return(pcb, -1*EMFILE); } //printf("process %d duping to new fd %d!\n",pcb->pid, fd_new); syscall_return(pcb, fd_new); } else { syscall_return(pcb,-1*EBADF); } }
void do_close(PCB* pcb){ int fd = pcb->registers[5]; struct File_Descriptor *fd_obj; //printf("process %d trying to close %d!\n",pcb->pid, fd); //printf("IGNORE THE BAD FILE DESCIPTOR BELOW\n"); if(valid_fd(pcb, fd, -1)){ close_fd(pcb,fd); syscall_return(pcb, 0); //0 on success }else{ syscall_return(pcb, -1*EBADF); //set to this according step 16 lab 3 cookbook } }
void do_getppid(PCB *pcb){ syscall_return(pcb, pcb->parent_pcb->pid); }
void do_getpagesize(PCB *pcb){ syscall_return(pcb, PageSize); }
void do_read(PCB *pcb){ int fd = pcb->registers[5], buf = pcb->registers[6], count = pcb->registers[7]; //printf("COUNT COUNT COUNT::::%d",count); if(valid_fd(pcb, fd, FD_READ)){ //todo: or valid fd if(buf < 0){ syscall_return(pcb,-1*EFAULT); } }else{ syscall_return(pcb,-1*EBADF); //Bad file number } struct File_Descriptor *fd_obj = pcb->fd_table[fd]; //if(!fd_obj->console_flag){ //printf("do_read: %d %d %d\n", fd, buf, count); //} if(check_buffer_address(pcb, buf) == FALSE){ syscall_return(pcb, -1*EFAULT); } if(count < 0){ syscall_return(pcb, -1*EINVAL); } int i = 0; int val; //printf("\ngot here to 1\n"); for(; i < count; i++){ //printf("obj id:%d, console flag:%d\n", fd_obj->id, fd_obj->console_flag); if(fd_obj->console_flag){ //printf("\ngot here to 0000\n"); P_kt_sem(nelem); Dllist first = dll_first(console_read_buf); val = jval_i(dll_val(first)); dll_delete_node(first); console_read_buf_size -= 1; }else{ //HMM, do we need a lock for buffer access? //printf("\ngot here to 2\n"); struct Pipe *pipe = fd_obj->pipe; //printf("read from pipe: %p\n", pipe); //printf("r:b\n"); P_kt_sem(pipe->empty_sem); val = pipe->buff[pipe->buff_start]; //printf("r:(%d) %c\n",val, val); pipe->buff_start++; if(pipe->buff_start == PIPE_BUFF_SIZE){ pipe->buff_start = 0; } //printf("\ngot here to 2.5\n"); V_kt_sem(pipe->full_sem); //printf("\ngot here to 3\n") //printf("r:a\n");; if(pipe->buff_start == pipe->buff_end){ break; } } if(val == -1 || val == 0){ break; } main_memory[pcb->User_Base+buf+i] = val; } if(!fd_obj->console_flag){ //printf("read done\n"); } //printf("syscall return\n"); syscall_return(pcb, i); }
void *initialize_user_process(void *arg){ PCB *user_process; Jval jval_pcb; Jval user_process_child_node; char **filename; int base; int arg_count; int errno; int i; arg_count = 0; errno = 0; i = 0; /* Unmarshalling */ filename = (char **) arg; /* Create the global init process */ init = (PCB *)malloc(sizeof(PCB)); init->registers = (int *)malloc(sizeof(int) * NumTotalRegs); // Initialize init's registers */ for (i = 0; i < NumTotalRegs; i++) { init->registers[i] = 0; } // Initialize init's other variables init->pid = (int *)0; init->waiter = make_kt_sem(0); init->waiters = new_dllist(); init->children = make_jrb(); /* Allocate new PCB and initialize registers */ user_process = (PCB *)malloc(sizeof(PCB)); user_process->registers = (int *)malloc(NumTotalRegs * sizeof(int)); for (i = 0; i < NumTotalRegs; i++) { user_process->registers[i] = 0; } // Obtain pid and partiton memory for new process user_process->pid = (int *)get_new_pid(); base = partition_memory(user_process->pid); // Initialize first process' other variables user_process->waiter = make_kt_sem(0); user_process->waiters = new_dllist(); user_process->children = make_jrb(); // Set base and limit for new process user_process->base = 0; user_process->limit = MemorySize/8; // Set User global vars User_Base = base; User_Limit = user_process->limit; // Set process' PCRegs user_process->registers[PCReg] = 0; user_process->registers[NextPCReg] = 4; // Set first process' parent as init and add to init's children user_process->parent = (struct PCB *)init; user_process_child_node.v = user_process; jrb_insert_int(init->children, (int)user_process->pid, user_process_child_node); // Get number of args and turn off exec flag. while (filename[arg_count] != NULL) { arg_count++; } totalArgs = arg_count; is_exec = 0; /* Call perform_execve */ errno = perform_execve(user_process, filename[0], filename); // If errors, returns proper errno if (errno != 1) { syscall_return(user_process, errno); } else { // Puts new job onto readyQ and calls kt_exit() jval_pcb.v = user_process; dll_append(readyQ, jval_pcb); kt_exit(); } }