Syntax
#include <sys/types.h>
#include <sys/socket.h>
int send_file(int *socket_descriptor,
struct sf_parms *sf_struct,
int flags)
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.
- 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 daa, 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:
- The descriptor pointed to by the socket_descriptor parameter is not a valid socket
descriptor.
- The file_descriptor parameter is not valid for this operation. The specified
descriptor is incorrect, does not refer to an open file, or refers to a
file that was only open for writing.
- [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:
- A NULL pointer was specified for the sf_struct parameter
- The file_offset parameter specified a negative value.
- The file_offset parameter specified a value that was greater than the
file size.
- The file_bytes parameter would have resulted in a read operation beyond
the end of the file.
- The flags parameter specified a value that was not valid.
- [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.
This error code indicates one of the following:
- 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 or AF_UNIX and a socket type of
SOCK_STREAM.
-
The O_NONBLOCK option is set for the descriptor pointed to by the socket_descriptor
parameter. Non-blocking is not supported on the send_file() function.
- [EOVERFLOW]
- Object is too large to process.
This error code indicates one of the following:
- The size of the file associated with file_descriptor
parameter is greater than 2 GB minus 1 byte.
- The total number of bytes to be sent, header_length + file_bytes +
trailer_length, is greater than 4 GB minus 1, the largest value that can be
stored in the bytes_sent output field.
- [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
- 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 or AF_UNIX 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.
-
Non-blocking mode is not supported for this function. If O_NONBLOCK
is set on the descriptor pointed to by the socket_descriptor parameter, -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:
- There are secondary threads active 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
- QLANSrv
-
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. For
additional information, see .
-
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 AS/400 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.
|
-
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