Esempio n. 1
0
File: main.c Progetto: Sciumo/minix
/*===========================================================================*
 *			       do_pending_pipe				     *
 *===========================================================================*/
static void *do_pending_pipe(void *arg)
{
  int r, op;
  struct job my_job;
  struct filp *f;
  tll_access_t locktype;

  my_job = *((struct job *) arg);
  fp = my_job.j_fp;

  lock_proc(fp, 1 /* force lock */);

  f = scratch(fp).file.filp;
  assert(f != NULL);
  scratch(fp).file.filp = NULL;

  locktype = (job_call_nr == READ) ? VNODE_READ : VNODE_WRITE;
  op = (job_call_nr == READ) ? READING : WRITING;
  lock_filp(f, locktype);

  r = rw_pipe(op, who_e, f, scratch(fp).io.io_buffer, scratch(fp).io.io_nbytes);

  if (r != SUSPEND)  /* Do we have results to report? */
	reply(fp->fp_endpoint, r);

  unlock_filp(f);

  thread_cleanup(fp);
  return(NULL);
}
Esempio n. 2
0
File: cdev.c Progetto: aunali1/exopc
static int 
cdev_ioctl(struct file *filp, unsigned int request, char *argp) {
  int status;
  dev_t device = filp->f_dev;

  unlock_filp(filp);
  signals_off();

  status = (*cdevsw[major(device)].d_ioctl)(device, request, argp, GENFLAG(filp), curproc);

  if (status == 0) {
#if 1
    if (request == TIOCSCTTY) {
      {int ret = proc_controlt(-1,-1,(int)filp); assert(ret == 0);}
    }
#endif
  } else {
    errno = status; status = -1;
  }
  signals_on();
  /* HBXX - Race condition, can receive a signal during the return and next
     unlock_filp() */
  lock_filp(filp);
  return status;
}
Esempio n. 3
0
File: mmap.c Progetto: aunali1/exopc
int mmap_exec(u_int k, int envid, int execonly) {
  /* munmap all non-MAP_INHERIT regions */
  struct Mmap *m2, *m = mmap_list.lh_first;

  if (!execonly) return 0;

  while (m)
    if (m->mmap_flags & MAP_INHERIT) {
      /* not implemented - need to set up a region of vm to mmap data */
      assert(0);
      m = m->mmap_link.le_next;
    }
    else {
      m2 = m->mmap_link.le_next;
      assert(msync(m->mmap_addr, m->mmap_len, 0) == 0);
      if (m->mmap_filp) {
	lock_filp(m->mmap_filp);
	filp_refcount_dec(m->mmap_filp);
	if (filp_refcount_get(m->mmap_filp) == 0) {
	  unlock_filp(m->mmap_filp);
	  close_filp(m->mmap_filp);
	} else
	  unlock_filp(m->mmap_filp);
      }
      m = m2;
    }

  return 0;
}
Esempio n. 4
0
/*===========================================================================*
 *			       do_pending_pipe				     *
 *===========================================================================*/
static void do_pending_pipe(void)
{
  int r, op;
  struct filp *f;
  tll_access_t locktype;

  f = fp->fp_filp[fp->fp_fd];
  assert(f != NULL);

  locktype = (job_call_nr == VFS_READ) ? VNODE_READ : VNODE_WRITE;
  op = (job_call_nr == VFS_READ) ? READING : WRITING;
  lock_filp(f, locktype);

  r = rw_pipe(op, who_e, f, fp->fp_io_buffer, fp->fp_io_nbytes);

  if (r != SUSPEND) { /* Do we have results to report? */
	/* Process is writing, but there is no reader. Send a SIGPIPE signal.
	 * This should match the corresponding code in read_write().
	 */
	if (r == EPIPE && op == WRITING) {
		if (!(f->filp_flags & O_NOSIGPIPE))
			sys_kill(fp->fp_endpoint, SIGPIPE);
	}

	replycode(fp->fp_endpoint, r);
  }

  unlock_filp(f);
}
Esempio n. 5
0
File: filedes.c Progetto: grd/minix
/*===========================================================================*
 *				do_filp_gc					     *
 *===========================================================================*/
