]> mj.ucw.cz Git - libucw.git/blob - lib/runcmd.c
hashtables: fixed combination of HASH_GIVE_ALLOC and HASH_TABLE_ALLOC
[libucw.git] / lib / runcmd.c
1 /*
2  *      UCW Library -- Running of Commands
3  *
4  *      (c) 2004 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <alloca.h>
15 #include <unistd.h>
16 #include <sys/wait.h>
17
18 void NONRET
19 exec_command_v(byte *cmd, va_list args)
20 {
21   va_list cargs;
22   va_copy(cargs, args);
23   int cnt = 2;
24   byte *arg;
25   while (arg = va_arg(cargs, byte *))
26     cnt++;
27   va_end(cargs);
28   char **argv = alloca(sizeof(byte *) * cnt);
29   argv[0] = cmd;
30   cnt = 1;
31   va_copy(cargs, args);
32   while (arg = va_arg(cargs, byte *))
33     argv[cnt++] = arg;
34   va_end(cargs);
35   argv[cnt] = NULL;
36   execv(cmd, argv);
37   byte echo[256];
38   echo_command_v(echo, sizeof(echo), cmd, args);
39   log(L_ERROR, "Cannot execute %s: %m", echo);
40   exit(255);
41 }
42
43 int
44 run_command_v(byte *cmd, va_list args)
45 {
46   pid_t p = fork();
47   if (p < 0)
48     {
49       log(L_ERROR, "fork() failed: %m");
50       return 0;
51     }
52   else if (!p)
53     exec_command_v(cmd, args);
54   else
55     {
56       int stat;
57       byte msg[EXIT_STATUS_MSG_SIZE];
58       p = waitpid(p, &stat, 0);
59       if (p < 0)
60         die("waitpid() failed: %m");
61       if (format_exit_status(msg, stat))
62         {
63           byte echo[256];
64           echo_command_v(echo, sizeof(echo), cmd, args);
65           log(L_ERROR, "`%s' failed: %s", echo, msg);
66           return 0;
67         }
68       return 1;
69     }
70 }
71
72 void
73 echo_command_v(byte *buf, int size, byte *cmd, va_list args)
74 {
75   byte *limit = buf + size - 4;
76   byte *p = buf;
77   byte *arg = cmd;
78   do
79     {
80       int l = strlen(arg);
81       if (p != buf && p < limit)
82         *p++ = ' ';
83       if (p+l > limit)
84         {
85           memcpy(p, arg, limit-p);
86           strcpy(limit, "...");
87           return;
88         }
89       memcpy(p, arg, l);
90       p += l;
91     }
92   while (arg = va_arg(args, byte *));
93   *p = 0;
94 }
95
96 int
97 run_command(byte *cmd, ...)
98 {
99   va_list args;
100   va_start(args, cmd);
101   int e = run_command_v(cmd, args);
102   va_end(args);
103   return e;
104 }
105
106 void NONRET
107 exec_command(byte *cmd, ...)
108 {
109   va_list args;
110   va_start(args, cmd);
111   exec_command_v(cmd, args);
112 }
113
114 void
115 echo_command(byte *buf, int len, byte *cmd, ...)
116 {
117   va_list args;
118   va_start(args, cmd);
119   echo_command_v(buf, len, cmd, args);
120   va_end(args);
121 }
122
123 #ifdef TEST
124
125 int main(void)
126 {
127   byte msg[1024];
128   echo_command(msg, sizeof(msg), "/bin/echo", "datel", "strakapoud", NULL);
129   log(L_INFO, "Running <%s>", msg);
130   run_command("/bin/echo", "datel", "strakapoud", NULL);
131   return 0;
132 }
133
134 #endif