1e66f31c5Sopenharmony_ciProcesses
2e66f31c5Sopenharmony_ci=========
3e66f31c5Sopenharmony_ci
4e66f31c5Sopenharmony_cilibuv offers considerable child process management, abstracting the platform
5e66f31c5Sopenharmony_cidifferences and allowing communication with the child process using streams or
6e66f31c5Sopenharmony_cinamed pipes.
7e66f31c5Sopenharmony_ci
8e66f31c5Sopenharmony_ciA common idiom in Unix is for every process to do one thing and do it well. In
9e66f31c5Sopenharmony_cisuch a case, a process often uses multiple child processes to achieve tasks
10e66f31c5Sopenharmony_ci(similar to using pipes in shells). A multi-process model with messages
11e66f31c5Sopenharmony_cimay also be easier to reason about compared to one with threads and shared
12e66f31c5Sopenharmony_cimemory.
13e66f31c5Sopenharmony_ci
14e66f31c5Sopenharmony_ciA common refrain against event-based programs is that they cannot take
15e66f31c5Sopenharmony_ciadvantage of multiple cores in modern computers. In a multi-threaded program
16e66f31c5Sopenharmony_cithe kernel can perform scheduling and assign different threads to different
17e66f31c5Sopenharmony_cicores, improving performance. But an event loop has only one thread.  The
18e66f31c5Sopenharmony_ciworkaround can be to launch multiple processes instead, with each process
19e66f31c5Sopenharmony_cirunning an event loop, and each process getting assigned to a separate CPU
20e66f31c5Sopenharmony_cicore.
21e66f31c5Sopenharmony_ci
22e66f31c5Sopenharmony_ciSpawning child processes
23e66f31c5Sopenharmony_ci------------------------
24e66f31c5Sopenharmony_ci
25e66f31c5Sopenharmony_ciThe simplest case is when you simply want to launch a process and know when it
26e66f31c5Sopenharmony_ciexits. This is achieved using ``uv_spawn``.
27e66f31c5Sopenharmony_ci
28e66f31c5Sopenharmony_ci.. rubric:: spawn/main.c
29e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/spawn/main.c
30e66f31c5Sopenharmony_ci    :language: c
31e66f31c5Sopenharmony_ci    :linenos:
32e66f31c5Sopenharmony_ci    :lines: 6-8,15-
33e66f31c5Sopenharmony_ci    :emphasize-lines: 11,13-17
34e66f31c5Sopenharmony_ci
35e66f31c5Sopenharmony_ci.. NOTE::
36e66f31c5Sopenharmony_ci
37e66f31c5Sopenharmony_ci    ``options`` is implicitly initialized with zeros since it is a global
38e66f31c5Sopenharmony_ci    variable.  If you change ``options`` to a local variable, remember to
39e66f31c5Sopenharmony_ci    initialize it to null out all unused fields::
40e66f31c5Sopenharmony_ci
41e66f31c5Sopenharmony_ci        uv_process_options_t options = {0};
42e66f31c5Sopenharmony_ci
43e66f31c5Sopenharmony_ciThe ``uv_process_t`` struct only acts as the handle, all options are set via
44e66f31c5Sopenharmony_ci``uv_process_options_t``. To simply launch a process, you need to set only the
45e66f31c5Sopenharmony_ci``file`` and ``args`` fields. ``file`` is the program to execute. Since
46e66f31c5Sopenharmony_ci``uv_spawn`` uses :man:`execvp(3)` internally, there is no need to supply the full
47e66f31c5Sopenharmony_cipath. Finally as per underlying conventions, **the arguments array has to be
48e66f31c5Sopenharmony_cione larger than the number of arguments, with the last element being NULL**.
49e66f31c5Sopenharmony_ci
50e66f31c5Sopenharmony_ciAfter the call to ``uv_spawn``, ``uv_process_t.pid`` will contain the process
51e66f31c5Sopenharmony_ciID of the child process.
52e66f31c5Sopenharmony_ci
53e66f31c5Sopenharmony_ciThe exit callback will be invoked with the *exit status* and the type of *signal*
54e66f31c5Sopenharmony_ciwhich caused the exit.
55e66f31c5Sopenharmony_ci
56e66f31c5Sopenharmony_ciNote that it is important **not** to call ``uv_close`` before the exit callback.
57e66f31c5Sopenharmony_ci
58e66f31c5Sopenharmony_ci.. rubric:: spawn/main.c
59e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/spawn/main.c
60e66f31c5Sopenharmony_ci    :language: c
61e66f31c5Sopenharmony_ci    :linenos:
62e66f31c5Sopenharmony_ci    :lines: 9-12
63e66f31c5Sopenharmony_ci    :emphasize-lines: 3
64e66f31c5Sopenharmony_ci
65e66f31c5Sopenharmony_ciIt is **required** to close the process watcher after the process exits.
66e66f31c5Sopenharmony_ci
67e66f31c5Sopenharmony_ciChanging process parameters
68e66f31c5Sopenharmony_ci---------------------------
69e66f31c5Sopenharmony_ci
70e66f31c5Sopenharmony_ciBefore the child process is launched you can control the execution environment
71e66f31c5Sopenharmony_ciusing fields in ``uv_process_options_t``.
72e66f31c5Sopenharmony_ci
73e66f31c5Sopenharmony_ciChange execution directory
74e66f31c5Sopenharmony_ci++++++++++++++++++++++++++
75e66f31c5Sopenharmony_ci
76e66f31c5Sopenharmony_ciSet ``uv_process_options_t.cwd`` to the corresponding directory.
77e66f31c5Sopenharmony_ci
78e66f31c5Sopenharmony_ciSet environment variables
79e66f31c5Sopenharmony_ci+++++++++++++++++++++++++
80e66f31c5Sopenharmony_ci
81e66f31c5Sopenharmony_ci``uv_process_options_t.env`` is a null-terminated array of strings, each of the
82e66f31c5Sopenharmony_ciform ``VAR=VALUE`` used to set up the environment variables for the process. Set
83e66f31c5Sopenharmony_cithis to ``NULL`` to inherit the environment from the parent (this) process.
84e66f31c5Sopenharmony_ci
85e66f31c5Sopenharmony_ciOption flags
86e66f31c5Sopenharmony_ci++++++++++++
87e66f31c5Sopenharmony_ci
88e66f31c5Sopenharmony_ciSetting ``uv_process_options_t.flags`` to a bitwise OR of the following flags,
89e66f31c5Sopenharmony_cimodifies the child process behaviour:
90e66f31c5Sopenharmony_ci
91e66f31c5Sopenharmony_ci* ``UV_PROCESS_SETUID`` - sets the child's execution user ID to ``uv_process_options_t.uid``.
92e66f31c5Sopenharmony_ci* ``UV_PROCESS_SETGID`` - sets the child's execution group ID to ``uv_process_options_t.gid``.
93e66f31c5Sopenharmony_ci
94e66f31c5Sopenharmony_ciChanging the UID/GID is only supported on Unix, ``uv_spawn`` will fail on
95e66f31c5Sopenharmony_ciWindows with ``UV_ENOTSUP``.
96e66f31c5Sopenharmony_ci
97e66f31c5Sopenharmony_ci* ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` - No quoting or escaping of
98e66f31c5Sopenharmony_ci  ``uv_process_options_t.args`` is done on Windows. Ignored on Unix.
99e66f31c5Sopenharmony_ci* ``UV_PROCESS_DETACHED`` - Starts the child process in a new session, which
100e66f31c5Sopenharmony_ci  will keep running after the parent process exits. See example below.
101e66f31c5Sopenharmony_ci
102e66f31c5Sopenharmony_ciDetaching processes
103e66f31c5Sopenharmony_ci-------------------
104e66f31c5Sopenharmony_ci
105e66f31c5Sopenharmony_ciPassing the flag ``UV_PROCESS_DETACHED`` can be used to launch daemons, or
106e66f31c5Sopenharmony_cichild processes which are independent of the parent so that the parent exiting
107e66f31c5Sopenharmony_cidoes not affect it.
108e66f31c5Sopenharmony_ci
109e66f31c5Sopenharmony_ci.. rubric:: detach/main.c
110e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/detach/main.c
111e66f31c5Sopenharmony_ci    :language: c
112e66f31c5Sopenharmony_ci    :linenos:
113e66f31c5Sopenharmony_ci    :lines: 9-30
114e66f31c5Sopenharmony_ci    :emphasize-lines: 12,19
115e66f31c5Sopenharmony_ci
116e66f31c5Sopenharmony_ciJust remember that the handle is still monitoring the child, so your program
117e66f31c5Sopenharmony_ciwon't exit. Use ``uv_unref()`` if you want to be more *fire-and-forget*.
118e66f31c5Sopenharmony_ci
119e66f31c5Sopenharmony_ciSending signals to processes
120e66f31c5Sopenharmony_ci----------------------------
121e66f31c5Sopenharmony_ci
122e66f31c5Sopenharmony_cilibuv wraps the standard ``kill(2)`` system call on Unix and implements one
123e66f31c5Sopenharmony_ciwith similar semantics on Windows, with *one caveat*: all of ``SIGTERM``,
124e66f31c5Sopenharmony_ci``SIGINT`` and ``SIGKILL``, lead to termination of the process. The signature
125e66f31c5Sopenharmony_ciof ``uv_kill`` is::
126e66f31c5Sopenharmony_ci
127e66f31c5Sopenharmony_ci    uv_err_t uv_kill(int pid, int signum);
128e66f31c5Sopenharmony_ci
129e66f31c5Sopenharmony_ciFor processes started using libuv, you may use ``uv_process_kill`` instead,
130e66f31c5Sopenharmony_ciwhich accepts the ``uv_process_t`` watcher as the first argument, rather than
131e66f31c5Sopenharmony_cithe pid. In this case, **remember to call** ``uv_close`` on the watcher _after_
132e66f31c5Sopenharmony_cithe exit callback has been called.
133e66f31c5Sopenharmony_ci
134e66f31c5Sopenharmony_ciSignals
135e66f31c5Sopenharmony_ci-------
136e66f31c5Sopenharmony_ci
137e66f31c5Sopenharmony_cilibuv provides wrappers around Unix signals with `some Windows support
138e66f31c5Sopenharmony_ci<http://docs.libuv.org/en/v1.x/signal.html#signal>`_ as well.
139e66f31c5Sopenharmony_ci
140e66f31c5Sopenharmony_ciUse ``uv_signal_init()`` to initialize
141e66f31c5Sopenharmony_cia handle and associate it with a loop. To listen for particular signals on
142e66f31c5Sopenharmony_cithat handler, use ``uv_signal_start()`` with the handler function. Each handler
143e66f31c5Sopenharmony_cican only be associated with one signal number, with subsequent calls to
144e66f31c5Sopenharmony_ci``uv_signal_start()`` overwriting earlier associations. Use ``uv_signal_stop()`` to
145e66f31c5Sopenharmony_cistop watching. Here is a small example demonstrating the various possibilities:
146e66f31c5Sopenharmony_ci
147e66f31c5Sopenharmony_ci.. rubric:: signal/main.c
148e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/signal/main.c
149e66f31c5Sopenharmony_ci    :language: c
150e66f31c5Sopenharmony_ci    :linenos:
151e66f31c5Sopenharmony_ci    :emphasize-lines: 17-18,27-28
152e66f31c5Sopenharmony_ci
153e66f31c5Sopenharmony_ci.. NOTE::
154e66f31c5Sopenharmony_ci
155e66f31c5Sopenharmony_ci    ``uv_run(loop, UV_RUN_NOWAIT)`` is similar to ``uv_run(loop, UV_RUN_ONCE)``
156e66f31c5Sopenharmony_ci    in that it will process only one event. UV_RUN_ONCE blocks if there are no
157e66f31c5Sopenharmony_ci    pending events, while UV_RUN_NOWAIT will return immediately. We use NOWAIT
158e66f31c5Sopenharmony_ci    so that one of the loops isn't starved because the other one has no pending
159e66f31c5Sopenharmony_ci    activity.
160e66f31c5Sopenharmony_ci
161e66f31c5Sopenharmony_ciSend ``SIGUSR1`` to the process, and you'll find the handler being invoked
162e66f31c5Sopenharmony_ci4 times, one for each ``uv_signal_t``. The handler just stops each handle,
163e66f31c5Sopenharmony_ciso that the program exits. This sort of dispatch to all handlers is very
164e66f31c5Sopenharmony_ciuseful. A server using multiple event loops could ensure that all data was
165e66f31c5Sopenharmony_cisafely saved before termination, simply by every loop adding a watcher for
166e66f31c5Sopenharmony_ci``SIGINT``.
167e66f31c5Sopenharmony_ci
168e66f31c5Sopenharmony_ciChild Process I/O
169e66f31c5Sopenharmony_ci-----------------
170e66f31c5Sopenharmony_ci
171e66f31c5Sopenharmony_ciA normal, newly spawned process has its own set of file descriptors, with 0,
172e66f31c5Sopenharmony_ci1 and 2 being ``stdin``, ``stdout`` and ``stderr`` respectively. Sometimes you
173e66f31c5Sopenharmony_cimay want to share file descriptors with the child. For example, perhaps your
174e66f31c5Sopenharmony_ciapplications launches a sub-command and you want any errors to go in the log
175e66f31c5Sopenharmony_cifile, but ignore ``stdout``. For this you'd like to have ``stderr`` of the
176e66f31c5Sopenharmony_cichild be the same as the stderr of the parent. In this case, libuv supports
177e66f31c5Sopenharmony_ci*inheriting* file descriptors. In this sample, we invoke the test program,
178e66f31c5Sopenharmony_ciwhich is:
179e66f31c5Sopenharmony_ci
180e66f31c5Sopenharmony_ci.. rubric:: proc-streams/test.c
181e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/proc-streams/test.c
182e66f31c5Sopenharmony_ci    :language: c
183e66f31c5Sopenharmony_ci
184e66f31c5Sopenharmony_ciThe actual program ``proc-streams`` runs this while sharing only ``stderr``.
185e66f31c5Sopenharmony_ciThe file descriptors of the child process are set using the ``stdio`` field in
186e66f31c5Sopenharmony_ci``uv_process_options_t``. First set the ``stdio_count`` field to the number of
187e66f31c5Sopenharmony_cifile descriptors being set. ``uv_process_options_t.stdio`` is an array of
188e66f31c5Sopenharmony_ci``uv_stdio_container_t``, which is:
189e66f31c5Sopenharmony_ci
190e66f31c5Sopenharmony_ci.. code-block:: c
191e66f31c5Sopenharmony_ci
192e66f31c5Sopenharmony_ci    typedef struct uv_stdio_container_s {
193e66f31c5Sopenharmony_ci        uv_stdio_flags flags;
194e66f31c5Sopenharmony_ci
195e66f31c5Sopenharmony_ci        union {
196e66f31c5Sopenharmony_ci            uv_stream_t* stream;
197e66f31c5Sopenharmony_ci            int fd;
198e66f31c5Sopenharmony_ci        } data;
199e66f31c5Sopenharmony_ci    } uv_stdio_container_t;
200e66f31c5Sopenharmony_ci
201e66f31c5Sopenharmony_ciwhere flags can have several values. Use ``UV_IGNORE`` if it isn't going to be
202e66f31c5Sopenharmony_ciused. If the first three ``stdio`` fields are marked as ``UV_IGNORE`` they'll
203e66f31c5Sopenharmony_ciredirect to ``/dev/null``.
204e66f31c5Sopenharmony_ci
205e66f31c5Sopenharmony_ciSince we want to pass on an existing descriptor, we'll use ``UV_INHERIT_FD``.
206e66f31c5Sopenharmony_ciThen we set the ``fd`` to ``stderr``.
207e66f31c5Sopenharmony_ci
208e66f31c5Sopenharmony_ci.. rubric:: proc-streams/main.c
209e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/proc-streams/main.c
210e66f31c5Sopenharmony_ci    :language: c
211e66f31c5Sopenharmony_ci    :linenos:
212e66f31c5Sopenharmony_ci    :lines: 15-17,27-
213e66f31c5Sopenharmony_ci    :emphasize-lines: 6,10,11,12
214e66f31c5Sopenharmony_ci
215e66f31c5Sopenharmony_ciIf you run ``proc-stream`` you'll see that only the line "This is stderr" will
216e66f31c5Sopenharmony_cibe displayed. Try marking ``stdout`` as being inherited and see the output.
217e66f31c5Sopenharmony_ci
218e66f31c5Sopenharmony_ciIt is dead simple to apply this redirection to streams.  By setting ``flags``
219e66f31c5Sopenharmony_cito ``UV_INHERIT_STREAM`` and setting ``data.stream`` to the stream in the
220e66f31c5Sopenharmony_ciparent process, the child process can treat that stream as standard I/O. This
221e66f31c5Sopenharmony_cican be used to implement something like CGI_.
222e66f31c5Sopenharmony_ci
223e66f31c5Sopenharmony_ci.. _CGI: https://en.wikipedia.org/wiki/Common_Gateway_Interface
224e66f31c5Sopenharmony_ci
225e66f31c5Sopenharmony_ciA sample CGI script/executable is:
226e66f31c5Sopenharmony_ci
227e66f31c5Sopenharmony_ci.. rubric:: cgi/tick.c
228e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/cgi/tick.c
229e66f31c5Sopenharmony_ci    :language: c
230e66f31c5Sopenharmony_ci
231e66f31c5Sopenharmony_ciThe CGI server combines the concepts from this chapter and :doc:`networking` so
232e66f31c5Sopenharmony_cithat every client is sent ten ticks after which that connection is closed.
233e66f31c5Sopenharmony_ci
234e66f31c5Sopenharmony_ci.. rubric:: cgi/main.c
235e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/cgi/main.c
236e66f31c5Sopenharmony_ci    :language: c
237e66f31c5Sopenharmony_ci    :linenos:
238e66f31c5Sopenharmony_ci    :lines: 49-63
239e66f31c5Sopenharmony_ci    :emphasize-lines: 10
240e66f31c5Sopenharmony_ci
241e66f31c5Sopenharmony_ciHere we simply accept the TCP connection and pass on the socket (*stream*) to
242e66f31c5Sopenharmony_ci``invoke_cgi_script``.
243e66f31c5Sopenharmony_ci
244e66f31c5Sopenharmony_ci.. rubric:: cgi/main.c
245e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/cgi/main.c
246e66f31c5Sopenharmony_ci    :language: c
247e66f31c5Sopenharmony_ci    :linenos:
248e66f31c5Sopenharmony_ci    :lines: 16, 25-45
249e66f31c5Sopenharmony_ci    :emphasize-lines: 8-9,18,20
250e66f31c5Sopenharmony_ci
251e66f31c5Sopenharmony_ciThe ``stdout`` of the CGI script is set to the socket so that whatever our tick
252e66f31c5Sopenharmony_ciscript prints, gets sent to the client. By using processes, we can offload the
253e66f31c5Sopenharmony_ciread/write buffering to the operating system, so in terms of convenience this
254e66f31c5Sopenharmony_ciis great. Just be warned that creating processes is a costly task.
255e66f31c5Sopenharmony_ci
256e66f31c5Sopenharmony_ci.. _pipes:
257e66f31c5Sopenharmony_ci
258e66f31c5Sopenharmony_ciParent-child IPC
259e66f31c5Sopenharmony_ci----------------
260e66f31c5Sopenharmony_ci
261e66f31c5Sopenharmony_ciA parent and child can have one or two way communication over a pipe created by
262e66f31c5Sopenharmony_cisettings ``uv_stdio_container_t.flags`` to a bit-wise combination of
263e66f31c5Sopenharmony_ci``UV_CREATE_PIPE`` and ``UV_READABLE_PIPE`` or ``UV_WRITABLE_PIPE``. The
264e66f31c5Sopenharmony_ciread/write flag is from the perspective of the child process.  In this case,
265e66f31c5Sopenharmony_cithe ``uv_stream_t* stream`` field must be set to point to an initialized,
266e66f31c5Sopenharmony_ciunopened ``uv_pipe_t`` instance.
267e66f31c5Sopenharmony_ci
268e66f31c5Sopenharmony_ciNew stdio Pipes
269e66f31c5Sopenharmony_ci+++++++++++++++
270e66f31c5Sopenharmony_ci
271e66f31c5Sopenharmony_ciThe ``uv_pipe_t`` structure represents more than just `pipe(7)`_ (or ``|``),
272e66f31c5Sopenharmony_cibut supports any streaming file-like objects. On Windows, the only object of
273e66f31c5Sopenharmony_cithat description is the `Named Pipe`_.  On Unix, this could be any of `Unix
274e66f31c5Sopenharmony_ciDomain Socket`_, or derived from `mkfifo(1)`_, or it could actually be a
275e66f31c5Sopenharmony_ci`pipe(7)`_.  When ``uv_spawn`` initializes a ``uv_pipe_t`` due to the
276e66f31c5Sopenharmony_ci`UV_CREATE_PIPE` flag, it opts for creating a `socketpair(2)`_.
277e66f31c5Sopenharmony_ci
278e66f31c5Sopenharmony_ciThis is intended for the purpose of allowing multiple libuv processes to
279e66f31c5Sopenharmony_cicommunicate with IPC. This is discussed below.
280e66f31c5Sopenharmony_ci
281e66f31c5Sopenharmony_ci.. _pipe(7): https://man7.org/linux/man-pages/man7/pipe.7.html
282e66f31c5Sopenharmony_ci.. _mkfifo(1): https://man7.org/linux/man-pages/man1/mkfifo.1.html
283e66f31c5Sopenharmony_ci.. _socketpair(2): https://man7.org/linux/man-pages/man2/socketpair.2.html
284e66f31c5Sopenharmony_ci.. _Unix Domain Socket: https://man7.org/linux/man-pages/man7/unix.7.html
285e66f31c5Sopenharmony_ci.. _Named Pipe: https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes
286e66f31c5Sopenharmony_ci
287e66f31c5Sopenharmony_ci
288e66f31c5Sopenharmony_ciArbitrary process IPC
289e66f31c5Sopenharmony_ci+++++++++++++++++++++
290e66f31c5Sopenharmony_ci
291e66f31c5Sopenharmony_ciSince domain sockets [#]_ can have a well known name and a location in the
292e66f31c5Sopenharmony_cifile-system they can be used for IPC between unrelated processes. The D-BUS_
293e66f31c5Sopenharmony_cisystem used by open source desktop environments uses domain sockets for event
294e66f31c5Sopenharmony_cinotification. Various applications can then react when a contact comes online
295e66f31c5Sopenharmony_cior new hardware is detected. The MySQL server also runs a domain socket on
296e66f31c5Sopenharmony_ciwhich clients can interact with it.
297e66f31c5Sopenharmony_ci
298e66f31c5Sopenharmony_ci.. _D-BUS: https://www.freedesktop.org/wiki/Software/dbus
299e66f31c5Sopenharmony_ci
300e66f31c5Sopenharmony_ciWhen using domain sockets, a client-server pattern is usually followed with the
301e66f31c5Sopenharmony_cicreator/owner of the socket acting as the server. After the initial setup,
302e66f31c5Sopenharmony_cimessaging is no different from TCP, so we'll re-use the echo server example.
303e66f31c5Sopenharmony_ci
304e66f31c5Sopenharmony_ci.. rubric:: pipe-echo-server/main.c
305e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/pipe-echo-server/main.c
306e66f31c5Sopenharmony_ci    :language: c
307e66f31c5Sopenharmony_ci    :linenos:
308e66f31c5Sopenharmony_ci    :lines: 70-
309e66f31c5Sopenharmony_ci    :emphasize-lines: 5,10,14
310e66f31c5Sopenharmony_ci
311e66f31c5Sopenharmony_ciWe name the socket ``echo.sock`` which means it will be created in the local
312e66f31c5Sopenharmony_cidirectory. This socket now behaves no different from TCP sockets as far as
313e66f31c5Sopenharmony_cithe stream API is concerned. You can test this server using `socat`_::
314e66f31c5Sopenharmony_ci
315e66f31c5Sopenharmony_ci    $ socat - /path/to/socket
316e66f31c5Sopenharmony_ci
317e66f31c5Sopenharmony_ciA client which wants to connect to a domain socket will use::
318e66f31c5Sopenharmony_ci
319e66f31c5Sopenharmony_ci    void uv_pipe_connect(uv_connect_t *req, uv_pipe_t *handle, const char *name, uv_connect_cb cb);
320e66f31c5Sopenharmony_ci
321e66f31c5Sopenharmony_ciwhere ``name`` will be ``echo.sock`` or similar. On Unix systems, ``name`` must
322e66f31c5Sopenharmony_cipoint to a valid file (e.g. ``/tmp/echo.sock``). On Windows, ``name`` follows a
323e66f31c5Sopenharmony_ci``\\?\pipe\echo.sock`` format.
324e66f31c5Sopenharmony_ci
325e66f31c5Sopenharmony_ci.. _socat: http://www.dest-unreach.org/socat/
326e66f31c5Sopenharmony_ci
327e66f31c5Sopenharmony_ciSending file descriptors over pipes
328e66f31c5Sopenharmony_ci+++++++++++++++++++++++++++++++++++
329e66f31c5Sopenharmony_ci
330e66f31c5Sopenharmony_ciThe cool thing about domain sockets is that file descriptors can be exchanged
331e66f31c5Sopenharmony_cibetween processes by sending them over a domain socket. This allows processes
332e66f31c5Sopenharmony_cito hand off their I/O to other processes. Applications include load-balancing
333e66f31c5Sopenharmony_ciservers, worker processes and other ways to make optimum use of CPU. libuv only
334e66f31c5Sopenharmony_cisupports sending **TCP sockets or other pipes** over pipes for now.
335e66f31c5Sopenharmony_ci
336e66f31c5Sopenharmony_ciTo demonstrate, we will look at a echo server implementation that hands of
337e66f31c5Sopenharmony_ciclients to worker processes in a round-robin fashion. This program is a bit
338e66f31c5Sopenharmony_ciinvolved, and while only snippets are included in the book, it is recommended
339e66f31c5Sopenharmony_cito read the full code to really understand it.
340e66f31c5Sopenharmony_ci
341e66f31c5Sopenharmony_ciThe worker process is quite simple, since the file-descriptor is handed over to
342e66f31c5Sopenharmony_ciit by the master.
343e66f31c5Sopenharmony_ci
344e66f31c5Sopenharmony_ci.. rubric:: multi-echo-server/worker.c
345e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/multi-echo-server/worker.c
346e66f31c5Sopenharmony_ci    :language: c
347e66f31c5Sopenharmony_ci    :linenos:
348e66f31c5Sopenharmony_ci    :lines: 7-9,81-
349e66f31c5Sopenharmony_ci    :emphasize-lines: 6-8
350e66f31c5Sopenharmony_ci
351e66f31c5Sopenharmony_ci``queue`` is the pipe connected to the master process on the other end, along
352e66f31c5Sopenharmony_ciwhich new file descriptors get sent. It is important to set the ``ipc``
353e66f31c5Sopenharmony_ciargument of ``uv_pipe_init`` to 1 to indicate this pipe will be used for
354e66f31c5Sopenharmony_ciinter-process communication! Since the master will write the file handle to the
355e66f31c5Sopenharmony_cistandard input of the worker, we connect the pipe to ``stdin`` using
356e66f31c5Sopenharmony_ci``uv_pipe_open``.
357e66f31c5Sopenharmony_ci
358e66f31c5Sopenharmony_ci.. rubric:: multi-echo-server/worker.c
359e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/multi-echo-server/worker.c
360e66f31c5Sopenharmony_ci    :language: c
361e66f31c5Sopenharmony_ci    :linenos:
362e66f31c5Sopenharmony_ci    :lines: 51-79
363e66f31c5Sopenharmony_ci    :emphasize-lines: 10,15,20
364e66f31c5Sopenharmony_ci
365e66f31c5Sopenharmony_ciFirst we call ``uv_pipe_pending_count()`` to ensure that a handle is available
366e66f31c5Sopenharmony_cito read out. If your program could deal with different types of handles,
367e66f31c5Sopenharmony_ci``uv_pipe_pending_type()`` can be used to determine the type.
368e66f31c5Sopenharmony_ciAlthough ``accept`` seems odd in this code, it actually makes sense. What
369e66f31c5Sopenharmony_ci``accept`` traditionally does is get a file descriptor (the client) from
370e66f31c5Sopenharmony_cianother file descriptor (The listening socket). Which is exactly what we do
371e66f31c5Sopenharmony_cihere. Fetch the file descriptor (``client``) from ``queue``. From this point
372e66f31c5Sopenharmony_cithe worker does standard echo server stuff.
373e66f31c5Sopenharmony_ci
374e66f31c5Sopenharmony_ciTurning now to the master, let's take a look at how the workers are launched to
375e66f31c5Sopenharmony_ciallow load balancing.
376e66f31c5Sopenharmony_ci
377e66f31c5Sopenharmony_ci.. rubric:: multi-echo-server/main.c
378e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/multi-echo-server/main.c
379e66f31c5Sopenharmony_ci    :language: c
380e66f31c5Sopenharmony_ci    :linenos:
381e66f31c5Sopenharmony_ci    :lines: 9-13
382e66f31c5Sopenharmony_ci
383e66f31c5Sopenharmony_ciThe ``child_worker`` structure wraps the process, and the pipe between the
384e66f31c5Sopenharmony_cimaster and the individual process.
385e66f31c5Sopenharmony_ci
386e66f31c5Sopenharmony_ci.. rubric:: multi-echo-server/main.c
387e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/multi-echo-server/main.c
388e66f31c5Sopenharmony_ci    :language: c
389e66f31c5Sopenharmony_ci    :linenos:
390e66f31c5Sopenharmony_ci    :lines: 51,61-95
391e66f31c5Sopenharmony_ci    :emphasize-lines: 17,20-21
392e66f31c5Sopenharmony_ci
393e66f31c5Sopenharmony_ciIn setting up the workers, we use the nifty libuv function ``uv_cpu_info`` to
394e66f31c5Sopenharmony_ciget the number of CPUs so we can launch an equal number of workers. Again it is
395e66f31c5Sopenharmony_ciimportant to initialize the pipe acting as the IPC channel with the third
396e66f31c5Sopenharmony_ciargument as 1. We then indicate that the child process' ``stdin`` is to be
397e66f31c5Sopenharmony_cia readable pipe (from the point of view of the child). Everything is
398e66f31c5Sopenharmony_cistraightforward till here. The workers are launched and waiting for file
399e66f31c5Sopenharmony_cidescriptors to be written to their standard input.
400e66f31c5Sopenharmony_ci
401e66f31c5Sopenharmony_ciIt is in ``on_new_connection`` (the TCP infrastructure is initialized in
402e66f31c5Sopenharmony_ci``main()``), that we accept the client socket and pass it along to the next
403e66f31c5Sopenharmony_ciworker in the round-robin.
404e66f31c5Sopenharmony_ci
405e66f31c5Sopenharmony_ci.. rubric:: multi-echo-server/main.c
406e66f31c5Sopenharmony_ci.. literalinclude:: ../../code/multi-echo-server/main.c
407e66f31c5Sopenharmony_ci    :language: c
408e66f31c5Sopenharmony_ci    :linenos:
409e66f31c5Sopenharmony_ci    :lines: 31-49
410e66f31c5Sopenharmony_ci    :emphasize-lines: 9,12-13
411e66f31c5Sopenharmony_ci
412e66f31c5Sopenharmony_ciThe ``uv_write2`` call handles all the abstraction and it is simply a matter of
413e66f31c5Sopenharmony_cipassing in the handle (``client``) as the right argument. With this our
414e66f31c5Sopenharmony_cimulti-process echo server is operational.
415e66f31c5Sopenharmony_ci
416e66f31c5Sopenharmony_ciThanks to Kyle for `pointing out`_ that ``uv_write2()`` requires a non-empty
417e66f31c5Sopenharmony_cibuffer even when sending handles.
418e66f31c5Sopenharmony_ci
419e66f31c5Sopenharmony_ci.. _pointing out: https://github.com/nikhilm/uvbook/issues/56
420e66f31c5Sopenharmony_ci
421e66f31c5Sopenharmony_ci----
422e66f31c5Sopenharmony_ci
423e66f31c5Sopenharmony_ci.. [#] In this section domain sockets stands in for named pipes on Windows as
424e66f31c5Sopenharmony_ci    well.
425