Add fcntl(F_DUPFD)

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1995 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-07-19 00:14:46 +00:00
parent e68c54fea0
commit 297cb5e256
14 changed files with 77 additions and 59 deletions

View File

@ -47,15 +47,8 @@
#include <nuttx/fs.h> #include <nuttx/fs.h>
#include "fs_internal.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 dup(int fildes)
{ {
int ret = OK;
/* Check the range of the descriptor to see if we got a file or a socket /* Check the range of the descriptor to see if we got a file or a socket
* descriptor. */ * 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? */ /* 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)) if ((unsigned int)fildes < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
{ {
/* Yes.. dup the socket descriptor */ /* Yes.. dup the socket descriptor */
return net_dup(fildes); ret = net_dup(fildes, CONFIG_NFILE_DESCRIPTORS);
} }
else else
#endif
{ {
/* No.. then it is a bad descriptor number */ /* No.. then it is a bad descriptor number */
errno = EBADF; errno = EBADF;
return ERROR; ret = ERROR;
} }
} }
else return ret;
{
/* Its a valid file descriptor.. dup the file descriptor */
return file_dup(fildes);
}
} }
#endif /* CONFIG_NFILE_DESCRIPTORS > 0 ... */

View File

@ -94,6 +94,11 @@ static inline int file_vfcntl(int fildes, int cmd, va_list ap)
* exec functions. * exec functions.
*/ */
{
ret = file_dup(fildes, va_arg(ap, int));
}
break;
case F_GETFD: case F_GETFD:
/* Get the file descriptor flags defined in <fcntl.h> that are associated /* Get the file descriptor flags defined in <fcntl.h> that are associated
* with the file descriptor fildes. File descriptor flags are associated * with the file descriptor fildes. File descriptor flags are associated

View File

@ -40,7 +40,6 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
#include <sched.h> #include <sched.h>
#include <errno.h> #include <errno.h>
@ -76,11 +75,7 @@
* *
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 int file_dup(int fildes, int minfd)
int file_dup(int fildes)
#else
int dup(int fildes)
#endif
{ {
FAR struct filelist *list; FAR struct filelist *list;
int fildes2; int fildes2;
@ -110,7 +105,8 @@ int dup(int fildes)
fildes2 = files_allocate(list->fl_files[fildes].f_inode, fildes2 = files_allocate(list->fl_files[fildes].f_inode,
list->fl_files[fildes].f_oflags, list->fl_files[fildes].f_oflags,
list->fl_files[fildes].f_pos); list->fl_files[fildes].f_pos,
minfd);
if (fildes2 < 0) if (fildes2 < 0)
{ {
errno = EMFILE; errno = EMFILE;

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* fs/fs_files.c * 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> * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* *
* Redistribution and use in source and binary forms, with or without * 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. * 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; FAR struct filelist *list;
int i; int i;
@ -370,7 +371,7 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos)
if (list) if (list)
{ {
_files_semtake(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) if (!list->fl_files[i].f_inode)
{ {

View File

@ -225,7 +225,7 @@ EXTERN void inode_release(FAR struct inode *inode);
/* fs_files.c ****************************************************************/ /* fs_files.c ****************************************************************/
EXTERN void weak_function files_initialize(void); 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 int files_close(int filedes);
EXTERN void files_release(int filedes); EXTERN void files_release(int filedes);

View File

