Standards
Standards / Extensions |
C or C++ |
Dependencies |
z/OS® UNIX |
both |
|
Format
#define _OPEN_SYS_SOCK_EXT2
#include <sys/socket.h>
int send_file(int *socket_ptr, struct sf_parms *sf_struct, int options);
General description
The send_file() function sends data from the file associated with
the open file handle over the connection associated with the socket.
The function takes the following arguments:
- socket_ptr
- A pointer to a socket file descriptor.
- sf_struct
- A pointer to a structure that contains variables needed by sendfile
- header information, file information, trailer information and results
of operation. See below for details.
- options
- Specifies one of the following options:
- SF_CLOSE
- Close the connection after the data has been successfully sent
or queued for transmission.
- SF_REUSE
- Prepare the socket for reuse after the data has been successfully
sent or queued for transmission and the existing connection closed.
Send_File Structure - sf_parms
Argument sf_struct points to a struct sf_parms that
contains the file descriptor, a header data buffer, and a trailer
data buffer.
The struct
sf_parms is defined in
<sys/sockets.h> and
contains the following elements:
- header_data
- Pointer to a buffer that contains header data which is to be
sent before the file data. It may be a NULL pointer if header_length is
zero.
- header_length
- Specifies the number of bytes in the header_data. It
must be set to zero to indicate that header data is not to be sent.
- file_descriptor
- File descriptor for a file that has been opened for read. This
is the descriptor for the file that contains the data to be transmitted.
- file_size
- The size, in bytes, of the file associated with file_descriptor.
This field is filled in by the system.
- file_offset
- Specifies the byte offset into the file from which to start
sending data.
- file_bytes
- Specifies the number of bytes from the file to be transmitted.
Setting file_bytes to -1 will transmit the entire file
from the offset. In this case the system will replace the -1
with (actual file size - file_offset). Setting file_bytes to
0 will result in no file data being transmitted and file_descriptor is
ignored. If file_descriptor is not a regular file it may
be necessary to supply a specific value for file_bytes unless
a normal End Of File (EOF) indication is expected from file_descriptor during
this operation or you simply want the operation to run forever transferring
bytes as they arrive.
- trailer_data
- Pointer to a buffer that contains trailer data which is to be
sent after the file data.
- trailer_length
- Specifies the number of bytes in the trailer_data.
- bytes_sent
- Number of bytes that were sent in this call to send_file().
If it takes multiple calls to send_file() to send all the data (due
to signal-handling) then this field contains the value for the last
call to send_file(), it is not a running total. This field is set
by the system.
The send_file() function attempts to write header_length bytes
from the buffer pointed to by header_data, followed by file_bytes from
the file associated with file_descriptor, followed by trailer_length bytes
from the buffer pointed to by trailer_data, over the connection
associated with the socket pointed to by socket_ptr.
As data is sent, the system will update elements in sf_struct so
that if the send_file() function is interrupted by a signal, the application
simply needs to reissue send_file()
If the application sets file_offset > the actual file
size, or file_bytes > (the actual file size - file_offset),
the return value will be -1 and errno set to EINVAL.
If O_NONBLOCK is set on the socket file descriptor, the function
may return -1 with errno set to EWOULDBLOCK or EAGAIN, or it may complete
before all the data is sent. If O_NONBLOCK is not set, send_file()
blocks until the requested data can be sent.
SF_CLOSE and SF_REUSE will only be effective
after all the data has been sent successfully.
If options = SF_REUSE, and socket reuse is
not supported, the system will close the socket and set the socket
pointed to by socket_ptr to -1. See Application usage for
details.
Application usage
send_file() is designed to work with accept_and_recv() to provide
an efficient file transfer capability for a connection oriented server
with short connection times and high connection rates.
On the first call to accept_and_recv(), it is recommended that
the application set the socket pointed to by accept_socket to -1.
This will cause the system to assign the accepting socket. On the
call to send_file(), if the application requests socket reuse (options = SF_REUSE)
and the system does not support it, the system will close the socket
pointed to by socket_ptr and will set the socket pointed
to by socket_ptr to -1. The application then passes
this value onto the next call to accept_and_recv() (by setting accept_socket = *socket_ptr).
To take full advantage of the performance improvements offered
by the accept_and_recv() and send_file() functions, a process/thread
model different from the one where a parent accepts in a loop and
spins off child process threads is needed. The parent/process thread
is eliminated. Multiple worker processes/threads are created, and
each worker process/thread then executes the accept_and_recv() and
send_file() functions in a loop. The performance benefits of accept_and_recv()
and send_file() include fewer buffer copies, recycled sockets, and
optimal scheduling.
Returned value
If successful, send_file() returns 0.
send_file() returns 1 if the request was interrupted by a signal,
or because a nonblocking descriptor would have blocked, while sending
data. Since the sf_parms structure is updated by the system
to account for the data that has been sent you can continue the operation
from where is was interrupted by recalling send_file() without changing
the sf_parms structure.
If unsuccessful, send_file() returns -1 and sets errno to
one of the following values:
- Error Code
- Description
- EACCES
- The calling process does not have the appropriate privileges.
- EAGAIN
- socket_ptr is in nonblocking mode and no data buffers are available
or the SO_SNDTIMEO timeout value was reached before buffers became
available.
- EBADF
- One of the following occurred:
- socket_ptr is not a valid descriptor or was not open
for writing.
- file_descriptor is not a valid descriptor or was not
open for reading.
- ECONNABORTED
- A connection has been aborted.
- ECONNRESET
- A connection has been forcibly closed by a peer.
- EFAULT
- The data buffer pointed to by socket_ptr, file_size, header_data,
or trailer_data was not valid.
- EINTR
- send_file() was interrupted by a signal that was caught before
any data was sent.
- EINVAL
- The value specified by options is not valid.
- EIO
- An I/O error occurred.
- EMSGSIZE
- The message is too large to be sent all at once, as the socket
requires.
- ENETDOWN
- The local interface to reach the destination is unknown.
- ENETUNREACH
- No route to the destination is present.
- ENOBUFS
- No buffer space is available.
- ENOMEM
- There was insufficient memory available to complete the operation.
- ENOSR
- There were insufficient STREAMS resources available for the
operation to complete.
- ENOSYS
- This function is not supported in the current environment.
- ENOTCONN
- The socket is not connected.
- ENOTSOCK
- The file descriptor pointed to by the socket_ptr argument
does not refer to a socket.
- EPIPE
- The socket is shutdown for writing, or the socket is in connection
mode and is no longer connected.
- EWOULDBLOCK
- socket_ptr is in nonblocking mode and no data buffers
are available or the SO_SNDTIMEO timeout value was reached before
buffers became available.