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

1434 lines
45 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>fcntl()--Perform File Control Command</title>
<!-- Begin Header Records ========================================== -->
<!-- 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. -->
<!-- file cleaned -->
<!-- Unix2 SCRIPT J converted by B2H R4.1 (346) (CMS) by V2KEA304 -->
<!-- at RCHVMW2 on 17 Feb 1999 at 11:05:09 -->
<!-- 011022 JTROUS Changes from API Review 1, V5R2 -->
<!-- 0202?? Edited by Kersten Feb 02 -->
<!-- IFS and Sockets versions merged for V5R2 -->
<!-- 020618 EMIG Updates for NFS threadsafety, V5R3 -->
<!-- 020718 MFENLON: updated for QFileSvr.400 threadsafety, V5R3 -->
<!-- 020826 JTROUS Changes for scan processing, V5R3a, DCR 98680 -->
<!-- 020601 JET : This file has undergone html cleanup June 2002 -->
<!-- 040319 JTROUS: Fixups on FASYNC and GETFL descriptions, V5R4 -->
<!-- 040721 JTROUS: fix OS/400 reference, no change flag, V5R4 -->
<!-- 050328 JTROUS: fix enums, move adv lock cmt, no chg flag, V5R4 -->
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</head>
<body>
<!-- End Header Records -->
<!-- Java sync-link-->
<script type="text/javascript" language="Javascript" src="../rzahg/synch.js">
</script>
<a name="Top_Of_Page"></a>
<h2>fcntl()--Perform File Control Command</h2>
<div class="box" style="width: 60%;">
<br>
&nbsp;&nbsp;Syntax
<pre>
#include &lt;sys/types.h&gt;
#include &lt;unistd.h&gt;
#include &lt;fcntl.h&gt;
int fcntl(int <em>descriptor</em>,
int <em>command</em>,
...)
</pre>
&nbsp;&nbsp;Service Program Name: QP0LLIB1<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Default Public Authority: *USE<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Threadsafe: Conditional; see <a href="#unotes">Usage
Notes</a>.&nbsp;<br>
<!-- iddvc RMBR -->
<br>
</div>
<p>The <strong>fcntl()</strong> function performs various actions on open
descriptors, such as obtaining or changing the attributes of a file or socket
descriptor.</p>
<br>
<h3>Parameters</h3>
<dl>
<dt><strong>descriptor</strong></dt>
<dd>(Input)&nbsp;&nbsp;The descriptor on which the control command is to be
performed, such as having its attributes retrieved or changed.<br>
<br>
</dd>
<dt><strong>command</strong></dt>
<dd>(Input)&nbsp;&nbsp;The command that is to be performed on the <em>
descriptor</em>.<br>
<br>
</dd>
<dt><strong>...</strong></dt>
<dd>(Input) A variable number of optional parameters that is dependent on the
<em>command</em>. Only some of the commands use this parameter.</dd>
</dl>
<p>The <em>fcntl()</em> commands that are supported are:</p>
<table cellpadding="5">
<!-- cols="15 85" -->
<tr>
<td align="left" valign="top"><em>F_DUPFD</em></td>
<td align="left" valign="top">Duplicates the descriptor. A third <strong>
int</strong> argument must be specified. <strong>fcntl()</strong> returns the
lowest descriptor greater than or equal to this third argument that is not
already associated with an open file. This descriptor refers to the same object
as <em>descriptor</em> and shares any locks. If the original descriptor was
opened in text mode, data conversion is also done on the duplicated descriptor.
The FD_CLOEXEC flag that is associated with the new descriptor is cleared.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_GETFD</em></td>
<td align="left" valign="top">Obtains the descriptor flags for <em>
descriptor</em>. <strong>fcntl()</strong> returns these flags as its result.
For a list of supported file descriptor flags, see <a href="#HDRFCNFLG">
Flags</a>. Descriptor flags are associated with a single descriptor and do not
affect other descriptors that refer to the same object.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_GETFL</em></td>
<td align="left" valign="top">Obtains the
<img src="delta.gif" alt="Start of change">
open
<img src="deltaend.gif" alt="End of change">
flags for <em>descriptor</em>. <strong>fcntl()</strong> returns these
flags as its result. For a list of
<img src="delta.gif" alt="Start of change">
the open
<img src="deltaend.gif" alt="End of change">
flags, see <a href="open.htm#HDROPNFLAG">Using the oflag Parameter</a> in
<strong>open()</strong>.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_GETLK</em></td>
<td align="left" valign="top">Obtains locking information for an object. You
must specify a third argument of type <samp>struct flock *</samp>. See <a href=
"#HDRFCNLOC">File Locking</a> for details. <strong>fcntl()</strong> returns 0
if it successfully obtains the locking information. When you develop in C-based
languages and the function is compiled with the _LARGE_FILES macro defined,
F_GETLK is mapped to the F_GETLK64 symbol.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_GETLK64</em></td>
<td align="left" valign="top">Obtains locking information for a large file. You
must specify a third argument of type <samp>struct flock64 *</samp>. See <a
href="#HDRFCNLOC">File Locking</a> for details. <strong>fcntl()</strong>
returns 0 if it successfully obtains the locking information. When you develop
in C-based languages, it is necessary to compile the function with the
_LARGE_FILE_API macro defined to use this symbol.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_GETOWN</em></td>
<td align="left" valign="top">Returns the process ID or process group ID that
is set to receive the <samp>SIGIO</samp> (I/O is possible on a descriptor) and
<samp>SIGURG</samp> (urgent condition is present) signals. For more
information, see <a href="unix5a1.htm">Signal APIs</a>.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_SETFD</em></td>
<td align="left" valign="top">Sets the descriptor flags for <em>
descriptor</em>. You must specify a third <em>int</em> argument, which gives
the new file descriptor flag settings (see <a href="#HDRFCNFLG">Flags</a>). If
any other bits in the third argument are set, <strong>fcntl()</strong> fails
with the [EINVAL] error. <strong>fcntl()</strong> returns 0 if it successfully
sets the flags. Descriptor flags are associated with a single descriptor and do
not affect other descriptors that refer to the same object.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_SETFL</em></td>
<td align="left" valign="top">Sets status flags for the descriptor. You must
specify a third <em>int</em> argument, giving the new file status flag settings
(see <a href="#HDRFCNFLG">Flags</a>). <strong>fcntl()</strong> does not change
the file access mode, and file access bits in the third argument are ignored.
All other oflag values that are valid on the <strong>open()</strong> API are
also ignored. If any other bits in the third argument are set, <strong>
fcntl()</strong> fails with the [EINVAL] error. <strong>fcntl()</strong>
returns <samp>0</samp> if it successfully sets the flags.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_SETLK</em></td>
<td align="left" valign="top">Sets or clears a file segment lock. You must
specify a third argument of type <samp>struct flock *</samp>. See <a href=
"#HDRFCNLOC">File Locking</a> for details. <strong>fcntl()</strong> returns 0
if it successfully clears the lock. When you develop in C-based languages and
the function is compiled with the _LARGE_FILES macro defined, F_SETLK is mapped
to the F_SETLK64 symbol.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_SETLK64</em></td>
<td align="left" valign="top">Sets or clears a file segment lock for a large
file. You must specify a third argument of type <samp>struct flock64 *</samp>.
See <a href="#HDRFCNLOC">File Locking</a> for details. <strong>fcntl()</strong>
returns 0 if it successfully clears the lock. When you develop in C-based
languages, it is necessary to compile the function with the _LARGE_FILE_API
macro defined to use this symbol.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_SETLKW</em></td>
<td align="left" valign="top">Sets or clears a file segment lock; however, if a
shared or exclusive lock is blocked by other locks, <strong>fcntl()</strong>
waits until the request can be satisfied. You must specify a third argument of
type <samp>struct flock *</samp>. See <a href="#HDRFCNLOC">File Locking</a> for
details. When you develop in C-based languages and the function is compiled
with the _LARGE_FILES macro defined, F_SETLKW is mapped to the F_SETLKW64
symbol.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_SETLKW64</em></td>
<td align="left" valign="top">Sets or clears a file segment lock on a large
file; however, if a shared or exclusive lock is blocked by other locks,
<strong>fcntl()</strong> waits until the request can be satisfied. See <a href=
"#HDRFCNLOC">File Locking</a> for details. You must specify a third argument of
type <samp>struct flock64 *</samp>. When you develop in C-based languages, it
is necessary to compile the function with the _LARGE_FILE_API macro defined to
use this symbol.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_SETOWN</em></td>
<td align="left" valign="top">Sets the process ID or process group ID that is
to receive the <samp>SIGIO</samp> and <samp>SIGURG</samp> signals. For more
information, see <a href="unix5a1.htm">Signal APIs</a>.
<!--<p><font color="red">John and Chris need to provide some text here possibly
for <em>F_GETOWN</em> also ???</font></p> --></td>
</tr>
</table>
<br>
<br>
<h3><a name="HDRFCNFLG">Flags</a></h3>
<p>There are several types of flags associated with each open object. Flags
for an object are represented by symbols defined in the
&lt;<strong>fcntl.h</strong> header file. The following <em>file status</em>
flags can be associated with an object:</p>
<table cellpadding="5">
<!-- cols="15 85" -->
<tr>
<td align="left" valign="top"><em>FASYNC</em></td>
<td align="left" valign="top">The <samp>SIGIO</samp> signal is sent to the
process when it is possible to do I/O.<br>
<img src="delta.gif" alt="Start of change">
This function will fail with
error code [EINVAL] when <em>fildes</em> is for an object other than a socket.
<img src="deltaend.gif" alt="End of change">
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>FNDELAY</em></td>
<td align="left" valign="top">This flag is defined to be equivalent to <samp>
O_NDELAY</samp>.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>O_APPEND</em></td>
<td align="left" valign="top">Append mode. If this flag is <samp>1</samp>,
every write operation on the file begins at the end of the file.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>O_DSYNC</em></td>
<td align="left" valign="top">Synchronous update - data only. If this flag is
<samp>1</samp>, all file data is written to permanent storage before the update
operation returns. Update operations include, but are not limited to, the
following: <strong>ftruncate()</strong>, <strong>open()</strong> with O_TRUNC,
and <strong>write()</strong>.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>O_NDELAY</em></td>
<td align="left" valign="top">This flag is defined to be equivalent to <samp>
O_NONBLOCK</samp>.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>O_NONBLOCK</em></td>
<td align="left" valign="top">Non-blocking mode. If this flag is <samp>
1</samp>, read or write operations on the file will not cause the thread to
block. This file status flag applies only to pipe, FIFO, and socket
descriptors.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>O_RSYNC</em></td>
<td align="left" valign="top">Synchronous read. If this flag is <samp>1</samp>,
read operations to the file will be performed synchronously. This flag is used
in combination with O_SYNC or O_DSYNC. When O_RSYNC and O_SYNC are set, all
file data and file attributes are written to permanent storage before the read
operation returns. When O_RSYNC and O_DSYNC are set, all file data is written
to permanent storage before the read operation returns.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>O_SYNC</em></td>
<td align="left" valign="top">Synchronous update. If this flag is <samp>
1</samp>, all file data and file attributes relative to the I/O operation are
written to permanent storage before the update operation returns. Update
operations include, but are not limited to, the following: <strong>
ftruncate()</strong>, <strong>open()</strong> with O_TRUNC, and <strong>
write()</strong>.<br>
<br>
</td>
</tr>
</table>
<p>The following <em>file access mode</em> flags can be associated with a
file:</p>
<table cellpadding="5">
<!-- cols="15 85" -->
<tr>
<td align="left" valign="top"><em>O_RDONLY</em></td>
<td align="left" valign="top">The file is opened for reading only.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>O_RDWR</em></td>
<td align="left" valign="top">The file is opened for reading and writing.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>O_WRONLY</em></td>
<td align="left" valign="top">The file is opened for writing only.</td>
</tr>
</table>
<p>A mask can be used to extract flags:</p>
<table cellpadding="5">
<!-- cols="15 85" -->
<tr>
<td align="left" valign="top"><em>O_ACCMODE</em></td>
<td align="left" valign="top">Extracts file access mode flags.</td>
</tr>
</table>
<p>The following <em>descriptor</em> flags can be associated with a
descriptor:</p>
<table cellpadding="5">
<!-- cols="15 85" -->
<tr>
<td align="left" valign="top"><em>FD_CLOEXEC</em></td>
<td align="left" valign="top">Controls descriptor inheritance during <strong>
spawn()</strong> and <strong>spawnp()</strong> when simple inheritance is being
used, as follows:<br>
<br>
<ul>
<li>If the FD_CLOEXEC flag is zero, the descriptor is inherited by the child
process that is created by the <strong>spawn()</strong> or <strong>
spawnp()</strong>API.<br>
<p><strong>Note:</strong> Descriptors that are created as a result of the
<strong>opendir()</strong> API (to implement open directory streams) are not
inherited, regardless of the value of the FD_CLOEXEC flag.</p>
</li>
<li>If the FD_CLOEXEC flag is set, the descriptor is not inherited by the child
process that is created by the <strong>spawn()</strong> or <strong>
spawnp()</strong> API.</li>
</ul>
</td>
</tr>
</table>
<p>Refer to <a href="spawn.htm">spawn()</a>--Spawn Process and <a href=
"spawnp.htm">spawnp()</a>--Spawn Process with Path for additional information
about FD_CLOEXEC.</p>
<br>
<h3><a name="HDRFCNLOC">File Locking</a></h3>
<p>A local or remote job can use <strong>fcntl()</strong> to lock out other
local or remote jobs from a part of a file. By locking out other jobs, the job
can read or write to that part of the file without interference from others.
File locking can ensure data integrity when several jobs have a file accessed
concurrently. For more information about remote locking, see information about
the network lock manager and the network status monitor in the <a href=
"../books/sc415714.pdf" target="_blank">Network File System
Support</a><img src="wbpdf.gif" alt="Link to PDF"> book.</p>
<p>All locks obtained using <strong>fcntl()</strong> are advisory only. Jobs
can use advisory locks to inform each other that they want to protect parts of
a file, but advisory locks do not prevent input and output on the locked parts.
If a job has appropriate permissions on a file, it can perform whatever I/O it
chooses, regardless of what advisory locks are set. Therefore, advisory locking
is only a convention, and it works only when all jobs respect the
convention.</p>
<p>Another type of lock, called a mandatory lock, can be set by a remote
personal computer application. Mandatory locks restrict I/O on the locked
parts. A read fails when reading a part that is locked with a mandatory write
lock. A write fails when writing a part that is locked with a mandatory read or
mandatory write lock.</p>
<p>Two different structures are used to control locking operations: <samp>
struct flock</samp> and <samp>struct flock64</samp> (both defined in the
&lt;<strong>fcntl.h</strong> header file). You can use <samp>struct
flock64</samp> with the F_GETLK64, F_SETLK64, and F_SETLKW64 commands to
control locks on large files (files greater than 2GB minus 1 byte). The <samp>
struct flock</samp> structure has the following members:</p>
<table cellpadding="5" border>
<!-- cols="10 15 75" -->
<tr>
<td align="left" valign="top">short</td>
<td align="left" valign="top">l_type</td>
<td align="left" valign="top">Indicates the type of lock, as indicated by one
of the following symbols (defined in the &lt;<strong>fcntl.h</strong>&gt;
header file):<br>
<table cellpadding="5">
<tr>
<td align="left" valign="top"><em>F_RDLCK</em></td>
<td align="left" valign="top">Indicates a <em>read lock</em>; also called a
<em>shared lock</em>. When a job has a read lock, no other job can obtain write
locks for that part of the file. More than one job can have a read lock on the
same part of a file simultaneously. To establish a read lock, a job must have
the file accessed for reading.</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_WRLCK</em></td>
<td align="left" valign="top">Indicates a <em>write lock</em>; also called an
<em>exclusive lock</em>. When a job has a write lock, no other job can obtain a
read lock or write lock on the same part or an overlapping part of that file. A
job cannot put a write lock on part of a file if another job already has a read
lock on an overlapping part of the file. To establish a write lock, a job must
have accessed the file for writing.</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_UNLCK</em></td>
<td align="left" valign="top">Unlocks a lock that was set previously.</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="left" valign="top">short</td>
<td align="left" valign="top">l_whence</td>
<td align="left" valign="top">One of three symbols used in determining the part
of the file that is affected by this lock. These symbols are defined in the
&lt;<strong>unistd.h</strong>&gt; header file and are the same as symbols used
by <strong>lseek()</strong>:<br>
<table cellpadding="5">
<tr>
<td align="left" valign="top"><em>SEEK_CUR</em></td>
<td align="left" valign="top">The current file offset in the file.</td>
</tr>
<tr>
<td align="left" valign="top"><em>SEEK_END</em></td>
<td align="left" valign="top">The end of the file.</td>
</tr>
<tr>
<td align="left" valign="top"><em>SEEK_SET</em></td>
<td align="left" valign="top">The start of the file.</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="left" valign="top">off_t</td>
<td align="left" valign="top">l_start</td>
<td align="left" valign="top">Gives a byte offset used to identify the part of
the file that is affected by this lock. If <samp>l_start</samp> is negative, it
is handled as an unsigned value. The part of the file affected by the lock
begins at this offset from the location given by <samp>l_whence</samp>. For
example, if <samp>l_whence</samp> is SEEK_SET and <samp>l_start</samp> is 10,
the locked part of the file begins at an offset of 10 bytes from the beginning
of the file.</td>
</tr>
<tr>
<td align="left" valign="top">off_t</td>
<td align="left" valign="top">l_len</td>
<td align="left" valign="top">Gives the size of the locked part of the file, in
bytes. If the size is negative, it is treated as an unsigned value. If <samp>
l_len</samp> is zero, the locked part of the file begins at the position
specified by <samp>l_whence</samp> and <samp>l_start</samp>, and extends to the
end of the file. Together, <samp>l_whence</samp>, <samp>l_start</samp>, and
<samp>l_len</samp> are used to describe the part of the file that is affected
by this lock.</td>
</tr>
<tr>
<td align="left" valign="top">pid_t</td>
<td align="left" valign="top">l_pid</td>
<td align="left" valign="top">Specifies the job ID of the job that holds the
lock. This is an output field used only with F_GETLK actions.</td>
</tr>
<tr>
<td align="left" valign="top">void</td>
<td align="left" valign="top">*l_reserved0</td>
<td align="left" valign="top">Reserved. Must be set to NULL.</td>
</tr>
<tr>
<td align="left" valign="top">void</td>
<td align="left" valign="top">*l_reserved1</td>
<td align="left" valign="top">Reserved. Must be set to NULL.</td>
</tr>
</table>
<p>When you develop in C-based languages and this function is compiled with
_LARGE_FILES defined, the <samp>struct flock</samp> data type will be mapped to
a <samp>struct flock64</samp> data type. To use the <samp>struct flock64</samp>
data type explicitly, it is necessary to compile the function with
_LARGE_FILE_API defined.</p>
<p>The <samp>struct flock64</samp> structure has the following members:</p>
<table cellpadding="5" border>
<!-- cols="10 15 75" -->
<tr>
<td align="left" valign="top">short</td>
<td align="left" valign="top">l_type</td>
<td align="left" valign="top">Indicates the type of lock, as indicated by one
of the following symbols (defined in the &lt;<strong>fcntl.h</strong> header
file):<br>
<table cellpadding="5">
<tr>
<td align="left" valign="top"><em>F_RDLCK</em></td>
<td align="left" valign="top">Indicates a <em>read lock</em>; also called a
<em>shared lock</em>. When a job has a read lock, no other job can obtain write
locks for that part of the file. More than one job can have a read lock on the
same part of a file simultaneously. To establish a read lock, a job must have
the file accessed for reading.<br>
<br>
</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_WRLCK</em></td>
<td align="left" valign="top">Indicates a <em>write lock</em>; also called an
<em>exclusive lock</em>. When a job has a write lock, no other job can obtain a
read lock or write lock on the same part or an overlapping part of that file. A
job cannot put a write lock on part of a file if another job already has a read
lock on an overlapping part of the file. To establish a write lock, a job must
have accessed the file for writing.</td>
</tr>
<tr>
<td align="left" valign="top"><em>F_UNLCK</em></td>
<td align="left" valign="top">Unlocks a lock that was set previously.</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="left" valign="top">short</td>
<td align="left" valign="top">l_whence</td>
<td align="left" valign="top">One of three symbols used in determining the part
of the file that is affected by this lock. These symbols are defined in the
&lt;<strong>unistd.h</strong>&gt; header file and are the same as symbols used
by <strong>lseek()</strong>:<br>
<table cellpadding="5">
<tr>
<td align="left" valign="top"><em>SEEK_CUR</em></td>
<td align="left" valign="top">The current file offset in the file.</td>
</tr>
<tr>
<td align="left" valign="top"><em>SEEK_END</em></td>
<td align="left" valign="top">The end of the file.</td>
</tr>
<tr>
<td align="left" valign="top"><em>SEEK_SET</em></td>
<td align="left" valign="top">The start of the file.</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="left" valign="top">char</td>
<td align="left" valign="top">l_reserved2[4]</td>
<td align="left" valign="top">Reserved field</td>
</tr>
<tr>
<td align="left" valign="top">off64_t</td>
<td align="left" valign="top">l_start</td>
<td align="left" valign="top">Gives a byte offset used to identify the part of
the file that is affected by this lock. <samp>l_start</samp> is handled as a
signed value. The part of the file affected by the lock begins at this offset
from the location given by <samp>l_whence</samp>. For example, if <samp>
l_whence</samp> is SEEK_SET and <samp>l_start</samp> is 10, the locked part of
the file begins at an offset of 10 bytes from the beginning of the file.</td>
</tr>
<tr>
<td align="left" valign="top">off64_t</td>
<td align="left" valign="top">l_len</td>
<td align="left" valign="top">Gives the size of the locked part of the file, in
bytes. If the size is negative, the part of the file affected is l_start +
l_len through l_start - 1. If <samp>l_len</samp> is zero, the locked part of
the file begins at the position specified by <samp>l_whence</samp> and <samp>
l_start</samp>, and extends to the end of the file. Together, <samp>
l_whence</samp>, <samp>l_start</samp>, and <samp>l_len</samp> are used to
describe the part of the file that is affected by this lock.</td>
</tr>
<tr>
<td align="left" valign="top">pid_t</td>
<td align="left" valign="top">l_pid</td>
<td align="left" valign="top">Specifies the job ID of the job that holds the
lock. This is an output field used only with F_GETLK actions.</td>
</tr>
<tr>
<td align="left" valign="top">char</td>
<td align="left" valign="top">reserved3[4]</td>
<td align="left" valign="top">Reserved field.</td>
</tr>
<tr>
<td align="left" valign="top">void</td>
<td align="left" valign="top">*l_reserved0</td>
<td align="left" valign="top">Reserved. Must be set to NULL.</td>
</tr>
<tr>
<td align="left" valign="top">void</td>
<td align="left" valign="top">*l_reserved1</td>
<td align="left" valign="top">Reserved. Must be set to NULL.</td>
</tr>
</table>
<p>You can set locks by specifying F_SETLK or F_SETLK64 as the <em>command</em>
argument for <strong>fcntl()</strong>. Such a function call requires a third
argument pointing to a <samp>struct flock</samp> structure (or <samp>struct
flock64</samp> in the case of F_SETLK64), as in this example:</p>
<pre>
struct flock lock_it;
lock_it.l_type = F_RDLCK;
lock_it.l_whence = SEEK_SET;
lock_it.l_start = 0;
lock_it.l_len = 100;
fcntl(file_descriptor,F_SETLK,&amp;lock_it);
</pre>
<p>This example sets up a flock structure describing a read lock on the first
100 bytes of a file, and then calls <strong>fcntl()</strong> to establish the
lock. You can unlock this lock by setting <samp>l_type</samp> to F_UNLCK and
making the same call. If an F_SETLK operation cannot set a lock, it returns
immediately with an error saying that the lock cannot be set.</p>
<p>The F_SETLKW and F_SETLKW64 operations are similar to F_SETLK and F_SETLK64,
except that they wait until the lock can be set. For example, if you want to
establish an exclusive lock and some other job already has a lock established
on an overlapping part of the file, <strong>fcntl()</strong> waits until the
other process has removed its lock.</p>
<p>F_SETLKW and F_SETLKW64 operations can encounter <em>deadlocks</em> when job
A is waiting for job B to unlock a region and job B is waiting for job A to
unlock a different region. If the system detects that an F_SETLKW or F_SETLKW64
might cause a deadlock, <strong>fcntl()</strong> fails with <em>errno</em> set
to [EDEADLK].</p>
<p>With the F_SETLK64, F_SETLKW64, and F_GETLK64 operations, the maximum offset
that can be specified is the largest value that can be held in an 8-byte,
signed integer.</p>
<p>A job can determine locking information about a file by using F_GETLK and
F_GETLK64 as the <em>command</em> argument for <strong>fcntl()</strong>. In
this case, the call to <strong>fcntl()</strong> should specify a third argument
pointing to a flock structure. The structure should describe the lock operation
you want. When <strong>fcntl()</strong> returns, the structure indicated by the
flock pointer is changed to show the first lock that would prevent the proposed
lock operation from taking place. The returned structure shows the type of lock
that is set, the part of the file that is locked, and the job ID of the job
that holds the lock. In the returned structure:</p>
<ul>
<li><samp>l_whence</samp> is always SEEK_SET.</li>
<li><samp>l_start</samp> gives the offset of the locked portion from the
beginning of the file.</li>
<li><samp>l_len</samp> is the length of the locked portion.</li>
</ul>
<p>If there are no locks that prevent the proposed lock operation, the returned
structure has F_UNLCK in <samp>l_type</samp> and is otherwise unchanged.</p>
<p>If <strong>fcntl()</strong> attempts to operate on a large file (one larger
than 2GB minus 1 byte) with the F_SETLK, F_GETLK, or FSETLKW commands, the API
fails with [EOVERFLOW]. To work with large files, compile with the
_LARGE_FILE_API macro defined (when you develop in C-based languages) and use
the F_SETLK64, F_GETLK64, or FSETLKW64 commands. When you develop in C-based
languages, it is also possible to work with large files by compiling the source
with the _LARGE_FILES macro label defined. Note that the file must have been
opened for large file access (either the <strong>open64()</strong> API was used
or the <strong>open()</strong> API was used with the O_LARGEFILE flag defined
in the oflag parameter).</p>
<p>An application that uses the F_SETLK or F_SETLKW commands may try to lock or
unlock a file that has been extended beyond 2GB minus 1 byte by another
application. If the value of l_len is set to 0 on the lock or unlock request,
the byte range held or released will go to the end of the file rather than
ending at offset 2GB minus 2.</p>
<p>An application that uses the F_SETLK or F_SETLKW commands also may try to
lock or unlock a file that has been extended beyond offset 2GB minus 2 with
l_len NOT set to 0. If this application attempts to lock or unlock the byte
range up to offset 2GB minus 2 and l_len is not 0, the unlock request will
unlock the file only up to offset 2GB minus 2 rather than to the end of the
file.</p>
<p>A job can have several locks on a file at the same time, but only one type
of lock can be set on a given byte. Therefore, if a job puts a new lock on a
part of a file that it had locked previously, the job has only one lock on that
part of the file. The type of the lock is the one specified in the most recent
locking operation.</p>
<p>Locks can start and extend beyond the current end of a file, but cannot
start or extend ahead of the beginning of a file.</p>
<p>All of the locks a job has on a file are removed when the job closes any
descriptor that refers to the locked file.</p>
<p>The maximum starting offset that can be specified by using the fnctl() API
is 2<sup>63</sup> - 1, the largest number that can be represented by a signed
8-byte integer. Mandatory locks set by a personal computer application or by a
user of the DosSetFileLocks64() API may lock a byte range that is greater than
2<sup>63</sup> - 1.</p>
<p>An application that uses the F_SETLK64 or F_SETLKW64 commands can lock the
offset range that is beyond 2<sup>63</sup> - 1 by locking offset 2<sup>63</sup>
- 1. When offset 2<sup>63</sup> - 1 is locked, it implicitly locks to the end
of the file. The end of the file is the largest number than can be represented
by an 8-byte unsigned integer or 2<sup>64</sup> - 1. This implicit lock may
inhibit the personal computer application from setting mandatory locks in the
range not explicitly accessable by the fcntl() API.</p>
<p>Any lock set using the fcntl() API that locks offset 2<sup>63</sup> - 1 will
have a length of 0.</p>
<p>An application that uses the F_GETLK64 may encounter a mandatory lock set by
a personal computer application, which locks a range of offsets greater than
2<sup>63</sup> - 1. This lock conflict will have a starting offset equal to or
less than 2<sup>63</sup> - 1 and a length of 0.</p>
<br>
<h3>Authorities</h3>
<p>No authorization is required.</p>
<br>
<h3>Return Value</h3>
<table cellpadding="5">
<!-- cols="10 90" -->
<tr>
<td align="left" valign="top"><em>value</em></td>
<td align="left" valign="top"><strong>fcntl()</strong> was successful. The
value returned depends on the <em>command</em> that was specified.</td>
</tr>
<tr>
<td align="left" valign="top"><em>-1</em></td>
<td align="left" valign="top"><strong>fcntl()</strong> was not successful. The
<em>errno</em> global variable is set to indicate the error.</td>
</tr>
</table>
<br>
<br>
<h3>Error Conditions</h3>
<p>If <strong>fcntl()</strong> is not successful, <em>errno</em> usually
indicates one of the following errors. Under some conditions, <em>errno</em>
could indicate an error other than those listed here.</p>
<table cellpadding="5">
<!-- cols="25 75" -->
<tr>
<th align="left" valign="bottom">Error condition</th>
<th align="left" valign="bottom">Additional information</th>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EACCES">EACCES</a>]</em></td>
<td align="left" valign="top">
<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 take
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>[<a href="unix14.htm#EAGAIN">EAGAIN</a>]</em></td>
<td align="left" valign="top">
<p>The process tried to lock with F_SETLK, but the lock is in conflict with a
previously established lock.</p>
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EBADF">EBADF</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EBADFID">EBADFID</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EBADFUNC">EBADFUNC</a>]</em></td>
<td align="left" valign="top">
<p>A given descriptor or directory pointer is not valid for this operation. The
specified descriptor is incorrect, or does not refer to an open object.</p>
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EBUSY">EBUSY</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EDAMAGE">EDAMAGE</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EDEADLK">EDEADLK</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EFAULT">EFAULT</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EINVAL">EINVAL</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EIO">EIO</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EMFILE">EMFILE</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENOLCK">ENOLCK</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENOMEM">ENOMEM</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENOSYS">ENOSYS</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENOTAVAIL">ENOTAVAIL</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENOTSAFE">ENOTSAFE</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EOVERFLOW">EOVERFLOW</a>]</em></td>
<td align="left" valign="top">
<p>One of the values to be returned cannot be represented correctly.
The command argument is F_GETLK, F_SETLK, or F_SETLKW and the offset of any
byte in the requested segment cannot be represented correctly in a variable of
type off_t (the offset is greater than 2GB minus 1 byte).</p>
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ESTALE">ESTALE</a>]</em></td>
<td align="left" valign="top">
<p>If you are accessing a remote file through the Network File System, the file
may have been deleted at the server.</p>
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EUNKNOWN">EUNKNOWN</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
</table>
<p>If interaction with a file server is required to access the object, <em>
errno</em> could also indicate one of the following errors:</p>
<table cellpadding="5">
<!-- cols="25 75" -->
<tr>
<th align="left" valign="bottom">Error condition</th>
<th align="left" valign="bottom">Additional information</th>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EADDRNOTAVAIL">EADDRNOTAVAIL</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ECONNABORTED">ECONNABORTED</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ECONNREFUSED">ECONNREFUSED</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ECONNRESET">ECONNRESET</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EHOSTDOWN">EHOSTDOWN</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EHOSTUNREACH">EHOSTUNREACH</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENETDOWN">ENETDOWN</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENETRESET">ENETRESET</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENETUNREACH">ENETUNREACH</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ETIMEDOUT">ETIMEDOUT</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EUNATCH">EUNATCH</a>]</em></td>
<td align="left" valign="top">
&nbsp;
</td>
</tr>
</table>
<br>
<br>
<h3>Error Messages</h3>
<p>The following messages may be sent from this function:</p>
<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 valign="top" width="15%">CPFA0D4 E</td>
<td valign="top" width="85%">File system error occurred. Error number
&amp;1.</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">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">CPE3418 E</td>
<td align="left" valign="top">Possible APAR condition or hardware failure.</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>
</table>
<br>
<br>
<h3><a name="unotes">Usage Notes</a></h3>
<ol>
<li>This function will fail with error code [ENOTSAFE] when all the following
conditions are true:<br>
<br>
<ul>
<li>Where multiple threads exist in the job.</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:<br>
<br>
<ul>
<li>"Root" (/)</li>
<li>QOpenSys</li>
<li>User-defined</li>
<li>QNTC</li>
<li>QSYS.LIB</li>
<li>Independent ASP QSYS.LIB</li>
<li>QOPT</li>
<li>Network File System</li>
<li>QFileSvr.400</li>
</ul>
<br>
</li>
</ul>
</li>
<li>
If F_DUPFD is specified as the <strong>fcntl()</strong> command,
this function will fail with
error code [EBADF] when <em>fildes</em> is a scan descriptor that was passed to
one of the scan-related exit programs. See <a href="ifsopenexit.htm">Integrated
File System Scan on Open Exit Programs</a> and <a href="ifscloseexit.htm">
Integrated File System Scan on Close Exit Programs</a> for more information.
<br>
<br></li>
<li>If the
<strong>fcntl()</strong> command is called
by a thread executing one of the scan-related exit programs (or any of its
created threads), it will fail with error code [ENOTSUP] if F_SETLK,
F_SETLK64, F_SETLKW or F_SETLKW64 is specified.
See <a href=
"ifsopenexit.htm">Integrated File System Scan on Open Exit Programs</a> and <a
href="ifscloseexit.htm">Integrated File System Scan on Close Exit Programs</a>
for more information. <br>
</li>
<li>QSYS.LIB and Independent ASP QSYS.LIB File System Differences<br>
<br>
<p>The following <strong>fcntl()</strong> commands are not supported:</p>
<ul>
<li>F_GETLK</li>
<li>F_SETLK</li>
<li>F_SETLKW</li>
</ul>
<p>Using any of these commands results in an [ENOSYS] error.</p>
</li>
<li>Network File System Differences<br>
<br>
<p>Reading and writing to a file with the Network File System relies on
byte-range locking to guarantee data integrity. To prevent data inconsistency,
use the <strong>fcntl()</strong> API to get and release these locks. For more
information about remote locking, see information about the network lock
manager and the network status monitor in the <a href=
"../books/sc415714.pdf" target="_blank">Network File System
Support</a><img src="wbpdf.gif" alt="Link to PDF"> book.</p>
</li>
<li>QNetWare File System Differences<br>
<br>
<p>F_GETLK and F_SETLKW are not supported. F_RDLCK and F_WRLCK are ignored. All
locks prevent reading and writing. Advisory locks are not supported. All locks
are mandatory locks. Locking a file that is opened more than once in the same
job with the same access mode is not supported, and its result is
undefined.</p>
</li>
<li>This function will fail with the [EOVERFLOW] error if the command is
F_GETLK, F_SETLK, or F_SETLKW and the offset or the length exceeds offset 2 GB
minus 2.<br>
<br>
</li>
<li>When you develop in C-based languages and an application is compiled with
the _LARGE_FILES macro defined, the <samp>struct flock</samp> data type will be
mapped to a <samp>struct flock64</samp> data type. To use the <samp>struct
flock64</samp> data type explicitly, it is necessary to compile the function
with the _LARGE_FILE_API defined.<br>
<br>
</li>
<li>In several cases, similar function can be obtained by using <em>
ioctl()</em>.</li>
</ol>
<br>
<h3>Related Information</h3>
<ul>
<li>The &lt;<strong>sys/types.h</strong>&gt; file (see <a href="unix13.htm">
Header Files for UNIX-Type Functions</a>)
</li>
<li>The &lt;<strong>unistd.h</strong>&gt; file (see <a href="unix13.htm">Header
Files for UNIX-Type Functions</a>)
</li>
<li>The &lt;<strong>fcntl.h</strong>&gt; file (see <a href="unix13.htm">Header
Files for UNIX-Type Functions</a>)
</li>
<li><a href="close.htm">close()</a>--Close File or Socket Descriptor
</li>
<li><a href="dup.htm">dup()</a>--Duplicate Open File Descriptor
</li>
<li><a href="dup2.htm">dup2()</a>--Duplicate Open File Descriptor to Another
Descriptor
</li>
<li><a href="ioctl.htm">ioctl()</a>--Perform I/O Control Request
</li>
<li><a href="lseek.htm">lseek()</a>--Set File Read/Write Offset
</li>
<li><a href="open.htm">open()</a>--Open File
</li>
<li><a href="spawn.htm">spawn()</a>--Spawn Process
</li>
<li><a href="spawnp.htm">spawnp()</a>--Spawn Process with Path
</li>
<li><a href="../books/sc415714.pdf" target="_blank">Network File
System Support</a><img src="wbpdf.gif" alt="Link to PDF"> book</li>
</ul>
<br>
<h3>Example</h3>
<p>See <a href="../apiref/aboutapis.htm#codedisclaimer">Code disclaimer information</a>
for information pertaining to code examples.</p>
<p>The following example uses <strong>fcntl()</strong>:</p>
<pre>
#include &lt;stdio.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;unistd.h&gt;
#include &lt;fcntl.h&gt;
int main()
{
int flags;
int append_flag;
int nonblock_flag;
int access_mode;
int file_descriptor; /* File Descriptor */
char *text1 = "abcdefghij";
char *text2 = "0123456789";
char read_buffer[25];
memset(read_buffer, '\0', 25);
/* create a new file */
file_descriptor = creat("testfile",S_IRWXU);
write(file_descriptor, text1, 10);
close(file_descriptor);
/* open the file with read/write access */
file_descriptor = open("testfile", O_RDWR);
read(file_descriptor, read_buffer,24);
printf("first read is \'%s\'\n",read_buffer);
/* reset file pointer to the beginning of the file */
lseek(file_descriptor, 0, SEEK_SET);
/* set append flag to prevent overwriting existing text */
fcntl(file_descriptor, F_SETFL, O_APPEND);
write(file_descriptor, text2, 10);
lseek(file_descriptor, 0, SEEK_SET);
read(file_descriptor, read_buffer,24);
printf("second read is \'%s\'\n",read_buffer);
close(file_descriptor);
unlink("testfile");
return 0;
}
</pre>
<p><strong>Output:</strong></p>
<pre>
first read is 'abcdefghij'
second read is 'abcdefghij0123456789'
</pre>
<br>
<hr>
API introduced: V3R1
<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>