Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | <!DOCTYPE html>\r |
2 | <html lang="en">\r | |
3 | <head>\r | |
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\r | |
5 | <meta name="generator" content="AsciiDoc 8.6.9">\r | |
6 | <title>MLtonProcess</title>\r | |
7 | <link rel="stylesheet" href="./asciidoc.css" type="text/css">\r | |
8 | <link rel="stylesheet" href="./pygments.css" type="text/css">\r | |
9 | \r | |
10 | \r | |
11 | <script type="text/javascript" src="./asciidoc.js"></script>\r | |
12 | <script type="text/javascript">\r | |
13 | /*<![CDATA[*/\r | |
14 | asciidoc.install();\r | |
15 | /*]]>*/\r | |
16 | </script>\r | |
17 | <link rel="stylesheet" href="./mlton.css" type="text/css">\r | |
18 | </head>\r | |
19 | <body class="article">\r | |
20 | <div id="banner">\r | |
21 | <div id="banner-home">\r | |
22 | <a href="./Home">MLton 20180207</a>\r | |
23 | </div>\r | |
24 | </div>\r | |
25 | <div id="header">\r | |
26 | <h1>MLtonProcess</h1>\r | |
27 | </div>\r | |
28 | <div id="content">\r | |
29 | <div id="preamble">\r | |
30 | <div class="sectionbody">\r | |
31 | <div class="listingblock">\r | |
32 | <div class="content"><div class="highlight"><pre><span class="k">signature</span><span class="w"> </span><span class="n">MLTON_PROCESS</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r | |
33 | <span class="w"> </span><span class="k">sig</span><span class="w"></span>\r | |
34 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">pid</span><span class="w"></span>\r | |
35 | \r | |
36 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">spawn</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="n">args</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">list</span><span class="p">,</span><span class="w"> </span><span class="n">path</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="p">}</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">pid</span><span class="w"></span>\r | |
37 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">spawne</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="n">args</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">list</span><span class="p">,</span><span class="w"> </span><span class="n">env</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">list</span><span class="p">,</span><span class="w"> </span><span class="n">path</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="p">}</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">pid</span><span class="w"></span>\r | |
38 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">spawnp</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="n">args</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">list</span><span class="p">,</span><span class="w"> </span><span class="n">file</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="p">}</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">pid</span><span class="w"></span>\r | |
39 | \r | |
40 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">'stderr</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
41 | \r | |
42 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">input</span><span class="w"></span>\r | |
43 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">output</span><span class="w"></span>\r | |
44 | \r | |
45 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">none</span><span class="w"></span>\r | |
46 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">chain</span><span class="w"></span>\r | |
47 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">any</span><span class="w"></span>\r | |
48 | \r | |
49 | <span class="w"> </span><span class="k">exception</span><span class="w"> </span><span class="n">MisuseOfForget</span><span class="w"></span>\r | |
50 | <span class="w"> </span><span class="k">exception</span><span class="w"> </span><span class="n">DoublyRedirected</span><span class="w"></span>\r | |
51 | \r | |
52 | <span class="w"> </span><span class="k">structure</span><span class="w"> </span><span class="n">Child</span><span class="p">:</span><span class="w"></span>\r | |
53 | <span class="w"> </span><span class="k">sig</span><span class="w"></span>\r | |
54 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="p">(</span><span class="n">'use</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
55 | \r | |
56 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">binIn</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">BinIO</span><span class="p">.</span><span class="n">instream</span><span class="p">,</span><span class="w"> </span><span class="n">input</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">BinIO</span><span class="p">.</span><span class="n">instream</span><span class="w"></span>\r | |
57 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">binOut</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">BinIO</span><span class="p">.</span><span class="n">outstream</span><span class="p">,</span><span class="w"> </span><span class="n">output</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">BinIO</span><span class="p">.</span><span class="n">outstream</span><span class="w"></span>\r | |
58 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">fd</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">Posix</span><span class="p">.</span><span class="n">FileSys</span><span class="p">.</span><span class="n">file_desc</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">Posix</span><span class="p">.</span><span class="n">FileSys</span><span class="p">.</span><span class="n">file_desc</span><span class="w"></span>\r | |
59 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">remember</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">any</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">'use</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
60 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">textIn</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">TextIO</span><span class="p">.</span><span class="n">instream</span><span class="p">,</span><span class="w"> </span><span class="n">input</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">TextIO</span><span class="p">.</span><span class="n">instream</span><span class="w"></span>\r | |
61 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">textOut</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">TextIO</span><span class="p">.</span><span class="n">outstream</span><span class="p">,</span><span class="w"> </span><span class="n">output</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">TextIO</span><span class="p">.</span><span class="n">outstream</span><span class="w"></span>\r | |
62 | <span class="w"> </span><span class="k">end</span><span class="w"></span>\r | |
63 | \r | |
64 | <span class="w"> </span><span class="k">structure</span><span class="w"> </span><span class="n">Param</span><span class="p">:</span><span class="w"></span>\r | |
65 | <span class="w"> </span><span class="k">sig</span><span class="w"></span>\r | |
66 | <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="p">(</span><span class="n">'use</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
67 | \r | |
68 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">child</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">chain</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">Child</span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">none</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
69 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">fd</span><span class="p">:</span><span class="w"> </span><span class="n">Posix</span><span class="p">.</span><span class="n">FileSys</span><span class="p">.</span><span class="n">file_desc</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">none</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
70 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">file</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">none</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
71 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">forget</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'use</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">any</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
72 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">null</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">none</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
73 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">pipe</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'use</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
74 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">self</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">none</span><span class="p">,</span><span class="w"> </span><span class="n">'dir</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
75 | <span class="w"> </span><span class="k">end</span><span class="w"></span>\r | |
76 | \r | |
77 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">create</span><span class="p">:</span><span class="w"></span>\r | |
78 | <span class="w"> </span><span class="p">{</span><span class="n">args</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">list</span><span class="p">,</span><span class="w"></span>\r | |
79 | <span class="w"> </span><span class="n">env</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">list</span><span class="w"> </span><span class="n">option</span><span class="p">,</span><span class="w"></span>\r | |
80 | <span class="w"> </span><span class="n">path</span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="p">,</span><span class="w"></span>\r | |
81 | <span class="w"> </span><span class="n">stderr</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'stderr</span><span class="p">,</span><span class="w"> </span><span class="n">output</span><span class="p">)</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">t</span><span class="p">,</span><span class="w"></span>\r | |
82 | <span class="w"> </span><span class="n">stdin</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">input</span><span class="p">)</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">t</span><span class="p">,</span><span class="w"></span>\r | |
83 | <span class="w"> </span><span class="n">stdout</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">output</span><span class="p">)</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">t</span><span class="p">}</span><span class="w"></span>\r | |
84 | <span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">'stderr</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r | |
85 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">getStderr</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">'stderr</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">'stderr</span><span class="p">,</span><span class="w"> </span><span class="n">input</span><span class="p">)</span><span class="w"> </span><span class="n">Child</span><span class="p">.</span><span class="n">t</span><span class="w"></span>\r | |
86 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">getStdin</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">'stderr</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">output</span><span class="p">)</span><span class="w"> </span><span class="n">Child</span><span class="p">.</span><span class="n">t</span><span class="w"></span>\r | |
87 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">getStdout</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">'stderr</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="p">(</span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">input</span><span class="p">)</span><span class="w"> </span><span class="n">Child</span><span class="p">.</span><span class="n">t</span><span class="w"></span>\r | |
88 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">kill</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">'stderr</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">Posix</span><span class="p">.</span><span class="n">Signal</span><span class="p">.</span><span class="n">signal</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">unit</span><span class="w"></span>\r | |
89 | <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">reap</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">'stdin</span><span class="p">,</span><span class="w"> </span><span class="n">'stdout</span><span class="p">,</span><span class="w"> </span><span class="n">'stderr</span><span class="p">)</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">Posix</span><span class="p">.</span><span class="n">Process</span><span class="p">.</span><span class="n">exit_status</span><span class="w"></span>\r | |
90 | <span class="w"> </span><span class="k">end</span><span class="w"></span>\r | |
91 | </pre></div></div></div>\r | |
92 | </div>\r | |
93 | </div>\r | |
94 | <div class="sect1">\r | |
95 | <h2 id="_spawn">Spawn</h2>\r | |
96 | <div class="sectionbody">\r | |
97 | <div class="paragraph"><p>The <span class="monospaced">spawn</span> functions provide an alternative to the\r | |
98 | <span class="monospaced">fork</span>/<span class="monospaced">exec</span> idiom that is typically used to create a new\r | |
99 | process. On most platforms, the <span class="monospaced">spawn</span> functions are simple\r | |
100 | wrappers around <span class="monospaced">fork</span>/<span class="monospaced">exec</span>. However, under Windows, the\r | |
101 | <span class="monospaced">spawn</span> functions are primitive. All <span class="monospaced">spawn</span> functions return\r | |
102 | the process id of the spawned process. They differ in how the\r | |
103 | executable is found and the environment that it uses.</p></div>\r | |
104 | <div class="ulist"><ul>\r | |
105 | <li>\r | |
106 | <p>\r | |
107 | <span class="monospaced">spawn {args, path}</span>\r | |
108 | </p>\r | |
109 | <div class="paragraph"><p>starts a new process running the executable specified by <span class="monospaced">path</span>\r | |
110 | with the arguments <span class="monospaced">args</span>. Like <span class="monospaced">Posix.Process.exec</span>.</p></div>\r | |
111 | </li>\r | |
112 | <li>\r | |
113 | <p>\r | |
114 | <span class="monospaced">spawne {args, env, path}</span>\r | |
115 | </p>\r | |
116 | <div class="paragraph"><p>starts a new process running the executable specified by <span class="monospaced">path</span> with\r | |
117 | the arguments <span class="monospaced">args</span> and environment <span class="monospaced">env</span>. Like\r | |
118 | <span class="monospaced">Posix.Process.exece</span>.</p></div>\r | |
119 | </li>\r | |
120 | <li>\r | |
121 | <p>\r | |
122 | <span class="monospaced">spawnp {args, file}</span>\r | |
123 | </p>\r | |
124 | <div class="paragraph"><p>search the <span class="monospaced">PATH</span> environment variable for an executable named <span class="monospaced">file</span>,\r | |
125 | and start a new process running that executable with the arguments\r | |
126 | <span class="monospaced">args</span>. Like <span class="monospaced">Posix.Process.execp</span>.</p></div>\r | |
127 | </li>\r | |
128 | </ul></div>\r | |
129 | </div>\r | |
130 | </div>\r | |
131 | <div class="sect1">\r | |
132 | <h2 id="_create">Create</h2>\r | |
133 | <div class="sectionbody">\r | |
134 | <div class="paragraph"><p><span class="monospaced">MLton.Process.create</span> provides functionality similar to\r | |
135 | <span class="monospaced">Unix.executeInEnv</span>, but provides more control control over the input,\r | |
136 | output, and error streams. In addition, <span class="monospaced">create</span> works on all\r | |
137 | platforms, including Cygwin and MinGW (Windows) where <span class="monospaced">Posix.fork</span> is\r | |
138 | unavailable. For greatest portability programs should still use the\r | |
139 | standard <span class="monospaced">Unix.execute</span>, <span class="monospaced">Unix.executeInEnv</span>, and <span class="monospaced">OS.Process.system</span>.</p></div>\r | |
140 | <div class="paragraph"><p>The following types and sub-structures are used by the <span class="monospaced">create</span>\r | |
141 | function. They provide static type checking of correct stream usage.</p></div>\r | |
142 | <div class="sect2">\r | |
143 | <h3 id="_child">Child</h3>\r | |
144 | <div class="ulist"><ul>\r | |
145 | <li>\r | |
146 | <p>\r | |
147 | <span class="monospaced">('use, 'dir) Child.t</span>\r | |
148 | </p>\r | |
149 | <div class="paragraph"><p>This represents a handle to one of a child’s standard streams. The\r | |
150 | <span class="monospaced">'dir</span> is viewed with respect to the parent. Thus a <span class="monospaced">('a, input)\r | |
151 | Child.t</span> handle means that the parent may input the output from the\r | |
152 | child.</p></div>\r | |
153 | </li>\r | |
154 | <li>\r | |
155 | <p>\r | |
156 | <span class="monospaced">Child.{bin,text}{In,Out} h</span>\r | |
157 | </p>\r | |
158 | <div class="paragraph"><p>These functions take a handle and bind it to a stream of the named\r | |
159 | type. The type system will detect attempts to reverse the direction\r | |
160 | of a stream or to use the same stream in multiple, incompatible ways.</p></div>\r | |
161 | </li>\r | |
162 | <li>\r | |
163 | <p>\r | |
164 | <span class="monospaced">Child.fd h</span>\r | |
165 | </p>\r | |
166 | <div class="paragraph"><p>This function behaves like the other <span class="monospaced">Child.*</span> functions; it opens a\r | |
167 | stream. However, it does not enforce that you read or write from the\r | |
168 | handle. If you use the descriptor in an inappropriate direction, the\r | |
169 | behavior is undefined. Furthermore, this function may potentially be\r | |
170 | unavailable on future MLton host platforms.</p></div>\r | |
171 | </li>\r | |
172 | <li>\r | |
173 | <p>\r | |
174 | <span class="monospaced">Child.remember h</span>\r | |
175 | </p>\r | |
176 | <div class="paragraph"><p>This function takes a stream of use <span class="monospaced">any</span> and resets the use of the\r | |
177 | stream so that the stream may be used by <span class="monospaced">Child.*</span>. An <span class="monospaced">any</span> stream\r | |
178 | may have had use <span class="monospaced">none</span> or <span class="monospaced">'use</span> prior to calling <span class="monospaced">Param.forget</span>. If\r | |
179 | the stream was <span class="monospaced">none</span> and is used, <span class="monospaced">MisuseOfForget</span> is raised.</p></div>\r | |
180 | </li>\r | |
181 | </ul></div>\r | |
182 | </div>\r | |
183 | <div class="sect2">\r | |
184 | <h3 id="_param">Param</h3>\r | |
185 | <div class="ulist"><ul>\r | |
186 | <li>\r | |
187 | <p>\r | |
188 | <span class="monospaced">('use, 'dir) Param.t</span>\r | |
189 | </p>\r | |
190 | <div class="paragraph"><p>This is a handle to an input/output source and will be passed to the\r | |
191 | created child process. The <span class="monospaced">'dir</span> is relative to the child process.\r | |
192 | Input means that the child process will read from this stream.</p></div>\r | |
193 | </li>\r | |
194 | <li>\r | |
195 | <p>\r | |
196 | <span class="monospaced">Param.child h</span>\r | |
197 | </p>\r | |
198 | <div class="paragraph"><p>Connect the stream of the new child process to the stream of a\r | |
199 | previously created child process. A single child stream should be\r | |
200 | connected to only one child process or else <span class="monospaced">DoublyRedirected</span> will be\r | |
201 | raised.</p></div>\r | |
202 | </li>\r | |
203 | <li>\r | |
204 | <p>\r | |
205 | <span class="monospaced">Param.fd fd</span>\r | |
206 | </p>\r | |
207 | <div class="paragraph"><p>This creates a stream from the provided file descriptor which will be\r | |
208 | closed when <span class="monospaced">create</span> is called. This function may not be available on\r | |
209 | future MLton host platforms.</p></div>\r | |
210 | </li>\r | |
211 | <li>\r | |
212 | <p>\r | |
213 | <span class="monospaced">Param.forget h</span>\r | |
214 | </p>\r | |
215 | <div class="paragraph"><p>This hides the type of the actual parameter as <span class="monospaced">any</span>. This is useful\r | |
216 | if you are implementing an application which conditionally attaches\r | |
217 | the child process to files or pipes. However, you must ensure that\r | |
218 | your use after <span class="monospaced">Child.remember</span> matches the original type.</p></div>\r | |
219 | </li>\r | |
220 | <li>\r | |
221 | <p>\r | |
222 | <span class="monospaced">Param.file s</span>\r | |
223 | </p>\r | |
224 | <div class="paragraph"><p>Open the given file and connect it to the child process. Note that the\r | |
225 | file will be opened only when <span class="monospaced">create</span> is called. So any exceptions\r | |
226 | will be raised there and not by this function. If used for <span class="monospaced">input</span>,\r | |
227 | the file is opened read-only. If used for <span class="monospaced">output</span>, the file is opened\r | |
228 | read-write.</p></div>\r | |
229 | </li>\r | |
230 | <li>\r | |
231 | <p>\r | |
232 | <span class="monospaced">Param.null</span>\r | |
233 | </p>\r | |
234 | <div class="paragraph"><p>In some situations, the child process should have its output\r | |
235 | discarded. The <span class="monospaced">null</span> param when passed as <span class="monospaced">stdout</span> or <span class="monospaced">stderr</span> does\r | |
236 | this. When used for <span class="monospaced">stdin</span>, the child process will either receive\r | |
237 | <span class="monospaced">EOF</span> or a failure condition if it attempts to read from <span class="monospaced">stdin</span>.</p></div>\r | |
238 | </li>\r | |
239 | <li>\r | |
240 | <p>\r | |
241 | <span class="monospaced">Param.pipe</span>\r | |
242 | </p>\r | |
243 | <div class="paragraph"><p>This will connect the input/output of the child process to a pipe\r | |
244 | which the parent process holds. This may later form the input to one\r | |
245 | of the <span class="monospaced">Child.*</span> functions and/or the <span class="monospaced">Param.child</span> function.</p></div>\r | |
246 | </li>\r | |
247 | <li>\r | |
248 | <p>\r | |
249 | <span class="monospaced">Param.self</span>\r | |
250 | </p>\r | |
251 | <div class="paragraph"><p>This will connect the input/output of the child process to the\r | |
252 | corresponding stream of the parent process.</p></div>\r | |
253 | </li>\r | |
254 | </ul></div>\r | |
255 | </div>\r | |
256 | <div class="sect2">\r | |
257 | <h3 id="_process">Process</h3>\r | |
258 | <div class="ulist"><ul>\r | |
259 | <li>\r | |
260 | <p>\r | |
261 | <span class="monospaced">type ('stdin, 'stdout, 'stderr) t</span>\r | |
262 | </p>\r | |
263 | <div class="paragraph"><p>represents a handle to a child process. The type arguments capture\r | |
264 | how the named stream of the child process may be used.</p></div>\r | |
265 | </li>\r | |
266 | <li>\r | |
267 | <p>\r | |
268 | <span class="monospaced">type any</span>\r | |
269 | </p>\r | |
270 | <div class="paragraph"><p>bypasses the type system in situations where an application does not\r | |
271 | want the it to enforce correct usage. See <span class="monospaced">Child.remember</span> and\r | |
272 | <span class="monospaced">Param.forget</span>.</p></div>\r | |
273 | </li>\r | |
274 | <li>\r | |
275 | <p>\r | |
276 | <span class="monospaced">type chain</span>\r | |
277 | </p>\r | |
278 | <div class="paragraph"><p>means that the child process’s stream was connected via a pipe to the\r | |
279 | parent process. The parent process may pass this pipe in turn to\r | |
280 | another child, thus chaining them together.</p></div>\r | |
281 | </li>\r | |
282 | <li>\r | |
283 | <p>\r | |
284 | <span class="monospaced">type input, output</span>\r | |
285 | </p>\r | |
286 | <div class="paragraph"><p>record the direction that a stream flows. They are used as a part of\r | |
287 | <span class="monospaced">Param.t</span> and <span class="monospaced">Child.t</span> and is detailed there.</p></div>\r | |
288 | </li>\r | |
289 | <li>\r | |
290 | <p>\r | |
291 | <span class="monospaced">type none</span>\r | |
292 | </p>\r | |
293 | <div class="paragraph"><p>means that the child process’s stream my not be used by the parent\r | |
294 | process. This happens when the child process is connected directly to\r | |
295 | some source.</p></div>\r | |
296 | <div class="paragraph"><p>The types <span class="monospaced">BinIO.instream</span>, <span class="monospaced">BinIO.outstream</span>, <span class="monospaced">TextIO.instream</span>,\r | |
297 | <span class="monospaced">TextIO.outstream</span>, and <span class="monospaced">Posix.FileSys.file_desc</span> are also valid types\r | |
298 | with which to instantiate child streams.</p></div>\r | |
299 | </li>\r | |
300 | <li>\r | |
301 | <p>\r | |
302 | <span class="monospaced">exception MisuseOfForget</span>\r | |
303 | </p>\r | |
304 | <div class="paragraph"><p>may be raised if <span class="monospaced">Child.remember</span> and <span class="monospaced">Param.forget</span> are used to\r | |
305 | bypass the normal type checking. This exception will only be raised\r | |
306 | in cases where the <span class="monospaced">forget</span> mechanism allows a misuse that would be\r | |
307 | impossible with the type-safe versions.</p></div>\r | |
308 | </li>\r | |
309 | <li>\r | |
310 | <p>\r | |
311 | <span class="monospaced">exception DoublyRedirected</span>\r | |
312 | </p>\r | |
313 | <div class="paragraph"><p>raised if a stream connected to a child process is redirected to two\r | |
314 | separate child processes. It is safe, though bad style, to use the a\r | |
315 | <span class="monospaced">Child.t</span> with the same <span class="monospaced">Child.*</span> function repeatedly.</p></div>\r | |
316 | </li>\r | |
317 | <li>\r | |
318 | <p>\r | |
319 | <span class="monospaced">create {args, path, env, stderr, stdin, stdout}</span>\r | |
320 | </p>\r | |
321 | <div class="paragraph"><p>starts a child process with the given command-line <span class="monospaced">args</span> (excluding\r | |
322 | the program name). <span class="monospaced">path</span> should be an absolute path to the executable\r | |
323 | run in the new child process; relative paths work, but are less\r | |
324 | robust. Optionally, the environment may be overridden with <span class="monospaced">env</span>\r | |
325 | where each string element has the form <span class="monospaced">"key=value"</span>. The <span class="monospaced">std*</span>\r | |
326 | options must be provided by the <span class="monospaced">Param.*</span> functions documented above.</p></div>\r | |
327 | <div class="paragraph"><p>Processes which are <span class="monospaced">create</span>-d must be either <span class="monospaced">reap</span>-ed or <span class="monospaced">kill</span>-ed.</p></div>\r | |
328 | </li>\r | |
329 | <li>\r | |
330 | <p>\r | |
331 | <span class="monospaced">getStd{in,out,err} proc</span>\r | |
332 | </p>\r | |
333 | <div class="paragraph"><p>gets a handle to the specified stream. These should be used by the\r | |
334 | <span class="monospaced">Child.*</span> functions. Failure to use a stream connected via pipe to a\r | |
335 | child process may result in runtime dead-lock and elicits a compiler\r | |
336 | warning.</p></div>\r | |
337 | </li>\r | |
338 | <li>\r | |
339 | <p>\r | |
340 | <span class="monospaced">kill (proc, sig)</span>\r | |
341 | </p>\r | |
342 | <div class="paragraph"><p>terminates the child process immediately. The signal may or may not\r | |
343 | mean anything depending on the host platform. A good value is\r | |
344 | <span class="monospaced">Posix.Signal.term</span>.</p></div>\r | |
345 | </li>\r | |
346 | <li>\r | |
347 | <p>\r | |
348 | <span class="monospaced">reap proc</span>\r | |
349 | </p>\r | |
350 | <div class="paragraph"><p>waits for the child process to terminate and return its exit status.</p></div>\r | |
351 | </li>\r | |
352 | </ul></div>\r | |
353 | </div>\r | |
354 | </div>\r | |
355 | </div>\r | |
356 | <div class="sect1">\r | |
357 | <h2 id="_important_usage_notes">Important usage notes</h2>\r | |
358 | <div class="sectionbody">\r | |
359 | <div class="paragraph"><p>When building an application with many pipes between child processes,\r | |
360 | it is important to ensure that there are no cycles in the undirected\r | |
361 | pipe graph. If this property is not maintained, deadlocks are a very\r | |
362 | serious potential bug which may only appear under difficult to\r | |
363 | reproduce conditions.</p></div>\r | |
364 | <div class="paragraph"><p>The danger lies in that most operating systems implement pipes with a\r | |
365 | fixed buffer size. If process A has two output pipes which process B\r | |
366 | reads, it can happen that process A blocks writing to pipe 2 because\r | |
367 | it is full while process B blocks reading from pipe 1 because it is\r | |
368 | empty. This same situation can happen with any undirected cycle formed\r | |
369 | between processes (vertexes) and pipes (undirected edges) in the\r | |
370 | graph.</p></div>\r | |
371 | <div class="paragraph"><p>It is possible to make this safe using low-level I/O primitives for\r | |
372 | polling. However, these primitives are not very portable and\r | |
373 | difficult to use properly. A far better approach is to make sure you\r | |
374 | never create a cycle in the first place.</p></div>\r | |
375 | <div class="paragraph"><p>For these reasons, the <span class="monospaced">Unix.executeInEnv</span> is a very dangerous\r | |
376 | function. Be careful when using it to ensure that the child process\r | |
377 | only operates on either <span class="monospaced">stdin</span> or <span class="monospaced">stdout</span>, but not both.</p></div>\r | |
378 | </div>\r | |
379 | </div>\r | |
380 | <div class="sect1">\r | |
381 | <h2 id="_example_use_of_mlton_process_create">Example use of MLton.Process.create</h2>\r | |
382 | <div class="sectionbody">\r | |
383 | <div class="paragraph"><p>The following example program launches the <span class="monospaced">ipconfig</span> utility, pipes\r | |
384 | its output through <span class="monospaced">grep</span>, and then reads the result back into the\r | |
385 | program.</p></div>\r | |
386 | <div class="listingblock">\r | |
387 | <div class="content"><div class="highlight"><pre><span class="k">open</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Process</span><span class="w"></span>\r | |
388 | <span class="k">val</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r | |
389 | <span class="w"> </span><span class="n">create</span><span class="w"> </span><span class="p">{</span><span class="n">args</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s">"/all"</span><span class="w"> </span><span class="p">],</span><span class="w"></span>\r | |
390 | <span class="w"> </span><span class="n">env</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">NONE</span><span class="p">,</span><span class="w"></span>\r | |
391 | <span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"C:</span><span class="se">\\</span><span class="s">WINDOWS</span><span class="se">\\</span><span class="s">system32</span><span class="se">\\</span><span class="s">ipconfig.exe"</span><span class="p">,</span><span class="w"></span>\r | |
392 | <span class="w"> </span><span class="n">stderr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">self</span><span class="p">,</span><span class="w"></span>\r | |
393 | <span class="w"> </span><span class="n">stdin</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">null</span><span class="p">,</span><span class="w"></span>\r | |
394 | <span class="w"> </span><span class="n">stdout</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">pipe</span><span class="p">}</span><span class="w"></span>\r | |
395 | <span class="k">val</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r | |
396 | <span class="w"> </span><span class="n">create</span><span class="w"> </span><span class="p">{</span><span class="n">args</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s">"IP-Ad"</span><span class="w"> </span><span class="p">],</span><span class="w"></span>\r | |
397 | <span class="w"> </span><span class="n">env</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">NONE</span><span class="p">,</span><span class="w"></span>\r | |
398 | <span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"C:</span><span class="se">\\</span><span class="s">msys</span><span class="se">\\</span><span class="s">bin</span><span class="se">\\</span><span class="s">grep.exe"</span><span class="p">,</span><span class="w"></span>\r | |
399 | <span class="w"> </span><span class="n">stderr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">self</span><span class="p">,</span><span class="w"></span>\r | |
400 | <span class="w"> </span><span class="n">stdin</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">child</span><span class="w"> </span><span class="p">(</span><span class="n">getStdout</span><span class="w"> </span><span class="n">p</span><span class="p">),</span><span class="w"></span>\r | |
401 | <span class="w"> </span><span class="n">stdout</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Param</span><span class="p">.</span><span class="n">pipe</span><span class="p">}</span><span class="w"></span>\r | |
402 | <span class="k">fun</span><span class="w"> </span><span class="n">suck</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r | |
403 | <span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">TextIO</span><span class="p">.</span><span class="n">inputLine</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">of</span><span class="w"></span>\r | |
404 | <span class="w"> </span><span class="n">NONE</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">()</span><span class="w"></span>\r | |
405 | <span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">SOME</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">(</span><span class="n">print</span><span class="w"> </span><span class="p">(</span><span class="s">"'"</span><span class="w"> </span><span class="n">^</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">^</span><span class="w"> </span><span class="s">"'</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span><span class="w"> </span><span class="n">suck</span><span class="w"> </span><span class="n">h</span><span class="p">)</span><span class="w"></span>\r | |
406 | \r | |
407 | <span class="k">val</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">suck</span><span class="w"> </span><span class="p">(</span><span class="n">Child</span><span class="p">.</span><span class="n">textIn</span><span class="w"> </span><span class="p">(</span><span class="n">getStdout</span><span class="w"> </span><span class="n">q</span><span class="p">))</span><span class="w"></span>\r | |
408 | </pre></div></div></div>\r | |
409 | </div>\r | |
410 | </div>\r | |
411 | </div>\r | |
412 | <div id="footnotes"><hr></div>\r | |
413 | <div id="footer">\r | |
414 | <div id="footer-text">\r | |
415 | </div>\r | |
416 | <div id="footer-badges">\r | |
417 | </div>\r | |
418 | </div>\r | |
419 | </body>\r | |
420 | </html>\r |