agent/
[gnupg.git] / g13 / runner.c
blob6cf88c0b447a1f456961de5ee5fb463dea0723d5
1 /* runner.c - Run and watch the backend engines
2 * Copyright (C) 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <assert.h>
27 #include <pth.h>
29 #include "g13.h"
30 #include "i18n.h"
31 #include "keyblob.h"
32 #include "runner.h"
33 #include "../common/exechelp.h"
34 #include "mountinfo.h"
36 /* The runner object. */
37 struct runner_s
39 char *name; /* The name of this runner. */
40 unsigned int identifier; /* The runner identifier. */
42 int spawned; /* True if runner_spawn has been called. */
43 pth_t threadid; /* The TID of the runner thread. */
44 runner_t next_running; /* Builds a list of all running threads. */
45 int canceled; /* Set if a cancel has already been send once. */
47 int cancel_flag; /* If set the thread should terminate itself. */
50 /* We use a reference counter to know when it is safe to remove the
51 object. Lackiong an explicit ref fucntion this counter will take
52 only these two values:
54 1 = Thread not running or only the thread is still running.
55 2 = Thread is running and someone is holding a reference. */
56 int refcount;
58 pid_t pid; /* PID of the backend's process (the engine). */
59 int in_fd; /* File descriptors to read from the engine. */
60 int out_fd; /* File descriptors to write to the engine. */
61 engine_handler_fnc_t handler; /* The handler functions. */
62 engine_handler_cleanup_fnc_t handler_cleanup;
63 void *handler_data; /* Private data of HANDLER and HANDLER_CLEANUP. */
65 /* Instead of IN_FD we use an estream. Note that the runner thread
66 may close the stream and set status_fp to NULL at any time. Thus
67 it won't be a good idea to use it while the runner thread is
68 running. */
69 estream_t status_fp;
73 /* The head of the list of all running threads. */
74 static runner_t running_threads;
79 /* Write NBYTES of BUF to file descriptor FD. */
80 static int
81 writen (int fd, const void *buf, size_t nbytes)
83 size_t nleft = nbytes;
84 int nwritten;
86 while (nleft > 0)
88 nwritten = pth_write (fd, buf, nleft);
89 if (nwritten < 0)
91 if (errno == EINTR)
92 nwritten = 0;
93 else
94 return -1;
96 nleft -= nwritten;
97 buf = (const char*)buf + nwritten;
100 return 0;
104 static int
105 check_already_spawned (runner_t runner, const char *funcname)
107 if (runner->spawned)
109 log_error ("BUG: runner already spawned - ignoring call to %s\n",
110 funcname);
111 return 1;
113 else
114 return 0;
118 /* Return the number of active threads. */
119 unsigned int
120 runner_get_threads (void)
122 unsigned int n = 0;
123 runner_t r;
125 for (r = running_threads; r; r = r->next_running)
126 n++;
127 return n;
131 /* The public release function. */
132 void
133 runner_release (runner_t runner)
135 gpg_error_t err;
137 if (!runner)
138 return;
140 if (!--runner->refcount)
141 return;
143 err = mountinfo_del_mount (NULL, NULL, runner->identifier);
144 if (err)
145 log_error ("failed to remove mount with rid %u from mtab: %s\n",
146 runner->identifier, gpg_strerror (err));
148 es_fclose (runner->status_fp);
149 if (runner->in_fd != -1)
150 close (runner->in_fd);
151 if (runner->out_fd != -1)
152 close (runner->out_fd);
154 /* Fixme: close the process. */
156 /* Tell the engine to release its data. */
157 if (runner->handler_cleanup)
158 runner->handler_cleanup (runner->handler_data);
160 if (runner->pid != (pid_t)(-1))
162 /* The process has not been cleaned up - do it now. */
163 gnupg_kill_process (runner->pid);
164 /* (Actually we should use the program name and not the
165 arbitrary NAME of the runner object. However it does not
166 matter because that information is only used for
167 diagnostics.) */
168 gnupg_wait_process (runner->name, runner->pid, NULL);
171 xfree (runner->name);
172 xfree (runner);
176 /* Create a new runner context. On success a new runner object is
177 stored at R_RUNNER. On failure NULL is stored at this address and
178 an error code returned. */
179 gpg_error_t
180 runner_new (runner_t *r_runner, const char *name)
182 static unsigned int namecounter; /* Global name counter. */
183 char *namebuffer;
184 runner_t runner, r;
186 *r_runner = NULL;
188 runner = xtrycalloc (1, sizeof *runner);
189 if (!runner)
190 return gpg_error_from_syserror ();
192 /* Bump up the namecounter. In case we ever had an overflow we
193 check that this number is currently not in use. The algorithm is
194 a bit lame but should be sufficient because such an wrap is not
195 very likely: Assuming that we do a mount 10 times a second, then
196 we would overwrap on a 32 bit system after 13 years. */
199 namecounter++;
200 for (r = running_threads; r; r = r->next_running)
201 if (r->identifier == namecounter)
202 break;
204 while (r);
206 runner->identifier = namecounter;
207 runner->name = namebuffer = xtryasprintf ("%s-%d", name, namecounter);
208 if (!runner->name)
210 xfree (runner);
211 return gpg_error_from_syserror ();
213 runner->refcount = 1;
214 runner->pid = (pid_t)(-1);
215 runner->in_fd = -1;
216 runner->out_fd = -1;
218 *r_runner = runner;
219 return 0;
223 /* Return the identifier of RUNNER. */
224 unsigned int
225 runner_get_rid (runner_t runner)
227 return runner->identifier;
231 /* Find a runner by its rid. Returns the runner object. The caller
232 must release the runner object. */
233 runner_t
234 runner_find_by_rid (unsigned int rid)
236 runner_t r;
238 for (r = running_threads; r; r = r->next_running)
239 if (r->identifier == rid)
241 r->refcount++;
242 return r;
244 return NULL;
248 /* A runner usually maintains two file descriptors to control the
249 backend engine. This function is used to set these file
250 descriptors. The function takes ownership of these file
251 descriptors. IN_FD will be used to read from engine and OUT_FD to
252 send data to the engine. */
253 void
254 runner_set_fds (runner_t runner, int in_fd, int out_fd)
256 if (check_already_spawned (runner, "runner_set_fds"))
257 return;
259 if (runner->in_fd != -1)
260 close (runner->in_fd);
261 if (runner->out_fd != -1)
262 close (runner->out_fd);
263 runner->in_fd = in_fd;
264 runner->out_fd = out_fd;
268 /* Set the PID of the backend engine. After this call the engine is
269 owned by the runner object. */
270 void
271 runner_set_pid (runner_t runner, pid_t pid)
273 if (check_already_spawned (runner, "runner_set_fds"))
274 return;
276 runner->pid = pid;
280 /* Register the engine handler fucntions HANDLER and HANDLER_CLEANUP
281 and its private HANDLER_DATA with RUNNER. */
282 void
283 runner_set_handler (runner_t runner,
284 engine_handler_fnc_t handler,
285 engine_handler_cleanup_fnc_t handler_cleanup,
286 void *handler_data)
288 if (check_already_spawned (runner, "runner_set_handler"))
289 return;
291 runner->handler = handler;
292 runner->handler_cleanup = handler_cleanup;
293 runner->handler_data = handler_data;
297 /* The thread spawned by runner_spawn. */
298 static void *
299 runner_thread (void *arg)
301 runner_t runner = arg;
302 gpg_error_t err = 0;
304 log_debug ("starting runner thread\n");
305 /* If a status_fp is available, the thread's main task is to read
306 from that stream and invoke the backend's handler function. This
307 is done on a line by line base and the line length is limited to
308 a reasonable value (about 1000 characters). Other work will
309 continue either due to an EOF of the stream or by demand of the
310 engine. */
311 if (runner->status_fp)
313 int c, cont_line;
314 unsigned int pos;
315 char buffer[1024];
316 estream_t fp = runner->status_fp;
318 pos = 0;
319 cont_line = 0;
320 while (!err && !runner->cancel_flag && (c=es_getc (fp)) != EOF)
322 buffer[pos++] = c;
323 if (pos >= sizeof buffer - 5 || c == '\n')
325 buffer[pos - (c == '\n')] = 0;
326 if (opt.verbose)
327 log_info ("%s%s: %s\n",
328 runner->name, cont_line? "(cont)":"", buffer);
329 /* We handle only complete lines and ignore any stuff we
330 possibly had to truncate. That is - at least for the
331 encfs engine - not an issue because our changes to
332 the tool make sure that only relatively short prompt
333 lines are of interest. */
334 if (!cont_line && runner->handler)
335 err = runner->handler (runner->handler_data,
336 runner, buffer);
337 pos = 0;
338 cont_line = (c != '\n');
341 if (!err && runner->cancel_flag)
342 log_debug ("runner thread noticed cancel flag\n");
343 else
344 log_debug ("runner thread saw EOF\n");
345 if (pos)
347 buffer[pos] = 0;
348 if (opt.verbose)
349 log_info ("%s%s: %s\n",
350 runner->name, cont_line? "(cont)":"", buffer);
351 if (!cont_line && !err && runner->handler)
352 err = runner->handler (runner->handler_data,
353 runner, buffer);
355 if (!err && es_ferror (fp))
357 err = gpg_error_from_syserror ();
358 log_error ("error reading from %s: %s\n",
359 runner->name, gpg_strerror (err));
362 runner->status_fp = NULL;
363 es_fclose (fp);
364 log_debug ("runner thread closed status fp\n");
367 /* Now wait for the process to finish. */
368 if (!err && runner->pid != (pid_t)(-1))
370 int exitcode;
372 log_debug ("runner thread waiting ...\n");
373 err = gnupg_wait_process (runner->name, runner->pid, &exitcode);
374 runner->pid = (pid_t)(-1);
375 if (err)
376 log_error ("running `%s' failed (exitcode=%d): %s\n",
377 runner->name, exitcode, gpg_strerror (err));
378 log_debug ("runner thread waiting finished\n");
381 /* Get rid of the runner object (note: it is refcounted). */
382 log_debug ("runner thread releasing runner ...\n");
384 runner_t r, rprev;
386 for (r = running_threads, rprev = NULL; r; rprev = r, r = r->next_running)
387 if (r == runner)
389 if (!rprev)
390 running_threads = r->next_running;
391 else
392 rprev->next_running = r->next_running;
393 r->next_running = NULL;
394 break;
397 runner_release (runner);
398 log_debug ("runner thread runner released\n");
400 return NULL;
404 /* Spawn a new thread to let RUNNER work as a coprocess. */
405 gpg_error_t
406 runner_spawn (runner_t runner)
408 gpg_error_t err;
409 pth_attr_t tattr;
410 pth_t tid;
412 if (check_already_spawned (runner, "runner_spawn"))
413 return gpg_error (GPG_ERR_BUG);
415 /* In case we have an input fd, open it as an estream so that the
416 Pth scheduling will work. The stdio functions don't work with
417 Pth because they don't call the pth counterparts of read and
418 write unless linker tricks are used. */
419 if (runner->in_fd != -1)
421 estream_t fp;
423 fp = es_fdopen (runner->in_fd, "r");
424 if (!fp)
426 err = gpg_error_from_syserror ();
427 log_error ("can't fdopen pipe for reading: %s\n", gpg_strerror (err));
428 return err;
430 runner->status_fp = fp;
431 runner->in_fd = -1; /* Now owned by status_fp. */
434 tattr = pth_attr_new ();
435 pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
436 pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 128*1024);
437 pth_attr_set (tattr, PTH_ATTR_NAME, runner->name);
439 tid = pth_spawn (tattr, runner_thread, runner);
440 if (!tid)
442 err = gpg_error_from_syserror ();
443 log_error ("error spawning runner thread: %s\n", gpg_strerror (err));
444 return err;
446 /* The scheduler has not yet kicked in, thus we can safely set the
447 spawned flag and the tid. */
448 runner->spawned = 1;
449 runner->threadid = tid;
450 runner->next_running = running_threads;
451 running_threads = runner;
453 pth_attr_destroy (tattr);
455 /* The runner thread is now runnable. */
457 return 0;
461 /* Cancel a running thread. */
462 void
463 runner_cancel (runner_t runner)
465 /* Warning: runner_cancel_all has knowledge of this code. */
466 if (runner->spawned)
468 runner->canceled = 1; /* Mark that we canceled this one already. */
469 /* FIXME: This does only work if the thread emits status lines. We
470 need to change the trhead to wait on an event. */
471 runner->cancel_flag = 1;
472 /* For now we use the brutal way and kill the process. */
473 gnupg_kill_process (runner->pid);
478 /* Cancel all runner threads. */
479 void
480 runner_cancel_all (void)
482 runner_t r;
486 for (r = running_threads; r; r = r->next_running)
487 if (r->spawned && !r->canceled)
489 runner_cancel (r);
490 break;
493 while (r);
497 /* Send a line of data down to the engine. This line may not contain
498 a binary Nul or a LF character. This function is used by the
499 engine's handler. */
500 gpg_error_t
501 runner_send_line (runner_t runner, const void *data, size_t datalen)
503 gpg_error_t err = 0;
505 if (!runner->spawned)
507 log_error ("BUG: runner for %s not spawned\n", runner->name);
508 err = gpg_error (GPG_ERR_INTERNAL);
510 else if (runner->out_fd == -1)
512 log_error ("no output file descriptor for runner %s\n", runner->name);
513 err = gpg_error (GPG_ERR_EBADF);
515 else if (data && datalen)
517 if (memchr (data, '\n', datalen))
519 log_error ("LF detected in response data\n");
520 err = gpg_error (GPG_ERR_BUG);
522 else if (memchr (data, 0, datalen))
524 log_error ("Nul detected in response data\n");
525 err = gpg_error (GPG_ERR_BUG);
527 else if (writen (runner->out_fd, data, datalen))
528 err = gpg_error_from_syserror ();
531 if (!err)
532 if (writen (runner->out_fd, "\n", 1))
533 err = gpg_error_from_syserror ();
535 return err;