Add API: set-wrappid-path.
[wrappi.git] / lib / wrappi.c
1 /* wrappi
2  * Copyright (C) 2011-2012 Red Hat Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #include <config.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <sys/types.h>
25 #include <sys/wait.h>
26
27 #include "wrappi.h"
28 #include "internal.h"
29
30 wrap_h *
31 wrap_create (void)
32 {
33   struct wrap_h *w = calloc (1, sizeof *w);
34   if (w == NULL)
35     return NULL;
36
37   w->serial = random ();
38
39   return w;
40 }
41
42 void
43 wrap_close (wrap_h *w)
44 {
45   if (w->pid)
46     waitpid (w->pid, NULL, 0);
47
48   if (w->rfp != NULL)
49     fclose (w->rfp);
50
51   if (w->wfp != NULL)
52     fclose (w->wfp);
53
54   free (w->hostname);
55   free (w->wrappid_path);
56   free (w);
57 }
58
59 static void
60 set_error_buf (struct wrap_internal_h *w,
61                char *buf, int errnum, const char *func)
62 {
63   free (w->error);
64   w->error = buf;
65   w->errnum = errnum;
66
67   /* 'func' is always statically allocated, since it comes from
68    * C99 __func__, so this is safe.
69    */
70   if (STRPREFIX (func, "impl_"))
71     func += 5;
72   else if (STRPREFIX (func, "wrap_"))
73     func += 5;
74   w->error_func = func;
75
76   /* XXX This will be conditional on the user setting an error handler. */
77   fprintf (stderr, "wrappi: %s: %s\n", func, buf);
78 }
79
80 void
81 wrap_int_set_error (struct wrap_internal_h *w,
82                     const char *func,
83                     const char *fs, ...)
84 {
85   va_list args;
86   char *msg;
87   int err;
88
89   va_start (args, fs);
90   err = vasprintf (&msg, fs, args);
91   va_end (args);
92
93   if (err < 0) return;
94
95   set_error_buf (w, msg, 0, func);
96 }
97
98 void
99 wrap_int_set_error_errno (struct wrap_internal_h *w,
100                           int errnum,
101                           const char *func,
102                           const char *fs, ...)
103 {
104   va_list args;
105   char *msg;
106   int err;
107
108   va_start (args, fs);
109   err = vasprintf (&msg, fs, args);
110   va_end (args);
111
112   if (err < 0) return;
113
114   set_error_buf (w, msg, errnum, func);
115 }
116
117 /* Note the gperf perfect hash in lib/internal-procs-lookup.gperf */
118 int
119 wrap_int_lookup_proc_entry (const char *name)
120 {
121   const struct proc_entry *v =
122     wrap_int_gperf_lookup_proc_entry (name, strlen (name));
123   if (v)
124     return v->proc_nr;
125   else
126     return -1;
127 }