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); } }
// returns non-zero if data is available on stdin int _kbhit(void) { if (!valid_fd(STDIN)) { if (!initStdHandlesInline()) return 0; if (!valid_fd(STDIN)) return 0; } if (fd_stdin->pipe != NULL) { return pipeReadable(fd_stdin->pipe) ? 1 : 0; } else return 0; }
static void uninitStdHandles() { if (!initialisedStdHandles) return; if (g_childData != NULL) { delete g_childData; g_childData = NULL; } if (valid_file(STDIN)) fclose(stdin); if (valid_file(STDOUT)) fclose(stdout); if (valid_file(STDERR)) fclose(stderr); if (valid_fd(STDIN)) close(STDIN); if (valid_fd(STDOUT)) close(STDOUT); if (valid_fd(STDERR)) close(STDERR); initialisedStdHandles = false; }
/* try to advise fds that were not manually closed */ static void destroy(void) { int i; pthread_mutex_lock(&lock); for(i = 0; i < max_fds; i++) { if(fds[i].fd == -1) continue; /* slot is empty */ if(!valid_fd(fds[i].fd)) continue; pthread_mutex_unlock(&lock); free_unclaimed_pages(fds[i].fd); pthread_mutex_lock(&lock); } pthread_mutex_unlock(&lock); }
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 } }
int dup2(int oldfd, int newfd) { int ret; /* if newfd is already opened, the kernel will close it directly * once dup2 is invoked. So now is the last chance to mark the * pages as "DONTNEED" */ if(valid_fd(newfd)) free_unclaimed_pages(newfd); if(!_original_dup2) _original_dup2 = (int (*)(int, int)) dlsym(RTLD_NEXT, "dup2"); assert(_original_dup2 != NULL); DEBUG("dup2(oldfd=%d, newfd=%d)\n", oldfd, newfd); if((ret = _original_dup2(oldfd, newfd)) != -1) store_pageinfo(newfd); return ret; }
/* * This function implements the mmap(2) syscall, but only * supports the MAP_SHARED, MAP_PRIVATE, MAP_FIXED, and * MAP_ANON flags. * * Add a mapping to the current process's address space. * You need to do some error checking; see the ERRORS section * of the manpage for the problems you should anticipate. * After error checking most of the work of this function is * done by vmmap_map(), but remember to clear the TLB. */ int do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off, void **ret) { if (len == 0){ return -EINVAL; } if (!valid_map_type(flags)){ return -EINVAL; } if (!PAGE_ALIGNED(off)){ return -EINVAL; } if (!(flags & MAP_ANON) && (flags & MAP_FIXED) && !PAGE_ALIGNED(addr)){ return -EINVAL; } if (addr != NULL && (uint32_t) addr < USER_MEM_LOW){ return -EINVAL; } if (len > USER_MEM_HIGH){ return -EINVAL; } if (addr != NULL && len > USER_MEM_HIGH - (uint32_t) addr){ return -EINVAL; } if (addr == 0 && (flags & MAP_FIXED)){ return -EINVAL; } /* if ((!(flags & MAP_PRIVATE) && !(flags & MAP_SHARED))*/ /*|| ((flags & MAP_PRIVATE) && (flags & MAP_SHARED)))*/ /*{*/ /*return -EINVAL;*/ /*}*/ vnode_t *vnode; if (!(flags & MAP_ANON)){ if (!valid_fd(fd) || curproc->p_files[fd] == NULL){ return -EBADF; } file_t *f = curproc->p_files[fd]; vnode = f->f_vnode; if ((flags & MAP_PRIVATE) && !(f->f_mode & FMODE_READ)){ return -EACCES; } if ((flags & MAP_SHARED) && (prot & PROT_WRITE) && !((f->f_mode & FMODE_READ) && (f->f_mode & FMODE_WRITE))) { return -EACCES; } /*if ((prot & PROT_WRITE) && (f->f_mode & FMODE_APPEND)){*/ /*return -EACCES;*/ /*}*/ } else { vnode = NULL; } vmarea_t *vma; int retval = vmmap_map(curproc->p_vmmap, vnode, ADDR_TO_PN(addr), (uint32_t) PAGE_ALIGN_UP(len) / PAGE_SIZE, prot, flags, off, VMMAP_DIR_HILO, &vma); KASSERT(retval == 0 || retval == -ENOMEM); if (ret != NULL && retval >= 0){ *ret = PN_TO_ADDR(vma->vma_start); pt_unmap_range(curproc->p_pagedir, (uintptr_t) PN_TO_ADDR(vma->vma_start), (uintptr_t) PN_TO_ADDR(vma->vma_start) + (uintptr_t) PAGE_ALIGN_UP(len)); tlb_flush_range((uintptr_t) PN_TO_ADDR(vma->vma_start), (uint32_t) PAGE_ALIGN_UP(len) / PAGE_SIZE); } return retval; }
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); }