@ -140,7 +140,7 @@ int open(const char *path, int oflags, ...)
/* Associate the inode with a file structure */ /* Associate the inode with a file structure */
fd = files_allocate(inode, oflags, 0); fd = files_allocate(inode, oflags, 0, 0);
if (fd < 0) if (fd < 0)
{ {
ret = EMFILE; ret = EMFILE;

View File

@ -344,15 +344,9 @@ EXTERN int files_dup(FAR struct file *filep1, FAR struct file *filep2);
/* fs_filedup.c **************************************************************/ /* fs_filedup.c **************************************************************/
/* This alternative naming is used when dup could operate on both file and /* Dupicate a file descriptor using any value greater than or equal to minfd */
* socket descritors to avoid drawing unused socket support into the link.
*/
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 EXTERN int file_dup(int fd, int minfd);
EXTERN int file_dup(int fd);
#else
# define file_dup(fd) dup(fd)
#endif
/* fs_filedup2.c *************************************************************/ /* fs_filedup2.c *************************************************************/

View File

@ -166,14 +166,10 @@ EXTERN int net_poll(int sockfd, struct pollfd *fds, boolean setup);
/* net_dup.c *****************************************************************/ /* net_dup.c *****************************************************************/
/* The standard dup() operation redirects operations on socket descriptors to /* 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, int minsd);
EXTERN int net_dup(int sockfd);
#else
# define net_dup(sockfd) dup(sockfd)
#endif
/* net_dup2.c ****************************************************************/ /* net_dup2.c ****************************************************************/
/* The standard dup2() operation redirects operations on socket descriptors to /* The standard dup2() operation redirects operations on socket descriptors to

View File

@ -318,7 +318,7 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
* (so that it cannot fail later) * (so that it cannot fail later)
*/ */
newfd = sockfd_allocate(); newfd = sockfd_allocate(0);
if (newfd < 0) if (newfd < 0)
{ {
err = ENFILE; err = ENFILE;

View File

@ -49,12 +49,16 @@
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Global Functions * Global Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: net_dup OR dup * Function: net_dup
* *
* Description: * Description:
* Clone a socket descriptor to an arbitray descriptor number. If file * 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, int minsd)
int net_dup(int sockfd)
#else
int dup(int sockfd)
#endif
{ {
FAR struct socket *psock1 = sockfd_socket(sockfd); FAR struct socket *psock1 = sockfd_socket(sockfd);
FAR struct socket *psock2; FAR struct socket *psock2;
@ -76,6 +76,22 @@ int dup(int sockfd)
int err; int err;
int ret; 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 */ /* Lock the scheduler throughout the following */
sched_lock(); sched_lock();
@ -94,7 +110,7 @@ int dup(int sockfd)
/* Allocate a new socket descriptor */ /* Allocate a new socket descriptor */
sockfd2 = sockfd_allocate(); sockfd2 = sockfd_allocate(minsd);
if (sockfd2 < 0) if (sockfd2 < 0)
{ {
err = ENFILE; err = ENFILE;

View File

@ -144,7 +144,7 @@ extern "C" {
/* net_sockets.c *************************************************************/ /* net_sockets.c *************************************************************/
EXTERN int sockfd_allocate(void); EXTERN int sockfd_allocate(int minsd);
EXTERN void sockfd_release(int sockfd); EXTERN void sockfd_release(int sockfd);
EXTERN FAR struct socket *sockfd_socket(int sockfd); EXTERN FAR struct socket *sockfd_socket(int sockfd);

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* net_sockets.c * 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> * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -192,7 +192,7 @@ int net_releaselist(FAR struct socketlist *list)
return OK; return OK;
} }
int sockfd_allocate(void) int sockfd_allocate(int minsd)
{ {
FAR struct socketlist *list; FAR struct socketlist *list;
int i; int i;
@ -205,14 +205,16 @@ int sockfd_allocate(void)
/* Search for a socket structure with no references */ /* Search for a socket structure with no references */
_net_semtake(list); _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? */ /* Are there references on this socket? */
if (!list->sl_sockets[i].s_crefs) if (!list->sl_sockets[i].s_crefs)
{ {
/* No take the reference and return the index + an offset /* No take the reference and return the index + an offset
* as the socket descriptor. * as the socket descriptor.
*/ */
memset(&list->sl_sockets[i], 0, sizeof(struct socket)); memset(&list->sl_sockets[i], 0, sizeof(struct socket));
list->sl_sockets[i].s_crefs = 1; list->sl_sockets[i].s_crefs = 1;
_net_semgive(list); _net_semgive(list);

View File

@ -49,6 +49,10 @@
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Global Functions * Global Functions
****************************************************************************/ ****************************************************************************/
@ -67,7 +71,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
goto errout; goto errout;
} }
#warning "fcntl() commands not yet implemented" #warning "Most fcntl() commands not yet implemented"
switch (cmd) switch (cmd)
{ {
case F_DUPFD: case F_DUPFD:
@ -81,6 +85,11 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
* exec functions. * exec functions.
*/ */
{
ret = net_dup(sockfd, va_arg(ap, int));
}
break;
case F_GETFD: case F_GETFD:
/* Get the file descriptor flags defined in <fcntl.h> that are associated /* Get the file descriptor flags defined in <fcntl.h> that are associated
* with the file descriptor fildes. File descriptor flags are associated * with the file descriptor fildes. File descriptor flags are associated

View File

@ -126,7 +126,7 @@ int socket(int domain, int type, int protocol)
/* Everything looks good. Allocate a socket descriptor */ /* Everything looks good. Allocate a socket descriptor */
sockfd = sockfd_allocate(); sockfd = sockfd_allocate(0);
if (sockfd < 0) if (sockfd < 0)
{ {
err = ENFILE; err = ENFILE;