474 lines
76 KiB
HTML
474 lines
76 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>POSIX Platforms</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<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">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Octagram.png" width=72 height=72">
|
|
</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>
|
|
</ul><h2>Example Webs</h2><ul>
|
|
<li><a href="../goldbach/index.html">goldbach</a></li>
|
|
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
|
|
<li><a href="../eastertide/index.html">eastertide</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</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>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'POSIX Platforms' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<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></div>
|
|
<p class="purpose">A version of our operating system interface suitable for POSIX-compliant operating systems.</p>
|
|
|
|
<ul class="toc"><li><a href="1-pp.html#SP3">§3. Mac OS X</a></li><li><a href="1-pp.html#SP4">§4. Generic Unix</a></li><li><a href="1-pp.html#SP5">§5. Linux</a></li><li><a href="1-pp.html#SP6">§6. Android</a></li><li><a href="1-pp.html#SP7">§7. Locale</a></li><li><a href="1-pp.html#SP8">§8. Environment variables</a></li><li><a href="1-pp.html#SP9">§9. Executable location</a></li><li><a href="1-pp.html#SP10">§10. Shell commands</a></li><li><a href="1-pp.html#SP12">§12. Directory handling</a></li><li><a href="1-pp.html#SP13">§13. Timestamp and file size</a></li><li><a href="1-pp.html#SP14">§14. Sync</a></li><li><a href="1-pp.html#SP15">§15. Sleep</a></li><li><a href="1-pp.html#SP16">§16. Notifications</a></li><li><a href="1-pp.html#SP18">§18. Concurrency</a></li><li><a href="1-pp.html#SP20">§20. Mutexes</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1"></a><b>§1. </b>The C standard library leaves many questions unanswered about how to deal
|
|
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>
|
|
|
|
<p class="commentary">This Foundation module therefore comes with two variant versions of the
|
|
<span class="extract"><span class="extract-syntax">Platform::</span></span> section of code. The one you're reading compiles on a POSIX
|
|
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>
|
|
<p class="commentary firstcommentary"><a id="SP2"></a><b>§2. </b>Some basics that apply to all POSIX-supporting systems.
|
|
</p>
|
|
|
|
<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>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><sys/stat.h></span>
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><sys/types.h></span>
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><errno.h></span>
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><dirent.h></span>
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><pthread.h></span>
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><limits.h></span>
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><unistd.h></span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3"></a><b>§3. Mac OS X. </b></p>
|
|
|
|
<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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4"></a><b>§4. Generic Unix. </b>These settings are used both for the Linux versions (both command-line, by
|
|
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>
|
|
|
|
<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>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><strings.h></span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_UNIX and PLATFORM_POSIX are defined.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5"></a><b>§5. Linux. </b>These settings are used both for the Linux versions (both command-line, by
|
|
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>
|
|
|
|
<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>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><strings.h></span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP6"></a><b>§6. Android. </b>These settings are used for Nathan Summers's Android versions.
|
|
</p>
|
|
|
|
<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>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><strings.h></span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_ANDROID and PLATFORM_POSIX are defined.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7"></a><b>§7. Locale. </b>The following definition handles possible differences of text encoding
|
|
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>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<p class="commentary firstcommentary"><a id="SP8"></a><b>§8. Environment variables. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<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">§4</a>), Pathnames (<a href="3-pth.html#SP2">§2</a>, <a href="3-pth.html#SP3">§3</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9"></a><b>§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
|
|
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
|
|
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>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<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>
|
|
<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></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-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></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-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">§9.1.1</a>, <a href="1-pp.html#SP9_1_2">§9.1.2</a>, <a href="1-pp.html#SP9_1_3">§9.1.3</a>, Windows Platform (<a href="1-wp.html#SP5">§5</a>), Pathnames (<a href="3-pth.html#SP3">§3</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9_1"></a><b>§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.
|
|
Follow that link to find the path. Normally when reading a symlink, one uses
|
|
<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>.
|
|
</p>
|
|
|
|
<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>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<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"> < </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></a></span><span class="plain-syntax">; </span><span class="comment-syntax"> unable to find</span>
|
|
<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">§9</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9_2"></a><b>§9.2. </b>Next, convert the obtained buffer (which is a string in the local filename
|
|
encoding, and possibly in a multibyte encoding such as UTF-8) to a wide-char
|
|
string.
|
|
</p>
|
|
|
|
<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>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<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></a></span><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">§9</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9_1_1"></a><b>§9.1.1. </b>And now the Mac version:
|
|
</p>
|
|
|
|
<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><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>
|
|
|
|
<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>
|
|
<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>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> Get "a path" to the executable</span>
|
|
<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">, &</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></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> Convert to canonical absolute path</span>
|
|
<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></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> Next, convert the obtained buffer (which is a string in the local</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>
|
|
<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></a></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::where_am_i is used in <a href="1-pp.html#SP9">§9</a>, <a href="1-pp.html#SP9_1_2">§9.1.2</a>, <a href="1-pp.html#SP9_1_3">§9.1.3</a>, Windows Platform (<a href="1-wp.html#SP5">§5</a>), Pathnames (<a href="3-pth.html#SP3">§3</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9_1_2"></a><b>§9.1.2. </b>For Unix, there's nothing we can generically do.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<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></a></span><span class="plain-syntax">;</span>
|
|
<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">§9</a>, <a href="1-pp.html#SP9_1_1">§9.1.1</a>, <a href="1-pp.html#SP9_1_3">§9.1.3</a>, Windows Platform (<a href="1-wp.html#SP5">§5</a>), Pathnames (<a href="3-pth.html#SP3">§3</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9_1_3"></a><b>§9.1.3. </b>On Android, there's no real need for this.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<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></a></span><span class="plain-syntax">;</span>
|
|
<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">§9</a>, <a href="1-pp.html#SP9_1_1">§9.1.1</a>, <a href="1-pp.html#SP9_1_2">§9.1.2</a>, Windows Platform (<a href="1-wp.html#SP5">§5</a>), Pathnames (<a href="3-pth.html#SP3">§3</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP9_1_4"></a><b>§9.1.4. </b>All of the above make use of:
|
|
</p>
|
|
|
|
<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>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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">§9.1</a>, <a href="1-pp.html#SP9_2">§9.2</a>, <a href="1-pp.html#SP9_1_1">§9.1.1</a> (three times), <a href="1-pp.html#SP9_1_2">§9.1.2</a>, <a href="1-pp.html#SP9_1_3">§9.1.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP10"></a><b>§10. Shell commands. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<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">§11</a>, <a href="1-pp.html#SP14">§14</a>, Windows Platform (<a href="1-wp.html#SP6">§6</a>), Shell (<a href="3-shl.html#SP5">§5</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP11"></a><b>§11. </b>In MacOS 10.5, a new implementation of the C standard library
|
|
crippled performance of <span class="extract"><span class="extract-syntax">system()</span></span> by placing it behind a global mutex, so
|
|
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,
|
|
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>
|
|
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>
|
|
|
|
<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>.
|
|
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 — essentially the standard way to implement <span class="extract"><span class="extract-syntax">system()</span></span>, if you forget
|
|
about signal-handling — led to obscure and unrepeatable memory corruption
|
|
bugs in Intest, with the worker threads apparently writing on each other's
|
|
memory space. Using <span class="extract"><span class="extract-syntax">posix_spawn()</span></span> instead appears to work better.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><spawn.h></span>
|
|
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax"><sys/wait.h></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>
|
|
|
|
<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>
|
|
<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">(&</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">, &</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">§10</a>, <a href="1-pp.html#SP14">§14</a>, Windows Platform (<a href="1-wp.html#SP6">§6</a>), Shell (<a href="3-shl.html#SP5">§5</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP12"></a><b>§12. Directory handling. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<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>
|
|
|
|
<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>
|
|
<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>
|
|
|
|
<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>
|
|
<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">-></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">, &</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">-></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">-></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>
|
|
|
|
<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>
|
|
<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">§7</a>), Pathnames (<a href="3-pth.html#SP9">§9</a>).</li><li>The function Platform::opendir is used in Windows Platform (<a href="1-wp.html#SP7">§7</a>), Directories (<a href="3-drc.html#SP2">§2</a>).</li><li>The function Platform::readdir is used in Windows Platform (<a href="1-wp.html#SP7">§7</a>), Directories (<a href="3-drc.html#SP2">§2</a>).</li><li>The function Platform::closedir is used in Windows Platform (<a href="1-wp.html#SP7">§7</a>), Directories (<a href="3-drc.html#SP2">§2</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP13"></a><b>§13. Timestamp and file size. </b>There are implementations of the C standard library where <span class="extract"><span class="extract-syntax">time_t</span></span> has
|
|
super-weird behaviour, but on almost all 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>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP13" 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>
|
|
<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>
|
|
|
|
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP13" 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>
|
|
<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">, &</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>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="1-wp.html#SP13" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="identifier-syntax">off_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP13" class="function-link"><span class="function-syntax">Platform::size</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>
|
|
<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">, &</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_size</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">off_t</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><li>The function Platform::never_time is used in Windows Platform (<a href="1-wp.html#SP13">§13</a>).</li><li>The function Platform::timestamp is used in Windows Platform (<a href="1-wp.html#SP13">§13</a>), Filenames (<a href="3-fln.html#SP12">§12</a>).</li><li>The function Platform::size is used in Windows Platform (<a href="1-wp.html#SP13">§13</a>), Filenames (<a href="3-fln.html#SP12">§12</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP14"></a><b>§14. Sync. </b>Both names here are of directories which do exist. The function makes
|
|
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>
|
|
|
|
<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>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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::rsync</span></a><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>
|
|
<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>
|
|
<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>
|
|
<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>
|
|
<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>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::quote_text</span><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>
|
|
<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><li>The function Platform::rsync is used in Windows Platform (<a href="1-wp.html#SP8">§8</a>), Pathnames (<a href="3-pth.html#SP10">§10</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15"></a><b>§15. Sleep. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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::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>
|
|
<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#SP9">§9</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP16"></a><b>§16. Notifications. </b>The "submarine" sound is a gloomy thunk; the "bell" is the three-tone rising
|
|
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>
|
|
|
|
<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>
|
|
to survive, given the MacOS team's current hostility to scripting; we're
|
|
actually running a one-line AppleScript here.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP10" 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>
|
|
<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>
|
|
<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>
|
|
<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">§17</a>, Windows Platform (<a href="1-wp.html#SP10">§10</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP17"></a><b>§17. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP10" 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>
|
|
<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">§16</a>, Windows Platform (<a href="1-wp.html#SP10">§10</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP18"></a><b>§18. Concurrency. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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>
|
|
<p class="commentary firstcommentary"><a id="SP19"></a><b>§19. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" 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>
|
|
<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>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::join_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><span class="reserved-syntax">void</span><span class="plain-syntax">** </span><span class="identifier-syntax">rv</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_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>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::init_thread</span></a><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="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</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_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>
|
|
|
|
<span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::get_thread_stack_size</span></a><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="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">, &</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#SP12">§12</a>).</li><li>The function Platform::join_thread is used in Windows Platform (<a href="1-wp.html#SP12">§12</a>).</li><li>The function Platform::init_thread is used in Windows Platform (<a href="1-wp.html#SP12">§12</a>).</li><li>The function Platform::get_thread_stack_size is used in Windows Platform (<a href="1-wp.html#SP12">§12</a>).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP20"></a><b>§20. Mutexes. </b></p>
|
|
|
|
<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">(&</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">(&</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="1-fm.html">❮</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresscurrentchapter">1</li><li class="progresssection"><a href="1-fm.html">fm</a></li><li class="progresscurrent">pp</li><li class="progresssection"><a href="1-wp.html">wp</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresschapter"><a href="4-chr.html">4</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="1-wp.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|