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]); } } } }
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]); }