From 17553d10657c2a395a2ab1f7d6629453fc5ed342 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 19 Jul 2009 00:14:46 +0000 Subject: Add fcntl(F_DUPFD) git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1995 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/net/accept.c | 2 +- nuttx/net/net_dup.c | 30 +++++++++++++++++++++++------- nuttx/net/net_internal.h | 2 +- nuttx/net/net_sockets.c | 8 +++++--- nuttx/net/net_vfcntl.c | 11 ++++++++++- nuttx/net/socket.c | 2 +- 6 files changed, 41 insertions(+), 14 deletions(-) (limited to 'nuttx/net') diff --git a/nuttx/net/accept.c b/nuttx/net/accept.c index a9701b2d5..c2e64153c 100644 --- a/nuttx/net/accept.c +++ b/nuttx/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/nuttx/net/net_dup.c b/nuttx/net/net_dup.c index f4ee15abe..e935e4749 100644 --- a/nuttx/net/net_dup.c +++ b/nuttx/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/nuttx/net/net_internal.h b/nuttx/net/net_internal.h index 9afa408be..a403a269f 100644 --- a/nuttx/net/net_internal.h +++ b/nuttx/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/nuttx/net/net_sockets.c b/nuttx/net/net_sockets.c index cda0c105e..3db69519d 100644 --- a/nuttx/net/net_sockets.c +++ b/nuttx/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 * * 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/nuttx/net/net_vfcntl.c b/nuttx/net/net_vfcntl.c index bf3e37d81..537a9031d 100644 --- a/nuttx/net/net_vfcntl.c +++ b/nuttx/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 that are associated * with the file descriptor fildes. File descriptor flags are associated diff --git a/nuttx/net/socket.c b/nuttx/net/socket.c index fddff2ccc..f8de67f9e 100644 --- a/nuttx/net/socket.c +++ b/nuttx/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; -- cgit v1.2.3