예제 #1
0
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;
}
예제 #2
0
파일: file_syscalls.c 프로젝트: gapry/os161
/*
 * 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;
}
예제 #3
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;
}
예제 #4
0
파일: file.c 프로젝트: klevstul/CSE-9201-OS
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;
}
예제 #5
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;
}
예제 #6
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;

}