Esempio n. 1
0
ssize_t read(int fd, FAR void *buf, size_t nbytes)
{
  ssize_t ret;

  /* read() is a cancellation point */

  (void)enter_cancellation_point();

  /* Did we get a valid file descriptor? */

#if CONFIG_NFILE_DESCRIPTORS > 0
  if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
#endif
    {
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
      /* No.. If networking is enabled, read() is the same as recv() with
       * the flags parameter set to zero.  Note that recv() sets
       * the errno variable.
       */

      ret = recv(fd, buf, nbytes, 0);
#else
      /* No networking... it is a bad descriptor in any event */

      set_errno(EBADF);
      ret = ERROR;
#endif
    }

#if CONFIG_NFILE_DESCRIPTORS > 0
  else
    {
      FAR struct file *filep;

      /* The descriptor is in a valid range to file descriptor... do the
       * read.  First, get the file structure.  Note that on failure,
       * fs_getfilep() will set the errno variable.
       */

      filep = fs_getfilep(fd);
      if (filep == NULL)
        {
          /* The errno value has already been set */

          ret = ERROR;
        }
      else
        {
          /* Then let file_read do all of the work.  Note that file_read()
           * sets the errno variable.
           */

          ret = file_read(filep, buf, nbytes);
        }
    }
#endif

  leave_cancellation_point();
  return ret;
}
Esempio n. 2
0
int fs_dupfd(int fd, int minfd)
{
  FAR struct file *filep;
  int ret;

  /* Get the file structure corresponding to the file descriptor. */

  ret = fs_getfilep(fd, &filep);
  if (ret < 0)
    {
      goto errout;
    }

  DEBUGASSERT(filep != NULL);

  /* Let file_dup() do the real work */

  ret = file_dup(filep, minfd);
  if (ret < 0)
    {
      goto errout;
    }

  return OK;

errout:
  set_errno(-ret);
  return ERROR;
}
Esempio n. 3
0
int fstat(int fd, FAR struct stat *buf)
{
  FAR struct file *filep;
  int ret;

  /* Did we get a valid file descriptor? */

  if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
    {
#if CONFIG_NSOCKET_DESCRIPTORS > 0
      /* Let the networking logic handle the fstat() */

      ret = net_fstat(fd, buf);
      if (ret < 0)
        {
          goto errout;
        }

      return OK;
#else
      /* No networking... it is just a bad descriptor */

      ret = -EBADF;
      goto errout;
#endif
    }

  /* The descriptor is in a valid range for a file descriptor... do the
   * fstat.  First, get the file structure.  Note that on failure,
   * fs_getfilep() will set the errno variable.
   */

  ret = fs_getfilep(fd, &filep);
  if (ret < 0)
    {
      goto errout;
    }

  /* Perform the fstat operation */

  ret = file_fstat(filep, buf);

  /* Check if the fstat operation was successful */

  if (ret >= 0)
    {
      /* Successfully fstat'ed the file */

      return OK;
    }

errout:
  set_errno(-ret);
  return ERROR;
}
Esempio n. 4
0
int fcntl(int fd, int cmd, ...)
{
	FAR struct file *filep;
	va_list ap;
	int ret;

	/* fcntl() is a cancellation point */
	(void)enter_cancellation_point();

	/* Setup to access the variable argument list */

	va_start(ap, cmd);

	/* Did we get a valid file descriptor? */

#if CONFIG_NFILE_DESCRIPTORS > 0
	if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS) {
		/* Get the file structure corresponding to the file descriptor. */

		filep = fs_getfilep(fd);
		if (!filep) {
			/* The errno value has already been set */

			va_end(ap);
			leave_cancellation_point();
			return ERROR;
		}

		/* Let file_vfcntl() do the real work */

		ret = file_vfcntl(filep, cmd, ap);
	} else
#endif
	{
		/* No... check for operations on a socket descriptor */

#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
		if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
			/* Yes.. defer socket descriptor operations to net_vfcntl() */
			ret = net_vfcntl(fd, cmd, ap);
		} else
