ibm-information-center/dist/eclipse/plugins/i5OS.ic.apis_5.4.0.1/sendfile.htm

639 lines
18 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
<title>send_file()--Send a File over a Socket Connection</title>
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<!-- Begin Header Records ========================================== -->
<!-- Unix8 SCRIPT J converted by B2H R4.1 (346) (CMS) by V2KEA304 -->
<!-- at RCHVMW2 on 17 Feb 1999 at 11:05:09 -->
<!-- 020618 EMIG: updated for NFS threadsafety, V5R3 -->
<!-- 020718 MFENLON: updated for QFileSvr.400 threadsafety, V5R3 -->
<!--End Header Records -->
<!-- Edited by Kersten Feb 02 -->
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</head>
<body>
<a name="Top_Of_Page"></a>
<!-- Java sync-link -->
<script type="text/javascript" language="Javascript" src="../rzahg/synch.js">
</script>
<h2>send_file()--Send a File over a Socket Connection</h2>
<div class="box" style="width: 60%;">
<br>
&nbsp;&nbsp;Syntax<br>
<pre>
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
int send_file(int *<em>socket_descriptor</em>,
struct sf_parms *<em>sf_struct</em>,
int <em>flags</em>)
</pre>
<br>
&nbsp;&nbsp;Service Program Name: QSOSRV1<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Default Public Authority: *USE<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Threadsafe: Conditional; see <a href="#HDRSDFUSAG">Usage Notes</a>.<br>
<!-- iddvc RMBR -->
<br>
</div>
<p>The <em>send_file()</em> function is used to send the contents of an open
file over an existing socket connection.</p>
<p>The <em>send_file()</em> API is a combination of the IFS <em>read()</em> and
the sockets <em>send()</em> and <em>close()</em> APIs. Socket applications that
transmit a file over a socket connection can, under certain circumstances,
obtain improved performance by using <em>send_file()</em>.</p>
<br>
<h3>Parameters</h3>
<dl>
<dt><strong>socket_descriptor</strong></dt>
<dd>(Input/Output) A pointer to the socket descriptor that is to be written
to.<br>
<br>
</dd>
<dt><strong>sf_struct</strong></dt>
<dd>(Input/Output) A pointer to the send_file structure that contains the
following:
<ul>
<li>The header buffer and length<br>
<br>
</li>
<li>The file descriptor, the offset into the file, the file size, and number of
bytes to send from the file<br>
<br>
</li>
<li>The trailer buffer and length<br>
<br>
</li>
<li>The number of bytes of data that were sent</li>
</ul>
<p>The structure pointed to by the <em>sf_struct</em> parameter is defined in
<strong>&lt;sys/socket.h&gt;</strong>.</p>
<pre>
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;
}
</pre>
<table cellpadding="5">
<!-- cols="15 85" -->
<tr>
<td align="left" valign="top"><em>header_data </em></td>
<td align="left" valign="top">(Input/Output) A pointer to a buffer that
contains data to be sent before the file data is sent.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>header_length</em> </td>
<td align="left" valign="top">(Input/Output) The length in bytes of
<em>header_data</em>.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>file_descriptor</em> </td>
<td align="left" valign="top">(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 <em>file_bytes</em>
field is set to 0.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>file_size</em> </td>
<td align="left" valign="top">(Output) The size in bytes of the file associated
with <em>file_descriptor</em>.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>file_offset </em></td>
<td align="left" valign="top">(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, <em>send_file()</em>
API will return with -1 and the <em>errno</em> will be set to EINVAL.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>file_bytes</em> </td>
<td align="left" valign="top">(Input/Output) The number of bytes from the file
to be transmitted. Set the <em>file_bytes</em> field to -1 to transmit all of
the data from the <em>file_offset</em> position in the file to the end of the
file. If the <em>file_bytes</em> field is set to 0, no data from the file will
be transmitted.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>trailer_data </em></td>
<td align="left" valign="top">(Input/Output) A pointer to a buffer that
contains data to be sent after the file data is sent.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>trailer_length</em> </td>
<td align="left" valign="top">(Input/Output) The length in bytes of
<em>trailer_data</em>.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>bytes_sent</em> </td>
<td align="left" valign="top">(Output) The number of bytes that have been
successfully sent. </td>
</tr>
</table>
<br>
<br>
</dd>
<dt><strong>flags</strong></dt>
<dd>(Input) A flag value that controls what is done with the socket connection
after the data has been transmitted. The <em>flags</em> value is either zero or
it is one of the following constants:
<table cellpadding="5">
<!-- cols="15 85" -->
<tr>
<td align="left" valign="top"><em>SF_CLOSE</em></td>
<td align="left" valign="top">After the <em>header_data</em>, file data, and
<em>trailer_data</em> have been successfully sent, the connection and the
socket descriptor are closed. The descriptor that is pointed to by the
<em>socket_descriptor</em> parameter is set to -1 before the
<em>send_file()</em> API returns to the application.</td>
</tr>
<tr>
<td align="left" valign="top"><em>SF_REUSE</em></td>
<td align="left" valign="top">After the <em>header_data</em>, file data, and
<em>trailer_data</em> have been successfully sent, the connection is closed. If
socket reuse is supported, the descriptor that is pointed to by the
<em>socket_descriptor</em> parameter is reset. If socket reuse is not
supported, the descriptor that is pointed to by the <em>socket_descriptor</em>
parameter is closed and set to -1.</td>
</tr>
</table>
</dd>
</dl>
<br>
<h3>Authorities</h3>
<p>No authorization is required.</p>
<br>
<h3>Return Value</h3>
<p><em>send_file()</em> returns an integer. Possible values are:</p>
<ul>
<li>-1 (unsuccessful call) Check <em>errno</em> for additional information</li>
<li>0 (successful call) All of the data has been successfully sent</li>
<li>1 (interrupted call) The command was interrupted while sending data</li>
</ul>
<br>
<h3>Error Conditions</h3>
<p>When <em>send_file()</em> fails, <em>errno</em> can be set to one of the
following:</p>
<table cellpadding="5">
<!-- cols="15 85" -->
<tr>
<td align="left" valign="top"><em>[EACCES]</em></td>
<td align="left" valign="top">Permission denied.
<p>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.</p>
<p>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.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EBADF]</em></td>
<td align="left" valign="top">Descriptor not valid.
<p>This error code indicates one of the following:</p>
<ul>
<li>The descriptor pointed to by the <em>socket_descriptor</em> parameter is
not a valid socket descriptor.<br>
<br>
</li>
<li>The <em>file_descriptor</em> 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.</li>
</ul>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ECONVERT]</em></td>
<td align="left" valign="top">Conversion error.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EFAULT]</em></td>
<td align="left" valign="top">Bad address.
<p>The system detected an address that was not valid while attempting to access
the <em>socket_descriptor</em> or one of the fields in the send_file
structure.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EINTR]</em></td>
<td align="left" valign="top">Interrupted function call.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EINVAL]</em></td>
<td align="left" valign="top">Parameter not valid.
<p>This error code indicates one of the following:</p>
<ul>
<li>A NULL pointer was specified for the <em>sf_struct</em> parameter<br>
<br>
</li>
<li>The <em>file_offset</em> parameter specified a negative value.<br>
<br>
</li>
<li>The <em>file_offset</em> parameter specified a value that was greater than
the file size.<br>
<br>
</li>
<li>The <em>file_bytes</em> parameter would have resulted in a read operation
beyond the end of the file.<br>
<br>
</li>
<li>The <em>flags</em> parameter specified a value that was not valid.</li>
</ul>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EIO]</em></td>
<td align="left" valign="top">Input/output error.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ENOBUFS]</em></td>
<td align="left" valign="top">There is not enough buffer space for the
requested operation.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ENOTCONN]</em></td>
<td align="left" valign="top">Requested operation requires a connection.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ENOTSAFE]</em></td>
<td align="left" valign="top">Function is not allowed in a job that is running
with multiple threads.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[ENOTSOCK]</em></td>
<td align="left" valign="top">The specified descriptor does not reference a
socket.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EOPNOTSUPP]</em></td>
<td align="left" valign="top">Operation not supported.
<p>The <em>socket_descriptor</em> parameter references a socket that does not
support the <em>send_file()</em> function. The <em>send_file()</em> function is
only valid on sockets that have an address family of <samp>AF_INET</samp>, <samp>AF_INET6</samp>, <samp>AF_UNIX</samp>, or
<samp>AF_UNIX_CCSID</samp> and a socket type of <samp>SOCK_STREAM</samp>.</p>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EOVERFLOW]</em></td>
<td align="left" valign="top">Object is too large to process.
<p>This error code indicates one of the following:</p>
<ul>
<li>The size of the file associated with <em>file_descriptor</em> parameter is
greater than 2 GB minus 1 byte.<br>
<br>
</li>
<li>The total number of bytes to be sent, <em>header_length</em> +
<em>file_bytes</em> + <em>trailer_length</em>, is greater than 4 GB minus 1,
the largest value that can be stored in the <em>bytes_sent</em> output
field.</li>
</ul>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EPIPE]</em></td>
<td align="left" valign="top">Broken pipe.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EUNATCH]</em></td>
<td align="left" valign="top">The protocol required to support the specified
address family is not available at this time.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>[EUNKNOWN]</em></td>
<td align="left" valign="top">Unknown system state.</td>
</tr>
</table>
<br>
<br>
<h3>Error Messages</h3>
<table width="100%" cellpadding="5">
<!-- cols="15 85" -->
<tr>
<th align="left" valign="top">Message ID</th>
<th align="left" valign="top">Error Message Text</th>
</tr>
<tr>
<td align="left" valign="top">CPE3418 E</td>
<td align="left" valign="top">Possible APAR condition or hardware failure.</td>
</tr>
<tr>
<td align="left" valign="top">CPF3CF2 E</td>
<td align="left" valign="top">Error(s) occurred during running of &amp;1
API.</td>
</tr>
<tr>
<td align="left" valign="top">CPF9872 E</td>
<td align="left" valign="top">Program or service program &amp;1 in library
&amp;2 ended. Reason code &amp;3.</td>
</tr>
<tr>
<td align="left" valign="top">CPFA081 E</td>
<td align="left" valign="top">Unable to set return value or error code.</td>
</tr>
<tr>
<td align="left" valign="top">CPFA0D4 E</td>
<td align="left" valign="top">File system error occurred.</td>
</tr>
</table>
<br>
<br>
<h3><a name="HDRSDFUSAG"><strong>Usage Notes</strong></a></h3>
<ol>
<li>The <em>send_file()</em> function is only valid on sockets that have an
address family of <samp>AF_INET</samp>, <samp>AF_INET6</samp>, <samp>AF_UNIX</samp>, or <samp>AF_UNIX_CCSID</samp> and a
socket type of <samp>SOCK_STREAM</samp>. If the descriptor pointed to by the
<em>socket_descriptor</em> parameter does not have the correct address family
and socket type, -1 is returned and the <em>errno</em> value is set to
EOPNOTSUPP.<br>
<br>
</li>
<li>This function will fail with error code [ENOTSAFE] when all the following
conditions are true:
<ul>
<li>Where multiple threads exist in the job.<br>
<br>
</li>
<li>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:
<ul>
<li>Root</li>
<li>QOpenSys</li>
<li>User-defined</li>
<li>QNTC</li>
<li>QSYS.LIB</li>
<li>QOPT</li>
<li>Network File System</li>
<li>QFileSvr.400</li>
</ul>
</li>
</ul>
<br>
</li>
<li>The <em>file_offset</em> parameter is used to specify a base zero location
in the file referenced by the <em>file_descriptor</em> parameter. If the
<em>file_bytes</em> parameter is set to a value of 1 and the
<em>file_offset</em> parameter is set to a value of 0, the first byte from the
file is sent. If the <em>file_offset</em> parameter is set to a value of 1, the
second byte from the file is sent.<br>
<br>
</li>
<li>An application that uses the <em>send_file()</em> API may specify the
O_SHARE_RDONLY or the O_SHARE_NONE option on the <em>open()</em> call when the
file represented by <em>file_descriptor</em> is first opened. These options
prevent other jobs or threads on the system from updating the file while it is
being transmitted.<br>
<br>
</li>
<li>If the O_TEXTDATA option was specified on the <em>open()</em> call when the
file represented by <em>file_descriptor</em> 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:<br>
<ul>
<li>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.<br>
<br>
</li>
<li>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.</li>
</ul>
<p>If O_TEXTDATA was not specified on the <em>open()</em> call, the data is
sent from the file without conversion.</p>
<p>Regardless of whether or not O_TEXTDATA was specified on the <em>open()</em>
call, the <em>header_data</em> and <em>trailer_data</em> are not translated. It
is the application's responsibility to translate the <em>header_data</em> and
<em>trailer_data</em> to the correct code page before calling
<em>send_file()</em>. The <em>send_file()</em> function will not translate the
data buffers pointed to by the <em>header_data</em> and <em>trailer_data</em>
parameters prior to sending them.</p>
<p><strong>Note:</strong> The ability to do code-page translation is an i5/OS
specific extension to the <em>send_file()</em> API. The overhead to translate
the file will have an effect on the performance of the <em>send_file()</em>
API.</p>
</li>
<li>The <em>send_file()</em> function attempts to write <em>header_length</em>
from the buffer pointed to by <em>header_data</em>, followed by
<em>file_bytes</em> from the file associated with <em>file_descriptor</em>,
followed by <em>trailer_length</em> from the buffer pointed to by
<em>trailer_data</em>, over the connection associated with
<em>socket_descriptor</em>. As the data is sent, the API will update the
variables in the sf_parms structure so that if the <em>send_file()</em> API is
interrupted by a signal, the application simply needs to reissue the
<em>send_file()</em> call using the same parameters.
<p><strong>Note:</strong> The value that is passed in for the <em>flags</em>
parameter is ignored if the <em>send_file()</em> API is interrupted by a
signal.</p>
</li>
<li>When you develop in C-based languages and this function is compiled with
_LARGE_FILES defined, it will be mapped to <em>send_file64()</em>. Note that
the type of the <em>sf_struct</em> parameter, <samp>struct sf_parms *</samp>,
also will be mapped to type <samp>struct sf_parms64 *</samp>.</li>
</ol>
<br>
<h3>Related Information</h3>
<ul>
<li><a href="acceptr.htm">accept_and_recv()</a>--Wait for Connection Request
and Receive the First Message That Was Sent<br>
<br>
</li>
<li><a href="close.htm">close()</a>--Close File or Socket Descriptor<br>
<br>
</li>
<li><a href="open.htm">open()</a>--Open File<br>
<br>
</li>
<li><a href="send.htm">send()</a>--Send Data</li>
</ul>
<br>
<hr>
API introduced: V4R3
<hr>
<center>
<table cellpadding="2" cellspacing="2">
<tr align="center">
<td valign="middle" align="center"><a href="#Top_Of_Page">Top</a> |
<a href="unix.htm">UNIX-Type APIs</a> |
<a href="aplist.htm">APIs by category</a> </td>
</tr>
</table>
</center>
</body>
</html>