diff options
-rw-r--r-- | apps/netutils/ftpc/ftpc_getfile.c | 44 | ||||
-rw-r--r-- | apps/netutils/ftpc/ftpc_putfile.c | 42 | ||||
-rw-r--r-- | apps/netutils/ftpc/ftpc_socket.c | 2 | ||||
-rw-r--r-- | apps/netutils/ftpc/ftpc_transfer.c | 35 | ||||
-rw-r--r-- | nuttx/ChangeLog | 7 | ||||
-rw-r--r-- | nuttx/net/recvfrom.c | 69 |
6 files changed, 62 insertions, 137 deletions
diff --git a/apps/netutils/ftpc/ftpc_getfile.c b/apps/netutils/ftpc/ftpc_getfile.c index 8a60c514b..366351636 100644 --- a/apps/netutils/ftpc/ftpc_getfile.c +++ b/apps/netutils/ftpc/ftpc_getfile.c @@ -167,31 +167,6 @@ static int ftpc_recvinit(struct ftpc_session_s *session, FAR const char *path, } /**************************************************************************** - * Name: ftpc_waitinput - * - * Description: - * Wait to receive data. - * - ****************************************************************************/ - -static int ftpc_waitinput(FAR struct ftpc_session_s *session) -{ - int ret; - do { - ret = ftpc_waitdata(session, session->data.instream, true); - if (ret == -1) { - if (errno == EINTR) - { - FTPC_SET_INTERRUPT(session); - } - return ERROR; - } - } while(ret == 0); - - return OK; -} - -/**************************************************************************** * Name: ftpc_recvbinary * * Description: @@ -219,16 +194,6 @@ static int ftpc_recvbinary(FAR struct ftpc_session_s *session, for (;;) { - /* Wait for input on the socket */ - - ret = ftpc_waitinput(session); - if (ret != OK) - { - nvdbg("ftpc_waitinput() failed\n"); - err = EIO; - goto errout_with_buf; - } - /* Read the data from the socket */ nread = fread(buf, sizeof(char), CONFIG_FTP_BUFSIZE, rinstream); @@ -451,15 +416,6 @@ int ftpc_recvtext(FAR struct ftpc_session_s *session, while ((ch = fgetc(rinstream)) != EOF) { - /* Wait for input on the socket */ - - ret = ftpc_waitinput(session); - if (ret != OK) - { - nvdbg("ftpc_waitinput() failed\n"); - break; - } - /* Is it a carriage return? Compress \r\n to \n */ if (ch == '\r') diff --git a/apps/netutils/ftpc/ftpc_putfile.c b/apps/netutils/ftpc/ftpc_putfile.c index e008da3b1..bc20853d7 100644 --- a/apps/netutils/ftpc/ftpc_putfile.c +++ b/apps/netutils/ftpc/ftpc_putfile.c @@ -72,30 +72,6 @@ ****************************************************************************/ /**************************************************************************** - * Name: ftpc_waitoutput - * - * Description: - * Wait to send data. - * - ****************************************************************************/ - -static int ftpc_waitoutput(FAR struct ftpc_session_s *session) -{ - int ret; - - do - { - ret = ftpc_waitdata(session, session->data.outstream, false); - if (ret < 0) - { - return ERROR; - } - } - while(ret == 0); - return OK; -} - -/**************************************************************************** * Name: ftpc_sendbinary * * Description: @@ -129,15 +105,6 @@ static int ftpc_sendbinary(FAR struct ftpc_session_s *session, break; } - /* Wait to make sure that we send the data without blocking */ - - ret = ftpc_waitoutput(session); - if (ret != OK) - { - ret = ERROR; - break; - } - /* Send the data */ nwritten = fwrite(buf, sizeof(char), nread, routstream); @@ -174,15 +141,8 @@ static int ftpc_sendtext(FAR struct ftpc_session_s *session, /* Write characters one at a time. */ - while((c = fgetc(linstream)) != EOF) + while ((c = fgetc(linstream)) != EOF) { - /* Make sure that we can send the character without blocking */ - - if (ftpc_waitoutput(session) != 0) - { - break; - } - /* If it is a newline, send a carriage return too */ if (c == '\n') diff --git a/apps/netutils/ftpc/ftpc_socket.c b/apps/netutils/ftpc/ftpc_socket.c index d245c812d..4ec022bd0 100644 --- a/apps/netutils/ftpc/ftpc_socket.c +++ b/apps/netutils/ftpc/ftpc_socket.c @@ -185,8 +185,8 @@ int ftpc_sockconnect(struct ftpc_socket_s *sock, struct sockaddr_in *addr) ndbg("ftpc_sockgetsockname() failed: %d\n", errno); return ERROR; } - sock->connected = true; + sock->connected = true; return OK; } diff --git a/apps/netutils/ftpc/ftpc_transfer.c b/apps/netutils/ftpc/ftpc_transfer.c index 4dfa6d47b..f808e67fb 100644 --- a/apps/netutils/ftpc/ftpc_transfer.c +++ b/apps/netutils/ftpc/ftpc_transfer.c @@ -43,7 +43,6 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> -#include <poll.h> #include <signal.h> #include <ctype.h> #include <errno.h> @@ -289,8 +288,8 @@ int ftpc_xfrinit(FAR struct ftpc_session_s *session) /* Configure the data socket */ ftpc_sockgetsockname(&session->cmd, &addr); - memcpy(&addr.sin_addr, addrport, (size_t)4); - memcpy(&addr.sin_port, addrport+4, (size_t)2); + memcpy(&addr.sin_addr, addrport, 4); + memcpy(&addr.sin_port, addrport+4, 2); /* Connect the data socket */ @@ -462,36 +461,6 @@ int ftpc_xfrabort(FAR struct ftpc_session_s *session, FAR FILE *stream) } /**************************************************************************** - * Name: ftpc_waitdata - * - * Description: - * Wait for dta to be available on the provided stream. - * - ****************************************************************************/ - -int ftpc_waitdata(FAR struct ftpc_session_s *session, FAR FILE *stream, bool rdwait) -{ - FAR struct pollfd fds; - int ret; - - /* Check the stream to see if it has input OR is ready for output */ - - fds.fd = fileno(stream); - fds.events = rdwait ? POLLIN : POLLOUT; - ret = poll(&fds, 1, 10*1000); - if (ret < 0) - { - if (errno == EINTR) - { - return OK; - } - return ERROR; - } - - return ret; -} - -/**************************************************************************** * Name: ftpc_timeout * * Description: diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 6bfbedeef..f0d87e379 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -1796,4 +1796,11 @@ testing of the FTP client shell. * fd/fs_fdopen.c and net/net_checksd.c: Add support so that fdopen may be used with socket descriptors. + * net/recvfrom.c: Fix an error found in receiving small files via FTP: + The small file is received a buffered in the readahead buffer, then the + socket is disconnected. When the app calls recvfrom, the socket is + already disconnected and the buffered data is stranded. Now, recvfrom + will continue to return success after the socket is disconnected until + the readahead buffer is drained. + diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index 335e2b322..d974b85cf 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -682,6 +682,13 @@ static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len, pstate->rf_starttime = clock_systimer(); #endif } + +/* The only uninitialization that has to be performed is destroying the + * semaphore. + */ + +#define recvfrom_uninit(s) sem_destroy(&(s)->rf_sem) + #endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */ /**************************************************************************** @@ -706,10 +713,6 @@ static ssize_t recvfrom_result(int result, struct recvfrom_s *pstate) { int save_errno = errno; /* In case something we do changes it */ - /* Release semaphore in the state structure */ - - sem_destroy(&pstate->rf_sem); - /* Check for a error/timeout detected by the interrupt handler. Errors are * signaled by negative errno values for the rcv length */ @@ -783,8 +786,7 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, ret = uip_udpconnect(conn, NULL); if (ret < 0) { - uip_unlock(save); - return ret; + goto errout_with_state; } /* Set up the callback in the connection */ @@ -814,7 +816,6 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, uip_udpdisable(conn); uip_udpcallbackfree(conn, state.rf_cb); - uip_unlock(save); ret = recvfrom_result(ret, &state); } else @@ -822,6 +823,9 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, ret = -EBUSY; } +errout_with_state: + uip_unlock(save); + recvfrom_uninit(&state); return ret; } #endif /* CONFIG_NET_UDP */ @@ -859,15 +863,6 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, uip_lock_t save; int ret = OK; - /* Verify that the SOCK_STREAM has been connected */ - - if (!_SS_ISCONNECTED(psock->s_flags)) - { - /* The SOCK_STREAM must be connected in order to receive */ - - return -ENOTCONN; - } - /* Initialize the state structure. This is done with interrupts * disabled because we don't want anything to happen until we * are ready. @@ -876,11 +871,47 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, save = uip_lock(); recvfrom_init(psock, buf, len, infrom, &state); + /* Handle any any TCP data already buffered in a read-ahead buffer. NOTE + * that there may be read-ahead data to be retrieved even after the + * socket has been disconnected. + */ + #if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 + recvfrom_readahead(&state); +#endif - /* Handle any any TCP data already buffered in a read-ahead buffer. */ + /* Verify that the SOCK_STREAM has been or still is connected */ - recvfrom_readahead(&state); + if (!_SS_ISCONNECTED(psock->s_flags)) + { + /* Was any data transferred from the readahead buffer after we were + * disconnected? + */ + +#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 + if (state.rf_recvlen <= 0) + { + /* Nothing was received. The SOCK_STREAM must be re-connected in + * order to receive an additional data. + */ + + ret = -ENOTCONN; + } + else + { + /* The socket is disconnected, but there is data in the read-ahead + * buffer. The return value is the number of bytes read from the + * read-ahead buffer */ + + ret = state.rf_recvlen; + } +#else + /* The SOCK_STREAM must be connected inorder to receive data. */ + + ret = -ENOTCONN; +#endif + } + else /* In general, this uIP-based implementation will not support non-blocking * socket operations... except in a few cases: Here for TCP receive with read-ahead @@ -888,6 +919,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, * if no data was obtained from the read-ahead buffers. */ +#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 if (_SS_ISNONBLOCK(psock->s_flags)) { /* Return OK if something was received; EGAIN if not */ @@ -944,6 +976,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, } uip_unlock(save); + recvfrom_uninit(&state); return ret; } #endif /* CONFIG_NET_TCP */ |