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

852 lines
28 KiB
HTML
Raw Permalink Normal View History

2024-04-02 14:02:31 +00:00
<!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>mmap()--Memory Map a File</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. -->
<!-- Change History: -->
<!-- YYMMDD USERID Change description -->
<!-- MMAP510 SCR A converted by B2H R4.1 (346) (CMS) by V2CDIJAB at -->
<!-- RCHVMW2 on 19 Sep 2000 at 08:29:17 -->
<!-- 010717 JTROUS Add info on journal limits, should have been -->
<!-- done in V5R1 -->
<!-- 011108 JTROUS Changes from CL Review 1, V5R2 -->
<!-- 020313 JTROUS Changes for scan processing, V5R3, DCR 98680 -->
<!-- 0203?? v2cdijab File cleanup completed Mar 2002 by v2cdijab -->
<!-- 0206?? JET This file has undergone html cleanup June 2002 by JET -->
<!-- 020918 Rosckes: Add ENOTAVAIL errno description, V5R3 -->
<!-- 050203 JTROUS Change errno for journaled, V5R4, fix errnos -->
<!-- 050310 JTROUS Add note on tagged pointers, V5R4, rvw fixups -->
<!-- 050505 JTROUS Add ftruncate, fclear to usage note on sync, V5R4 -->
<!-- End Header Records -->
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</head>
<body>
<!-- Java sync-link -->
<script language="Javascript" src="../rzahg/synch.js" type="text/javascript">
</script>
<a name="Top_Of_Page"></a>
<h2>mmap()--Memory Map a File</h2>
<div class="box" style="width: 60%;">
<br>
&nbsp;&nbsp;Syntax<br>
<pre>
#include &lt;sys/types.h&gt;
#include &lt;sys/mman.h&gt;
void *mmap( void <em>*addr</em>,
size_t <em>len</em>,
int <em>protection</em>,
int <em>flags</em>,
int <em>fildes</em>,
off_t <em>off</em>);
</pre>
&nbsp;&nbsp;Service Program Name: QP0LLIB1 &nbsp;&nbsp;<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Default Public Authority: *USE<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Threadsafe: Yes<br>
<!-- iddvc RMBR -->
<br>
</div>
<p>The mmap() function establishes a mapping between a process' address space
and a stream file.</p>
<p>The address space of the process from the address returned to the caller,
for a length of <em>len</em>, is mapped onto a stream file starting at offset
<em>off</em>.</p>
<p>The portion of the stream file being mapped is from starting offset <em>
off</em> for a length of <em>len</em> bytes. The actual address returned from
the function is derived from the values of <em>flags</em> and the value
specified for <em>address</em>.</p>
<p>The <strong>mmap()</strong> function causes a reference to be associated
with the file represented by <em>fildes</em>. This reference is not removed by
subsequent close operations. The file remains referenced as long as a mapping
exists over the file.</p>
<p>If a mapping already exists for the portion of the processes address space
that is to be mapped and the value MAP_FIXED was specified for <em>flags</em>,
then the previous mappings for the affected pages are implicitly unmapped. If
one or more files affected by the implicit unmap no longer have active
mappings, these files will be unreferenced as a result of <strong>
mmap()</strong>.</p>
<p>The use of the <strong>mmap()</strong> function is restricted by the
<strong><em>QSHRMEMCTL</em></strong> System Value. When this system value is 0,
the <strong>mmap()</strong> function may not create a shared mapping having
with <strong><em>PROT_WRITE</em></strong> capability. Essentially, this
prevents the creation of a memory map that could alter the contents of the
stream file being mapped. If the <em>flags</em> parameter indicated <strong>
<em>MAP_SHARED</em></strong>, the <strong><em>prot</em></strong> parameter
specifies <strong><em>PROT_WRITE</em></strong> and the <strong><em>
QSHRMEMCTL</em></strong> system value is 0, then the <strong>mmap()</strong>
functions will fail and an error number of <strong><em>EACCES</em></strong>
results.</p>
<p>When the <strong>mmap()</strong> function creates a memory map, the current
value of the <strong><em>QSHRMEMCTL</em></strong> system value is stored with
the mapping. This further restricts attempts to change the protection of the
mapping through the use of the <strong>mprotect</strong> function. Changing the
system valueonly affects memory maps created after the system value is
changed.</p>
<p>If the size of the file increases after the <strong>mmap()</strong> function
completes, then the whole pages beyond the original end of file will not be
accessible via the mapping.</p>
<p>If the size of the mapped file is decreased after <strong>mmap()</strong>,
attempts to reference beyond the end of the file are undefined and may result
in an MCH0601 exception.</p>
<p>Any data written to that portion of the file that is allocated beyond
end-of-file may not be preserved. Changes made beyond end of file via mapped
access may not be preserved.</p>
<p>The portion of the file beyond end-of-file is assumed to be zero by the
traditional file access APIs such as <strong>read()</strong>, <strong>
readv()</strong>, <strong>write()</strong>, <strong>writev()</strong>, and
<strong>ftruncate()</strong>. The system may clear a partial page, or whole
pages allocated beyond end-of-file. This must be taken into account when
directly changing a memory mapped file beyond end-of-file. It is not
recommended that data be directly changed beyond end-of-file because the extra
space allocated varies and unpredictable results may occur.</p>
<p>The <strong>mmap()</strong> function is only supported for *TYPE2 stream
files (*STMF) existing in the "root" (/), QOpenSys, and user-defined file
systems.</p>
<p>Journaling cannot be started while a file is memory mapped. Likewise, a
journaled file cannot be memory mapped. The <strong>mmap()</strong> function
will fail with
<img src="delta.gif" alt="Start of change">
ENOTSUP
<img src="deltaend.gif" alt="End of change">
if the file is journaled.</p>
<p>The <em>off</em> parameter must be zero or a multiple of the system page
size. The _SC_PAGESIZE or _SC_PAGE_SIZE options on the
<a href="sysconf.htm">sysconf()</a> function may be used to retrieve the system page size.</p>
<br>
<h3>Parameters</h3>
<dl>
<dt><strong><em>addr</em></strong></dt>
<dd>(Input) The starting address of the memory area to be mapped. If the
MAP_FIXED value is specified with the <em>flag</em> parameter, then <em>
address</em> must be a multiple of the system page size. Use the _SC_PAGESIZE
or _SC_PAGE_SIZE options of the <strong>sysconf()</strong> API to obtain the
actual page size in an implementation-independent manner. When the MAP_FIXED
flag is specified, this address must not be zero.<br>
<br>
</dd>
<dt><strong><em>len</em></strong></dt>
<dd>(Input) The length in bytes to map. A length of zero will result in an
errno of EINVAL.<br>
<br>
</dd>
<dt><strong><em>protection</em></strong></dt>
<dd>(Input) The access allowed to this process for this mapping. Specify
PROT_NONE, PROT_READ, PROT_WRITE, or a the inclusive-or of PROT_READ and
PROT_WRITE. You cannot specify a protection value more permissive than the mode
in which the file was opened.
<p>The PROT_WRITE value requires that the file be opened for write and read
access.</p>
<p>The following table shows the symbolic constants allowed for the protection
parameter.</p>
<table border width="80%">
<tr>
<th align="left" valign="top">Symbolic Constant</th>
<th align="left" valign="top">Decimal<br>
Value</th>
<th align="left" valign="bottom">Description</th>
</tr>
<tr>
<td align="left" valign="top" width="20%">PROT_READ</td>
<td align="center" valign="top" width="15%">1</td>
<td align="left" valign="top" width="65%">Read access is allowed.</td>
</tr>
<tr>
<td align="left" valign="top">PROT_WRITE</td>
<td align="center" valign="top">2</td>
<td align="left" valign="top">Write access is allowed. Note that this value
assumes PROT_READ also.</td>
</tr>
<tr>
<td align="left" valign="top">PROT_NONE</td>
<td align="center" valign="top">8</td>
<td align="left" valign="top">No data access is allowed.</td>
</tr>
<tr>
<td align="left" valign="top">PROT_EXEC</td>
<td align="center" valign="top">4</td>
<td align="left" valign="top">This value is allowed, but is equivalent to
PROT_READ.</td>
</tr>
</table>
<br>
</dd>
<dt><strong><em>flags</em></strong></dt>
<dd>(Input) Further defines the type of mapping desired. There are actually two
independent options controlled through the <em>flags</em> parameter.
<p>The first attribute controls whether or not changes made through the mapping
will be seen by other processes. The MAP_PRIVATE option will cause a copy on
write mapping to be created. A change to the mapping results in a change to a
private copy of the affected portion of the file. These changes cannot be seen
by other processes. The MAP_SHARED option provides a memory mapping of the file
where changes (if allowed by the <em>protection</em> parameter) are made to the
file. Changes are shared with other processes when MAP_SHARED is specified.</p>
<p>The second control provided by the <em>flags</em> parameter in conjunction
with the value of the <em>addr</em> parameter influences the address range
assigned to the mapping. You may request one of the following address selection
modes:</p>
<ol type="1">
<li>An exact address range specification. The system will set up the mapping at
this location if the address range is valid. Any mapping in the successfully
mapping range that existed prior to the mapping operation is implicitly
unmapped by this operation.<br>
<br>
</li>
<li>A suggested address range. The system will select a range close to the
suggested range.<br>
<br>
</li>
<li>System selected. The system will select an address range. This usually is
used to acquire the initial memory map range. Subsequent ranges can be mapped
relative to this range.</li>
</ol>
<p>The MAP_FIXED flag value specifies that the virtual address has been
specified through the <em>addr</em> parameter. The <strong>mmap()</strong>
function will use the value of <em>addr</em> as the starting point of the
memory map.</p>
<p>When MAP_FIXED is set in the flags parameter, the system is informed that
the return value must be equal to the value of <em>addr</em>. An invalid value
of <em>addr</em> when MAP_FIXED is specified will result in a value of
MAP_FAILED, which has a value of 0, for the returned value and the the value of
errno will be set to EINVAL.</p>
<p>When MAP_FIXED is not specified, a value of zero for parameter <em>addr</em>
indicates that the system may choose the value for the return value. If
MAP_FIXED is not specified and a nonzero value is specified for <em>addr</em>,
the system will take this as a suggestion to find a contiguous address range
close to the specified address.</p>
<p>The following table shows the symbolic constants allowed for the flags
parameter.</p>
<table border width="80%">
<tr>
<th align="left" valign="top">Symbolic Constant</th>
<th align="left" valign="top">Decimal<br>
Value</th>
<th align="left" valign="bottom">Description</th>
</tr>
<tr>
<td align="left" valign="top" width="20%">MAP_SHARED</td>
<td align="center" valign="top" width="15%">4</td>
<td align="left" valign="top" width="65%">Changes are shared.</td>
</tr>
<tr>
<td align="left" valign="top">MAP_PRIVATE</td>
<td align="center" valign="top">2</td>
<td align="left" valign="top">Changes are private.</td>
</tr>
<tr>
<td align="left" valign="top">MAP_FIXED</td>
<td align="center" valign="top">1</td>
<td align="left" valign="top">Parameter <em>addr</em> has exact address</td>
</tr>
</table>
<br>
</dd>
<dt><strong><em>fildes</em></strong></dt>
<dd>(Input) An open file descriptor.<br>
<br>
</dd>
<dt><strong><em>off</em></strong></dt>
<dd>(Input) The offset into the file, in bytes, where the map should
begin.</dd>
</dl>
<br>
<h3>Authorities</h3>
<p>No authority checking is performed by the <strong>mmap()</strong> function
because this was done by the <strong>open()</strong> functions which assigned
the file descriptor, <em>fildes</em>, used by the <strong>mmap()</strong>
function.</p>
<p>The following table shows the open access intent that is required for the
various combinations of the mapping sharing mode and mapping intent.</p>
<table border width="80%">
<tr>
<th align="left" valign="top">Mapping Sharing Mode</th>
<th align="left" valign="top">Mapping Intent</th>
<th align="left" valign="top">Open access intents allowed</th>
</tr>
<tr>
<td align="left" valign="top" width="35%">MAP_SHARED</td>
<td align="left" valign="top" width="30%">PROT_READ</td>
<td align="left" valign="top" width="35%">O_RDONLY or O_RDWR</td>
</tr>
<tr>
<td align="left" valign="top">MAP_SHARED</td>
<td align="left" valign="top">PROT_WRITE</td>
<td align="left" valign="top">O_RDWR</td>
</tr>
<tr>
<td align="left" valign="top">MAP_SHARED</td>
<td align="left" valign="top">PROT_NONE</td>
<td align="left" valign="top">O_RDONLY or O_RDWR</td>
</tr>
<tr>
<td align="left" valign="top">MAP_PRIVATE</td>
<td align="left" valign="top">PROT_READ</td>
<td align="left" valign="top">O_RDONLY or O_RDWR</td>
</tr>
<tr>
<td align="left" valign="top">MAP_PRIVATE</td>
<td align="left" valign="top">PROT_WRITE</td>
<td align="left" valign="top">O_RDONLY or O_RDWR</td>
</tr>
<tr>
<td align="left" valign="top">MAP_PRIVATE</td>
<td align="left" valign="top">PROT_NONE</td>
<td align="left" valign="top">O_RDONLY or O_RDWR</td>
</tr>
</table>
<br>
<br>
<h3>Return Value</h3>
<p>Upon successful completion, the <strong>mmap()</strong> function returns the
address at which the mapping was placed; otherwise, it returns a value of
MAP_FAILED, which has a value of 0, and sets errno to indicate the error. The
symbol MAP_FAILED is defined in the header &lt;sys/mman.h&gt;.</p>
<p>If successful, function <strong>mmap()</strong> will never return a value of
MAP_FAILED.</p>
<p>If <strong>mmap()</strong> fails for reasons other than EBADF, EINVAL, or
ENOTSUP, some of the mappings in the address range starting at <em>addr</em>
and continuing for <em>len</em> bytes may have been unmapped and no new
mappings are created.</p>
<br>
<h3>Error Conditions</h3>
<p>When the <strong>mmap()</strong> function fails, it returns MAP_FAILED,
which has a value of 0, and sets the errno as follows.</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>
<p>The file referenced by fildes is not open for read, or the file is not
opened for write and PROT_WRITE for a shared mapping is being requested. This
error also results when the <strong><em>QSHRMEMCTL</em></strong> system value
is 0 and PROT_WRITE is specified.</p>
</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 file descriptor or directory pointer is not valid for this
operation. The specified descriptor is incorrect, or does not refer to an open
file.</p>
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EINVAL">EINVAL</a>]</em></td>
<td align="left" valign="top">
<p>The value of the <em>addr</em> parameter is not valid. This can occur when
MAP_FIXED is specified and the value of the <em>addr</em> parameter is not a
multiple of the system page size. This may also occur if the value for
parameter <em>addr</em> is not a valid VOID* pointer or is not within the range
allowed.</p>
<p>This error number is also returned if the value of the <em>flags</em>
parameter does not indicate either MAP_SHARED or MAP_PRIVATE.</p>
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENODEV">ENODEV</a>]</em></td>
<td align="left" valign="top">
<p>The <em>fildes</em> parameter does not refer to a *TYPE2 stream file (*STMF)
in the "root" (/), QOpenSys, or user-defined file systems.</p>
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENOMEM">ENOMEM</a>]</em></td>
<td align="left" valign="top">
<p>This can occur if the portion of the local process address space reserved
for memory mapping has been exceeded.</p>
<p>When MAP_FIXED is specified, it may also occur if the address range
specified by the combination of the <em>addr</em> and <em>len</em> parameters
results in a range outside the range reserved for process local storage.</p>
</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#ENOTSUP">ENOTSUP</a>]</em></td>
<td align="left" valign="top">
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#ENXIO">ENXIO</a>]</em></td>
<td align="left" valign="top">
<p>The portion of the file, as specified by <em>off</em> and <em>len</em> is
not valid for the current size of the file.</p>
</td>
</tr>
<tr>
<td align="left" valign="top">
<em>[<a href="unix14.htm#EOVERFLOW">EOVERFLOW</a>]</em></td>
<td align="left" valign="top">
</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>
<br>
<h3>Error Messages</h3>
<p>The following messages may be sent from this function.</p>
<table width="100%" cellpadding="5">
<tr>
<th align="left" valign="top" nowrap>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">CPFA0D4 E</td>
<td align="left" valign="top">File system error occurred.</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>
</table>
<br>
<br>
<h3><a name="HDRCRTUSAG">Usage Notes</a></h3>
<ol>
<li>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>The <strong>msync()</strong> function must be used to write changed pages
of a shared mapping to disk. If a system crash occurs before the <strong>
msync</strong> function is executed, some data may not be preserved.<br>
<br>
</li>
<li>If the application chooses to mix file access methods such as <strong>
read()</strong>, <strong>readv()</strong>, <strong>write()</strong>,
<strong>writev()</strong>,
<img src="delta.gif" alt="Start of change">
<strong>ftruncate()</strong>, <strong>fclear()</strong> or their related
APIs
<img src="deltaend.gif" alt="End of change">
with <strong>mmap()</strong>, then the application
must ensure proper synchronization. While operations such as <strong>
read()</strong> , <strong>write()</strong>
<img src="delta.gif" alt="Start of change">
<strong>ftruncate()</strong>, and <strong>fclear()</strong>
<img src="deltaend.gif" alt="End of change">
are relatively atomic because of
internal locking, access through the memory map created by <strong>
mmap()</strong> does not synchronize with the <strong>read()</strong>, <strong>
readv()</strong>, <strong>write()</strong>, <strong>writev()</strong>
<img src="delta.gif" alt="Start of change">
<strong>ftruncate()</strong>, and <strong>fclear()</strong>
<img src="deltaend.gif" alt="End of change">
functions. Several synchronization functions are available, including the
<strong>fcntl()</strong> API, the <strong>DosDetFileLocks()</strong> API, and
the mutex functions. Use one of these synchronization methods around access and
modifications if atomic access is required. These techniques also will ensure
atomic access in a multiprocessor environment.<br>
<br>
</li>
<li>When using <strong>mmap()</strong>, it is necessary to first make a
nonspecific mapping request to generate a valid address. This is easily done by
specifying a requested address (<em>addr</em>) of <strong><em>0</em></strong>
and not specifying <em>MAP_FIXED</em>. Then, using the returned address <em>
pa</em> as the new requested address (<em>addr</em>) and also specifying <em>
MAP_FIXED</em> for the <em>flags</em> parameter. The example below illustrates
how this technique can be applied to achieve a contiguous mapping of several
files.<br>
<br>
</li>
<li>The address pointer returned by <strong>mmap()</strong> can only be used
with the V4R4M0 or later versions of the following languages:
<ul>
<li>ILE COBOL</li>
<li>ILE RPG</li>
<li>ILE C if the TERASPACE parameter is used when compiling the program.</li>
</ul>
<br>
</li>
<li>
<img src="delta.gif" alt="Start of change">
The application cannot write or store any data via the memory mapping which
includes any tagged (16-byte) pointers because the pointer attribute will be lost.
Some examples of tagged pointers include space pointers, system pointers,
invocation pointers etc..
<p>If the DTAMDL(*LLP64) parameter is used when compiling an ILE C program,
this limitation does not apply as the pointers will be 8 byte pointers, and their
pointer attribute will be preserved.
<img src="deltaend.gif" alt="End of change">
</li>
</ol>
<br>
<h3>Related Information</h3>
<ul>
<li><img src="delta.gif" alt="Start of change">
<a href="dossfllk.htm">DosSetFileLocks()</a>--Lock and Unlock a Byte Range
of an Open File</li>
<li><a href="fcntl.htm">fcntl()</a>--Perform File Control Command
</li>
<li><a href="fclear.htm">fclear()</a>--Write (Binary Zeros) to Descriptor
</li>
<li><a href="ftruncat.htm">ftruncate()</a>--Truncate File
<img src="deltaend.gif" alt="End of change">
</li>
<li><a href="mmap64.htm">mmap64()</a>--Memory Map a Stream File (Large File
Enabled)
</li>
<li><a href="munmap.htm">munmap()</a>--Remove Memory Mapping
</li>
<li><a href="mprotect.htm">mprotect()</a>--Change Access Protection for Memory
Mapping
</li>
<li><a href="msync.htm">msync()</a>--Synchronize Modified Data with Mapped
File</li>
<li><a href="open.htm">open()</a>--Open File
</li>
<li><a href="open64.htm">open64()</a>--Open File (Large File Enabled)
</li>
<li><img src="delta.gif" alt="Start of change">
<a href="read.htm">read()</a>--Read from Descriptor
</li>
<li><a href="readv.htm">readv()</a>--Read from Descriptor Using Multiple
Buffers
</li>
<li><a href="sysconf.htm">sysconf()</a>--Get system configuration variables</li>
<li><a href="write.htm">write()</a>--Write to Descriptor</li>
<li><a href="writev.htm">writev()</a>--Write to Descriptor Using Multiple
Buffers
<img src="deltaend.gif" alt="End of change"></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 creates two files and then produces a contiguous
memory mapping of the first data page of each file using two invocations of
<strong>mmap()</strong>.</p>
<pre>
#include &lt;errno.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/mman.h&gt;
main(void) {
size_t bytesWritten = 0;
int my_offset = 0;
char text1&Yacute;="Data for file 1.";
char text2&Yacute;="Data for file 2.";
int fd1,fd2;
int PageSize;
void *address;
void *address2;
fd1 = open("/tmp/mmaptest1",
(O_CREAT | O_TRUNC | O_RDWR),
(S_IRWXU | S_IRWXG | S_IRWXO) );
if ( fd1 &lt; 0 )
perror("open() error");
else {
bytesWritten = write(fd1, text1, strlen(text1));
if ( bytesWritten != strlen(text1) ) {
perror("write() error");
int closeRC = close(fd1);
return -1;
}
fd2 = open("/tmp/mmaptest2",
(O_CREAT | O_TRUNC | O_RDWR),
(S_IRWXU | S_IRWXG | S_IRWXO) );
if (fd2 &lt; 0 )
perror("open() error");
else {
bytesWritten = write(fd2, text2, strlen(text2));
if ( bytesWritten != strlen(text2) )
perror("write() error");
PageSize = (int)sysconf(_SC_PAGESIZE);
if ( PageSize &lt; 0) {
perror("sysconf() error");
}
else {
off_t lastoffset = lseek( fd1, PageSize-1, SEEK_SET);
if (lastoffset &lt; 0 ) {
perror("lseek() error");
}
else {
bytesWritten = write(fd1, " ", 1); /* grow file 1 to 1 page. */
off_t lastoffset = lseek( fd2, PageSize-1, SEEK_SET);
bytesWritten = write(fd2, " ", 1); /* grow file 2 to 1 page. */
/*
* We want to show how to memory map two files with
* the same memory map. We are going to create a two page
* memory map over file number 1, even though there is only
* one page available. Then we will come back and remap
* the 2nd page of the address range returned from step 1
* over the first 4096 bytes of file 2.
*/
int len;
my_offset = 0;
len = PageSize; /* Map one page */
address = mmap(NULL,
len,
PROT_READ,
MAP_SHARED,
fd1,
my_offset );
if ( address != MAP_FAILED ) {
address2 = mmap( ((char*)address)+PageSize,
len,
PROT_READ,
MAP_SHARED | MAP_FIXED, fd2,
my_offset );
if ( address2 != MAP_FAILED ) {
/* print data from file 1 */
printf("\n%s",address);
/* print data from file 2 */
printf("\n%s",address2);
} /* address 2 was okay. */
else {
perror("mmap() error=");
} /* mmap for file 2 failed. */
}
else {
perror("munmap() error=");
}
/*
* Unmap two pages.
*/
if ( munmap(address, 2*PageSize) &lt; 0) {
perror("munmap() error");
}
else;
}
}
close(fd2);
unlink( "/tmp/mmaptest2");
}
close(fd1);
unlink( "/tmp/mmaptest1");
}
/*
* Unmap two pages.
*/
if ( munmap(address, 2*PageSize) &lt; 0) {
perror("munmap() error");
}
else;
}
</pre>
<strong>Output:</strong>
<pre>
Data for file 1
Data for file 2
</pre>
<hr>
API introduced: V5R1
<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>