コード例 #1
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Remove a file */
bool remove(const char *f_name) {
    struct dir* cur_dir;
    char name[15];
    /* Checks the validity of the given pointer */
    //printf("going to remove file %s\n\n", f_name);
    if (!checkva(f_name))
        exit(-1);
    
    

    if (!decompose_dir(f_name, name, &cur_dir))
        return false;
    
    if (strcmp(".", name) == 0 || strcmp("..", name) == 0)
        return false;
    lock_acquire(&filesys_lock);
    /* Remove the file, while locking the file system. */
    bool flag = filesys_dir_remove(name, cur_dir);
    //printf("name decomposed! %x\n\n", cur_dir);
    
    dir_close(cur_dir);

    lock_release(&filesys_lock);
    return flag;
}
コード例 #2
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Read from file */
int read(uint32_t fd, void *buffer, unsigned size) {
    uint8_t* addr_e;
    struct supp_table* st;
    
    /* Check the validity of given pointer */
    if ((!checkva(buffer)) || (!checkva(buffer + size))){
        exit(-1);
    }
    
    for (addr_e = (uint8_t*) pg_round_down(buffer); 
         addr_e < (uint8_t*) buffer + size; addr_e += PGSIZE){
        st = find_supp_table(addr_e);
        if (st && !st->writable)
            exit(-1);
    }
    
    int read_size = 0;
    if (fd == STDIN_FILENO) {
        /* If std-in, then read using input_getc() */
        unsigned i;
        for (i = 0; i < size; i++){
            *((uint8_t*) buffer) = input_getc();
            ++ read_size;
            ++ buffer;
        }
    } else {
        /* Otherwise, first find the file of this fd. */
        struct f_info* f = findfile(fd);
        
        /* We should read a dir like a file. */
        if (f->isdir)
            exit(-1);
        
        struct file* fin = f->f;
        off_t pos = f->pos;
        
        /* Read from the file at f->pos */
        //lock_acquire(&filesys_lock);
        read_size = (int) file_read_at(fin, buffer, (off_t) size, pos);
        f->pos += (off_t) read_size;
        //lock_release(&filesys_lock);
        
    }
    return read_size;

}
コード例 #3
0
ファイル: syscall.c プロジェクト: khanotations/pios
// Copy data to/from user space,
// using checkva() above to validate the address range
// and using sysrecover() to recover from any traps during the copy.
void usercopy(trapframe *utf, bool copyout,
			void *kva, uint32_t uva, size_t size) {
	checkva(utf, uva, size);
  cpu *c = cpu_cur();
  c->recover = sysrecover;

  if(copyout)
    memmove((void*)uva, kva, size);
  else
    memmove(kva, (void*)uva, size);

  c->recover = NULL;
}
コード例 #4
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Write to file. */
int write(uint32_t fd, const void *buffer, unsigned size) {
    uint8_t* addr_e;
    struct supp_table *st;
    /* Check the validity of given pointer */
    if ((!checkva(buffer)) || (!checkva(buffer + size)))
        exit(-1);
    /* Checking we are not writing to unwritable pages. */
    
    int write_size = 0;
    
    if (fd == STDOUT_FILENO) {
        /* If std-out, then write using putbuf() */
        putbuf(buffer, size);
        write_size = size;
        
    } else {
        /* Otherwise, first find the file of this fd. */
        struct f_info* f = findfile(fd);
        
        /* We should write to a directory just like a file. */
        if (f->isdir)
            exit(-1);
        
        struct file* fout = f->f;
        off_t pos = f->pos;
        
        /* Write to the file at f->pos */
        //lock_acquire(&filesys_lock);
        write_size = (int) file_write_at(fout, buffer, (off_t) size, pos);

        f->pos += (off_t) write_size;
        //lock_release(&filesys_lock);
        
    }

    return write_size;

}
コード例 #5
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Reads a directory entry from file descriptor fd. If successful, stores,
 * the null-terminated file name in name. If no entries are left in 
 * directory, returns false. */
bool _readdir(uint32_t fd, char* name){
    /* Check for the validity of the pointer. */
    if (!checkva(name))
        return false;
    
    /* Get the f_info struct of this fd*/
    struct f_info* f = findfile(fd);
    
    /*Check that we are opening a directory. */
    if (!f->isdir)
        return false;
    
    /* Use the defined dir_readir to finish the function. */
    return dir_readdir(f->d, name);
}
コード例 #6
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Create a file */
bool create(const char *f_name, unsigned initial_size) {
    struct dir* cur_dir;
    char name[15];
    /* Checks the validity of the given pointer */
    if (!checkva(f_name) || !(*f_name))
        exit(-1);
    
    if (!decompose_dir(f_name, name, &cur_dir)){
        return false;
    }
    lock_acquire(&filesys_lock); 
    /* Create the file, while locking the file system. */
    bool flag = filesys_dir_create(name, (off_t) initial_size, cur_dir);

    dir_close(cur_dir);
    lock_release(&filesys_lock);
    return flag;

}
コード例 #7
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Creates the directory named dir. Return true if successful, but false
 * if dir already exists or if any directory name in dir, besides the last
 * one does not exist. */
