コード例 #1
0
/*===========================================================================*
 *				actual_llseek				     *
 *===========================================================================*/
int actual_llseek(struct fproc *rfp, message *m_out, int seekfd, int seekwhence,
	u64_t offset)
{
/* Perform the llseek(ls_fd, offset, whence) system call. */
  register struct filp *rfilp;
  u64_t pos, newpos;
  int r = OK;
  long off_hi = ex64hi(offset);

  /* Check to see if the file descriptor is valid. */
  if ( (rfilp = get_filp2(rfp, seekfd, VNODE_READ)) == NULL) {
	return(err_code);
  }

  /* No lseek on pipes. */
  if (S_ISFIFO(rfilp->filp_vno->v_mode)) {
	unlock_filp(rfilp);
	return(ESPIPE);
  }

  /* The value of 'whence' determines the start position to use. */
  switch(seekwhence) {
    case SEEK_SET: pos = cvu64(0);	break;
    case SEEK_CUR: pos = rfilp->filp_pos;	break;
    case SEEK_END: pos = cvul64(rfilp->filp_vno->v_size);	break;
    default: unlock_filp(rfilp); return(EINVAL);
  }

  newpos = pos + offset;

  /* Check for overflow. */
  if ((off_hi > 0) && cmp64(newpos, pos) < 0)
      r = EINVAL;
  else if ((off_hi < 0) && cmp64(newpos, pos) > 0)
      r = EINVAL;
  else {
	/* insert the new position into the output message */
	m_out->reply_l1 = ex64lo(newpos);
	m_out->reply_l2 = ex64hi(newpos);

	if (cmp64(newpos, rfilp->filp_pos) != 0) {
		rfilp->filp_pos = newpos;

		/* Inhibit read ahead request */
		r = req_inhibread(rfilp->filp_vno->v_fs_e,
				  rfilp->filp_vno->v_inode_nr);
	}
  }

  unlock_filp(rfilp);
  return(r);
}
コード例 #2
0
ファイル: misc.c プロジェクト: wieck/minix
int dupvm(struct fproc *rfp, int pfd, int *vmfd, struct filp **newfilp)
{
	int result, procfd;
	struct filp *f = NULL;
	struct fproc *vmf = &fproc[VM_PROC_NR];

	*newfilp = NULL;

	if ((f = get_filp2(rfp, pfd, VNODE_READ)) == NULL) {
		printf("VFS dupvm: get_filp2 failed\n");
		return EBADF;
	}

	if(!f->filp_vno->v_vmnt->m_haspeek) {
		unlock_filp(f);
		printf("VFS dupvm: no peek available\n");
		return EINVAL;
	}

	assert(f->filp_vno);
	assert(f->filp_vno->v_vmnt);

	if (!S_ISREG(f->filp_vno->v_mode) && !S_ISBLK(f->filp_vno->v_mode)) {
		printf("VFS: mmap regular/blockdev only; dev 0x%x ino %d has mode 0%o\n",
			(int) f->filp_vno->v_dev, (int) f->filp_vno->v_inode_nr, (int) f->filp_vno->v_mode);
		unlock_filp(f);
		return EINVAL;
	}

	/* get free FD in VM */
	if((result=get_fd(vmf, 0, 0, &procfd, NULL)) != OK) {
		unlock_filp(f);
		printf("VFS dupvm: getfd failed\n");
		return result;
	}

	*vmfd = procfd;

	f->filp_count++;
	assert(f->filp_count > 0);
	vmf->fp_filp[procfd] = f;

	/* mmap FD's are inuse */
	FD_SET(procfd, &vmf->fp_filp_inuse);

	*newfilp = f;

	return OK;
}
コード例 #3
0
ファイル: misc.c プロジェクト: Hooman3/minix
int dupvm(struct fproc *rfp, int pfd, int *vmfd, struct filp **newfilp)
{
	int result, procfd;
	struct filp *f = NULL;
	struct fproc *vmf = fproc_addr(VM_PROC_NR);

	*newfilp = NULL;

	if ((f = get_filp2(rfp, pfd, VNODE_READ)) == NULL) {
		printf("VFS dupvm: get_filp2 failed\n");
		return EBADF;
	}

	if(!(f->filp_vno->v_vmnt->m_fs_flags & RES_HASPEEK)) {
		unlock_filp(f);
#if 0	/* Noisy diagnostic for mmap() by ld.so */
		printf("VFS dupvm: no peek available\n");
#endif
		return EINVAL;
	}

	assert(f->filp_vno);
	assert(f->filp_vno->v_vmnt);

	if (!S_ISREG(f->filp_vno->v_mode) && !S_ISBLK(f->filp_vno->v_mode)) {
		printf("VFS: mmap regular/blockdev only; dev 0x%llx ino %llu has mode 0%o\n",
			f->filp_vno->v_dev, f->filp_vno->v_inode_nr, f->filp_vno->v_mode);
		unlock_filp(f);
		return EINVAL;
	}

	/* get free FD in VM */
	if((result=get_fd(vmf, 0, 0, &procfd, NULL)) != OK) {
		unlock_filp(f);
		printf("VFS dupvm: getfd failed\n");
		return result;
	}

	*vmfd = procfd;

	f->filp_count++;
	assert(f->filp_count > 0);
	vmf->fp_filp[procfd] = f;

	*newfilp = f;

	return OK;
}
コード例 #4
0
/*===========================================================================*
 *				actual_lseek				     *
 *===========================================================================*/
