1ZPROC(3)                          CZMQ Manual                         ZPROC(3)
2
3
4

NAME

6       zproc - Class for process configuration and status
7

SYNOPSIS

9       //  This is a draft class, and may change without notice. It is disabled in
10       //  stable builds by default. If you use this in applications, please ask
11       //  for it to be pushed to stable state. Use --enable-drafts to enable.
12       #ifdef CZMQ_BUILD_DRAFT_API
13       //  *** Draft method, for development use, may change without warning ***
14       //  Create a new zproc.
15       //  NOTE: On Windows and with libzmq3 and libzmq2 this function
16       //  returns NULL. Code needs to be ported there.
17       CZMQ_EXPORT zproc_t *
18           zproc_new (void);
19
20       //  *** Draft method, for development use, may change without warning ***
21       //  Destroy zproc, wait until process ends.
22       CZMQ_EXPORT void
23           zproc_destroy (zproc_t **self_p);
24
25       //  *** Draft method, for development use, may change without warning ***
26       //  Return command line arguments (the first item is the executable) or
27       //  NULL if not set.
28       //  Caller owns return value and must destroy it when done.
29       CZMQ_EXPORT zlist_t *
30           zproc_args (zproc_t *self);
31
32       //  *** Draft method, for development use, may change without warning ***
33       //  Setup the command line arguments, the first item must be an (absolute) filename
34       //  to run.
35       CZMQ_EXPORT void
36           zproc_set_args (zproc_t *self, zlist_t **arguments);
37
38       //  *** Draft method, for development use, may change without warning ***
39       //  Setup the command line arguments, the first item must be an (absolute) filename
40       //  to run. Variadic function, must be NULL terminated.
41       CZMQ_EXPORT void
42           zproc_set_argsx (zproc_t *self, const char *arguments, ...);
43
44       //  *** Draft method, for development use, may change without warning ***
45       //  Setup the environment variables for the process.
46       CZMQ_EXPORT void
47           zproc_set_env (zproc_t *self, zhash_t **arguments);
48
49       //  *** Draft method, for development use, may change without warning ***
50       //  Connects process stdin with a readable ('>', connect) zeromq socket. If
51       //  socket argument is NULL, zproc creates own managed pair of inproc
52       //  sockets.  The writable one is then accessbile via zproc_stdin method.
53       CZMQ_EXPORT void
54           zproc_set_stdin (zproc_t *self, void *socket);
55
56       //  *** Draft method, for development use, may change without warning ***
57       //  Connects process stdout with a writable ('@', bind) zeromq socket. If
58       //  socket argument is NULL, zproc creates own managed pair of inproc
59       //  sockets.  The readable one is then accessbile via zproc_stdout method.
60       CZMQ_EXPORT void
61           zproc_set_stdout (zproc_t *self, void *socket);
62
63       //  *** Draft method, for development use, may change without warning ***
64       //  Connects process stderr with a writable ('@', bind) zeromq socket. If
65       //  socket argument is NULL, zproc creates own managed pair of inproc
66       //  sockets.  The readable one is then accessbile via zproc_stderr method.
67       CZMQ_EXPORT void
68           zproc_set_stderr (zproc_t *self, void *socket);
69
70       //  *** Draft method, for development use, may change without warning ***
71       //  Return subprocess stdin writable socket. NULL for
72       //  not initialized or external sockets.
73       CZMQ_EXPORT void *
74           zproc_stdin (zproc_t *self);
75
76       //  *** Draft method, for development use, may change without warning ***
77       //  Return subprocess stdout readable socket. NULL for
78       //  not initialized or external sockets.
79       CZMQ_EXPORT void *
80           zproc_stdout (zproc_t *self);
81
82       //  *** Draft method, for development use, may change without warning ***
83       //  Return subprocess stderr readable socket. NULL for
84       //  not initialized or external sockets.
85       CZMQ_EXPORT void *
86           zproc_stderr (zproc_t *self);
87
88       //  *** Draft method, for development use, may change without warning ***
89       //  Starts the process, return just before execve/CreateProcess.
90       CZMQ_EXPORT int
91           zproc_run (zproc_t *self);
92
93       //  *** Draft method, for development use, may change without warning ***
94       //  process exit code
95       CZMQ_EXPORT int
96           zproc_returncode (zproc_t *self);
97
98       //  *** Draft method, for development use, may change without warning ***
99       //  PID of the process
100       CZMQ_EXPORT int
101           zproc_pid (zproc_t *self);
102
103       //  *** Draft method, for development use, may change without warning ***
104       //  return true if process is running, false if not yet started or finished
105       CZMQ_EXPORT bool
106           zproc_running (zproc_t *self);
107
108       //  *** Draft method, for development use, may change without warning ***
109       //  wait or poll process status, return return code
110       CZMQ_EXPORT int
111           zproc_wait (zproc_t *self, bool hang);
112
113       //  *** Draft method, for development use, may change without warning ***
114       //  return internal actor, usefull for the polling if process died
115       CZMQ_EXPORT void *
116           zproc_actor (zproc_t *self);
117
118       //  *** Draft method, for development use, may change without warning ***
119       //  send a signal to the subprocess
120       CZMQ_EXPORT void
121           zproc_kill (zproc_t *self, int signal);
122
123       //  *** Draft method, for development use, may change without warning ***
124       //  set verbose mode
125       CZMQ_EXPORT void
126           zproc_set_verbose (zproc_t *self, bool verbose);
127
128       //  *** Draft method, for development use, may change without warning ***
129       //  Self test of this class.
130       CZMQ_EXPORT void
131           zproc_test (bool verbose);
132
133       #endif // CZMQ_BUILD_DRAFT_API
134       Please add '@interface' section in './../src/zproc.c'.
135

