static inline void sched_dupfiles(FAR _TCB *tcb)
{
  /* The parent task is the one at the head of the ready-to-run list */

  FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
  FAR struct file *parent;
  FAR struct file *child;
  int i;

  /* Duplicate the file descriptors.  This will be either all of the
   * file descriptors or just the first three (stdin, stdout, and stderr)
   * if CONFIG_FDCLONE_STDIO is defined.  NFSDS_TOCLONE is set
   * accordingly above.
   */

  if (rtcb->filelist)
    {
      /* Get pointers to the parent and child task file lists */

      parent = rtcb->filelist->fl_files;
      child  = tcb->filelist->fl_files;

      /* Check each file in the parent file list */

      for (i = 0; i < NFDS_TOCLONE; i++)
        {
          /* Check if this file is opened by the parent.  We can tell if
           * if the file is open because it contain a reference to a non-NULL
           * i-node structure.
           */

          if (parent[i].f_inode)
            {
              /* Yes... duplicate it for the child */

              (void)files_dup(&parent[i], &child[i]);
            }
        }
    }
}
Example #2
0
int dup2(int fildes1, int fildes2)
#endif
{
  FAR struct filelist *list;

  /* Get the thread-specific file list */

  list = sched_getfiles();
  if (!list)
    {
      set_errno(EMFILE);
      return ERROR;
    }

  /* Verify that fildes is a valid, open file descriptor */

  if (!DUP_ISOPEN(fildes1, list))
    {
      set_errno(EBADF);
      return ERROR;
    }

  /* Handle a special case */

  if (fildes1 == fildes2)
    {
      return fildes1;
    }

  /* Verify fildes2 */

  if ((unsigned int)fildes2 >= CONFIG_NFILE_DESCRIPTORS)
    {
      set_errno(EBADF);
      return ERROR;
    }

  return files_dup(&list->fl_files[fildes1], &list->fl_files[fildes2]);
}