/* To dup a file: * o fget(fd) to up fd's refcount * o get_empty_fd() * o point the new fd to the same file_t* as the given fd * o return the new file descriptor * * Don't fput() the fd unless something goes wrong. Since we are creating * another reference to the file_t*, we want to up the refcount. * * Error cases you must handle for this function at the VFS level: * o EBADF * fd isn't an open file descriptor. * o EMFILE * The process already has the maximum number of file descriptors open * and tried to open a new one. */ int do_dup(int fd) { /*NOT_YET_IMPLEMENTED("VFS: do_dup"); return -1;*/ if(fd<0||(curproc->p_files[fd]==NULL)) { dbg(DBG_PRINT,"(GRADING2B)\n"); dbg(DBG_PRINT,"ERROR: do_dup return error. EBADF: Not a valid file descriptor.\n"); return -EBADF; } file_t *f = NULL; f = fget(fd); if(f == NULL) { dbg(DBG_PRINT,"(GRADING2B)\n"); dbg(DBG_PRINT,"Error: do_dup return error. EBADF: Not a valid file descriptor\n"); return -EBADF; } int emptyfd = 0; emptyfd = get_empty_fd(curproc); if(emptyfd < 0 ) { dbg(DBG_PRINT,"(GRADING2D)\n"); fput(f); dbg(DBG_PRINT,"Error: do_dup return error. EBADF: Not a valid file descriptor\n"); return emptyfd; } curproc->p_files[emptyfd]=f; return emptyfd; }
/* To dup a file: * o fget(fd) to up fd's refcount * o get_empty_fd() * o point the new fd to the same file_t* as the given fd * o return the new file descriptor * * Don't fput() the fd unless something goes wrong. Since we are creating * another reference to the file_t*, we want to up the refcount. * * Error cases you must handle for this function at the VFS level: * o EBADF * fd isn't an open file descriptor. * o EMFILE * The process already has the maximum number of file descriptors open * and tried to open a new one. */ int do_dup(int fd) { file_t *file; int new_fd; if (fd < 0){ dbg(DBG_PRINT,"(GRADING2B)\n"); return -EBADF; } file = fget(fd); dbg(DBG_PRINT,"(GRADING2B)\n"); if (file == NULL){ return -EBADF; dbg(DBG_PRINT,"(GRADING2B)\n"); } new_fd = get_empty_fd(curproc); if (new_fd == -EMFILE) { fput(file); return -EMFILE; } dbg(DBG_PRINT,"(GRADING2B)\n"); curproc->p_files[new_fd] = file; return new_fd; /*NOT_YET_IMPLEMENTED("VFS: do_dup");*/ }
/* To dup a file: * o fget(fd) to up fd's refcount * o get_empty_fd() * o point the new fd to the same file_t* as the given fd * o return the new file descriptor * * Don't fput() the fd unless something goes wrong. Since we are creating * another reference to the file_t*, we want to up the refcount. * * Error cases you must handle for this function at the VFS level: * o EBADF * fd isn't an open file descriptor. * o EMFILE * The process already has the maximum number of file descriptors open * and tried to open a new one. */ int do_dup(int fd) { if(fd < 0 || fd >= NFILES) { dbg(DBG_PRINT,"(GRADING2B) given file descriptor is not valid\n"); dbg(DBG_ERROR,"File Desciptor not valid\n"); return -EBADF; } file_t *f; int new_fd; if((f=fget(fd)) == NULL || curproc->p_files[fd] == NULL) { dbg(DBG_PRINT,"(GRADING2B) given file descriptor is not valid\n"); dbg(DBG_ERROR,"do_dup(): fd is not a valid file descriptor.\n"); return -EBADF; } if((new_fd = get_empty_fd(curproc)) <0) { dbg(DBG_PRINT,"(GRADING2B) out of file descriptors\n"); dbg(DBG_ERROR, "do_dup(): out of file descriptors: The process already has NFILES descriptors opened\n"); fput(f); return new_fd; } curproc->p_files[new_fd]= f; /* can change to file */ return new_fd; /*NOT_YET_IMPLEMENTED("VFS: do_dup"); return -1;*/ }
/* To dup a file: * o fget(fd) to up fd's refcount * o get_empty_fd() * o point the new fd to the same file_t* as the given fd * o return the new file descriptor * * Don't fput() the fd unless something goes wrong. Since we are creating * another reference to the file_t*, we want to up the refcount. * * Error cases you must handle for this function at the VFS level: * o EBADF * fd isn't an open file descriptor. * o EMFILE * The process already has the maximum number of file descriptors open * and tried to open a new one. */ int do_dup(int fd) { if(fd>=NFILES||fd<0||curproc->p_files[fd]==NULL){ dbg(DBG_PRINT, "(GRADING2D 3.j): fd is not a valid file descriptor or is not open for reading\n"); return -EBADF; } /*NOT_YET_IMPLEMENTED("VFS: do_dup");*/ file_t *reqFile; reqFile=fget(fd); /*if(reqFile==NULL) { return -EBADF; }*/ int aNewFd = get_empty_fd(curproc); /*function in fs/open.c */ /*if (aNewFd==-EMFILE) { fput(reqFile);*/ /* Have to do --refcount because a duplicate failed (no space for a new fd) */ /* return -EMFILE; } */ curproc->p_files[aNewFd]=reqFile; /*Make the new fd entry of this process point to the same file_t. No need to do --refcount*/ return aNewFd; }
/* To dup a file: * o fget(fd) to up fd's refcount * o get_empty_fd() * o point the new fd to the same file_t* as the given fd * o return the new file descriptor * * Don't fput() the fd unless something goes wrong. Since we are creating * another reference to the file_t*, we want to up the refcount. * * Error cases you must handle for this function at the VFS level: * o EBADF * fd isn't an open file descriptor. * o EMFILE * The process already has the maximum number of file descriptors open * and tried to open a new one. */ int do_dup(int fd) { /*NOT_YET_IMPLEMENTED("VFS: do_dup");*/ if (fd < 0 || fd >= NFILES) { dbg(DBG_PRINT, "(GRADING2B)\n"); return -EBADF; } file_t* file = fget(fd); if (file == NULL) { dbg(DBG_PRINT, "(GRADING2B)\n"); return -EBADF; } int new_empty_fd = get_empty_fd(curproc); /* if (new_empty_fd == -EMFILE) { fput(file); dbg(DBG_ERROR, "3\n"); return -EMFILE; } */ curproc->p_files[new_empty_fd] = file; /*file_t* newfile = fget(new_empty_fd); */ dbg(DBG_PRINT, "(GRADING2B)\n"); return new_empty_fd; }
/* To dup a file: * o fget(fd) to up fd's refcount * o get_empty_fd() * o point the new fd to the same file_t* as the given fd * o return the new file descriptor * * Don't fput() the fd unless something goes wrong. Since we are creating * another reference to the file_t*, we want to up the refcount. * * Error cases you must handle for this function at the VFS level: * o EBADF * fd isn't an open file descriptor. * o EMFILE * The process already has the maximum number of file descriptors open * and tried to open a new one. */ int do_dup(int fd) { file_t *temp; int new_fd; if(fd<0 || fd>=NFILES) { dbg(DBG_PRINT,"(GRADING2B) invalid file desciptor return -EBADF\n"); return -EBADF; } /*this calls fref, which increments refcount*/ temp=fget(fd); /*Alekhya: checking if it is a valid file descriptor*/ if(temp==NULL) { dbg(DBG_PRINT,"(GRADING2B) invalid file desciptor, return -EBADF\n"); return -EBADF; } new_fd=get_empty_fd(curproc); /*Alekhya: get_empty_fd return -EMFILE if the max has been reached*/ if(new_fd==(-EMFILE)) { dbg(DBG_PRINT,"(GRADING2C 1.g) Process has maximum number of file descriptors"); /*Alekhya: Calling fput because something went wrong*/ fput(temp); return -EMFILE; } /*Alekhya: Pointing the fd to the same file_t * as given*/ curproc->p_files[new_fd]=temp; return new_fd; /******** NOT_YET_IMPLEMENTED("VFS: do_dup"); return -1;*/ }
/* To dup a file: * o fget(fd) to up fd's refcount * o get_empty_fd() * o point the new fd to the same file_t* as the given fd * o return the new file descriptor * * Don't fput() the fd unless something goes wrong. Since we are creating * another reference to the file_t*, we want to up the refcount. * * Error cases you must handle for this function at the VFS level: * o EBADF * fd isn't an open file descriptor. * o EMFILE * The process already has the maximum number of file descriptors open * and tried to open a new one. */ int do_dup(int fd) { /*NOT_YET_IMPLEMENTED("VFS: do_dup"); return -1; */ /*dbg(DBG_PRINT,"Entering do_dup ****************************************\n"); */ int newfd; dbg(DBG_PRINT,"(GRADING2C)\n"); if (fd == -1) { /*dbg(DBG_PRINT," EBADF Leaving do_dup ****************************************\n"); */ dbg(DBG_PRINT,"(GRADING2C)\n"); return -EBADF; } file_t *f = fget(fd); if (NULL == f){ dbg(DBG_PRINT,"(GRADING2C)\n"); /*dbg(DBG_PRINT," EBADF Leaving do_dup ****************************************\n");*/ return -EBADF; } newfd = get_empty_fd(curproc); /*if( newfd == -EMFILE) { dbg(DBG_PRINT,"(GRADING2C V12)\n"); fput(f); dbg(DBG_PRINT," EMFILE Leaving do_dup ****************************************\n"); return -EMFILE; } */ curproc->p_files[newfd] = f; /*dbg(DBG_PRINT," Leaving do_dup ****************************************\n");*/ return newfd; }
/* To dup a file: * o fget(fd) to up fd's refcount * o get_empty_fd() * o point the new fd to the same file_t* as the given fd * o return the new file descriptor * * Don't fput() the fd unless something goes wrong. Since we are creating * another reference to the file_t*, we want to up the refcount. * * Error cases you must handle for this function at the VFS level: * o EBADF * fd isn't an open file descriptor. * o EMFILE * The process already has the maximum number of file descriptors open * and tried to open a new one. */ int do_dup(int fd) { dbg(DBG_PRINT,"do_dup called for fd = %d\n", fd); /* NOT_YET_IMPLEMENTED("VFS: do_dup"); */ /*ERROR!!! fd is outside of allowed range of file descriptors*/ if ((fd >= NFILES) || ( fd < 0)) { dbg(DBG_PRINT,"ERROR!!! fd = %d is out of range\n", fd); return -EBADF; } /* o fget(fd) to up fd's refcount*/ file_t *cur_file_t = fget(fd); /* fd is not a valid file descriptor*/ if (cur_file_t == NULL) { dbg(DBG_PRINT,"ERROR!!! No file descriptor entry for correspoding fd = %d\n", fd); /* fput(cur_file_t); */ return -EBADF; } /* o get_empty_fd()*/ int new_fd = get_empty_fd(curproc); /* ERROR!!! The process already has the maximum number of files open.*/ if (new_fd == -EMFILE){ dbg(DBG_PRINT,"ERROR!!! Max limit of file descriptors reached fd\n"); fput(cur_file_t); return -EMFILE; } /* o point the new fd to the same file_t* as the given fd*/ curproc->p_files[new_fd] = cur_file_t; /* o return the new file descriptor*/ dbg(DBG_PRINT,"Returning fd = %d\n", new_fd); return new_fd; }
int do_open(const char *filename, int oflags) { /*NOT_YET_IMPLEMENTED("VFS: do_open");*/ if (oflags!=O_RDONLY && oflags!=O_WRONLY && oflags!=O_RDWR && oflags!=O_APPEND && oflags!= (O_RDONLY | O_CREAT) && oflags != (O_RDWR | O_CREAT) && oflags != (O_RDWR | O_APPEND)) { return -EINVAL; } int fd = get_empty_fd(curproc); if( fd == -EMFILE){ return -EMFILE; } file_t *f = fget(-1); if( f == NULL){ return -ENOMEM; } curproc->p_files[fd] = f; /*Set file_t->f_mode to OR of FMODE_(READ|WRITE|APPEND) based on * oflags, which can be O_RDONLY, O_WRONLY or O_RDWR, possibly OR'd with * O_APPEND. */ /*FIXME check the logic below*/ if(oflags == O_RDONLY){ f->f_mode = FMODE_READ; }else if(oflags == O_WRONLY){ f->f_mode = FMODE_WRITE; }else if(oflags == O_RDWR){ f->f_mode = FMODE_READ | FMODE_WRITE; }else if(oflags == O_APPEND){ f->f_mode = FMODE_WRITE | FMODE_APPEND; }else if(oflags == (O_RDONLY | O_CREAT)){ f->f_mode = FMODE_READ; }else if(oflags == (O_RDWR | O_CREAT) ){ f->f_mode = FMODE_READ | FMODE_WRITE; }else if(oflags == (O_RDWR | O_APPEND) ){ f->f_mode = FMODE_READ | FMODE_WRITE | FMODE_APPEND; } vnode_t *pVnode; int s = open_namev(filename, oflags, &pVnode, NULL); if(s != 0){ curproc->p_files[fd] = NULL; fput(f); return s; } if(S_ISDIR(pVnode->vn_mode) && ((oflags & O_WRONLY) || (oflags & O_RDWR)) ){ curproc->p_files[fd] = NULL; vput(pVnode); fput(f); return -EISDIR; } if(S_ISBLK(pVnode->vn_mode)){ if(!(pVnode->vn_bdev = blockdev_lookup(pVnode->vn_devid))){ curproc->p_files[fd] = NULL; fput(f); vput(pVnode); return -ENXIO; } } if(S_ISCHR(pVnode->vn_mode)){ if(!(pVnode->vn_cdev = bytedev_lookup(pVnode->vn_devid))){ curproc->p_files[fd] = NULL; fput(f); vput(pVnode); return -ENXIO; } } f->f_pos=0; f->f_vnode = pVnode; return fd; }
int do_open(const char *filename, int oflags) { /* check invalid combinations */ int wr = oflags & O_WRONLY; int rdwr = oflags & O_RDWR; int rd = 0; if( (wr == 0) && (rdwr == 0)){ rd = 1; } int append = oflags & O_APPEND; int trunc = oflags &O_TRUNC; int creat = oflags & O_CREAT; if( (wr != 0) && (rdwr != 0) ){ return -EINVAL; } /* 1. Get the next empty file descriptor */ int fd = get_empty_fd(curproc); if(fd == -EMFILE){ return -EMFILE; } /* 2. Call fget to get a fresh file_t */ file_t* file = fget(-1); if(file == NULL){ /* not sure for this error */ return -ENOMEM; } /* 3. Save the file_t in curproc's file descriptor table */ curproc -> p_files[fd] = file; /* 4. Set file_t->f_mode to OR of FMODE_(READ|WRITE|APPEND) based on * oflags, which can be O_RDONLY, O_WRONLY or O_RDWR, possibly OR'd with * O_APPEND. */ int mode = -1; if( (wr != 0) ||(rd != 0) || (rdwr != 0)){ if(rd != 0){ mode = FMODE_READ; } else if(wr != 0){ mode = FMODE_WRITE; } else if(rdwr != 0){ mode = FMODE_READ | FMODE_WRITE; } /* last check append */ if( append != 0){ mode |= FMODE_APPEND; } } if(mode == -1){ /* invalid combination */ curproc -> p_files[fd] = NULL; fput(file); return -EINVAL; } file -> f_mode = mode; /* 5. Use open_namev() to get the vnode for the file_t. */ vnode_t* res_vnode = NULL; vnode_t* base = curproc -> p_cwd; int res = open_namev(filename, oflags, &res_vnode, base); if(res < 0){ curproc -> p_files[fd] = NULL; if(res_vnode) vput(res_vnode); fput(file); return res;/* including errors: ENAMETOOLONG, ENOTDIR, ENOENT */ } if( ((res_vnode -> vn_mode & S_IFDIR) != 0) && (mode != FMODE_READ)){ curproc -> p_files[fd] = NULL; vput(res_vnode); fput(file); return -EISDIR; } /* 6. Fill in the fields of the file_t */ file->f_vnode = res_vnode; file->f_pos = 0; /* 7. return new fd */ return fd; }
int do_open(const char *filename, int oflags) { vnode_t *res_vnode; int status_flag = 0, access_flag = 0, fd = 0, errno = 0; dbg(DBG_PRINT | DBG_VFS,"Kernel2:SysMsg: begin do_open(), filename =%s\n",filename); /*Error cases*/ if ( strlen(filename) > MAXPATHLEN ) { dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg: in do_open(), filename =%s - The component of the Filename too long\n",filename); return -ENAMETOOLONG; } if ( strlen(filename) < 1 ) { dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg: in do_open(), filename =%s - Invalid file as length is less than 1 \n",filename); return -EINVAL; } /*set up the access and status flags*/ status_flag = oflags & 0x700; /*O_CREAT,O_TRUNC,O_APPEND*/ access_flag = oflags & 0x003; /*O_RDONLY,O_WRONLY,O_RDWR*/ if ( access_flag != O_RDONLY && access_flag != O_WRONLY && access_flag != O_RDWR ) { dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg: in do_open(), filename =%s - Invalid file\n",filename); return -EINVAL; } /* get empty file descriptor, open file,O_CREAT handled in open_namev */ fd = get_empty_fd(curproc); if ( fd < 0 ) { dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg: in do_open(), filename =%s - Maximum number of files open\n",filename); return -EMFILE; } curproc->p_files[fd] = fget(-1); if ( curproc->p_files[fd] == NULL ) { dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg: in do_open(), filename =%s - Insufficient Kernel memory\n",filename); return -ENOMEM; } errno = open_namev(filename,status_flag,&res_vnode,NULL); if ( errno < 0 ) { fput(curproc->p_files[fd]); return errno; } /* Check error for opening a dir for write*/ if ( S_ISDIR(res_vnode->vn_mode) && (access_flag == O_RDWR || access_flag == O_WRONLY)) { fput(curproc->p_files[fd]); vput(res_vnode); dbg(DBG_ERROR | DBG_VFS,"Kernel2:SysMsg: in do_open(), filename =%s - The pathname is a directory or the access requested requires writing\n",filename); return -EISDIR; } /* Make O_TRUNC behavior default */ if ( errno == 0 && (status_flag & O_APPEND) != O_APPEND && access_flag == O_WRONLY) { vput(res_vnode); errno = do_unlink(filename); if ( errno < 0 ) { fput(curproc->p_files[fd]); return errno; } errno = open_namev(filename,O_CREAT,&res_vnode,NULL); if ( errno < 0 ) { fput(curproc->p_files[fd]); return errno; } } curproc->p_files[fd]->f_vnode = res_vnode; /*Handle file O_APPEND or O_TRUNC*/ switch ( status_flag ) { case O_APPEND : curproc->p_files[fd]->f_mode = FMODE_APPEND; break; case O_APPEND | O_CREAT : curproc->p_files[fd]->f_mode = FMODE_APPEND; break; default : curproc->p_files[fd]->f_mode = 0; curproc->p_files[fd]->f_pos = 0; break; } /*Handle file access*/ switch ( access_flag ) { case O_RDONLY : curproc->p_files[fd]->f_mode |= FMODE_READ; break; case O_WRONLY : curproc->p_files[fd]->f_mode |= FMODE_WRITE; break; case O_RDWR : curproc->p_files[fd]->f_mode |= FMODE_WRITE | FMODE_READ; break; } dbg(DBG_PRINT | DBG_VFS,"Kernel2:SysMsg: begin do_open(), return fd \n"); return fd; }
int do_open(const char *filename, int oflags) { /*NOT_YET_IMPLEMENTED("VFS: do_open");*/ dbg(DBG_PRINT, "Entering do_open()....%s\n", filename); int fd = get_empty_fd(curproc); if(fd == -EMFILE) { dbg(DBG_PRINT, "Exiting do_open()....\n"); return fd; } if((oflags & O_RDONLY) != O_RDONLY && (oflags & O_WRONLY) != O_WRONLY && (oflags & O_RDWR) != O_RDWR) { dbg(DBG_PRINT,"None of the access modes(O_RDONLY, O_WRONLY, O_RDWR) set......\n"); dbg(DBG_PRINT, "Exiting do_open()....\n"); return -EINVAL; } if((oflags & O_RDWR) == O_RDWR && (oflags & O_WRONLY) == O_WRONLY) { dbg(DBG_PRINT, "Invalid flags set.........\n"); dbg(DBG_PRINT, "Exiting do_open()....\n"); return -EINVAL; } if((oflags & O_TRUNC) == O_TRUNC) { if((oflags & O_RDWR) != O_RDWR && (oflags & O_WRONLY) != O_WRONLY) { dbg(DBG_PRINT, "O_TRUNC set but none of the write flags are set...\n"); dbg(DBG_PRINT, "Exiting do_open()....\n"); return -EINVAL; } } if((oflags & O_APPEND) == O_APPEND) { if((oflags & O_RDWR) != O_RDWR && (oflags & O_WRONLY) != O_WRONLY) { dbg(DBG_PRINT, "O_APPEND set but none of the write flags are set...........\n"); dbg(DBG_PRINT, "Exiting do_open()....\n"); return -EINVAL; } } int count = 0; /*const char *p = filename;*/ if(strlen(filename) > MAXPATHLEN) return -ENAMETOOLONG; file_t *sft = fget(-1); if(sft == NULL) return ENOMEM; /* not sure ..........................*/ curproc->p_files[fd] = sft; if((oflags & O_WRONLY) == O_WRONLY) { sft->f_mode = FMODE_WRITE; } else if((oflags & O_RDWR) == O_RDWR) { sft->f_mode = FMODE_WRITE | FMODE_READ; } else { sft->f_mode = FMODE_READ; } if((oflags & O_APPEND) == O_APPEND) { sft->f_mode |= FMODE_APPEND; } vnode_t *res_vnode; /*vfs_is_in_use(vfs_root_vn->vn_fs);*/ int openv_ret = open_namev(filename, oflags, &res_vnode, NULL); if(openv_ret < 0) { /*dbg(DBG_PRINT, "do_open()\n", openv_ret);*/ fput(sft); /*Not Sure................................*/ if(openv_ret == -ENOENT && (oflags & O_CREAT) != O_CREAT) { dbg(DBG_PRINT, "Exiting do_open()....\n"); return -ENOENT; } else { dbg(DBG_PRINT, "Exiting do_open()....\n"); return openv_ret; } } if(S_ISDIR(res_vnode->vn_mode) && ((oflags & O_WRONLY) == O_WRONLY || (oflags & O_RDWR) == O_RDWR)) { dbg(DBG_PRINT, "Exiting from do_open()\n"); fput(sft); vput(res_vnode); return -EISDIR; } sft->f_pos = 0; sft->f_vnode = res_vnode; /*sft->f_refcount += 1;*/ if((oflags & O_TRUNC) == O_TRUNC) { sft->f_vnode->vn_len = 0; } if(S_ISCHR(sft->f_vnode->vn_mode)) { if(sft->f_vnode->vn_cdev == NULL) { dbg(DBG_PRINT, "Exiting do_open()....\n"); /*vput(res_vnode);*/ return -ENXIO; } } if(S_ISBLK(sft->f_vnode->vn_mode)) { if(sft->f_vnode->vn_bdev == NULL) { dbg(DBG_PRINT, "Exiting do_open()....\n"); /*vput(res_vnode);*/ return -ENXIO; } } dbg(DBG_PRINT, "Exiting do_open() normally....\n"); return fd; }
int do_open(const char *filename, int oflags) { /* VFS {{{ */ int fd; file_t *f; vnode_t *file_vnode; int ret; if ((oflags & O_WRONLY) && (oflags & O_RDWR)) { return -EINVAL; } if ((fd = get_empty_fd(curproc)) < 0) { return fd; } if ((f = fget(-1)) == NULL) { return -ENOMEM; } curproc->p_files[fd] = f; dbg(DBG_VFS, "open on %s, file at %p\n", filename, curproc->p_files[fd]); switch (oflags & 0x3) { case O_RDONLY: f->f_mode = FMODE_READ; break; case O_WRONLY: f->f_mode = FMODE_WRITE; break; case O_RDWR: f->f_mode = FMODE_READ | FMODE_WRITE; break; default: /*kthread_cleanup_pop(1);*/ nukefd(fd); return -EINVAL; } if ((ret = open_namev(filename, oflags, &file_vnode, NULL)) < 0) { /*kthread_cleanup_pop(1);*/ nukefd(fd); return ret; } if (((oflags & O_WRONLY) || (oflags & O_RDWR)) && S_ISDIR(file_vnode->vn_mode)) { /*kthread_cleanup_pop(1);*/ nukefd(fd); vput(file_vnode); return -EISDIR; } if (S_ISBLK(file_vnode->vn_mode) && (!file_vnode->vn_bdev)) { /*kthread_cleanup_pop(1);*/ nukefd(fd); vput(file_vnode); return -ENXIO; } if (S_ISCHR(file_vnode->vn_mode) && (!file_vnode->vn_cdev)) { /*kthread_cleanup_pop(1);*/ nukefd(fd); vput(file_vnode); return -ENXIO; } f->f_vnode = file_vnode; dbg(DBG_VFS, " vnode at %p\n", file_vnode); if (oflags & O_APPEND) { f->f_mode |= FMODE_APPEND; } /*kthread_cleanup_pop(0);*/ return fd; /* VFS }}} */ return -1; }
int do_open(const char *filename, int oflags) { dbg(DBG_VFS, "calling do_open on %s\n", filename); /* step 1: get next empty file descriptor */ int fd = get_empty_fd(curproc); /* error case 2 */ if (fd == -EMFILE){ return -EMFILE; } /* step 2: Call fget to get a fresh file_t */ file_t *f = fget(-1); /* error case 3 */ if (f == NULL){ return -ENOMEM; } KASSERT(f != NULL); KASSERT(f->f_refcount == 1); /* step 3: Save file_t in curproc's file descriptor table */ KASSERT(curproc->p_files[fd] == NULL); curproc->p_files[fd] = f; /* step 4: Set the file_t->f-mode */ f->f_mode = 0; if (oflags & O_APPEND){ f->f_mode = FMODE_APPEND; } if ((oflags & O_WRONLY) && !(oflags & O_RDWR)){ f->f_mode |= FMODE_WRITE; } else if ((oflags & O_RDWR) && !(oflags & O_WRONLY)){ f->f_mode |= FMODE_READ | FMODE_WRITE; } else if (oflags == O_RDONLY || oflags == (O_RDONLY | O_CREAT) || oflags == (O_RDONLY | O_APPEND) || oflags == (O_RDONLY | O_CREAT | O_APPEND)){ f->f_mode |= FMODE_READ; } else { dbg(DBG_VFS, "oflags not valid\n"); fput(f); curproc->p_files[fd] = NULL; return -EINVAL; } /* make sure we have a valid mode */ KASSERT(f->f_mode == FMODE_READ || f->f_mode == FMODE_WRITE || f->f_mode == (FMODE_READ | FMODE_WRITE) || f->f_mode == (FMODE_WRITE | FMODE_APPEND) || f->f_mode == (FMODE_READ | FMODE_WRITE | FMODE_APPEND)); /* step 5: use open_namev to get the vnode for the file_t */ int open_result = open_namev(filename, oflags, &f->f_vnode, NULL); if (open_result < 0){ curproc->p_files[fd] = NULL; fput(f); return open_result; } dbg(DBG_VFS, "found the vnode with id %d. Current refcount is %d\n", f->f_vnode->vn_vno, f->f_vnode->vn_mmobj.mmo_refcount); /* step 6: fill in the fields of the file_t */ /* no need to call vref, since open_namev() took care of that*/ f->f_pos = 0; f->f_refcount = 1; /* step 7: return new fd */ return fd; }
int do_open(const char *filename, int oflags) { int status; file_t *f; int fd = get_empty_fd(curproc); if(fd!=EMFILE) { /* can fail if memory not allocated */ f = fget(-1); if(f==NULL) return -ENOMEM; curproc->p_files[fd] = f; if(oflags & O_RDONLY) f->f_mode = FMODE_READ; else if(oflags & O_WRONLY) f->f_mode = FMODE_WRITE; else if(oflags & O_RDWR) f->f_mode = FMODE_READ | FMODE_WRITE; else if(oflags & (O_WRONLY|O_APPEND)) f->f_mode = FMODE_WRITE|FMODE_APPEND; else if(oflags & (O_RDWR|O_APPEND)) f->f_mode = FMODE_READ|FMODE_WRITE|FMODE_APPEND; else return -EINVAL; /* not sure if other combinations should be handled */ if(S_ISDIR(f->f_vnode->vn_mode) && (O_WRONLY | O_RDWR)) { curproc->p_files[fd] = NULL; fput(f); return -EISDIR; } if( S_ISCHR(f->f_vnode->vn_mode) || S_ISBLK(f->f_vnode->vn_mode)) { curproc->p_files[fd] = NULL; fput(f); return -ENXIO; } /* returns int */ status = open_namev(filename, oflags, (vnode_t **)(&(f->f_vnode)), NULL); if(status<0) { curproc->p_files[fd] = NULL; fput(f); return status; } /* can return error codes*/ status = do_lseek(fd,0,0); /* 3rd argument SEEK_SET = 0 is not defined, not sure to do this as lseek.h not included */ if(status<0) { curproc->p_files[fd] = NULL; fput(f); return status; } return fd; } else return -EMFILE; /*NOT_YET_IMPLEMENTED("VFS: do_open"); return -1;*/ }
int do_open(const char *filename, int oflags) { /*NOT_YET_IMPLEMENTED("VFS: do_open");*/ /* Check validity of oflags */ int flag_write_only = oflags & O_WRONLY; int flag_readwrite = oflags & O_RDWR; int flag_append = oflags & O_APPEND; int flag_create = oflags & O_CREAT; /* oflags is Read_Only and also trying to write/append/create if( !oflags && ( flag_write_only || flag_readwrite || flag_append || flag_create) ) { dbg(DBG_PRINT, "Add self test dbg here (GRADING1C 7)\n"); return(-EINVAL); }*/ /* Trying to read from write_only */ if( flag_write_only && flag_readwrite ) { dbg(DBG_PRINT, "(GRADING2B)\n"); return(-EINVAL); } int file_mode = 0; if( oflags == 0 ) { dbg(DBG_PRINT, "(GRADING2B)\n"); file_mode = file_mode | FMODE_READ; } if( flag_write_only ) { dbg(DBG_PRINT, "(GRADING2B)\n"); file_mode = file_mode | FMODE_WRITE; } if( flag_readwrite ) { dbg(DBG_PRINT, "(GRADING2B)\n"); file_mode = file_mode | FMODE_READ | FMODE_WRITE; } if( flag_append ) { dbg(DBG_PRINT, "(GRADING2B)\n"); file_mode = file_mode | FMODE_APPEND; } vnode_t *new_vnode; int namev_ret = open_namev(filename, oflags, &new_vnode , NULL); if( namev_ret ) { dbg(DBG_PRINT, "(GRADING2B)\n"); return namev_ret; } int next_fd; next_fd = get_empty_fd(curproc); /*if ( next_fd == -EMFILE ) { vput(new_vnode); return -EMFILE; }*/ curproc->p_files[next_fd] = fget(-1); curproc->p_files[next_fd]->f_mode = file_mode; if( S_ISDIR(new_vnode->vn_mode) && (flag_write_only || flag_readwrite) ) { dbg(DBG_PRINT, "(GRADING2B)\n"); fput(curproc->p_files[next_fd]); curproc->p_files[next_fd] = NULL; vput(new_vnode); return(-EISDIR); } if( S_ISCHR(new_vnode->vn_mode) && !(new_vnode->vn_cdev) ) { dbg(DBG_PRINT, "(GRADING2B)\n"); fput( curproc->p_files[next_fd] ); curproc->p_files[next_fd] = NULL; vput(new_vnode); return(-ENXIO); } if( S_ISBLK(new_vnode->vn_mode) && !(new_vnode->vn_bdev) ) { dbg(DBG_PRINT, "(GRADING2B)\n"); fput( curproc->p_files[next_fd] ); curproc->p_files[next_fd] = NULL; vput(new_vnode); return(-ENXIO); } curproc->p_files[next_fd]->f_vnode = new_vnode; curproc->p_files[next_fd]->f_pos = 0; return next_fd; }