off_t lseek(int fd,off_t pos, int whence,int *err) { off_t nPos=0; struct stat eoFILE; //kprintf("lseek entered\n"); if ( fd < 0 || fd > OPEN_MAX) { *err = EBADF; return -1; } if (curthread->ft[fd] == NULL) { *err = EBADF; return -1; } //kprintf("curthread->ft[fd] == NULL\n"); //kprintf("fd < 0 || fd > OPEN_MAX\n"); if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) { *err = EINVAL; return -1; } //kprintf("whence != SEEK_SET || whence != SEEK_CUR || whence != SEEK_END\n"); //kprintf("Acquiring lock\n"); lock_acquire(curthread->ft[fd]->lock); //kprintf("Stat gathering\n"); VOP_STAT(curthread->ft[fd]->vn,&eoFILE); if (whence == SEEK_SET) { nPos = pos; } if (whence == SEEK_CUR) { nPos = curthread->ft[fd]->offset+pos; } if (whence == SEEK_END) { nPos = eoFILE.st_size+pos; } if (nPos < 0) { *err = EINVAL; lock_release(curthread->ft[fd]->lock); return -1; } //kprintf("NPos %llu\n",nPos); *err = VOP_TRYSEEK(curthread->ft[fd]->vn,nPos); if (*err) { lock_release(curthread->ft[fd]->lock); return -1; } curthread->ft[fd]->offset = nPos; lock_release(curthread->ft[fd]->lock); //kprintf("New position %llu\n",nPos); return curthread->ft[fd]->offset; }
/* * sys_lseek * */ int sys_lseek(int fd, off_t offset, int whence, off_t *retval) { DEBUG(DB_VFS, "Lseeking fd %d with offset %d\n", fd, (int)offset); struct filetable *ft = curthread->t_filetable; spinlock_acquire(&ft->ft_spinlock); /* If fd is not a valid file descriptor, return error. */ if ((fd < 0) || (fd >= __OPEN_MAX) || (ft->ft_entries[fd] == NULL) || (ft->ft_entries[fd]->ft_vnode == NULL)) { spinlock_release(&ft->ft_spinlock); return EBADF; } int pos; if (whence == SEEK_SET) { /* Update new position to offset.*/ pos = (int)offset; } else if (whence == SEEK_CUR) { /* Update new position to current position + pos. */ pos = (ft->ft_entries[fd]->ft_pos + (int)offset); } else if (whence == SEEK_END) { /* Update new positionto end-of-file + pos. */ struct stat ft_stat; VOP_STAT(ft->ft_entries[fd]->ft_vnode, &ft_stat); pos = ft_stat.st_size + offset; } else { /* whence value is invalid. return error. */ spinlock_release(&ft->ft_spinlock); return EINVAL; } /* If resulting position is negative, return error. */ if (pos < 0) { spinlock_release(&ft->ft_spinlock); return EINVAL; } int result = VOP_TRYSEEK(ft->ft_entries[fd]->ft_vnode, pos); if (result != 0) { DEBUG(DB_VFS, " tryseek failed with %d\n", result); spinlock_release(&ft->ft_spinlock); return ESPIPE; } ft->ft_entries[fd]->ft_pos = pos; *retval = (off_t)pos; spinlock_release(&ft->ft_spinlock); return 0; }
off_t sys_lseek(int fd,off_t pos, int whence, int *err){ if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END){ *err = EINVAL; return -1; } if (fd < 0 || fd >= MAX_FILE_DESCRIPTOR){ *err = EBADF; return -1; } if (curthread->fd[fd] == NULL){ *err = EBADF; return -1; } lock_acquire(curthread->fd[fd]->mutex); if (curthread->fd[fd]->update_pos == 0){ *err = ESPIPE; lock_release(curthread->fd[fd]->mutex); return -1; } off_t newpos; struct stat stat; VOP_STAT(curthread->fd[fd]->file,&stat); if (whence == SEEK_SET) newpos = pos; if (whence == SEEK_CUR) newpos = curthread->fd[fd]->offset+pos; if (whence == SEEK_END) newpos = stat.st_size+pos; if (newpos < 0){ *err = EINVAL; lock_release(curthread->fd[fd]->mutex); return -1; } *err = VOP_TRYSEEK(curthread->fd[fd]->file,newpos); if (*err){ lock_release(curthread->fd[fd]->mutex); return -1; } curthread->fd[fd]->offset = newpos; lock_release(curthread->fd[fd]->mutex); return curthread->fd[fd]->offset; }
int sys_lseek(int filehandle, off_t pos, int code, int *retval) { off_t newfp; int r; struct stat statbuf; /* check file handle */ r = check_fd_access(filehandle, curthread->t_fdt, F_ANY); if (r) return r; switch (code) { case SEEK_SET: newfp = pos; break; case SEEK_CUR: newfp = curthread->t_fdt->fd[filehandle]->fp + pos; break; case SEEK_END: r = VOP_STAT(curthread->t_fdt->fd[filehandle]->vn, &statbuf); if (r) return r; newfp = statbuf.st_size + pos; break; default: return EINVAL; } if (newfp < 0) { return EINVAL; } r = VOP_TRYSEEK(curthread->t_fdt->fd[filehandle]->vn, newfp); if (r < 0) { return r; } curthread->t_fdt->fd[filehandle]->fp = newfp; *retval = newfp; return 0; }
int sys_lseek(int fid, off_t offset, int whence, int* retval) { struct openfile* seekfile = (struct openfile*)array_getguy(curthread->t_openfiletable,fid); if (seekfile == NULL) { return EBADF; } if (whence == SEEK_SET) { offset = offset; } else if(whence == SEEK_CUR) { offset = seekfile->offset + offset; } else if (whence == SEEK_END) { //end of file plus offset } else { return EINVAL; } *retval = VOP_TRYSEEK(seekfile->data,offset); if (*retval < 0) { return EINVAL; } return 0; }
/* lseek() call handler */ int sys_lseek(int fd, off_t pos, int whence, off_t * retVal64){ int err; off_t currentPosition; off_t endPosition; off_t posSeek; struct stat buffer; /* Step 1: Check if the file descriptor passed in is valid */ if (fd >= OPEN_MAX || fd < 0) { // fd is out of bounds of the file table return EBADF; } struct fhandle * fdesc = curthread->t_fdtable[fd]; if (fdesc == NULL) { return EBADF; } /* Adding locks to synchronize the whole process */ lock_acquire(fdesc->lock); switch(whence) { // logic for different cases case SEEK_SET: //VOP_TRYSEEK(vnode, position) if (pos < 0) { lock_release(fdesc->lock); return EINVAL; // seek position is negative } posSeek = pos; if ((err = VOP_TRYSEEK(fdesc->vn, posSeek)) != 0) { lock_release(fdesc->lock); return ESPIPE; // in case the SEEK fails } fdesc->offset = posSeek; *retVal64 = fdesc->offset; break; case SEEK_CUR: currentPosition = fdesc->offset; posSeek = currentPosition + pos; if (posSeek < 0) { lock_release(fdesc->lock); return EINVAL; } if ((err = VOP_TRYSEEK(fdesc->vn, posSeek)) != 0) { lock_release(fdesc->lock); return ESPIPE; } fdesc->offset = posSeek; *retVal64 = fdesc->offset; break; case SEEK_END: VOP_STAT(fdesc->vn, &buffer); endPosition = buffer.st_size; posSeek = endPosition + pos; if (posSeek < 0) { lock_release(fdesc->lock); return EINVAL; } if ((err = VOP_TRYSEEK(fdesc->vn, posSeek)) != 0) { lock_release(fdesc->lock); return ESPIPE; } if (pos < 0) { fdesc->offset = posSeek + pos; } else { fdesc->offset = posSeek; } *retVal64 = fdesc->offset; break; default: return EINVAL; } lock_release(fdesc->lock); return 0; }