send_file Subroutine

Purpose

Sends the contents of a file through a socket.

Library

Standard C Library (libc.a)

Syntax

#include < sys/socket.h >

ssize_t send_file(Socket_p, sf_iobuf, flags)

int * Socket_p;
struct sf_parms * sf_iobuf;
uint_t  flags;

Description

The send_file subroutine sends data from the opened file specified in the sf_iobuf parameter, over the connected socket pointed to by the Socket_p parameter.

Note: Currently, the send_file only supports the TCP/IP protocol (SOCK_STREAM socket in AF_INET). An error will be returned when this function is used on any other types of sockets.

Parameters

Item Description
Socket_p Points to the socket descriptor of the socket which the file will be sent to.
Note: This is different from most of the socket functions.
sf_iobuf Points to a sf_parms structure defined as follows:
/*
 * Structure for the send_file system call
 */
#ifdef __64BIT__
#define SF_INT64(x)     int64_t x;
#define SF_UINT64(x)    uint64_t x;
#else
#ifdef _LONG_LONG
#define SF_INT64(x)     int64_t x;
#define SF_UINT64(x)    uint64_t x;
#else
#define SF_INT64(x)     int filler_##x; int x;
#define SF_UINT64(x)    int filler_##x; uint_t x;
#endif
#endif

struct sf_parms {
    /* --------- header parms ---------- */
    void      *header_data;         /* Input/Output. Points to header buf */
    uint_t      header_length;      /* Input/Output. Length of the header */
    /* --------- file parms ------------ */
    int       file_descriptor;      /* Input. File descriptor of the file */
    SF_UINT64(file_size)            /* Output. Size of the file */
    SF_UINT64(file_offset)          /* Input/Output. Starting offset */
    SF_INT64(file_bytes)            /* Input/Output. number of bytes to send */
    /* --------- trailer parms --------- */
   void      *trailer_data;         /* Input/Output. Points to trailer buf */
   uint_t    trailer_length;        /* Input/Output. Length of the trailer */
    /* --------- return info ----------- */
    SF_UINT64(bytes_sent)           /* Output. number of bytes sent */
};
header_data
Points to a buffer that contains header data which is to be sent before the file data. May be a NULL pointer if header_length is 0. This field will be updated by send_file when header is transmitted - that is, header_data + number of bytes of the header sent.
header_length
Specifies the number of bytes in the header_data. This field must be set to 0 to indicate that header data is not to be sent. This field will be updated by send_file when header is transmitted - that is, header_length - number of bytes of the header sent.
file_descriptor
Specifies the file descriptor for a file that has been opened and is readable. This is the descriptor for the file that contains the data to be transmitted. The file_descriptor is ignored when file_bytes = 0. This field is not updated by send_file.
file_size
Contains the byte size of the file specified by file_descriptor. This field is filled in by the kernel.
file_offset
Specifies the byte offset into the file from which to start sending data. This field is updated by the send_file when file data is transmitted - that is, file_offset + number of bytes of the file data sent.
file_bytes
Specifies the number of bytes from the file to be transmitted. Setting file_bytes to -1 transmits the entire file from the file_offset. When this field is not set to -1, it is updated by send_file when file data is transmitted - that is, file_bytes - number of bytes of the file data sent.
trailer_data
Points to a buffer that contains trailer data which is to be sent after the file data. May be a NULL pointer if trailer_length is 0. This field will be updated by send_file when trailer is transmitted - that is, trailer_data + number of bytes of the trailer sent.
trailer_length
Specifies the number of bytes in the trailer_data. This field must be set to 0 to indicate that trailer data is not to be sent. This field will be updated by send_file when trailer is transmitted - that is, trailer_length - number of bytes of the trailer sent.
bytes_sent
Contains number of bytes that were actually sent in this call to send_file. This field is filled in by the kernel.

All fields marked with Input in the sf_parms structure requires setup by an application prior to the send_file calls. All fields marked with Output in the sf_parms structure adjusts by send_file when it successfully transmitted data, that is, either the specified data transmission is partially or completely done.

The send_file subroutine 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_p.

As the data is sent, the kernel updates the parameters pointed by sf_iobuf so that if the send_file has to be called multiple times (either due to interruptions by signals, or due to non-blocking I/O mode) in order to complete a file data transmission, the application can reissue the send_file command without setting or re-adjusting the parameters over and over again.