#endif
		{
			/* No.. this descriptor number is out of range */

			set_errno(EBADF);
			ret = ERROR;
		}
	}

	va_end(ap);
	leave_cancellation_point();
	return ret;
}
Esempio n. 5
0
static inline int fs_checkfd(FAR struct tcb_s *tcb, int fd, int oflags)
{
  FAR struct file *filep;
  FAR struct inode *inode;
  int ret;

  DEBUGASSERT(tcb && tcb->group);

  /* Get the file structure corresponding to the file descriptor. */

  ret = fs_getfilep(fd, &filep);
  if (ret < 0)
    {
      return ret;
    }

  /* Get the inode associated with the file descriptor.  This should
   * normally be the case if fd >= 0.  But not in the case where the
   * called attempts to explicitly stdin with fdopen(0) but stdin has
   * been closed.
   */

  inode = filep->f_inode;
  if (!inode)
    {
      /* No inode -- descriptor does not correspond to an open file */

      return -ENOENT;
    }

  /* Make sure that the inode supports the requested access.  In
   * the case of fdopen, we are not actually creating the file -- in
   * particular w and w+ do not truncate the file and any files have
   * already been created.
   */

  if (inode_checkflags(inode, oflags) != OK)
    {
      /* Cannot support the requested access */

      return -EACCES;
    }

  /* Looks good to me */

  return OK;
}
Esempio n. 6
0
off_t lseek(int fd, off_t offset, int whence)
{
  FAR struct file *filep;

  /* Get the file structure corresponding to the file descriptor. */

  filep = fs_getfilep(fd);
  if (!filep)
    {
      /* The errno value has already been set */

      return (off_t)ERROR;
    }

  /* Then let file_seek do the real work */

   return file_seek(filep, offset, whence);
}
Esempio n. 7
0
ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset)
{
  FAR struct file *filep;

  /* Get the file structure corresponding to the file descriptor. */

  filep = fs_getfilep(fd);
  if (!filep)
    {
      /* The errno value has already been set */

      return (ssize_t)ERROR;
    }

  /* Let file_pread do the real work */

  return file_pread(filep, buf, nbytes, offset);
}
Esempio n. 8
0
ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count)
{
#if defined(CONFIG_NET_TCP) && CONFIG_NSOCKET_DESCRIPTORS > 0

    /* Check the destination file descriptor:  Is it a (probable) file
     * descriptor?  Check the source file:  Is it a normal file?
     */

    if ((unsigned int)outfd >= CONFIG_NFILE_DESCRIPTORS &&
            (unsigned int)infd < CONFIG_NFILE_DESCRIPTORS)
    {
        FAR struct file *filep;

        /* This appears to be a file-to-socket transfer.  Get the file
         * structure.
         */

        filep = fs_getfilep(fd);
        if (!filep)
        {
            /* The errno value has already been set */

            return ERROR;
        }

        /* Then let net_sendfile do the work. */

        return net_sendfile(outfd, filep, offset, count);
    }
    else
#endif
    {
        /* No... then this is probably a file-to-file transfer.  The generic
         * lib_sendfile() can handle that case.
         */

        return lib_sendfile(outfd, infd, offset, count);
    }
}
Esempio n. 9
0
int fcntl(int fd, int cmd, ...)
{
  FAR struct file *filep;
  va_list ap;
  int ret;

  /* fcntl() is a cancellation point */

  (void)enter_cancellation_point();

  /* Setup to access the variable argument list */

  va_start(ap, cmd);

  /* Did we get a valid file descriptor? */

#if CONFIG_NFILE_DESCRIPTORS > 0
  if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS)
    {
      /* Get the file structure corresponding to the file descriptor. */

      ret = fs_getfilep(fd, &filep);
      if (ret >= 0)
        {
          DEBUGASSERT(filep != NULL);

          /* Let file_vfcntl() do the real work.  The errno is not set on
           * failures.
           */

          ret = file_vfcntl(filep, cmd, ap);
        }
    }
  else
