diff --git a/fs/fs_dup.c b/fs/fs_dup.c index 20b7fbf279c9c1da71fc79a419733ae3bbc998c0..c041aa4ca1ab27d0dd410dd71cee7cec14c78ea2 100644 --- a/fs/fs_dup.c +++ b/fs/fs_dup.c @@ -47,15 +47,8 @@ #include <nuttx/fs.h> #include "fs_internal.h" -/* This logic in this applies only when both socket and file descriptors are - * in that case, this function descriminates which type of dup is being - * performed. - */ - -#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 - /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ /**************************************************************************** @@ -76,34 +69,40 @@ int dup(int fildes) { + int ret = OK; + /* Check the range of the descriptor to see if we got a file or a socket * descriptor. */ - if ((unsigned int)fildes >= CONFIG_NFILE_DESCRIPTORS) +#if CONFIG_NFILE_DESCRIPTORS > 0 + if ((unsigned int)fildes < CONFIG_NFILE_DESCRIPTORS) + { + /* Its a valid file descriptor.. dup the file descriptor using any + * other file descriptor*/ + + ret = file_dup(fildes, 0); + } + else +#endif { /* Not a vailid file descriptor. Did we get a valid socket descriptor? */ +#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 if ((unsigned int)fildes < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS)) { /* Yes.. dup the socket descriptor */ - return net_dup(fildes); + ret = net_dup(fildes, CONFIG_NFILE_DESCRIPTORS); } else +#endif { /* No.. then it is a bad descriptor number */ errno = EBADF; - return ERROR; + ret = ERROR; } } - else - { - /* Its a valid file descriptor.. dup the file descriptor */ - - return file_dup(fildes); - } + return ret; } -#endif /* CONFIG_NFILE_DESCRIPTORS > 0 ... */ - diff --git a/fs/fs_fcntl.c b/fs/fs_fcntl.c index 524bd22b0ccfa1441c0a9c4d42e274940f345afd..d8afd51a205268273b57b4340c7e1f1fc7fc2859 100644 --- a/fs/fs_fcntl.c +++ b/fs/fs_fcntl.c @@ -94,6 +94,11 @@ static inline int file_vfcntl(int fildes, int cmd, va_list ap) * exec functions. */ + { + ret = file_dup(fildes, va_arg(ap, int)); + } + break; + case F_GETFD: /* Get the file descriptor flags defined in <fcntl.h> that are associated * with the file descriptor fildes. File descriptor flags are associated diff --git a/fs/fs_filedup.c b/fs/fs_filedup.c index 71f625877d4310e26dcbd5b544c534d987611653..10c2eba04b4c7e0c8c7eb9e5c35890f448ef6d7c 100644 --- a/fs/fs_filedup.c +++ b/fs/fs_filedup.c @@ -40,7 +40,6 @@ #include <nuttx/config.h> #include <sys/types.h> -#include <unistd.h> #include <sched.h> #include <errno.h> @@ -76,11 +75,7 @@ * ****************************************************************************/ -#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 -int file_dup(int fildes) -#else -int dup(int fildes) -#endif +int file_dup(int fildes, int minfd) { FAR struct filelist *list; int fildes2; @@ -110,7 +105,8 @@ int dup(int fildes) fildes2 = files_allocate(list->fl_files[fildes].f_inode, list->fl_files[fildes].f_oflags, - list->fl_files[fildes].f_pos); + list->fl_files[fildes].f_pos, + minfd); if (fildes2 < 0) { errno = EMFILE; diff --git a/fs/fs_files.c b/fs/fs_files.c index d0c3fff529d07e68a5c4807188c28f0b90b4ae53..e872d155842e6498b5c3a9d1194dd56e6e48ad17 100644 --- a/fs/fs_files.c +++ b/fs/fs_files.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/fs_files.c * - * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -361,7 +361,8 @@ errout: * Returns the file descriptor == index into the files array. * ****************************************************************************/ -int files_allocate(FAR struct inode *inode, int oflags, off_t pos) + +int files_allocate(FAR struct inode *inode, int oflags, off_t pos, int minfd) { FAR struct filelist *list; int i; @@ -370,7 +371,7 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos) if (list) { _files_semtake(list); - for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + for (i = minfd; i < CONFIG_NFILE_DESCRIPTORS; i++) { if (!list->fl_files[i].f_inode) { diff --git a/fs/fs_internal.h b/fs/fs_internal.h index e34c451342f5464a4d5f3d66322455623f47d029..34b722e982194ca3701301de88d4135ea3d46077 100644 --- a/fs/fs_internal.h +++ b/fs/fs_internal.h @@ -225,7 +225,7 @@ EXTERN void inode_release(FAR struct inode *inode); /* fs_files.c ****************************************************************/ EXTERN void weak_function files_initialize(void); -EXTERN int files_allocate(FAR struct inode *inode, int oflags, off_t pos); +EXTERN int files_allocate(FAR struct inode *inode, int oflags, off_t pos, int minfd); EXTERN int files_close(int filedes); EXTERN void files_release(int filedes); diff --git a/fs/fs_open.c b/fs/fs_open.c index 8ab6503769d23e66042b7d1434d3e5ad3e69b830..76b941f95992273672c6dda3ee640035368d5452 100644 --- a/fs/fs_open.c +++ b/fs/fs_open.c @@ -140,7 +140,7 @@ int open(const char *path, int oflags, ...) /* Associate the inode with a file structure */ - fd = files_allocate(inode, oflags, 0); + fd = files_allocate(inode, oflags, 0, 0); if (fd < 0) { ret = EMFILE; diff --git a/include/nuttx/fs.h b/include/nuttx/fs.h index b33bfa234cf4f4ef2c5df440be34b611c137ecbe..a0c70390ddfa529b678ff9d9a3d9ec790a93881e 100644 --- a/include/nuttx/fs.h +++ b/include/nuttx/fs.h @@ -344,15 +344,9 @@ EXTERN int files_dup(FAR struct file *filep1, FAR struct file *filep2); /* fs_filedup.c **************************************************************/ -/* This alternative naming is used when dup could operate on both file and - * socket descritors to avoid drawing unused socket support into the link. - */ +/* Dupicate a file descriptor using any value greater than or equal to minfd */ -#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 -EXTERN int file_dup(int fd); -#else -# define file_dup(fd) dup(fd) -#endif +EXTERN int file_dup(int fd, int minfd); /* fs_filedup2.c *************************************************************/ diff --git a/include/nuttx/net.h b/include/nuttx/net.h index efe897073f4a3b2c09f5c36456d2425f6c5ce769..db29524b66c181eeb3b9823f15cce3ba22be34f5 100644 --- a/include/nuttx/net.h +++ b/include/nuttx/net.h @@ -166,14 +166,10 @@ EXTERN int net_poll(int sockfd, struct pollfd *fds, boolean setup); /* net_dup.c *****************************************************************/ /* The standard dup() operation redirects operations on socket descriptors to - * this function (when both file and socket descriptors are supported) + * this function */ -#if CONFIG_NFILE_DESCRIPTOR > 0 -EXTERN int net_dup(int sockfd); -#else -# define net_dup(sockfd) dup(sockfd) -#endif +EXTERN int net_dup(int sockfd, int minsd); /* net_dup2.c ****************************************************************/ /* The standard dup2() operation redirects operations on socket descriptors to diff --git a/net/accept.c b/net/accept.c index a9701b2d5464af14b7ad25b826a4fdf623387e18..c2e64153c6420fb017dc0f3ec7a083939a1ce73b 100644 --- a/net/accept.c +++ b/net/accept.c @@ -318,7 +318,7 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) * (so that it cannot fail later) */ - newfd = sockfd_allocate(); + newfd = sockfd_allocate(0); if (newfd < 0) { err = ENFILE; diff --git a/net/net_dup.c b/net/net_dup.c index f4ee15abed3e4fc88d5413fc8f36d1298ba911d6..e935e4749744ad37550de956981443a9524621e7 100644 --- a/net/net_dup.c +++ b/net/net_dup.c @@ -49,12 +49,16 @@ #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + /**************************************************************************** * Global Functions ****************************************************************************/ /**************************************************************************** - * Function: net_dup OR dup + * Function: net_dup * * Description: * Clone a socket descriptor to an arbitray descriptor number. If file @@ -64,11 +68,7 @@ * ****************************************************************************/ -#if CONFIG_NFILE_DESCRIPTOR > 0 -int net_dup(int sockfd) -#else -int dup(int sockfd) -#endif +int net_dup(int sockfd, int minsd) { FAR struct socket *psock1 = sockfd_socket(sockfd); FAR struct socket *psock2; @@ -76,6 +76,22 @@ int dup(int sockfd) int err; int ret; + /* Make sure that the minimum socket descriptor is within the legal range. + * the minimum value we receive is relative to file descriptor 0; we need + * map it relative of the first socket descriptor. + */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + if (minsd >= CONFIG_NFILE_DESCRIPTORS) + { + minsd -= CONFIG_NFILE_DESCRIPTORS; + } + else + { + minsd = 0; + } +#endif + /* Lock the scheduler throughout the following */ sched_lock(); @@ -94,7 +110,7 @@ int dup(int sockfd) /* Allocate a new socket descriptor */ - sockfd2 = sockfd_allocate(); + sockfd2 = sockfd_allocate(minsd); if (sockfd2 < 0) { err = ENFILE; diff --git a/net/net_internal.h b/net/net_internal.h index 9afa408beef7ce0de907651aaeb8a962c397e07f..a403a269faf4910ab8ea31c75eac97bfe07ab378 100644 --- a/net/net_internal.h +++ b/net/net_internal.h @@ -144,7 +144,7 @@ extern "C" { /* net_sockets.c *************************************************************/ -EXTERN int sockfd_allocate(void); +EXTERN int sockfd_allocate(int minsd); EXTERN void sockfd_release(int sockfd); EXTERN FAR struct socket *sockfd_socket(int sockfd); diff --git a/net/net_sockets.c b/net/net_sockets.c index cda0c105e9322b0905dac90d72f130ff3b77dab2..3db69519d8a74a16e20754fbdfc84b3ef4fc47b9 100644 --- a/net/net_sockets.c +++ b/net/net_sockets.c @@ -1,7 +1,7 @@ /**************************************************************************** * net_sockets.c * - * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2007- 2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without @@ -192,7 +192,7 @@ int net_releaselist(FAR struct socketlist *list) return OK; } -int sockfd_allocate(void) +int sockfd_allocate(int minsd) { FAR struct socketlist *list; int i; @@ -205,14 +205,16 @@ int sockfd_allocate(void) /* Search for a socket structure with no references */ _net_semtake(list); - for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++) + for (i = minsd; i < CONFIG_NSOCKET_DESCRIPTORS; i++) { /* Are there references on this socket? */ + if (!list->sl_sockets[i].s_crefs) { /* No take the reference and return the index + an offset * as the socket descriptor. */ + memset(&list->sl_sockets[i], 0, sizeof(struct socket)); list->sl_sockets[i].s_crefs = 1; _net_semgive(list); diff --git a/net/net_vfcntl.c b/net/net_vfcntl.c index bf3e37d814e9579c4f9e93e84edf1c22440bdaf6..537a9031d5d7d335ad61a8306d6bc854706947e7 100644 --- a/net/net_vfcntl.c +++ b/net/net_vfcntl.c @@ -49,6 +49,10 @@ #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + /**************************************************************************** * Global Functions ****************************************************************************/ @@ -67,7 +71,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap) goto errout; } -#warning "fcntl() commands not yet implemented" +#warning "Most fcntl() commands not yet implemented" switch (cmd) { case F_DUPFD: @@ -81,6 +85,11 @@ int net_vfcntl(int sockfd, int cmd, va_list ap) * exec functions. */ + { + ret = net_dup(sockfd, va_arg(ap, int)); + } + break; + case F_GETFD: /* Get the file descriptor flags defined in <fcntl.h> that are associated * with the file descriptor fildes. File descriptor flags are associated diff --git a/net/socket.c b/net/socket.c index fddff2ccc7e6da1e46cd9699f6851174816a112c..f8de67f9e2951e815a371501812e443f25cdf199 100644 --- a/net/socket.c +++ b/net/socket.c @@ -126,7 +126,7 @@ int socket(int domain, int type, int protocol) /* Everything looks good. Allocate a socket descriptor */ - sockfd = sockfd_allocate(); + sockfd = sockfd_allocate(0); if (sockfd < 0) { err = ENFILE;