void *do_filp_gc(void *UNUSED(arg))
{
  struct filp *f;
  struct vnode *vp;

  for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
	if (!(f->filp_state & FS_INVALIDATED)) continue;

	if (f->filp_mode == FILP_CLOSED || f->filp_vno == NULL) {
		/* File was already closed before gc could kick in */
		assert(f->filp_count <= 0);
		f->filp_state &= ~FS_INVALIDATED;
		f->filp_count = 0;
		continue;
	}

	assert(f->filp_vno != NULL);
	vp = f->filp_vno;

	/* Synchronize with worker thread that might hold a lock on the vp */
	lock_vnode(vp, VNODE_OPCL);
	unlock_vnode(vp);

	/* If garbage collection was invoked due to a failed device open
	 * request, then common_open has already cleaned up and we have
	 * nothing to do.
	 */
	if (!(f->filp_state & FS_INVALIDATED)) {
		continue;
	}

	/* If garbage collection was invoked due to a failed device close
	 * request, the close_filp has already cleaned up and we have nothing
	 * to do.
	 */
	if (f->filp_mode != FILP_CLOSED) {
		assert(f->filp_count == 0);
		f->filp_count = 1;	/* So lock_filp and close_filp will do
					 * their job */
		lock_filp(f, VNODE_READ);
		close_filp(f);
	}

	f->filp_state &= ~FS_INVALIDATED;
  }

  thread_cleanup(NULL);
  return(NULL);
}
Esempio n. 6
0
File: mmap.c Progetto: aunali1/exopc
int mmap_fork(u_int k, int envid, int NewPid) {
  /* increase the refcounts */
  struct Mmap *m = mmap_list.lh_first;

  while (m) {
    if (m->mmap_filp) {
      lock_filp(m->mmap_filp);
      filp_refcount_inc(m->mmap_filp);
      unlock_filp(m->mmap_filp);
    }
    m = m->mmap_link.le_next;
  }

  return 0;
}
Esempio n. 7
0
File: mmap.c Progetto: aunali1/exopc
static inline void close_filp(struct file *filp) {
  int fd;

  for (fd = NR_OPEN - 1; fd >= 0; fd--)
    if (__current->fd[fd] == NULL) {
      __current->fd[fd] = filp;
      break;
    }
  assert(fd >= 0);
  __current->cloexec_flag[fd] = 0;
  lock_filp(filp);
  filp_refcount_inc(filp);
  unlock_filp(filp);
  close(fd);
}
Esempio n. 8
0
File: cdev.c Progetto: aunali1/exopc
static int
cdev_write(struct file *filp, char *buffer, int nbyte, int blocking) {
  int status;
  dev_t dev = filp->f_dev;
  struct uio uio;
  struct iovec iov[4];
  char buf[CLALLOCSZ*8];
  int i;

  demand(filp, bogus filp);

  unlock_filp(filp);
  signals_off();

  DPRINTF(CLU_LEVEL,
	  ("cdev_write: filp: %08x offset: %qd nbyte: %d\n",
	   (int)filp, filp->f_pos, nbyte));

  assert(nbyte <= CLALLOCSZ*8);
  memcpy(buf,buffer,nbyte);
  iov[0].iov_base = buf;
  iov[0].iov_len = nbyte;
  uio.uio_iov = iov;
  uio.uio_iovcnt = 1;
  uio.uio_offset = 0;
  uio.uio_resid = nbyte;
  uio.uio_rw = UIO_WRITE;
  k0printf("Write: %d: ",uio.uio_resid);
  for (i = 0; i < uio.uio_resid; i++) 
    k0printf(">%d (%c)",(unsigned int)buf[i],buf[i]);

  EnterCritical();
  status = (*cdevsw[major(dev)].d_write)(dev, &uio, GENFLAG(filp));
  ExitCritical();

  k0printf("Read: %d: ",nbyte - uio.uio_resid);
  if (status == 0) {
    status = nbyte - uio.uio_resid;
  } else {
    errno = status; status = -1;
  }

  signals_on();
  /* HBXX - Race condition, can receive a signal during the return and next
     unlock_filp() */
  lock_filp(filp);
  return status;
}
Esempio n. 9
0
File: cdev.c Progetto: aunali1/exopc
static int
cdev_read(struct file *filp, char *buffer, int nbyte, int blocking) {
  int status;
  dev_t dev = filp->f_dev;
  struct uio uio;
  struct iovec iov[4];

  demand(filp, bogus filp);
  DPRINTF(CLU_LEVEL,
	  ("cdev_read: filp: %08x offset: %qd nbyte: %d\n",
	   (int)filp, filp->f_pos, nbyte));
  /* if (nbyte > CLALLOCSZ) {fprintf(stderr,"ncdev_read, warn large nbyte\n");} */
  iov[0].iov_base = buffer;
  iov[0].iov_len = nbyte;
  uio.uio_iov = iov;
  uio.uio_iovcnt = 1;
  uio.uio_offset = 0;
  uio.uio_resid = nbyte;
  uio.uio_rw = UIO_READ;

  signals_off();
  unlock_filp(filp);
  EnterCritical();
  status = (*cdevsw[major(dev)].d_read)(dev, &uio, GENFLAG(filp));
  ExitCritical();
  signals_on();

  k0printf("Read: %d: ",nbyte - uio.uio_resid);
  if (status == 0) {
    status = nbyte - uio.uio_resid;
  } else {
    errno = status; 
    status = -1;
  }
  /* HBXX - Race condition, can receive a signal during the return and next
     unlock_filp() */
  lock_filp(filp);
#if 0
  if (status >= 0) {
    extern void pr_uio();
    kprintf("read(%d,%d) ",major(dev),minor(dev));
    pr_uio(&uio);
  }
#endif
  return status;
}
Esempio n. 10
0
File: mmap.c Progetto: aunali1/exopc
void mmap_exit(void *arg) {
  /* munmap all regions */
  struct Mmap *m2, *m = mmap_list.lh_first;

  while (m) {
    m2 = m->mmap_link.le_next;
    assert(msync(m->mmap_addr, m->mmap_len, 0) == 0);
    if (m->mmap_filp) {
      lock_filp(m->mmap_filp);
      filp_refcount_dec(m->mmap_filp);
      if (filp_refcount_get(m->mmap_filp) == 0) {
	unlock_filp(m->mmap_filp);
	close_filp(m->mmap_filp);
      } else
	unlock_filp(m->mmap_filp);
    }
    m = m2;
  }
}
/*===========================================================================*
 *			       do_pending_pipe				     *
 *===========================================================================*/