bool _mkdir(const char* dir) {
    /* Inode for the new directory created. */
    struct inode* next_inode;
    
    /* Parent directory. */
    struct dir* cur_dir;
    
    /* Name of the directory. */
    char name[15];
    
    /* Sector number allocated to the new directory. */
    block_sector_t sector;
    
    /* Check the validity of the pointer*/
    if (!checkva(dir))
       exit(-1);
    
    /* The compose the path to a final dir name and its parent directory. */
    if (!decompose_dir(dir, name, &cur_dir)){
        return false;
    }
    ASSERT(cur_dir != NULL);
    
    /* Allocate a new sector for this new directory;
     * Create a new directory */
    if (!free_map_allocate(1, &sector) || 
        !dir_create(sector, 0, dir_get_inode(cur_dir)->sector)){
        
        dir_close(cur_dir);
        return false;
    }
    
    /* Add the new directory to its parent directory. */
    if (!dir_add(cur_dir, name, sector)){
        free_map_release(sector, 1);
        dir_close(cur_dir);
        return false;
    }
    
    dir_close(cur_dir);
    return true;
}
コード例 #8
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Changes the working directory of the current process (i.e. 
 * thread->cur_dir). Returns true if the operation is successfull
 * and false otherwise. */
bool _chdir(const char* dir){
    /* The current process*/
    struct thread* t = thread_current();
    
    /* inode for the new directory*/
    struct inode* next_inode;
    
    /* new directory struct*/
    struct dir* cur_dir;
    
    /* name of the directory*/
    char name[15];
    
    
    /* Check validity of the pointer*/
    if (!checkva(dir)){
       exit(-1);
    }
   
   /* Decompose the path to a final name and parent directory. */
    if (!decompose_dir(dir, name, &cur_dir))
        return false;
    
    if (strcmp(name, "\0") != 0){
        
        /* If name is not empty, then we simply look for the name
         * under the parent directory cur_dir, and get the inode
         * of this destination directory. */
        if (!dir_lookup(cur_dir, name, &next_inode)) {
            dir_close(cur_dir);
            return false;
        }
        
        /* Close the parent directory, as we do not need it any more. */
        dir_close(cur_dir);
        
        /* Check that the inode we are opening is a directory. */
        if  (next_inode->data.type != DIR_INODE_DISK) {
            inode_close(next_inode);
            return false;
        }
        
        /* Open up the inode to directory struct*/
        cur_dir = dir_open(next_inode);
        if (cur_dir == NULL) {
            inode_close(next_inode);
            return false;
        }
        
    } else if (dir[strlen(dir)] != '/'){
        /* If the name is not empty, and the give path does not end with "/" 
         * then this path is an invalid directory path. 
         * Note if the path is in fact valid and the name we get is empty,
         * then the distiniation directory has been already opened in 
         * cur_dir. */
        dir_close(cur_dir);
        return false;
    }
    
    /* Update the current process's working directory */
    dir_close(t->cur_dir);
    t->cur_dir = dir_reopen(cur_dir);
    dir_close(cur_dir);
    
    return true;
}
コード例 #9
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Memory map from file to user address. */
mapid_t mmap(uint32_t fd, void* addr){
    
    int f_size;
    void* addr_e;
    mapid_t mapid;
    uint32_t read_bytes, zero_bytes;
    uint8_t *upage;
    off_t ofs;
    struct file* file;
    struct f_info* f;
    struct mmap_elem* me;
    struct supp_table* st;
    struct thread* t = thread_current();
    
    if (!checkva(addr))
        return MAP_FAIL;

    /* Check for the invalid conditions:
     * fd is standard io; file size of the given fd is 0; give user address
     * is not valie; given address is not page aligned; given address is 0.
     * If invalid, then return MAP_FAIL. */
    if (fd == STDIN_FILENO ||
        fd == STDOUT_FILENO ||
        filesize(fd) == 0 ||
        pg_ofs(addr) != 0 ||
        addr == 0) {
            return MAP_FAIL;
    }
    
    /* Get the file size of the file. And check the entire range of the
     * to-be-mapped user address does not overlap with any already allocated
     * pages. */
    f_size = filesize(fd);
    for (addr_e = addr; addr_e < addr + f_size; addr_e += PGSIZE){
            if (find_supp_table(addr_e) != NULL){
                /* If found a supplemental page entry of this page address,
                 * Then this is already alocated. Return MAP_FAIL. */
                return MAP_FAIL;
            }   
    }
    
    /* Increment the thread's max mmapid to give this mmapping a unque ID. */
    ++ t->mmapid_max;
    mapid = t->mmapid_max;
    
    /* Allocated the new mmap struct */
    me = (struct mmap_elem*) malloc(sizeof(struct mmap_elem));
    if (me == NULL)
        return MAP_FAIL;
    
    /* Reopen the file according to the file descriptor. */
    f = findfile(fd);
    if (f->isdir)
        return MAP_FAIL;
    lock_acquire(&filesys_lock);
    file = file_reopen(f->f);
    lock_release(&filesys_lock);
    
    /* If the file is NULL, then free the struct and return MAP_FAIL. */
    if (file == NULL){
        free(me);
        return MAP_FAIL;
    }
    
    /* Setup the fields of the mmap struct.*/
    me->file = file;
    me->mapid = mapid;
    /* Push the mmap struct to the list of mmap of this process. */
    list_push_back(&(t->mmap_lst), &(me->elem));
    list_init(&(me->s_table));
    
    /* Allocate pages for the read-in file data.*/
    upage = addr;
    ofs = 0;
    read_bytes = f_size;
    
    if (read_bytes >= PGSIZE)
        zero_bytes = 0;
    else
        zero_bytes = PGSIZE - read_bytes;
    
    while (read_bytes > 0) {
        /* Calculate how to fill this page.
           We will read PAGE_READ_BYTES bytes from FILE
           and zero the final PAGE_ZERO_BYTES bytes. */
        size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
        size_t page_zero_bytes = PGSIZE - page_read_bytes;
        
        /* Create a new supplemental page entry for this page*/
        st = create_mmap_supp_table(file, ofs, upage, page_read_bytes, 
                                    page_zero_bytes, true);
        /* Push the page entry to the mmap struct's list */
        list_push_back(&(me->s_table), &(st->map_elem));
        
        /* Update the remaining read_bytes, zero_bytes;
         * Update upage, and ofs. This is for the next page to load the file.*/
        read_bytes -= page_read_bytes;
        zero_bytes -= page_zero_bytes;
        upage += PGSIZE;
        ofs += page_read_bytes;
        
    }
    return mapid;
}
コード例 #10
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Open a file or an directory */
int open(const char *f_name) {
    /* The parent directory of the opening file or directory. */
    struct dir* cur_dir;
    
    /* Name of the file or the directory. */
    char name[15];
    
    /* CUrrent thread. */
    struct thread *t;
    
    /* file info struct for creating fd to this thread. */
    struct f_info *f;
    
    /* dir struct or file struct depending what we are opening */
    struct dir* d_open;
    struct file* f_open;
    
    /* The flag for whether we are opening a directory. */
    bool isdir;
    
    /* fd number assigned to this file / directory */
    uint32_t fd;
    
    /* Inode of the file / dir we are opening. */
    struct inode* inode;

    /* Checks the validity of the given pointer */
    if (!checkva(f_name) || f_name[0] == '\0'){
       return -1;
    }
    
    /* Decomposes a path to the final file / dir name
     * and its corresponding parent dir. */
    if (!decompose_dir(f_name, name, &cur_dir)){
        return -1;
    }
    
    /* Open the file when locking the file system. */
    lock_acquire(&filesys_lock);
    
    if (strcmp(name, "\0") != 0){
        /* If file / dir name is not empty, then look for it in its parent 
         * directory. */
        if (!dir_lookup(cur_dir, name, &inode)){
            lock_release(&filesys_lock);
            return -1;
        }
        
        /* Decide whether the inode is a directory or a file. */
        isdir = (inode->data.type == DIR_INODE_DISK);
        
        /* Open the file / dir */
        if (isdir)
            d_open = dir_open(inode);
        else
            f_open = file_open(inode);
        lock_release(&filesys_lock);
    } else {
        /* Since we decomposed the entire path to a diretory
         * then we must be opening a directory. */
        isdir = true;
        /* Reopen the directory, to store in f_info */
        d_open = dir_reopen(cur_dir);
    }
    
    if (f_open == NULL && dir_open == NULL) {
        inode_close(inode);
        /* If file open failed, then exit with error. */
        return -1;
    } else {
        /* Assign fd to the file / dir */
        t = thread_current();
        if (t->f_count > 127){
            if (isdir){
                dir_close(d_open);
            } else {
                file_close(f_open);  
            }
            return -1;
        }
        
        /* Set up new f_info */
        f = (struct f_info*) malloc(sizeof(struct f_info));
        f->isdir = isdir;
        if (isdir)
            f->d = d_open;
        else
            f->f = f_open;
        f->pos = 0;
        
        /* Update the process's fd info */
        lock_acquire(&filesys_lock);
        fd = (++(t->fd_max));
        f->fd = fd;
        
        /* Push f_info to the thread's list, 
         * and update thread's list count. */
        list_push_back(&(t->f_lst), &(f->elem));
        ++(t->f_count);
        lock_release(&filesys_lock);
    }
    return fd;

}
コード例 #11
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! execute a command-line */
pid_t exec(const char *cmd_line) {
    if (checkva(cmd_line))
        return process_execute(cmd_line);
    exit(-1);
}
コード例 #12
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Reads for bytes from the stack according to the offset. */
static uint32_t read4(struct intr_frame * f, int offset) {
    if (!checkva(f->esp + offset))
        exit(-1);
    return *((uint32_t *) (f->esp + offset));
}