inweb-bootstrap/docs/foundation-module/1-pp.html

473 lines
76 KiB
HTML
Raw Normal View History

2019-02-04 22:26:45 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
2020-04-08 22:41:00 +00:00
<title>POSIX Platforms</title>
2020-04-23 22:23:44 +00:00
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
2019-02-04 22:26:45 +00:00
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
2020-04-20 22:26:08 +00:00
2020-04-25 10:33:39 +00:00
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-20 22:26:08 +00:00
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-21 16:55:17 +00:00
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-23 22:23:44 +00:00
2019-02-04 22:26:45 +00:00
</head>
2020-04-25 10:33:39 +00:00
<body class="commentary-font">
<nav role="navigation">
2020-04-13 16:06:45 +00:00
<h1><a href="../index.html">
2020-04-20 22:26:08 +00:00
<img src="../docs-assets/Octagram.png" width=72 height=72">
2020-04-13 16:06:45 +00:00
</a></h1>
<ul><li><a href="../inweb/index.html">inweb</a></li>
</ul><h2>Foundation Module</h2><ul>
<li><a href="index.html"><span class="selectedlink">foundation</span></a></li>
<li><a href="../foundation-test/index.html">foundation-test</a></li>
2020-04-13 16:06:45 +00:00
</ul><h2>Example Webs</h2><ul>
2020-04-12 16:24:23 +00:00
<li><a href="../goldbach/index.html">goldbach</a></li>
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
2020-04-15 22:45:08 +00:00
<li><a href="../eastertide/index.html">eastertide</a></li>
2020-04-14 17:36:42 +00:00
</ul><h2>Repository</h2><ul>
2020-04-20 22:34:44 +00:00
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
2020-04-14 17:36:42 +00:00
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inform/docs/index.html">inform</a></li>
<li><a href="../../../intest/docs/index.html">intest</a></li>
2020-04-13 16:06:45 +00:00
</ul>
</nav>
<main role="main">
2020-04-23 22:23:44 +00:00
<!--Weave of 'POSIX Platforms' generated by Inweb-->
2020-04-13 16:06:45 +00:00
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>POSIX Platforms</b></li></ul><p class="purpose">A version of our operating system interface suitable for POSIX-compliant operating systems.</p>
2019-02-04 22:26:45 +00:00
2020-04-15 22:45:08 +00:00
<ul class="toc"><li><a href="1-pp.html#SP3">&#167;3. Mac OS X</a></li><li><a href="1-pp.html#SP4">&#167;4. Generic Unix</a></li><li><a href="1-pp.html#SP5">&#167;5. Linux</a></li><li><a href="1-pp.html#SP6">&#167;6. Android</a></li><li><a href="1-pp.html#SP7">&#167;7. Locale</a></li><li><a href="1-pp.html#SP8">&#167;8. Environment variables</a></li><li><a href="1-pp.html#SP9">&#167;9. Executable location</a></li><li><a href="1-pp.html#SP10">&#167;10. Shell commands</a></li><li><a href="1-pp.html#SP12">&#167;12. Directory handling</a></li><li><a href="1-pp.html#SP13">&#167;13. Timestamp</a></li><li><a href="1-pp.html#SP14">&#167;14. Sync</a></li><li><a href="1-pp.html#SP15">&#167;15. Sleep</a></li><li><a href="1-pp.html#SP16">&#167;16. Notifications</a></li><li><a href="1-pp.html#SP18">&#167;18. Concurrency</a></li><li><a href="1-pp.html#SP20">&#167;20. Mutexes</a></li></ul><hr class="tocbar">
2019-02-04 22:26:45 +00:00
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>The C standard library leaves many questions unanswered about how to deal
2019-02-04 22:26:45 +00:00
with the host operating system: for example, it knows very little about
directories, or about concurrency. The POSIX standard ("Portable Operating
System Interface") aims to fill these gaps by providing facilities which
ought to exist across any Unix-like system. POSIX is neither fully present
on Unix-like systems nor fully absent from Windows, but for the limited
purposes we need here, it's simplest to divide all operating systems into
two groups: the POSIX group, and Windows.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">This Foundation module therefore comes with two variant versions of the
2020-04-22 22:57:09 +00:00
<span class="extract"><span class="extract-syntax">Platform::</span></span> section of code. The one you're reading compiles on a POSIX
2019-02-04 22:26:45 +00:00
operating system, and the other one on Windows.
</p>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>Some basics that apply to all POSIX-supporting systems.
2019-02-04 22:26:45 +00:00
</p>
2020-04-25 10:33:39 +00:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">FOLDER_SEPARATOR</span><span class="plain-syntax"> </span><span class="character-syntax">'/'</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">SHELL_QUOTE_CHARACTER</span><span class="plain-syntax"> </span><span class="character-syntax">'\''</span>
2019-02-04 22:26:45 +00:00
</pre>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">sys</span><span class="plain-syntax">/</span><span class="identifier-syntax">stat</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">sys</span><span class="plain-syntax">/</span><span class="identifier-syntax">types</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">errno</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">dirent</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">pthread</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">limits</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">unistd</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. Mac OS X. </b></p>
2019-02-04 22:26:45 +00:00
2020-04-25 10:33:39 +00:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PLATFORM_STRING</span><span class="plain-syntax"> </span><span class="string-syntax">"macos"</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">SHELL_QUOTE_CHARACTER</span><span class="plain-syntax"> </span><span class="character-syntax">'\''</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INFORM_FOLDER_RELATIVE_TO_HOME</span><span class="plain-syntax"> </span><span class="string-syntax">"Library"</span>
2019-02-04 22:26:45 +00:00
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. Generic Unix. </b>These settings are used both for the Linux versions (both command-line, by
2019-02-04 22:26:45 +00:00
Adam Thornton, and for Ubuntu, Fedora, Debian and so forth, by Philip
Chimento) and also for Solaris variants: they can probably be used for any
Unix-based system.
</p>
2020-04-25 10:33:39 +00:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PLATFORM_STRING</span><span class="plain-syntax"> </span><span class="string-syntax">"unix"</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INFORM_FOLDER_RELATIVE_TO_HOME</span><span class="plain-syntax"> </span><span class="string-syntax">""</span>
2019-02-04 22:26:45 +00:00
</pre>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">strings</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_UNIX and PLATFORM_POSIX are defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. Linux. </b>These settings are used both for the Linux versions (both command-line, by
2019-02-04 22:26:45 +00:00
Adam Thornton, and for Ubuntu, Fedora, Debian and so forth, by Philip
Chimento) and also for Solaris variants: they can probably be used for any
Unix-based system.
</p>
2020-04-25 10:33:39 +00:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PLATFORM_STRING</span><span class="plain-syntax"> </span><span class="string-syntax">"linux"</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INFORM_FOLDER_RELATIVE_TO_HOME</span><span class="plain-syntax"> </span><span class="string-syntax">""</span>
2019-02-04 22:26:45 +00:00
</pre>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">strings</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. Android. </b>These settings are used for Nathan Summers's Android versions.
2019-02-04 22:26:45 +00:00
</p>
2020-04-25 10:33:39 +00:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PLATFORM_STRING</span><span class="plain-syntax"> </span><span class="string-syntax">"android"</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">SUPPRESS_MAIN</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INFORM_FOLDER_RELATIVE_TO_HOME</span><span class="plain-syntax"> </span><span class="string-syntax">""</span>
2019-02-04 22:26:45 +00:00
</pre>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">strings</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_ANDROID and PLATFORM_POSIX are defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. Locale. </b>The following definition handles possible differences of text encoding
2019-02-04 22:26:45 +00:00
in filenames, which depend on the current "locale". Locale is an odd piece
of old Unix terminology, but one thing it includes is how the textual names
of files are encoded (as ASCII, as ISO Latin-1, as UTF-8, etc.). The default
here is UTF-8 since OS X and Linux both adopt this.
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">#</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="constant-syntax">LOCALE_IS_ISO</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">ifndef</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOCALE_IS_UTF8</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">define</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOCALE_IS_UTF8</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. Environment variables. </b></p>
2020-04-21 16:55:17 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><a href="1-wp.html#SP4" class="function-link"><span class="function-syntax">Platform::getenv</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">getenv</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::getenv is used in Windows Platform (<a href="1-wp.html#SP4">&#167;4</a>), Pathnames (<a href="3-pth.html#SP2">&#167;2</a>, <a href="3-pth.html#SP3">&#167;3</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. Executable location. </b>Fill the wide-char buffer <span class="extract"><span class="extract-syntax">p</span></span> with the path to the current executable, up to
2020-04-22 22:57:09 +00:00
length <span class="extract"><span class="extract-syntax">length</span></span>. This function is guaranteed to be called from only one
thread. Should the information be unavailable, or fail to fit into <span class="extract"><span class="extract-syntax">p</span></span>,
truncate <span class="extract"><span class="extract-syntax">p</span></span> to zero length. (On some platforms, the information will
2019-02-04 22:26:45 +00:00
always be unavailable: that doesn't mean we can't run on those platforms,
just that installation and use of Foundation-built tools is less convenient.)
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP5" class="function-link"><span class="function-syntax">Platform::where_am_i</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">PATH_MAX</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">];</span>
2020-04-25 10:33:39 +00:00
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Follow the proc filesystem symlink to the real filesystem's file</span><span class="named-paragraph-number">9.1</span></span></a><span class="character-syntax">;</span>
<span class="character-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_2" class="named-paragraph-link"><span class="named-paragraph">Transcode buffer, which is locale-encoded, into the wide-char buffer</span><span class="named-paragraph-number">9.2</span></span></a><span class="character-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="character-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.</li><li>The function Platform::where_am_i is used in <a href="1-pp.html#SP9_1_1">&#167;9.1.1</a>, <a href="1-pp.html#SP9_1_2">&#167;9.1.2</a>, <a href="1-pp.html#SP9_1_3">&#167;9.1.3</a>, Windows Platform (<a href="1-wp.html#SP5">&#167;5</a>), Pathnames (<a href="3-pth.html#SP3">&#167;3</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP9_1"></a><b>&#167;9.1. </b>On Linux, <span class="extract"><span class="extract-syntax">/proc/self/exe</span></span> is a symlink to the current process's executable.
2019-02-04 22:26:45 +00:00
Follow that link to find the path. Normally when reading a symlink, one uses
2020-04-22 22:57:09 +00:00
<span class="extract"><span class="extract-syntax">lstat()</span></span> to find the path length instead of guessing <span class="extract"><span class="extract-syntax">PATH_MAX</span></span>, but the
symlinks in <span class="extract"><span class="extract-syntax">/proc</span></span> are special and don't provide a length to <span class="extract"><span class="extract-syntax">lstat()</span></span>.
2019-02-04 22:26:45 +00:00
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Follow the proc filesystem symlink to the real filesystem's file</span><span class="named-paragraph-number">9.1</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">ssize_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">link_len</span><span class="plain-syntax"> = </span><span class="identifier-syntax">readlink</span><span class="plain-syntax">(</span><span class="string-syntax">"/proc/self/exe"</span><span class="plain-syntax">, </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">PATH_MAX</span><span class="plain-syntax">);</span>
2020-04-25 10:33:39 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">link_len</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="comment-syntax"> unable to find</span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_1_4" class="named-paragraph-link"><span class="named-paragraph">Fail</span><span class="named-paragraph-number">9.1.4</span></span></a><span class="plain-syntax">; </span><span class="comment-syntax"> unable to find</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">link_len</span><span class="plain-syntax">] = </span><span class="character-syntax">'\0'</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>This code is used in <a href="1-pp.html#SP9">&#167;9</a>.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP9_2"></a><b>&#167;9.2. </b>Next, convert the obtained buffer (which is a string in the local filename
2019-02-04 22:26:45 +00:00
encoding, and possibly in a multibyte encoding such as UTF-8) to a wide-char
string.
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Transcode buffer, which is locale-encoded, into the wide-char buffer</span><span class="named-paragraph-number">9.2</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">convert_len</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mbstowcs</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">length</span><span class="plain-syntax">);</span>
2020-04-25 10:33:39 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">convert_len</span><span class="plain-syntax"> == (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">)-1) </span><span class="comment-syntax"> wouldn't fit</span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_1_4" class="named-paragraph-link"><span class="named-paragraph">Fail</span><span class="named-paragraph-number">9.1.4</span></span></a><span class="plain-syntax">; </span><span class="comment-syntax"> wouldn't fit</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>This code is used in <a href="1-pp.html#SP9">&#167;9</a>.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP9_1_1"></a><b>&#167;9.1.1. </b>And now the Mac version:
2019-02-09 12:33:40 +00:00
</p>
2019-02-04 22:26:45 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">_NSGetExecutablePath</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">_NSGetExecutablePath</span></span>:<br>none</span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax">* </span><span class="identifier-syntax">buf</span><span class="plain-syntax">, </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax">* </span><span class="identifier-syntax">bufsize</span><span class="plain-syntax">);</span>
2020-04-20 22:26:08 +00:00
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP5" class="function-link"><span class="function-syntax">Platform::where_am_i</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">relative_path</span><span class="plain-syntax">[4 * </span><span class="identifier-syntax">PATH_MAX</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">absolute_path</span><span class="plain-syntax">[</span><span class="identifier-syntax">PATH_MAX</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">convert_len</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">pathsize</span><span class="plain-syntax"> = </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="identifier-syntax">relative_path</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">tempsize</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pathsize</span><span class="plain-syntax">;</span>
2020-04-20 22:26:08 +00:00
2020-04-24 23:06:02 +00:00
<span class="plain-syntax"> </span><span class="comment-syntax"> Get "a path" to the executable</span>
2020-04-25 10:33:39 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="1-pp.html#SP9_1_1" class="function-link"><span class="function-syntax">_NSGetExecutablePath</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">relative_path</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">tempsize</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_1_4" class="named-paragraph-link"><span class="named-paragraph">Fail</span><span class="named-paragraph-number">9.1.4</span></span></a><span class="plain-syntax">;</span>
2020-04-20 22:26:08 +00:00
2020-04-24 23:06:02 +00:00
<span class="plain-syntax"> </span><span class="comment-syntax"> Convert to canonical absolute path</span>
2020-04-25 10:33:39 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">realpath</span><span class="plain-syntax">(</span><span class="identifier-syntax">relative_path</span><span class="plain-syntax">, </span><span class="identifier-syntax">absolute_path</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_1_4" class="named-paragraph-link"><span class="named-paragraph">Fail</span><span class="named-paragraph-number">9.1.4</span></span></a><span class="plain-syntax">;</span>
2020-04-20 22:26:08 +00:00
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span>
<span class="plain-syntax"> * </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> </span><span class="identifier-syntax">encoding</span><span class="plain-syntax">, </span><span class="identifier-syntax">possibly</span><span class="plain-syntax"> </span><span class="identifier-syntax">multibyte</span><span class="plain-syntax">) </span><span class="identifier-syntax">to</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">wide</span><span class="plain-syntax">-</span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">string</span><span class="plain-syntax">. */</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">convert_len</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mbstowcs</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">absolute_path</span><span class="plain-syntax">, </span><span class="identifier-syntax">length</span><span class="plain-syntax">);</span>
2020-04-25 10:33:39 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">convert_len</span><span class="plain-syntax"> == (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">)-1) </span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_1_4" class="named-paragraph-link"><span class="named-paragraph">Fail</span><span class="named-paragraph-number">9.1.4</span></span></a><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::where_am_i is used in <a href="1-pp.html#SP9">&#167;9</a>, <a href="1-pp.html#SP9_1_2">&#167;9.1.2</a>, <a href="1-pp.html#SP9_1_3">&#167;9.1.3</a>, Windows Platform (<a href="1-wp.html#SP5">&#167;5</a>), Pathnames (<a href="3-pth.html#SP3">&#167;3</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP9_1_2"></a><b>&#167;9.1.2. </b>For Unix, there's nothing we can generically do.
2019-02-09 12:33:40 +00:00
</p>
2019-02-04 22:26:45 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP5" class="function-link"><span class="function-syntax">Platform::where_am_i</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax">) {</span>
2020-04-25 10:33:39 +00:00
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_1_4" class="named-paragraph-link"><span class="named-paragraph">Fail</span><span class="named-paragraph-number">9.1.4</span></span></a><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_UNIX and PLATFORM_POSIX are defined.</li><li>The function Platform::where_am_i is used in <a href="1-pp.html#SP9">&#167;9</a>, <a href="1-pp.html#SP9_1_1">&#167;9.1.1</a>, <a href="1-pp.html#SP9_1_3">&#167;9.1.3</a>, Windows Platform (<a href="1-wp.html#SP5">&#167;5</a>), Pathnames (<a href="3-pth.html#SP3">&#167;3</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP9_1_3"></a><b>&#167;9.1.3. </b>On Android, there's no real need for this.
2019-02-09 12:33:40 +00:00
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP5" class="function-link"><span class="function-syntax">Platform::where_am_i</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax">) {</span>
2020-04-25 10:33:39 +00:00
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pp.html#SP9_1_4" class="named-paragraph-link"><span class="named-paragraph">Fail</span><span class="named-paragraph-number">9.1.4</span></span></a><span class="plain-syntax">;</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_ANDROID and PLATFORM_POSIX are defined.</li><li>The function Platform::where_am_i is used in <a href="1-pp.html#SP9">&#167;9</a>, <a href="1-pp.html#SP9_1_1">&#167;9.1.1</a>, <a href="1-pp.html#SP9_1_2">&#167;9.1.2</a>, Windows Platform (<a href="1-wp.html#SP5">&#167;5</a>), Pathnames (<a href="3-pth.html#SP3">&#167;3</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP9_1_4"></a><b>&#167;9.1.4. </b>All of the above make use of:
2019-02-09 12:33:40 +00:00
</p>
2020-04-25 10:33:39 +00:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail</span><span class="named-paragraph-number">9.1.4</span></span><span class="comment-syntax"> =</span>
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">[0] = </span><span class="character-syntax">'\0'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>This code is used in <a href="1-pp.html#SP9_1">&#167;9.1</a>, <a href="1-pp.html#SP9_2">&#167;9.2</a>, <a href="1-pp.html#SP9_1_1">&#167;9.1.1</a> (three times), <a href="1-pp.html#SP9_1_2">&#167;9.1.2</a>, <a href="1-pp.html#SP9_1_3">&#167;9.1.3</a>.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. Shell commands. </b></p>
2019-02-04 22:26:45 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP6" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">system</span><span class="plain-syntax">(</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.</li><li>The function Platform::system is used in <a href="1-pp.html#SP11">&#167;11</a>, <a href="1-pp.html#SP14">&#167;14</a>, Windows Platform (<a href="1-wp.html#SP6">&#167;6</a>), Shell (<a href="3-shl.html#SP5">&#167;5</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. </b>In MacOS 10.5, a new implementation of the C standard library
2020-04-22 22:57:09 +00:00
crippled performance of <span class="extract"><span class="extract-syntax">system()</span></span> by placing it behind a global mutex, so
2019-03-12 23:32:12 +00:00
that it was impossible for two cores to be calling the function at the same
time. The net effect of this is that the Inform test suite, executing in
Intest, ran in 1/16th speed. This issue didn't come to light until 2019,
2020-04-22 22:57:09 +00:00
however, because the build setting <span class="extract"><span class="extract-syntax">-mmacosx-version-min=10.4</span></span> turned out
to force use of the (perfectly good) pre-10.5 library, where <span class="extract"><span class="extract-syntax">system()</span></span>
2019-03-12 23:32:12 +00:00
continued to run in a multi-threaded way, just as it does on Linux and
most all other Unixes. The old library was eventually withdrawn by Apple
in 2018, and in any case would stop working at some point in 2019-20 due
to the final removal of 32-bit binary support from MacOS.
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">It took several days to find a pthread-safe way to reimplement <span class="extract"><span class="extract-syntax">system()</span></span>.
2020-04-22 22:57:09 +00:00
The obvious way, using <span class="extract"><span class="extract-syntax">fork()</span></span> and then running <span class="extract"><span class="extract-syntax">execve()</span></span> on the child
process &mdash; essentially the standard way to implement <span class="extract"><span class="extract-syntax">system()</span></span>, if you forget
2019-03-12 23:32:12 +00:00
about signal-handling &mdash; led to obscure and unrepeatable memory corruption
bugs in Intest, with the worker threads apparently writing on each other's
2020-04-22 22:57:09 +00:00
memory space. Using <span class="extract"><span class="extract-syntax">posix_spawn()</span></span> instead appears to work better.
2019-03-12 23:32:12 +00:00
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">spawn</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> &lt;</span><span class="identifier-syntax">sys</span><span class="plain-syntax">/</span><span class="identifier-syntax">wait</span><span class="plain-syntax">.</span><span class="identifier-syntax">h</span><span class="plain-syntax">&gt;</span>
<span class="reserved-syntax">extern</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> **</span><span class="identifier-syntax">environ</span><span class="plain-syntax">;</span>
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP6" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">argv</span><span class="plain-syntax">[] = {</span><span class="string-syntax">"sh"</span><span class="plain-syntax">, </span><span class="string-syntax">"-c"</span><span class="plain-syntax">, (</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">cmd</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">};</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pid_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">pid</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">status</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posix_spawn</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">pid</span><span class="plain-syntax">, </span><span class="string-syntax">"/bin/sh"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">argv</span><span class="plain-syntax">, </span><span class="identifier-syntax">environ</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">status</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">waitpid</span><span class="plain-syntax">(</span><span class="identifier-syntax">pid</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">status</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">) != -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">status</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"waitpid failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"posix_spawn: %s\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">strerror</span><span class="plain-syntax">(</span><span class="identifier-syntax">status</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"posix_spawn failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::system is used in <a href="1-pp.html#SP10">&#167;10</a>, <a href="1-pp.html#SP14">&#167;14</a>, Windows Platform (<a href="1-wp.html#SP6">&#167;6</a>), Shell (<a href="3-shl.html#SP5">&#167;5</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. Directory handling. </b></p>
2020-04-21 16:55:17 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::mkdir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mkdir</span><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">S_IRWXU</span><span class="plain-syntax"> | </span><span class="identifier-syntax">S_IRWXG</span><span class="plain-syntax"> | </span><span class="identifier-syntax">S_IROTH</span><span class="plain-syntax"> | </span><span class="identifier-syntax">S_IXOTH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">errno</span><span class="plain-syntax"> == </span><span class="identifier-syntax">EEXIST</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::opendir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dirp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">opendir</span><span class="plain-syntax">(</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">dirp</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::readdir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">path_to</span><span class="plain-syntax">[2*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">+2];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">stat</span><span class="plain-syntax"> </span><span class="identifier-syntax">file_status</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dirp</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">dirent</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">dp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">readdir</span><span class="plain-syntax">(</span><span class="identifier-syntax">dirp</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">path_to</span><span class="plain-syntax">, </span><span class="string-syntax">"%s%c%s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">, </span><span class="constant-syntax">FOLDER_SEPARATOR</span><span class="plain-syntax">, </span><span class="identifier-syntax">dp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">d_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">stat</span><span class="plain-syntax">(</span><span class="identifier-syntax">path_to</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">file_status</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">S_ISDIR</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_status</span><span class="plain-syntax">.</span><span class="identifier-syntax">st_mode</span><span class="plain-syntax">)) </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">, </span><span class="string-syntax">"%s/"</span><span class="plain-syntax">, </span><span class="identifier-syntax">dp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">d_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">, </span><span class="identifier-syntax">dp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">d_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::closedir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dirp</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">closedir</span><span class="plain-syntax">(</span><span class="identifier-syntax">dirp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::mkdir is used in Windows Platform (<a href="1-wp.html#SP7">&#167;7</a>), Pathnames (<a href="3-pth.html#SP9">&#167;9</a>).</li><li>The function Platform::opendir is used in Windows Platform (<a href="1-wp.html#SP7">&#167;7</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li><li>The function Platform::readdir is used in Windows Platform (<a href="1-wp.html#SP7">&#167;7</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li><li>The function Platform::closedir is used in Windows Platform (<a href="1-wp.html#SP7">&#167;7</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP13"></a><b>&#167;13. Timestamp. </b>There are implementations of the C standard library where <span class="extract"><span class="extract-syntax">time_t</span></span> has
2020-03-29 23:29:23 +00:00
super-weird behaviour, but on almost POSIX systems, time 0 corresponds to
midnight on 1 January 1970. All we really need is that the "never" value
is one which is earlier than any possible timestamp on the files we'll
be dealing with.
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">time_t</span><span class="plain-syntax">) </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2020-04-21 23:52:25 +00:00
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::timestamp</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">stat</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stat</span><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">filestat</span><span class="plain-syntax">) != -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">.</span><span class="identifier-syntax">st_mtime</span><span class="plain-syntax">;</span>
2020-04-21 23:52:25 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">();</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::never_time is used in Windows Platform (<a href="1-wp.html#SP12">&#167;12</a>).</li><li>The function Platform::timestamp is used in Windows Platform (<a href="1-wp.html#SP12">&#167;12</a>), Filenames (<a href="3-fln.html#SP12">&#167;12</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP14"></a><b>&#167;14. Sync. </b>Both names here are of directories which do exist. The function makes
2020-04-22 22:57:09 +00:00
the <span class="extract"><span class="extract-syntax">dest</span></span> tree an exact copy of the <span class="extract"><span class="extract-syntax">source</span></span> tree (and therefore deletes
anything different which was originally in <span class="extract"><span class="extract-syntax">dest</span></span>).
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">In POSIX world, we can fairly well depend on <span class="extract"><span class="extract-syntax">rsync</span></span> being around:
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::rsync</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Platform::rsync</span></span>:<br>Pathnames - <a href="3-pth.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">[10*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">, </span><span class="string-syntax">"rsync -a --delete "</span><span class="plain-syntax">);</span>
2020-04-21 23:52:25 +00:00
<span class="plain-syntax"> </span><a href="1-pp.html#SP14" class="function-link"><span class="function-syntax">Platform::quote_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax"> + </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">), </span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">);</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax"> + </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">), </span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
2020-04-21 23:52:25 +00:00
<span class="plain-syntax"> </span><a href="1-pp.html#SP14" class="function-link"><span class="function-syntax">Platform::quote_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax"> + </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">), </span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP6" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">);</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">}</span>
2020-04-25 10:33:39 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::quote_text</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Platform::quote_text</span></span>:<br>none</span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">quoted</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">raw</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">terminate</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">quoted</span><span class="plain-syntax">[0] = </span><span class="constant-syntax">SHELL_QUOTE_CHARACTER</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">qp</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">raw</span><span class="plain-syntax">[</span><span class="identifier-syntax">rp</span><span class="plain-syntax">]; </span><span class="identifier-syntax">rp</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">raw</span><span class="plain-syntax">[</span><span class="identifier-syntax">rp</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">SHELL_QUOTE_CHARACTER</span><span class="plain-syntax">) </span><span class="identifier-syntax">quoted</span><span class="plain-syntax">[</span><span class="identifier-syntax">qp</span><span class="plain-syntax">++] = </span><span class="character-syntax">'\\'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">quoted</span><span class="plain-syntax">[</span><span class="identifier-syntax">qp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">terminate</span><span class="plain-syntax">) </span><span class="identifier-syntax">quoted</span><span class="plain-syntax">[</span><span class="identifier-syntax">qp</span><span class="plain-syntax">++] = </span><span class="constant-syntax">FOLDER_SEPARATOR</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">quoted</span><span class="plain-syntax">[</span><span class="identifier-syntax">qp</span><span class="plain-syntax">++] = </span><span class="constant-syntax">SHELL_QUOTE_CHARACTER</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">quoted</span><span class="plain-syntax">[</span><span class="identifier-syntax">qp</span><span class="plain-syntax">++] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP15"></a><b>&#167;15. Sleep. </b></p>
2020-04-21 16:55:17 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::sleep</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">seconds</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">sleep</span><span class="plain-syntax">((</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">seconds</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::sleep is used in Windows Platform (<a href="1-wp.html#SP8">&#167;8</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP16"></a><b>&#167;16. Notifications. </b>The "submarine" sound is a gloomy thunk; the "bell" is the three-tone rising
2019-02-04 22:26:45 +00:00
alert noise which iPhones make when they receive texts, but which hackers of a
certain age will remember as the "I have ripped your music CD now" alert from
SoundJam, the program which Apple bought and rebranded as iTunes. Apple now
seems to consider this alert a general-purpose "something good has happened".
</p>
2020-04-24 23:06:02 +00:00
<p class="commentary">It is anybody's guess how long Apple will permit the shell command <span class="extract"><span class="extract-syntax">osascript</span></span>
2019-02-04 22:26:45 +00:00
to survive, given the MacOS team's current hostility to scripting; we're
actually running a one-line AppleScript here.
</p>
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::notification</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">happy</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sound_name</span><span class="plain-syntax"> = </span><span class="string-syntax">"Bell.aiff"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">happy</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">sound_name</span><span class="plain-syntax"> = </span><span class="string-syntax">"Submarine.aiff"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="string-syntax">"osascript -e 'display notification \"%S\" "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"sound name \"%s\" with title \"intest Results\"'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">sound_name</span><span class="plain-syntax">);</span>
2020-04-21 23:52:25 +00:00
<span class="plain-syntax"> </span><a href="3-shl.html#SP5" class="function-link"><span class="function-syntax">Shell::run</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">);</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::notification is used in <a href="1-pp.html#SP17">&#167;17</a>, Windows Platform (<a href="1-wp.html#SP9">&#167;9</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP17"></a><b>&#167;17. </b></p>
2020-04-21 16:55:17 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::notification</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">happy</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.</li><li>The function Platform::notification is used in <a href="1-pp.html#SP16">&#167;16</a>, Windows Platform (<a href="1-wp.html#SP9">&#167;9</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP18"></a><b>&#167;18. Concurrency. </b></p>
2020-04-21 16:55:17 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 16:55:17 +00:00
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_attr_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP19"></a><b>&#167;19. </b></p>
2020-04-21 16:55:17 +00:00
2020-04-25 10:33:39 +00:00
<pre class="displayed-code all-displayed-code code-font">
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP11" class="function-link"><span class="function-syntax">Platform::create_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">,</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *(*</span><span class="identifier-syntax">fn</span><span class="plain-syntax">)(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *), </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">arg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_create</span><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="identifier-syntax">arg</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP11" class="function-link"><span class="function-syntax">Platform::join_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pthread_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax">** </span><span class="identifier-syntax">rv</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_join</span><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">rv</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
2020-04-21 23:52:25 +00:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP11" class="function-link"><span class="function-syntax">Platform::init_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pthread_attr_t</span><span class="plain-syntax">* </span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pthread_attr_init</span><span class="plain-syntax">(</span><span class="identifier-syntax">pa</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"thread initialisation failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pthread_attr_setstacksize</span><span class="plain-syntax">(</span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">size</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"thread stack sizing failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
2020-04-21 23:52:25 +00:00
<span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP11" class="function-link"><span class="function-syntax">Platform::get_thread_stack_size</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pthread_attr_t</span><span class="plain-syntax">* </span><span class="identifier-syntax">pa</span><span class="plain-syntax">) {</span>
2020-04-21 16:55:17 +00:00
<span class="plain-syntax"> </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">mystacksize</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pthread_attr_getstacksize</span><span class="plain-syntax">(</span><span class="identifier-syntax">pa</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">mystacksize</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">mystacksize</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::create_thread is used in Windows Platform (<a href="1-wp.html#SP11">&#167;11</a>).</li><li>The function Platform::join_thread is used in Windows Platform (<a href="1-wp.html#SP11">&#167;11</a>).</li><li>The function Platform::init_thread is used in Windows Platform (<a href="1-wp.html#SP11">&#167;11</a>).</li><li>The function Platform::get_thread_stack_size is used in Windows Platform (<a href="1-wp.html#SP11">&#167;11</a>).</li></ul>
2020-04-24 23:06:02 +00:00
<p class="commentary firstcommentary"><a id="SP20"></a><b>&#167;20. Mutexes. </b></p>
2019-02-04 22:26:45 +00:00
2020-04-25 10:33:39 +00:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">CREATE_MUTEX</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">static</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_mutex_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PTHREAD_MUTEX_INITIALIZER</span><span class="plain-syntax">;</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOCK_MUTEX</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">) </span><span class="identifier-syntax">pthread_mutex_lock</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">UNLOCK_MUTEX</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">) </span><span class="identifier-syntax">pthread_mutex_unlock</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
2019-02-04 22:26:45 +00:00
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
<hr class="tocbar">
2020-04-09 17:32:37 +00:00
<ul class="toc"><li><a href="1-fm.html">Back to 'Foundation Module'</a></li><li><a href="1-wp.html">Continue with 'Windows Platform'</a></li></ul><hr class="tocbar">
<!--End of weave-->
2020-04-23 22:23:44 +00:00
</main>
2019-02-04 22:26:45 +00:00
</body>
</html>