static void do_pending_pipe(void)
{
  vir_bytes buf;
  size_t nbytes, cum_io;
  int r, op, fd;
  struct filp *f;
  tll_access_t locktype;

  assert(fp->fp_blocked_on == FP_BLOCKED_ON_NONE);

  /*
   * We take all our needed resumption state from the m_in message, which is
   * filled by unblock().  Since this is an internal resumption, there is no
   * need to perform extensive checks on the message fields.
   */
  fd = job_m_in.m_lc_vfs_readwrite.fd;
  buf = job_m_in.m_lc_vfs_readwrite.buf;
  nbytes = job_m_in.m_lc_vfs_readwrite.len;
  cum_io = job_m_in.m_lc_vfs_readwrite.cum_io;

  f = fp->fp_filp[fd];
  assert(f != NULL);

  locktype = (job_call_nr == VFS_READ) ? VNODE_READ : VNODE_WRITE;
  op = (job_call_nr == VFS_READ) ? READING : WRITING;
  lock_filp(f, locktype);

  r = rw_pipe(op, who_e, f, job_call_nr, fd, buf, nbytes, cum_io);

  if (r != SUSPEND) { /* Do we have results to report? */
	/* Process is writing, but there is no reader. Send a SIGPIPE signal.
	 * This should match the corresponding code in read_write().
	 */
	if (r == EPIPE && op == WRITING) {
		if (!(f->filp_flags & O_NOSIGPIPE))
			sys_kill(fp->fp_endpoint, SIGPIPE);
	}

	replycode(fp->fp_endpoint, r);
  }

  unlock_filp(f);
}
Esempio n. 12
0
File: misc.c Progetto: Hooman3/minix
/*===========================================================================*
 *				free_proc				     *
 *===========================================================================*/
