send_file()--Send a File over a Socket Connection
Syntax
#include <sys/types.h> #include <sys/socket.h> int send_file(int *socket_descriptor, struct sf_parms *sf_struct, int flags)
Service Program Name: QSOSRV1
Default Public Authority: *USE
Threadsafe: Conditional; see Usage Notes.
The send_file() function is used to send the contents of an open file over an existing socket connection.
The send_file() API is a combination of the IFS read() and the sockets send() and close() APIs. Socket applications that transmit a file over a socket connection can, under certain circumstances, obtain improved performance by using send_file().
Parameters
- socket_descriptor
- (Input/Output) A pointer to the socket descriptor that is to be written
to.
- sf_struct
- (Input/Output) A pointer to the send_file structure that contains the
following:
- The header buffer and length
- The file descriptor, the offset into the file, the file size, and number of
bytes to send from the file
- The trailer buffer and length
- The number of bytes of data that were sent
The structure pointed to by the sf_struct parameter is defined in <sys/socket.h>.
struct sf_parms { void *header_data; size_t header_length; int file_descriptor; size_t file_size; off_t file_offset; ssize_t file_bytes; void *trailer_data; size_t trailer_length; size_t bytes_sent; }
header_data (Input/Output) A pointer to a buffer that contains data to be sent before the file data is sent.
header_length (Input/Output) The length in bytes of header_data.
file_descriptor (Input) The file descriptor for a file that has been opened for read access. This is the descriptor for the file that contains the data to be transmitted. This field is ignored if the file_bytes field is set to 0.
file_size (Output) The size in bytes of the file associated with file_descriptor.
file_offset (Input/Output) The byte offset into the file from which to start sending data. Specify a value of 0 to start sending data from the start of the file. If a negative value is passed in, send_file() API will return with -1 and the errno will be set to EINVAL.
file_bytes (Input/Output) The number of bytes from the file to be transmitted. Set the file_bytes field to -1 to transmit all of the data from the file_offset position in the file to the end of the file. If the file_bytes field is set to 0, no data from the file will be transmitted.
trailer_data (Input/Output) A pointer to a buffer that contains data to be sent after the file data is sent.
trailer_length (Input/Output) The length in bytes of trailer_data.
bytes_sent (Output) The number of bytes that have been successfully sent.
- The header buffer and length
- flags
- (Input) A flag value that controls what is done with the socket connection
after the data has been transmitted. The flags value is either zero or
it is one of the following constants:
SF_CLOSE After the header_data, file data, and trailer_data have been successfully sent, the connection and the socket descriptor are closed. The descriptor that is pointed to by the socket_descriptor parameter is set to -1 before the send_file() API returns to the application. SF_REUSE After the header_data, file data, and trailer_data have been successfully sent, the connection is closed. If socket reuse is supported, the descriptor that is pointed to by the socket_descriptor parameter is reset. If socket reuse is not supported, the descriptor that is pointed to by the socket_descriptor parameter is closed and set to -1.
Authorities
No authorization is required.
Return Value
send_file() returns an integer. Possible values are:
- -1 (unsuccessful call) Check errno for additional information
- 0 (successful call) All of the data has been successfully sent
- 1 (interrupted call) The command was interrupted while sending data
Error Conditions
When send_file() fails, errno can be set to one of the following:
[EACCES] | Permission denied.
An attempt was made to access an object in a way forbidden by its object access permissions. A thread does not have access to the specified file, directory, component, or path. If you are accessing a remote file through the Network File System, update operations to file permissions at the server are not reflected at the client until updates to data that is stored locally by the Network File System takes place. (Several options on the Add Mounted File System (ADDMFS) command determine the time between refresh operations of local data.) Access to a remote file may also fail due to different mappings of user IDs (UID) or group IDs (GID) on the local and remote systems. |
[EBADF] | Descriptor not valid.
This error code indicates one of the following:
|
[ECONVERT] | Conversion error. |
[EFAULT] | Bad address.
The system detected an address that was not valid while attempting to access the socket_descriptor or one of the fields in the send_file structure. |
[EINTR] | Interrupted function call. |
[EINVAL] | Parameter not valid.
This error code indicates one of the following:
|
[EIO] | Input/output error. |
[ENOBUFS] | There is not enough buffer space for the
requested operation. |
[ENOTCONN] | Requested operation requires a connection. |
[ENOTSAFE] | Function is not allowed in a job that is running
with multiple threads. |
[ENOTSOCK] | The specified descriptor does not reference a
socket. |
[EOPNOTSUPP] | Operation not supported.
The socket_descriptor parameter references a socket that does not support the send_file() function. The send_file() function is only valid on sockets that have an address family of AF_INET, AF_INET6, AF_UNIX, or AF_UNIX_CCSID and a socket type of SOCK_STREAM. |
[EOVERFLOW] | Object is too large to process.
This error code indicates one of the following:
|
[EPIPE] | Broken pipe. |
[EUNATCH] | The protocol required to support the specified
address family is not available at this time. |
[EUNKNOWN] | Unknown system state. |
Error Messages
Message ID | Error Message Text |
---|---|
CPE3418 E | Possible APAR condition or hardware failure. |
CPF3CF2 E | Error(s) occurred during running of &1 API. |
CPF9872 E | Program or service program &1 in library &2 ended. Reason code &3. |
CPFA081 E | Unable to set return value or error code. |
CPFA0D4 E | File system error occurred. |
Usage Notes
- The send_file() function is only valid on sockets that have an
address family of AF_INET, AF_INET6, AF_UNIX, or AF_UNIX_CCSID and a
socket type of SOCK_STREAM. If the descriptor pointed to by the
socket_descriptor parameter does not have the correct address family
and socket type, -1 is returned and the errno value is set to
EOPNOTSUPP.
- This function will fail with error code [ENOTSAFE] when all the following
conditions are true:
- Where multiple threads exist in the job.
- The object on which this function is operating resides in a file system
that is not threadsafe. Only the following file systems are threadsafe for this
function:
- Root
- QOpenSys
- User-defined
- QNTC
- QSYS.LIB
- QOPT
- Network File System
- QFileSvr.400
- Where multiple threads exist in the job.
- The file_offset parameter is used to specify a base zero location
in the file referenced by the file_descriptor parameter. If the
file_bytes parameter is set to a value of 1 and the
file_offset parameter is set to a value of 0, the first byte from the
file is sent. If the file_offset parameter is set to a value of 1, the
second byte from the file is sent.
- An application that uses the send_file() API may specify the
O_SHARE_RDONLY or the O_SHARE_NONE option on the open() call when the
file represented by file_descriptor is first opened. These options
prevent other jobs or threads on the system from updating the file while it is
being transmitted.
- If the O_TEXTDATA option was specified on the open() call when the
file represented by file_descriptor was first opened, the data is sent
from the file assuming it is in textual form. The data is converted from the
code page of the file to the code page of the application, job, or system as
follows:
- When reading from a true stream file, any line-formatting characters (such
as carriage return, tab, and end-of-file) are just converted from one code page
to another.
- When reading from record files that are being used as stream files, end-of-line characters are added to the end of the data in each record.
If O_TEXTDATA was not specified on the open() call, the data is sent from the file without conversion.
Regardless of whether or not O_TEXTDATA was specified on the open() call, the header_data and trailer_data are not translated. It is the application's responsibility to translate the header_data and trailer_data to the correct code page before calling send_file(). The send_file() function will not translate the data buffers pointed to by the header_data and trailer_data parameters prior to sending them.
Note: The ability to do code-page translation is an IBM® i-specific extension to the send_file() API. The overhead to translate the file will have an effect on the performance of the send_file() API.
- When reading from a true stream file, any line-formatting characters (such
as carriage return, tab, and end-of-file) are just converted from one code page
to another.
- The send_file() function attempts to write header_length
from the buffer pointed to by header_data, followed by
file_bytes from the file associated with file_descriptor,
followed by trailer_length from the buffer pointed to by
trailer_data, over the connection associated with
socket_descriptor. As the data is sent, the API will update the
variables in the sf_parms structure so that if the send_file() API is
interrupted by a signal, the application simply needs to reissue the
send_file() call using the same parameters.
Note: The value that is passed in for the flags parameter is ignored if the send_file() API is interrupted by a signal.
- When you develop in C-based languages and this function is compiled with _LARGE_FILES defined, it will be mapped to send_file64(). Note that the type of the sf_struct parameter, struct sf_parms *, also will be mapped to type struct sf_parms64 *.
Related Information
- accept_and_recv()--Wait for Connection Request
and Receive the First Message That Was Sent
- close()--Close File or Socket Descriptor
- open()--Open File
- send()--Send Data
API introduced: V4R3