DESCRIPTION

137       zproc - process configuration and status, plus unix pipes on steroids
138
139           Warning
140           zproc class have several limitations atm * is tested on zmq4 on
141           Linux and OSX. * does not work on Windows, where you get empty
142           stubs for most of the methods * does not work on libzmq3 and
143           libzmq2. We have experienced stalls and timeouts when running tests
144           against such old version
145
146       Note: zproc is not yet stable, so there are no guarantees regarding API
147       stability. Some methods can have weird semantics or strange API.
148
149       Class zproc run an external process and to use ZeroMQ sockets to
150       communicate with it. In other words standard input and outputs MAY be
151       connected with appropriate zeromq socket and data flow is managed by
152       zproc itself. This makes zproc the best in class way how to run and
153       manage sub processes.
154
155       Data are sent and received as zframes (zframe_t), so zproc does not try
156       to interpret content of the messages in any way. See test example on
157       how to use it.
158
159           +----------------------------------------+
160           |    /bin/cat cat /etc/passwd            |
161           |    stdin   | stdout      |    stderr   |
162           |------||--------||---------------||-----|
163           |      fd1       fd2              fd3    |
164           |       ^         v                v     |
165           |zmq://stdin |zmq://stdout |zmq://stderr |
166           |         [zproc supervisor]          |
167           +----------------------------------------+
168
169           ----------> zeromq magic here <-----------
170
171           +----------------------------------------+
172           |zmq://stdin |zmq://stdout |zmq://stderr |
173           |                                        |
174           |          consumer                      |
175           |                                        |
176           |                                        |
177           +----------------------------------------+
178
179       Please add @discuss section in ./../src/zproc.c.
180

EXAMPLE

