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 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 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:


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.

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:

  • 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

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

  1. 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.

  2. This function will fail with error code [ENOTSAFE] when all the following conditions are true:
  3. 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.

  4. 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.

  5. 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:

    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.

  6. 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.

  7. 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



API introduced: V4R3

[ Back to top | UNIX-Type APIs | APIs by category ]