<html><head><meta charset="UTF-8">
<title>Update normative reference to POSIX</title>
  <style type='text/css'>
  body {font-variant-ligatures: none;}
  p {text-align:justify}
  li {text-align:justify}
  blockquote.note, div.note
  {
          background-color:#E0E0E0;
          padding-left: 15px;
          padding-right: 15px;
          padding-top: 1px;
          padding-bottom: 1px;
  }
  p code {color:navy}
  ins p code {color:#00A000}
  p ins code {color:#00A000}
  p del code {color:#A00000}
  ins {color:#00A000}
  del {color:#A00000}
  table#boilerplate { border:0 }
  table#boilerplate td { padding-left: 2em }
  table.bordered, table.bordered th, table.bordered td {
    border: 1px solid;
    text-align: center;
  }
  ins.block {color:#00A000; text-decoration: none}
  del.block {color:#A00000; text-decoration: none}
  #hidedel:checked ~ * del, #hidedel:checked ~ * del * { display:none; visibility:hidden }
  </style>
</head><body>
<table id="boilerplate">
<tr><td>Document number</td><td>P2227R0</td></tr>
<tr><td>Date</td><td>2020-10-02</td></tr>
<tr><td>Audience</td><td>LWG</td></tr>
<tr><td>Reply-to</td><td>Jonathan Wakely &lt;cxx&#x40;kayari.org&gt;</td></tr>
</table><hr>
<h1>Update normative reference to POSIX</h1>
<ul>
 <li>
 <ul>
  <li><a href="#Introduction">Introduction</a></li>
  <li><a href="#Motivation">Motivation</a>
  <ul>
   <li><a href="#Relation-to-the-C-standard">Relation to the C standard</a></li>
   <li><a href="#Undefined--3c-code-3e-errno-3c--2f-code-3e--constants">Undefined <code>errno</code> constants</a></li>
   <li><a href="#File-system-operations">File system operations</a></li>
   <li><a href="#Regular-expressions">Regular expressions</a></li>
   <li><a href="#Other-mentions-of-POSIX">Other mentions of POSIX</a></li>
  </ul>
  </li>
  <li><a href="#Proposed-Changes">Proposed Changes</a></li>
  <li><a href="#POSIX-versions">POSIX versions</a></li>
  <li><a href="#Acknowledgments">Acknowledgments</a></li>
  <li><a href="#References">References</a></li>
 </ul>
 </li>
</ul>
<a name="Introduction"></a>
<h2>Introduction</h2>

<p>The C++ standard has a normative reference to ISO/IEC 9945:2003
(aka POSIX.1-2001 aka The Single UNIX Specification, version 3).
However, the C++ standard library refers to POSIX functions and macros
which are not defined in that document, as they weren't added until
ISO/IEC/IEEE 9945:2009 (aka POSIX.1-2008 aka SUSv4).
The C++ standard should update its reference.</p>

<a name="Motivation"></a>
<h2>Motivation</h2>

<p>When we refer to something in POSIX, we should ensure it is actually defined
in the document we reference.</p>

<p>The index only contains three references to POSIX
(for [intro.refs] and [re.matchflag])
which is woefully incomplete.</p>

<p>The relevant references to POSIX in the current C++ working paper are:</p>

<ul>
<li>[namespace.posix] refers to "ISO/IEC 9945".</li>
<li>[errno] refers to <code>&lt;errno.h&gt;</code> and the <code>Exxx</code> constants. See below.</li>
<li>[fs.conform.9945] refers to POSIX, but not to any specific features of it.</li>
<li>[fs.class.path.general] has an example which refers to
<a href="https://pubs.opengroup.org/onlinepubs/009696799/basedefs/xbd_chap04.html#tag_04_11">4.11 Pathname Resolution</a>.</li>
<li>[fs.path.generic] refers to the
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282">Portable Filename Character Set</a>
which is unchanged.</li>
<li>[fs.enum.perms] [tab:fs.enum.perms] refers to the
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html"><code>&lt;sys/stat.h&gt;</code></a>
macros, which are unchanged.</li>
<li>[fs.class.directory.iterator.general] refers to <code>readdir_r</code>.</li>
<li>[fs.op.create.directory] "as if by POSIX <code>mkdir()</code>".</li>
<li>[fs.op.create.dir.symlk] "as if by POSIX <code>symlink()</code>".</li>
<li>[fs.op.create.hard.lk] "as if by POSIX <code>link()</code>".</li>
<li>[fs.op.create.symlink] "as if by POSIX <code>symlink()</code>".</li>
<li>[fs.op.current.path] "as if by POSIX <code>getcwd()</code>", "as if by POSIX <code>chdir()</code>".</li>
<li>[fs.op.equivalent] "as if by the values of the POSIX <code>stat</code> class" (non-normative).</li>
<li>[fs.op.file.size] "as if by POSIX <code>stat</code>".</li>
<li>[fs.op.last.write.time] "as if by POSIX <code>stat()</code>", "as if by POSIX <code>futimens()</code>" (see below).</li>
<li>[fs.op.permissions] "as if by POSIX <code>fchmodat()</code>" (see below).</li>
<li>[fs.op.remove] "as if by POSIX <code>remove()</code>".</li>
<li>[fs.op.remove.all] "as if by POSIX <code>remove()</code>".</li>
<li>[fs.op.rename] "as if by POSIX <code>rename()</code>".</li>
<li>[fs.op.resize.file] "as if by POSIX <code>truncate()</code>" (see below).</li>
<li>[fs.op.space] "by using POSIX <code>statvfs</code> to obtain a POSIX <code>struct statvfs</code>"
(see below).</li>
<li>[fs.op.status] "as if by using POSIX <code>stat()</code>", "as if by POSIX <code>S_ISREG</code>" etc.</li>
<li>[fs.op.symlink.status] "as if by using POSIX <code>lstat()</code> to obtain a POSIX <code>struct stat</code>", "as if by POSIX <code>S_ISLNK</code>".</li>
<li>[re.matchflag] [tab:re.synopt] "See also: POSIX, Base Definitions and Headers, Section 9.3",
"See also: POSIX, Base Definitions and Headers, Section 9.4".</li>
<li>[re.grammar] "equivalent to that of the same features in regular expressions in POSIX".</li>
<li>[thread.req.exception] "an errno of EPERM is reported by a POSIX API call",
"since POSIX specifies an errno of EPERM".</li>
</ul>


<a name="Relation-to-the-C-standard"></a>
<h3>Relation to the C standard</h3>

<p>It is worth noting that POSIX.1-2001 and later editions refer to C99
by reference.
C++17 refers to C11 and since C++20 we refer to C17.
I don't think this is a problem.</p>

<p>We only ever define behaviour "as if by POSIX <code>foo</code>",
not by actually requiring <code>foo</code> to exist in the C++ implementation,
or for the C++ library implementation to actually use <code>foo</code> under the hood
(which certainly isn't the case for the Microsoft Visual C++ library).
As long as the behaviour of the C++ library functions is consistent with
the specified behaviour of the POSIX function, it doesn't matter that
the program is not executing in a C99 environment (or a C environment at all!)</p>

<p>The next revision of POSIX is likely to refer to C17, as C++20 does.
If that is published before C++23 we can revisit this topic and
in all probability reference the new POSIX standard.
But I see no reason we can't make the important fixes proposed below
without having the references to C be the same.</p>

<a name="Undefined--3c-code-3e-errno-3c--2f-code-3e--constants"></a>
<h3>Undefined <code>errno</code> constants</h3>

<p>In the original C++ standard the <code>&lt;cerrno&gt;</code> and <code>&lt;errno.h&gt;</code> headers contained
only the macros required by ISO C, <code>EDOM</code>, <code>ERANGE</code> and <code>errno</code>.
The C++11 standard expanded this and subclause [errno] now says:</p>

<blockquote><p>The contents of the header <code>&lt;cerrno&gt;</code> are the same as the POSIX header
<code>&lt;errno.h&gt;</code>, except that <code>errno</code> shall be defined as a macro.</p></blockquote>

<p>Following this statement is a list of all the <code>Exxx</code> macros defined in the
header.
This list includes <code>ENOTRECOVERABLE</code> and <code>EOWNERDEAD</code>,
but those macros are not defined in the document named in [intro.refs],
see <a href="https://pubs.opengroup.org/onlinepubs/009696799/basedefs/errno.h.html">POSIX.1-2001 <code>errno.h</code></a>.
Those error numbers were added to POSIX in the 2008 revision,
see <a href="https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/basedefs/errno.h.html">POSIX.1-2008 <code>errno.h</code></a>, which says:</p>

<blockquote><p>The [ENOTRECOVERABLE] and [EOWNERDEAD] errors are added from
The Open Group Technical Standard, 2006, Extended API Set Part 2.</p></blockquote>

<p>The 2008 revision also allows <code>ENOTSUP</code> and <code>EOPNOTSUPP</code> to have the same value,
which was not the case in POSIX.1-2001.</p>

<p>The POSIX-1.2008 standard also defines some additional error numbers
which are not present in the C++ standard,
<code>EDQUOT</code>, <code>EMULTIHOP</code>, and <code>ENOLINK</code>.
POSIX doesn't give any meaning to these,
it just says they are "Reserved".
We should consider whether we want to reserve those in C++ too,
as we already do for <code>ESTALE</code>,
but I am not proposing that here.</p>

<a name="File-system-operations"></a>
<h3>File system operations</h3>

<p>The C++17 standard incorporated the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html">File System TS</a>,
adding many new functions which are defined by reference to similar
POSIX functions.
The File System TS has a normative reference to POSIX,
but uses an undated reference to ISO/IEC 9945
(which by ISO convention means the latest revision of that standard).
When the contents of the TS were incorporated into the C++ IS we didn't
ensure our reference to ISO/IEC 9945:2003 was still appropriate.</p>

<p>The reference to 4.11 from [fs.class.path.general] needs to be updated.
It is
<a href="https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/basedefs/V1_chap04.html#tag_04_12">4.12 Pathname Resolution</a>
in POSIX.1-2008
and
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13">4.13 Pathname Resolution</a>
in POSIX.1-2017
(which is ISO/IEC/IEEE 9945:2009 plus the 2013 and 2017 Technical Corrigenda).
Since the TCs are just lists of changes, not a complete document,
the 4.12 section number from ISO/IEC/IEEE 9945:2009 seems to be correct still.</p>

<p>Most of the POSIX functions we refer to are present in POSIX.1-2001,
but the <code>futimens</code> functions used in [fs.ops.last.write.time]
and the <code>fchmodat</code> function used in [fs.op.permissions]
don't exist at all in POSIX.1-2001.
Strictly speaking, this means the semantics of <code>filesystem::last_write_time</code>
and <code>filesystem::permissions</code> are undefined.</p>

<p>Two other functions,
(<a href="https://pubs.opengroup.org/onlinepubs/009696799/functions/truncate.html"><code>truncate</code></a>
and
<a href="https://pubs.opengroup.org/onlinepubs/009696799/functions/statvfs.html"><code>statvfs</code></a>),
are optional and not required to exist on conforming POSIX systems
(they are part of the X/Open System Interfaces Extension (aka XSI)).
In the POSIX.1-2008 revision those functions are moved from the XSI option
to the Base specification, so they are no longer optional.</p>

<p>The <code>S_ISVTX</code> macro used with <code>stat</code> is an optional feature, part of XSI again.
It remains optional even in POSIX.1-2008 and POSIX.1-2017.</p>

<p>There is also a non-normative note referencing <code>readdir_r</code> which is
part of the Thread-Safe Functions (TSF) option in POSIX.1-2001,
but moved to Base for POSIX.1-2008.
However, the <code>readdir_r</code> API is flawed, deprecated by some implementations,
and may be removed in a future version of POSIX.
We should just refer to <code>readdir</code> in this note, as we are not dependent
on anything specific to <code>readdir_r</code> here.</p>

<a name="Regular-expressions"></a>
<h3>Regular expressions</h3>

<p>The references in [re.grammar] are still the right sections for the latest
POSIX standard, see
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03">9.3 Basic Regular Expressions</a>
and
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">9.4 Extended Regular Expressions</a>.</p>

<a name="Other-mentions-of-POSIX"></a>
<h3>Other mentions of POSIX</h3>

<p>The subclause [value.error.codes] and several places in [filesystem] refer to
POSIX-based operating systems,
but that's a general description and not a specific reference to anything
defined in POSIX.
Those are not relevant here.</p>

<p>The subclause [support.runtime.general] refers to
"the POSIX functions <code>setenv</code> and <code>getenv</code>",
which needs no changes.</p>

<p>Subclause [format.string.std] has a note saying
"This is similar to the semantics of the POSIX <code>wcswidth</code> function."
That function is an XSI extension, so optional for POSIX implementations.
But we aren't requiring it to be supported,
only pointing out a similarity.
The following paragraph has another use of "POSIX-based operating systems"
which isn't relevant here.</p>

<p>Two footnotes in [locale.time.put.virtuals] refer to POSIX,
but need no changes related to this paper
(they shouldn't use "should" in notes, but that's another topic).</p>

<a name="Proposed-Changes"></a>
<h2>Proposed Changes</h2>

<p>To fix these problems we need to change the normative reference in [intro.refs]
to be a later revision of the POSIX standard,
ISO/IEC/IEEE 9945:2009 including Corrigenda 1 (2013) and Corrigenda 2 (2017).</p>

<ul>
<li>Update [intro.refs] paragraph 1 as shown:</li>
</ul>


<blockquote><p>(1.6) &mdash; ISO/IEC<ins>/IEEE</ins> 9945:<del>2003</del><ins>2009</ins>, Information Technology — Portable Operating System Interface (POSIX)<br/>
(1.?) <ins>&mdash; ISO/IEC/IEEE 9945:2009/Cor 1:2013, Information Technology — Portable Operating System Interface (POSIX), Technical Corrigendum 1</ins><br/>
(1.?) <ins>&mdash; ISO/IEC/IEEE 9945:2009/Cor 2:2017, Information Technology — Portable Operating System Interface (POSIX), Technical Corrigendum 2</ins></p></blockquote>

<ul>
<li>Update [namespace.posix] to add IEEE to the document number:</li>
</ul>


<blockquote><p>The namespace <code>posix</code> is reserved for use by
  ISO/IEC<ins>/IEEE</ins> 9945 and other POSIX standards.</p></blockquote>

<ul>
<li>Update [fs.class.path.general] paragraph 6 as shown:</li>
</ul>


<blockquote><p><em>Pathname resolution</em> is the operating system dependent mechanism
  for resolving a pathname to a particular file in a file hierarchy.
  There may be multiple pathnames that resolve to the same file.
  <em>[Example 1:</em> POSIX specifies the mechanism in section
  4.<del>11</del><ins>12</ins>, Pathname resolution.  — <em>end example]</em></p></blockquote>

<ul>
<li>Update [fs.class.directory.iterator.general] paragraph 11 as shown:</li>
</ul>


<blockquote><p> See POSIX <code>readdir<del>_r</del></code>.</p></blockquote>

<a name="POSIX-versions"></a>
<h2>POSIX versions</h2>

<p>Because the POSIX standard is republished by a number of different bodies
it has different names and even publication years depending who you ask.
See <a href="https://en.wikipedia.org/wiki/POSIX#Versions">POSIX Versions</a> and
<a href="https://en.wikipedia.org/wiki/Single_UNIX_Specification#History">Single UNIX Specification History</a>
if you want to see what's what.</p>

<a name="Acknowledgments"></a>
<h2>Acknowledgments</h2>

<p>Thanks to Aaron Ballman and Eric Blake for comments on the initial draft.</p>

<a name="References"></a>
<h2>References</h2>

<p>ISO/IEC 14882:2017
Programming languages — C++
<a href="https://www.iso.org/standard/68564.html">https://www.iso.org/standard/68564.html</a></p>

<p>ISO/IEC 9945-1:2003
Information technology — Portable Operating System Interface (POSIX) — Part 1: Base Definitions
<a href="https://www.iso.org/standard/38789.html">https://www.iso.org/standard/38789.html</a></p>

<p>ISO/IEC/IEEE 9945:2009
Information technology — Portable Operating System Interface (POSIX®) Base Specifications, Issue 7,
<a href="https://www.iso.org/standard/50516.html">https://www.iso.org/standard/50516.html</a></p>

<p>ISO/IEC/IEEE 9945:2009/Cor 1:2013
Information technology — Portable Operating System Interface (POSIX®) Base Specifications, Issue 7 — Technical Corrigendum 1,
<a href="https://www.iso.org/standard/62005.html">https://www.iso.org/standard/62005.html</a></p>

<p>ISO/IEC/IEEE 9945:2009/Cor 2:2017
Information technology — Portable Operating System Interface (POSIX®) Base Specifications, Issue 7 — Technical Corrigendum 2,
<a href="https://www.iso.org/standard/73314.html">https://www.iso.org/standard/73314.html</a></p>

<p>ISO/IEC TS 18822:2015
Programming languages — C++ — File System Technical Specification
<a href="https://www.iso.org/standard/63483.html">https://www.iso.org/standard/63483.html</a></p>
</body></html>
