1
0
Fork 0
forked from nuttx/nuttx-update

net/tcp: tcp_sendfile need restore the file location at the end

quote from https://man7.org/linux/man-pages/man2/sendfile.2.html:
If offset is not NULL, then it points to a variable holding the
file offset from which sendfile() will start reading data from
in_fd.  When sendfile() returns, this variable will be set to the
offset of the byte following the last byte that was read.  If
offset is not NULL, then sendfile() does not modify the file
offset of in_fd; otherwise the file offset is adjusted to reflect
the number of bytes read from in_fd.
If offset is NULL, then data will be read from in_fd starting at
the file offset, and the file offset will be updated by the call.

The change also align with the implementation at:
libs/libc/misc/lib_sendfile.c

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: I607944f40b04f76731af7b205dcd319b0637fa04
This commit is contained in:
Xiang Xiao 2021-07-11 21:00:59 +08:00 committed by David Sidrane
parent 2e43815c92
commit 906cb8b0f4

View file

@ -451,6 +451,7 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
{
FAR struct tcp_conn_s *conn;
struct sendfile_s state;
off_t startpos;
int ret;
/* If this is an un-connected socket, then return ENOTCONN */
@ -497,6 +498,14 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
}
#endif /* CONFIG_NET_ARP_SEND || CONFIG_NET_ICMPv6_NEIGHBOR */
/* Get the current file position. */
startpos = file_seek(infile, 0, SEEK_CUR);
if (startpos < 0)
{
return startpos;
}
/* Initialize the state structure. This is done with the network
* locked because we don't want anything to happen until we are
* ready.
@ -509,13 +518,13 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
* priority inheritance enabled.
*/
nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */
nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */
nxsem_set_protocol(&state.snd_sem, SEM_PRIO_NONE);
state.snd_sock = psock; /* Socket descriptor to use */
state.snd_foffset = offset ? *offset : 0; /* Input file offset */
state.snd_flen = count; /* Number of bytes to send */
state.snd_file = infile; /* File to read from */
state.snd_sock = psock; /* Socket descriptor to use */
state.snd_foffset = offset ? *offset : startpos; /* Input file offset */
state.snd_flen = count; /* Number of bytes to send */
state.snd_file = infile; /* File to read from */
/* Allocate resources to receive a callback */
@ -581,10 +590,34 @@ errout_datacb:
tcp_callback_free(conn, state.snd_datacb);
errout_locked:
nxsem_destroy(&state.snd_sem);
net_unlock();
/* Return the current file position */
if (offset)
{
/* Use lseek to get the current file position */
off_t curpos = file_seek(infile, 0, SEEK_CUR);
if (curpos < 0)
{
return curpos;
}
/* Return the current file position */
*offset = curpos;
/* Use lseek again to restore the original file position */
startpos = file_seek(infile, startpos, SEEK_SET);
if (startpos < 0)
{
return startpos;
}
}
if (ret < 0)
{
return ret;