If the application sets file_offset greater than the actual file size, or file_bytes greater than (the actual file size - file_offset), the return value will be -1 with errno EINVAL.

flags Specifies the following attributes:
SF_CLOSE
Closes the socket pointed to by Socket_p after the data has been successfully sent or queued for transmission.
SF_REUSE
Prepares the socket for reuse after the data has been successfully sent or queued for transmission and the existing connection closed.
Note: This option is currently not supported on this operating system.
SF_DONT_CACHE
Does not put the specified file in the Network Buffer Cache.
SF_SYNC_CACHE
Verifies/Updates the Network Buffer Cache for the specified file before transmission.

When the SF_CLOSE flag is set, the connected socket specified by Socket_p will be disconnected and closed by send_file after the requested transmission has been successfully done. The socket descriptor pointed to by Socket_p will be set to -1. This flag won't take effect if send_file returns non-0.

The flag SF_REUSE currently is not supported by AIX®. When this flag is specified, the socket pointed by Socket_p will be closed and returned as -1. A new socket needs to be created for the next connection.

send_file will take advantage of a Network Buffer Cache in kernel memory to dynamically cache the output file data. This will help to improve the send_file performance for files which are:

  1. accessed repetitively through network and
  2. not changed frequently.

Applications can exclude the specified file from being cached by using the SF_DONT_CACHE flag. send_file will update the cache every so often to make sure that the file data in cache is valid for a certain time period. The network option parameter "send_file_duration" controlled by the no command can be modified to configure the interval of the send_file cache validation, the default is 300 (in seconds). Applications can use the SF_SYNC_CACHE flag to ensure that a cache validation of the specified file will occur before the file is sent by send_file, regardless the value of the "send_file_duration". Other Network Buffer Cache related parameters are "nbc_limit", nbc_max_cache", and nbc_min_cache". For additional infromation, see the no command.

Return Value

There are three possible return values from send_file:

Value Description
-1 an error has occurred, errno contains the error code.
0 the command has completed successfully.
1 the command was completed partially, some data has been transmitted but the command has to return for some reason, for example, the command was interrupted by signals.

The fields marked with Output in the sf_parms structure (pointed to by sf_iobuf) is updated by send_file when the return value is either 0 or 1. The bytes_sent field contains the total number of bytes that were sent in this call. It is always true that bytes_sent (Output) <= header_length(Input) + file_bytes(Input) + trailer_length (Input).

The send_file supports the blocking I/O mode and the non-blocking I/O mode. In the blocking I/O mode, send_file blocks until all file data (plus the header and the trailer) is sent. It adjusts the sf_iobuf to reflect the transmission results, and return 0. It is possible that send_file can be interrupted before the request is fully done, in that case, it adjusts the sf_iobuf to reflect the transmission progress, and return 1.

In the non-blocking I/O mode, the send_file transmits as much as the socket space allows, adjusts the sf_iobuf to reflect the transmission progress, and returns either 0 or 1. When there is no socket space in the system to buffer any of the data, the send_file returns -1 and sets errno to EWOULDBLOCK. select or poll can be used to determine when it is possible to send more data.

Possible errno returned:
EBADF Either the socket or the file descriptor parameter is not valid.
ENOTSOCK The socket parameter refers to a file, not a socket.
EPROTONOSUPPORT Protocol not supported.
EFAULT The addresses specified in the HeaderTailer parameter is not in a writable part of the user-address space.
EINTR The operation was interrupted by a signal before any data was sent. (If some data was sent, send_file returns the number of bytes sent before the signal, and EINTR is not set).
EINVAL The offset, length of the HeaderTrailer, or flags parameter is invalid.
ENOTCONN A send_file on a socket that is not connected, a send_file on a socket that has not completed the connect sequence with its peer, or is no longer connected to its peer.
EWOULDBLOCK The socket is marked non-blocking and the requested operation would block.
ENOMEM No memory is available in the system to perform the operation.

PerformanceNote

By taking advantage of the Network Buffer Cache, send_file provides better performance and network throughput for file transmission. It is recommanded for files bigger than 4K bytes.