static void free_proc(int flags)
{
  int i;
  register struct fproc *rfp;
  register struct filp *rfilp;
  register struct vnode *vp;
  dev_t dev;

  if (fp->fp_endpoint == NONE)
	panic("free_proc: already free");

  if (fp_is_blocked(fp))
	unpause();

  /* Loop on file descriptors, closing any that are open. */
  for (i = 0; i < OPEN_MAX; i++) {
	(void) close_fd(fp, i);
  }

  /* Release root and working directories. */
  if (fp->fp_rd) { put_vnode(fp->fp_rd); fp->fp_rd = NULL; }
  if (fp->fp_wd) { put_vnode(fp->fp_wd); fp->fp_wd = NULL; }

  /* The rest of these actions is only done when processes actually exit. */
  if (!(flags & FP_EXITING)) return;

  fp->fp_flags |= FP_EXITING;

  /* Check if any process is SUSPENDed on this driver.
   * If a driver exits, unmap its entries in the dmap table.
   * (unmapping has to be done after the first step, because the
   * dmap table is used in the first step.)
   */
  unsuspend_by_endpt(fp->fp_endpoint);
  dmap_unmap_by_endpt(fp->fp_endpoint);

  worker_stop_by_endpt(fp->fp_endpoint); /* Unblock waiting threads */
  vmnt_unmap_by_endpt(fp->fp_endpoint); /* Invalidate open files if this
					     * was an active FS */

  /* If a session leader exits and it has a controlling tty, then revoke
   * access to its controlling tty from all other processes using it.
   */
  if ((fp->fp_flags & FP_SESLDR) && fp->fp_tty != 0) {
      dev = fp->fp_tty;
      for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
	  if(rfp->fp_pid == PID_FREE) continue;
          if (rfp->fp_tty == dev) rfp->fp_tty = 0;

          for (i = 0; i < OPEN_MAX; i++) {
		if ((rfilp = rfp->fp_filp[i]) == NULL) continue;
		if (rfilp->filp_mode == FILP_CLOSED) continue;
		vp = rfilp->filp_vno;
		if (!S_ISCHR(vp->v_mode)) continue;
		if (vp->v_sdev != dev) continue;
		lock_filp(rfilp, VNODE_READ);
		(void) cdev_close(dev); /* Ignore any errors. */
		/* FIXME: missing select check */
		rfilp->filp_mode = FILP_CLOSED;
		unlock_filp(rfilp);
          }
      }
  }

  /* Exit done. Mark slot as free. */
  fp->fp_endpoint = NONE;
  fp->fp_pid = PID_FREE;
  fp->fp_flags = FP_NOFLAGS;
}
Esempio n. 13
0
File: mmap.c Progetto: aunali1/exopc
int munmap(void *addr, size_t len) {
  struct Mmap *m;
  struct mmap_ustruct *mus;
  void *nextaddr;
  size_t nextlen;

  OSCALLENTER(OSCALL_munmap);
  /* page-ify */
  len += (((u_int)addr) & PGMASK);
  addr = (void*)PGROUNDDOWN((u_int)addr);
  len = PGROUNDUP(len);
  /* impossible to do what man page says! */
#if 0
  if ((((u_int)addr) & PGMASK) || len < 0) {
    errno = EINVAL;
    OSCALLEXIT(OSCALL_munmap);
    return -1;
  }
#endif
  if (len == 0) {
    OSCALLEXIT(OSCALL_munmap);
    return 0;
  }

  nextlen = len;

  do {
    /* get info on the to-be-freed region */
    mus = (struct mmap_ustruct *)mregion_get_ustruct(addr);
    if (!mus) {
      errno = EINVAL;
      OSCALLEXIT(OSCALL_munmap);
      return -1;
    }
    m = &(mus->m);

    if (addr+len > m->mmap_addr+m->mmap_len)
      len -= addr+len - (m->mmap_addr+m->mmap_len);

    /* something strange, shouldn't happen */
    if (addr >= m->mmap_addr+m->mmap_len ||
	addr+len <= m->mmap_addr) {
      OSCALLEXIT(OSCALL_munmap);
      return 0;
    }

    /* if completely freed */
    if (addr <= m->mmap_addr && len >= m->mmap_len) {
      __vm_free_region((u_int)m->mmap_addr, m->mmap_len,
		       CAP_ROOT); /* XXX - error check */
      __free(m->mmap_addr); /* if wasn't __malloc'd then this will do nothing */
      LIST_REMOVE(m, mmap_link);
      if (m->mmap_filp) {
	lock_filp(m->mmap_filp);
	filp_refcount_dec(m->mmap_filp);
	if (filp_refcount_get(m->mmap_filp) == 0) {
	  unlock_filp(m->mmap_filp);
	  close_filp(m->mmap_filp);
	} else
	  unlock_filp(m->mmap_filp);
      }
      exos_pinned_free(mus);
      /* retore original handler to region */
      if (mregion_alloc(addr, len, mus->oldmru) < 0) {
	errno = EINVAL;
	OSCALLEXIT(OSCALL_munmap);
	return -1;
      }
    } /* if the end is freed */
    else if (addr > m->mmap_addr && addr+len >= m->mmap_addr+m->mmap_len) {
      m->mmap_len = addr-m->mmap_addr;
      __vm_free_region((u_int)addr, len, CAP_ROOT); /* XXX - error check */
      __free2(addr, 0); /* if wasn't __malloc'd then this will do nothing */
      /* retore original handler to region */
      if (mregion_alloc(addr, len, mus->oldmru) < 0) {
	errno = EINVAL;
	OSCALLEXIT(OSCALL_munmap);
	return -1;
      }
    } /* if the beginning is freed */
    else if (addr <= m->mmap_addr && addr+len < m->mmap_addr+m->mmap_len) {
      __vm_free_region((u_int)addr, len, CAP_ROOT); /* XXX - error check */
      __free2(m->mmap_addr, addr+len - m->mmap_addr);
      m->mmap_len = m->mmap_addr+m->mmap_len - (addr+len);
      m->mmap_addr = addr+len;
      /* retore original handler to region */
      if (mregion_alloc(addr, len, mus->oldmru) < 0) {
	errno = EINVAL;
	OSCALLEXIT(OSCALL_munmap);
	return -1;
      }
    } /* if the middle is freed */
    else {
      __vm_free_region((u_int)addr, len, CAP_ROOT); /* XXX - error check */
      /* retore original handler to region */
      if (mregion_alloc(addr, len, mus->oldmru) < 0) {
	errno = EINVAL;
	OSCALLEXIT(OSCALL_munmap);
	return -1;
      }
      assert(0); /* XXX - too much trouble right now */
    }

    nextaddr = addr+len;
    nextlen -= len;
    addr = nextaddr;
    len = nextlen;
  } while (len > 0);

  OSCALLEXIT(OSCALL_munmap);
  return 0;
}
Esempio n. 14
0
File: mmap.c Progetto: aunali1/exopc
void *mmap (void *addr, size_t len, int prot, int flags, int fd,
	    off_t offset)
{

  u_int pageoff;
  caddr_t ret;
  off_t pos = offset;
  size_t size = len;
  struct Mmap *m;
  struct stat sb;
  struct file *filp;
  struct mmap_ustruct *mus;

  OSCALLENTER(OSCALL_mmap);
  if (!mmap_inited) mmap_init();

  /* if given a bad fd then return */
  if (fd != -1 && fstat (fd, &sb) < 0) {
    errno = EINVAL;
    OSCALLEXIT(OSCALL_mmap);
    return (caddr_t )-1;
  }

  if ((flags & MAP_COPY) && (flags & MAP_ANON)) flags &= ~MAP_COPY;

  /* OpenBSD 2.1 code */
  /*
   * Align the file position to a page boundary,
   * and save its page offset component.
   */
  pageoff = (pos & PGMASK);
  pos -= pageoff;

  /* Adjust size for rounding (on both ends). */
  size += pageoff;	/* low end... */
  size = PGROUNDUP(size); /* hi end */

  /* Do not allow mappings that cause address wrap... */
  if ((ssize_t)size < 0) {
    errno = EINVAL;
    OSCALLEXIT(OSCALL_mmap);
    return (caddr_t)-1;
  }

  /*
   * Check for illegal addresses.  Watch out for address wrap...
   */
  if (flags & MAP_FIXED) {
    /*
     * The specified address must have the same remainder
     * as the file offset taken modulo NBPG, so it
     * should be aligned after adjustment by pageoff.
     */
    addr -= pageoff;
    if ((u_int)addr & PGMASK) {
      errno = EINVAL;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }
    /* Address range must be all in user VM space. */
    if (UTOP > 0 && (u_int)addr + size > UTOP) {
      errno = EINVAL;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }
    if ((u_int)addr > (u_int)addr + size) {
      errno = EINVAL;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }
  }

  if ((flags & MAP_ANON) == 0) {
    if (fd < 0 || fd > NR_OPEN || __current->fd[fd] == NULL) {
      errno = EBADF;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }

    /*
     * XXX hack to handle use of /dev/zero to map anon
     * memory (ala SunOS).
     */
    if (S_ISCHR(__current->fd[fd]->f_mode) &&
	mmap_iszerodev(__current->fd[fd]->f_dev)) {
      flags |= MAP_ANON;
      goto is_anon;
    }

    /*
     * Only files and cdevs are mappable, and cdevs does not
     * provide private mappings of any kind.
     */
    if (!S_ISREG(__current->fd[fd]->f_mode) &&
	(!S_ISCHR(__current->fd[fd]->f_mode) ||
	 (flags & (MAP_PRIVATE|MAP_COPY)))) {
      errno = EINVAL;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }

    /*
     * Ensure that file and memory protections are
     * compatible.  Note that we only worry about
     * writability if mapping is shared; in this case,
     * current and max prot are dictated by the open file.
     * XXX use the vnode instead?  Problem is: what
     * credentials do we use for determination?
     * What if proc does a setuid?
     */
    if (((__current->fd[fd]->f_flags & O_ACCMODE) == O_WRONLY) &&
	(prot & PROT_READ)) {
      errno = EACCES;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }

    /*
     * If we are sharing potential changes (either via MAP_SHARED
     * or via the implicit sharing of character device mappings),
     * and we are trying to get write permission although we
     * opened it without asking for it, bail out.
     */
    if (((flags & MAP_SHARED) != 0 || S_ISCHR(__current->fd[fd]->f_mode)) &&
	((__current->fd[fd]->f_flags & O_ACCMODE) == O_RDONLY) &&
	(prot & PROT_WRITE) != 0) {
      errno = EACCES;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }
  } else {
    /*
     * (flags & MAP_ANON) == TRUE
     * Mapping blank space is trivial.
     */
    if (fd != -1) {
      errno = EINVAL;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }
  is_anon:
    pos = 0;
  }

  if (size == 0) {
    OSCALLEXIT(OSCALL_mmap);
    return addr; 
  }

  if (fd >= 0)
    filp = __current->fd[fd];
  else
    filp = NULL;

  if ((flags & MAP_FIXED) == 0) {
    addr = __malloc(size);
    if (addr == NULL) {
      __free(addr);
      errno = ENOMEM;
      OSCALLEXIT(OSCALL_mmap);
      return (caddr_t)-1;
    }
  }

  mus = exos_pinned_malloc(sizeof(*mus));
  if (mus == NULL) {
    if ((flags & MAP_FIXED) == 0) __free(addr);
    errno = ENOMEM;
    OSCALLEXIT(OSCALL_mmap);
    return (caddr_t)-1;
  }

  m = &(mus->m);
  m->mmap_addr = addr;
  m->mmap_len = size;
  m->mmap_prot = prot;
  m->mmap_flags = flags;
  m->mmap_offset = pos;
  m->mmap_filp = filp;
  m->mmap_dev = ((fd != -1) ? sb.st_dev : 0);
  LIST_INSERT_HEAD (&mmap_list, m, mmap_link);

  mus->mru.handler = mmap_fault_handler;
  mus->oldmru = mregion_get_ustruct(addr); /* XXX - check return value */

  if (__vm_free_region((u_int)addr, size, 0) < 0 ||
      mregion_alloc(addr, size, (struct mregion_ustruct*)mus) != 0) {
    if ((flags & MAP_FIXED) == 0) __free(addr);
    exos_pinned_free(mus);
    errno = ENOMEM;
    OSCALLEXIT(OSCALL_mmap);
    return (caddr_t)-1;
  }

  if (filp) {
    lock_filp(filp);
    filp_refcount_inc(filp);
    unlock_filp(filp);
  }

  if (flags & MAP_COPY)
    ret = __mmap(addr, size, prot, flags, fd, pos, 0, __envid);
  else
    ret = addr + pageoff;

  OSCALLEXIT(OSCALL_mmap);
  return ret;
}
Esempio n. 15
0
File: pty.c Progetto: aunali1/exopc
static int
pty_read(struct file *filp, char *buffer, int nbyte, int blocking) {
  struct pty *pty;
  struct pipe *pipeb;
#if 0
  int  final = 0,len;
#else
  int total;
#endif
  int foundnl,master;

  demand(filp, bogus filp);
  DPRINTF(CLU_LEVEL,
	  ("pty_read: filp: %08x offset: %qd nbyte: %d\n",
	   (int)filp, filp->f_pos, nbyte));
  pty = GETPTYP(filp);
				/*   lock_pty(pty); */
  master = filp->f_pos;
  demand (master == 1 || master == 0,master flag set improperly);

  pipeb = &(pty->pipe[master]);

  if (!(PTY_BUSY(1 - master,pty)) && pipeb->length == PTY_BUFFER_SIZE) {
      /* someone closed the other end, and nothing to read */
      return 0;
  }

  if (pipeb->length == PTY_BUFFER_SIZE && CHECKNB(filp)) {
    errno = EWOULDBLOCK;
    return -1;
  }
    

  while(pipeb->length == PTY_BUFFER_SIZE) {
      /* we block if cant read anything */
      unlock_filp(filp);
      wk_waitfor_value_lt (&pipeb->length, PTY_BUFFER_SIZE, 0);
#if 0
      yield(-1);
#endif
      lock_filp(filp);
  }

  if (!(PTY_BUSY(1 - master,pty)) && pipeb->length == PTY_BUFFER_SIZE) {
      /* someone closed the other end, and nothing to read */
      return 0;
  }
  
  lock_pipepty(pipeb); 

  if (master) {
      /* master pty does not have line discipline */
      total = piperead(pipeb,buffer,nbyte,0,&foundnl);
  } else {
      /* slave pty have line discipline */
      total = piperead(pipeb,buffer,nbyte,1,&foundnl);
  }
  unlock_pipepty(pipeb); 
				/*   unlock_pty(pty); */
				/*   if (master) pr_ptyp(pty);   */
  return total;
}