182       From zproc_test method.
183
184           //  variable file contains path to zsp executable:
185           //  char *file = "path/to/zsp";
186
187           #if defined (__WINDOWS__)
188           printf ("Very limited (on Windows) ");
189           {
190               zsys_init ();
191               zproc_t *self = zproc_new ();
192               assert (self);
193
194               zproc_set_verbose (self, verbose);
195               zproc_set_argsx (self, file, "-v", NULL);
196               zproc_run (self);
197               zclock_sleep (100); // to let actor start the process
198               assert (zproc_pid (self));
199
200               zproc_kill (self, SIGTERM);
201               assert (zproc_returncode (self) == 255);
202               zproc_destroy (&self);
203           }
204           printf ("OK\n");
205           return;
206           #endif
207           // Test case #1: run command, wait until it ends and get the (stdandard) output
208           zproc_t *self = zproc_new ();
209           assert (self);
210           zproc_set_verbose (self, verbose);
211
212           //  join stdout of the process to zeromq socket
213           //  all data will be readable from zproc_stdout socket
214           assert (!zproc_stdout (self));
215           zproc_set_stdout (self, NULL);
216           assert (zproc_stdout (self));
217
218           zproc_set_argsx (self, file, "--help", NULL);
219
220           if (verbose)
221               zsys_debug("zproc_test() : launching helper '%s' --help", file );
222
223           int r = zproc_run (self);
224           assert (r == 0);
225           zframe_t *frame;
226           zsock_brecv (zproc_stdout (self), "f", &frame);
227           assert (frame);
228           assert (zframe_data (frame));
229           // TODO: real test
230           if (verbose)
231               zframe_print (frame, "1:");
232           zframe_destroy (&frame);
233           r = zproc_wait (self, true);
234           assert (r == 0);
235           zproc_destroy (&self);
236
237           // Test case #2: use never ending subprocess and poller to read data from it
238           //  Create new zproc instance
239           self = zproc_new ();
240           zproc_set_verbose (self, verbose);
241           assert (self);
242           //  join stdout of the process to zeromq socket
243           //  all data will be readable from zproc_stdout socket
244           zproc_set_stdout (self, NULL);
245
246           zlist_t *args = zlist_new ();
247           zlist_autofree (args);
248           zlist_append (args, file);
249           zlist_append (args, "--stdout");
250           zproc_set_args (self, &args);
251
252           zhash_t *env = zhash_new ();
253           zhash_autofree (env);
254           zhash_insert (env, "ZSP_MESSAGE", "czmq is great\n");
255           zproc_set_env (self, &env);
256
257           // execute the binary. It runs in own actor, which monitor the process and
258           // pass data accross pipes and zeromq sockets
259           if (verbose)
260               zsys_debug("zproc_test() : launching helper '%s'", file );
261           zproc_run (self);
262           zpoller_t *poller = zpoller_new (zproc_stdout (self), NULL);
263
264           // kill the binary, it never ends, but the test must:
265           // termination also flushes the output streams so we can
266           // read them entirely; note that other process runs in
267           // parallel to this thread
268           if (verbose)
269               zsys_debug("zproc_test() : sleeping 4000 msec to gather some output from helper");
270           zclock_sleep (4000);
271           zproc_kill (self, SIGTERM);
272           zproc_wait (self, true);
273
274           // read the content from zproc_stdout - use zpoller and a loop
275           bool stdout_read = false;
276           int64_t zproc_timeout_msec = 10000;
277           int64_t zproc_test_start_msec = zclock_mono();
278           int64_t zproc_test_elapsed_msec = 0;
279
280           while (!zsys_interrupted) {
281               void *which = zpoller_wait (poller, 800);
282               zproc_test_elapsed_msec = zclock_mono() - zproc_test_start_msec;
283
284               if (!which) {
285                   if (stdout_read) {
286                       if (verbose)
287                           zsys_debug("zproc_test() : did not get stdout from helper, but we already have some (%" PRIi64 " msec remaining to retry)", (zproc_timeout_msec - zproc_test_elapsed_msec) );
288                       break;
289                   }
290                   if (zproc_timeout_msec > zproc_test_elapsed_msec) {
291                       if (verbose)
292                           zsys_debug("zproc_test() : did not get stdout from helper, %" PRIi64 " msec remaining to retry", (zproc_timeout_msec - zproc_test_elapsed_msec) );
293                       continue;
294                   }
295                   // ...else : we've slept a lot and got no response; kill the helper
296                   if (verbose)
297                       zsys_debug("zproc_test() : did not get stdout from helper, patience expired (%" PRIi64 " msec remaining to retry)", (zproc_timeout_msec - zproc_test_elapsed_msec) );
298                   break;
299               }
300
301               if (which == zproc_stdout (self)) {
302                   // it suffices for us to have read something
303                   // we only check the first frame, others may start with the
304                   // expected key string broken mid-way due to alignment etc.,
305                   // but we drain the whole incoming queue of stdout frames.
306                   zframe_t *frame;
307                   zsock_brecv (zproc_stdout (self), "f", &frame);
308                   assert (frame);
309                   assert (zframe_data (frame));
310                   if (!stdout_read) {
311                       if (verbose)
312                           zsys_debug("zproc_test() : got stdout from helper, %" PRIi64 " msec was remaining to retry", (zproc_timeout_msec - zproc_test_elapsed_msec));
313                       assert (!strncmp(
314                           "czmq is great\n",
315                           (char*) zframe_data (frame),
316                           14));
317                       stdout_read = true;
318                   }
319
320                   if (verbose)
321                       zframe_print (frame, "zproc_test");
322
323                   zframe_destroy (&frame);
324                   continue;
325               }
326
327               // should not get there
328               if (verbose)
329                   zsys_debug("zproc_test() : reached the unreachable point (unexpected zpoller result), %" PRIi64 " msec was remaining to retry", (zproc_timeout_msec - zproc_test_elapsed_msec) );
330               assert (false);
331           }
332
333           assert (stdout_read);
334           zpoller_destroy (&poller);
335           zproc_destroy (&self);
336
337

AUTHORS

339       The czmq manual was written by the authors in the AUTHORS file.
340

RESOURCES

342       Main web site:
343
344       Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
345
347       Copyright (c) the Contributors as noted in the AUTHORS file. This file
348       is part of CZMQ, the high-level C binding for 0MQ:
349       http://czmq.zeromq.org. This Source Code Form is subject to the terms
350       of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
351       distributed with this file, You can obtain one at
352       http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
353       distribution.
354

NOTES

356        1. zeromq-dev@lists.zeromq.org
357           mailto:zeromq-dev@lists.zeromq.org
358
359
360
361CZMQ 4.1.1                        07/24/2019                          ZPROC(3)
Impressum