#endif
    {
      /* No... check for operations on a socket descriptor */

#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
      if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
        {
          /* Yes.. defer socket descriptor operations to net_vfcntl(). The
           * errno is not set on failures.
           */

          ret = net_vfcntl(fd, cmd, ap);
        }
      else
#endif
        {
          /* No.. this descriptor number is out of range */

          ret = -EBADF;
        }
    }

  va_end(ap);

  if (ret < 0)
    {
      set_errno(-ret);
      ret = ERROR;
    }

  leave_cancellation_point();
  return ret;
}
Esempio n. 10
0
ssize_t writev(int fd, FAR const struct iovec *iov, int iovcnt)
{
int seg;
#if CONFIG_NFILE_DESCRIPTORS > 0
  FAR struct file *filep;
#endif

  /* check the input parameters */
  if (iov == NULL || iovcnt == 0)
    {
      return 0;
    }

  if (iovcnt > UIO_MAXIOV)
    {
      set_errno(EINVAL);
      return ERROR;
    }

  for (seg = 0; seg < iovcnt; seg++)
    {
      void *buf = iov[seg].iov_base;
      ssize_t len = (ssize_t)iov[seg].iov_len;

      if (len < 0 || buf == NULL)
        {
          set_errno(EINVAL);
          return ERROR;
        }
    }
  /* Did we get a valid file descriptor? */

#if CONFIG_NFILE_DESCRIPTORS > 0
  if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
#endif
    {
      /* Write to a socket descriptor is equivalent to send with flags == 0 */

#if defined(CONFIG_NET_TCP) && CONFIG_NSOCKET_DESCRIPTORS > 0
      return sock_sendv(fd, iov, iovcnt);
#else
      set_errno(EBADF);
      return ERROR;
#endif
    }

#if CONFIG_NFILE_DESCRIPTORS > 0
  /* The descriptor is in the right range to be a file descriptor... write
   * to the file.
   */

  filep = fs_getfilep(fd);
  if (!filep)
    {
      /* The errno value has already been set */

      return ERROR;
    }

  /* Perform the write operation using the file descriptor as an index */

  return file_writev(filep, iov, iovcnt);
#endif
}
Esempio n. 11
0
FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp)
{
  FAR struct aio_container_s *aioc;
  union
  {
#ifdef AIO_HAVE_FILEP
    FAR struct file *filep;
#endif
#ifdef AIO_HAVE_FILEP
    FAR struct socket *psock;
#endif
    FAR void *ptr;
  } u;
#ifdef CONFIG_PRIORITY_INHERITANCE
  struct sched_param param;
#endif

#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK)
  if (aiocbp->aio_fildes  >= CONFIG_NFILE_DESCRIPTORS)
#endif
#ifdef AIO_HAVE_FILEP
    {
      /* Get the file structure corresponding to the file descriptor. */

      u.filep = fs_getfilep(aiocbp->aio_fildes);
      if (!u.filep)
        {
          /* The errno value has already been set */

          return NULL;
        }
    }
#endif
#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK)
  else
#endif
#ifdef AIO_HAVE_PSOCK
    {
      /* Get the socket structure corresponding to the socket descriptor */

      u.psock = sockfd_socket(aiocbp->aio_fildes);
      if (!u.psock)
        {
          /* Does not set the errno.  EBADF is the most likely explanation. */

          set_errno(EBADF);
          return NULL;
        }
    }
#endif

  /* Allocate the AIO control block container, waiting for one to become
   * available if necessary.  This should never fail.
   */

  aioc = aioc_alloc();
  DEBUGASSERT(aioc);

  /* Initialize the container */

  memset(aioc, 0, sizeof(struct aio_container_s));
  aioc->aioc_aiocbp = aiocbp;
  aioc->u.aioc_filep = u.ptr;
  aioc->aioc_pid = getpid();

#ifdef CONFIG_PRIORITY_INHERITANCE
  DEBUGVERIFY(sched_getparam (aioc->aioc_pid, &param));
  aioc->aioc_prio = param.sched_priority;
#endif

  /* Add the container to the pending transfer list. */

  aio_lock();
  dq_addlast(&aioc->aioc_link, &g_aio_pending);
  aio_unlock();
  return aioc;
}
Esempio n. 12
0
int open(const char *path, int oflags, ...)
{
  FAR struct file *filep;
  FAR struct inode *inode;
  FAR const char *relpath = NULL;
#if defined(CONFIG_FILE_MODE) || !defined(CONFIG_DISABLE_MOUNTPOINT)
  mode_t mode = 0666;
#endif
  int ret;
  int fd;

#ifdef CONFIG_FILE_MODE
#  ifdef CONFIG_CPP_HAVE_WARNING
#    warning "File creation not implemented"
#  endif

  /* If the file is opened for creation, then get the mode bits */

  if ((oflags & (O_WRONLY | O_CREAT)) != 0)
    {
      va_list ap;
      va_start(ap, oflags);
      mode = va_arg(ap, mode_t);
      va_end(ap);
    }
#endif

  /* Get an inode for this file */

  inode = inode_find(path, &relpath);
  if (!inode)
    {
      /* "O_CREAT is not set and the named file does not exist.  Or, a
       * directory component in pathname does not exist or is a dangling
       * symbolic link."
       */

      ret = ENOENT;
      goto errout;
    }

#if !defined(CONFIG_DISABLE_PSEUDOFS_OPERATIONS) && \
    !defined(CONFIG_DISABLE_MOUNTPOINT)
   /* If the inode is block driver, then we may return a character driver
    * proxy for the block driver.  block_proxy() will instantiate a BCH
    * character driver wrapper around the block driver, open(), then
    * unlink() the character driver.  On success, block_proxy() will
    * return the file descriptor of the opened character driver.
    *
    * NOTE: This will recurse to open the character driver proxy.
    */

   if (INODE_IS_BLOCK(inode))
     {
       /* Release the inode reference */

       inode_release(inode);

       /* Get the file descriptor of the opened character driver proxy */

       fd = block_proxy(path, oflags);
       if (fd < 0)
         {
           ret = fd;
           goto errout;
         }

       /* Return the file descriptor */

       return fd;
     }
   else
#endif

  /* Verify that the inode is either a "normal" character driver or a
   * mountpoint.  We specifically "special" inodes (semaphores, message
   * queues, shared memory).
   */

#ifndef CONFIG_DISABLE_MOUNTPOINT
  if ((!INODE_IS_DRIVER(inode) && !INODE_IS_MOUNTPT(inode)) || !inode->u.i_ops)
#else
  if (!INODE_IS_DRIVER(inode) || !inode->u.i_ops)
#endif
    {
      ret = ENXIO;
      goto errout_with_inode;
    }

  /* Make sure that the inode supports the requested access */

  ret = inode_checkflags(inode, oflags);
  if (ret < 0)
    {
      ret = -ret;
      goto errout_with_inode;
    }

  /* Associate the inode with a file structure */

  fd = files_allocate(inode, oflags, 0, 0);
  if (fd < 0)
    {
      ret = EMFILE;
      goto errout_with_inode;
    }

  /* Get the file structure corresponding to the file descriptor. */

  filep = fs_getfilep(fd);
  if (!filep)
    {
      /* The errno value has already been set */

      return ERROR;
    }

  /* Perform the driver open operation.  NOTE that the open method may be
   * called many times.  The driver/mountpoint logic should handled this
   * because it may also be closed that many times.
   */

  ret = OK;
  if (inode->u.i_ops->open)
    {
#ifndef CONFIG_DISABLE_MOUNTPOINT
      if (INODE_IS_MOUNTPT(inode))
        {
          ret = inode->u.i_mops->open(filep, relpath, oflags, mode);
        }
      else
#endif
        {
          ret = inode->u.i_ops->open(filep);
        }
    }

  if (ret < 0)
    {
      ret = -ret;
      goto errout_with_fd;
    }

  return fd;

errout_with_fd:
  files_release(fd);
errout_with_inode:
  inode_release(inode);
errout:
  set_errno(ret);
  return ERROR;
}