int actual_lseek(struct fproc *rfp, int seekfd, int seekwhence, off_t offset,
	off_t *newposp)
{
  register struct filp *rfilp;
  int r = OK;
  off_t pos, newpos;

  /* Check to see if the file descriptor is valid. */
  if ( (rfilp = get_filp2(rfp, seekfd, VNODE_READ)) == NULL) {
	return(err_code);
  }

  /* No lseek on pipes. */
  if (S_ISFIFO(rfilp->filp_vno->v_mode)) {
	unlock_filp(rfilp);
	return(ESPIPE);
  }

  /* The value of 'whence' determines the start position to use. */
  switch(seekwhence) {
    case SEEK_SET: pos = 0; break;
    case SEEK_CUR: pos = rfilp->filp_pos; break;
    case SEEK_END: pos = rfilp->filp_vno->v_size; break;
    default: unlock_filp(rfilp); return(EINVAL);
  }

  newpos = pos + offset;

  /* Check for overflow. */
  if ((offset > 0) && (newpos <= pos)) {
	r = EOVERFLOW;
  } else if ((offset < 0) && (newpos >= pos)) {
	r = EOVERFLOW;
  } else {
	if (newposp != NULL) *newposp = newpos;

	if (newpos != rfilp->filp_pos) {
		rfilp->filp_pos = newpos;

		/* Inhibit read ahead request */
		r = req_inhibread(rfilp->filp_vno->v_fs_e,
				  rfilp->filp_vno->v_inode_nr);
	}
  }

  unlock_filp(rfilp);
  return(r);
}
コード例 #5
0
/*===========================================================================*
 *				close_fd				     *
 *===========================================================================*/
int
close_fd(struct fproc * rfp, int fd_nr, int may_suspend)
{
/* Perform the close(fd) system call. */
  register struct filp *rfilp;
  register struct vnode *vp;
  struct file_lock *flp;
  int r, lock_count;

  /* First locate the vnode that belongs to the file descriptor. */
  if ( (rfilp = get_filp2(rfp, fd_nr, VNODE_OPCL)) == NULL) return(err_code);

  vp = rfilp->filp_vno;

  /* first, make all future get_filp2()'s fail; otherwise
   * we might try to close the same fd in different threads
   */
  rfp->fp_filp[fd_nr] = NULL;

  r = close_filp(rfilp, may_suspend);

  FD_CLR(fd_nr, &rfp->fp_cloexec_set);

  /* Check to see if the file is locked.  If so, release all locks. */
  if (nr_locks > 0) {
	lock_count = nr_locks;	/* save count of locks */
	for (flp = &file_lock[0]; flp < &file_lock[NR_LOCKS]; flp++) {
		if (flp->lock_type == 0) continue;	/* slot not in use */
		if (flp->lock_vnode == vp && flp->lock_pid == rfp->fp_pid) {
			flp->lock_type = 0;
			nr_locks--;
		}
	}
	if (nr_locks < lock_count)
		lock_revive();	/* one or more locks released */
  }

  return(r);
}
コード例 #6
0
/*===========================================================================*
 *				actual_read_write_peek			     *
 *===========================================================================*/
int actual_read_write_peek(struct fproc *rfp, int rw_flag, int io_fd,
	vir_bytes io_buf, size_t io_nbytes)
{
/* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
  struct filp *f;
  tll_access_t locktype;
  int r;
  int ro = 1;

  if(rw_flag == WRITING) ro = 0;

  scratch(rfp).file.fd_nr = io_fd;
  scratch(rfp).io.io_buffer = io_buf;
  scratch(rfp).io.io_nbytes = io_nbytes;

  locktype = rw_flag == WRITING ? VNODE_WRITE : VNODE_READ;
  if ((f = get_filp2(rfp, scratch(rfp).file.fd_nr, locktype)) == NULL)
	return(err_code);

  assert(f->filp_count > 0);

  if (((f->filp_mode) & (ro ? R_BIT : W_BIT)) == 0) {
	unlock_filp(f);
	return(EBADF);
  }
  if (scratch(rfp).io.io_nbytes == 0) {
	unlock_filp(f);
	return(0);	/* so char special files need not check for 0*/
  }

  r = read_write(rfp, rw_flag, f, scratch(rfp).io.io_buffer,
	scratch(rfp).io.io_nbytes, who_e);

  unlock_filp(f);
  return(r);
}