command.h 8.6 KB
Newer Older
1 2 3
/*
 * command.h: Child command execution
 *
4
 * Copyright (C) 2010-2011 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 */

#ifndef __VIR_COMMAND_H__
# define __VIR_COMMAND_H__

# include "internal.h"
# include "util.h"
27
# include "buf.h"
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

typedef struct _virCommand virCommand;
typedef virCommand *virCommandPtr;

/*
 * Create a new command for named binary
 */
virCommandPtr virCommandNew(const char *binary) ATTRIBUTE_NONNULL(1);

/*
 * Create a new command with a NULL terminated
 * set of args, taking binary from argv[0]
 */
virCommandPtr virCommandNewArgs(const char *const*args) ATTRIBUTE_NONNULL(1);

/*
 * Create a new command with a NULL terminated
 * list of args, starting with the binary to run
 */
virCommandPtr virCommandNewArgList(const char *binary, ...)
    ATTRIBUTE_NONNULL(1) ATTRIBUTE_SENTINEL;

/* All error report from these setup APIs is
 * delayed until the Run/RunAsync methods
 */

/*
 * Preserve the specified file descriptor
 * in the child, instead of closing it.
 * The parent is still responsible for managing fd.
 */
void virCommandPreserveFD(virCommandPtr cmd,
                          int fd);

/*
 * Transfer the specified file descriptor
 * to the child, instead of closing it.
 * Close the fd in the parent during Run/RunAsync/Free.
 */
void virCommandTransferFD(virCommandPtr cmd,
                          int fd);

/*
 * Save the child PID in a pidfile
 */
void virCommandSetPidFile(virCommandPtr cmd,
                          const char *pidfile) ATTRIBUTE_NONNULL(2);

/*
 * Remove all capabilities from the child
 */
void virCommandClearCaps(virCommandPtr cmd);

# if 0
/*
 * Re-allow a specific capability
 */
void virCommandAllowCap(virCommandPtr cmd,
                        int capability);
# endif

/*
 * Daemonize the child process
 */
void virCommandDaemonize(virCommandPtr cmd);

/*
 * Set FDs created by virCommandSetOutputFD and virCommandSetErrorFD
 * as non-blocking in the parent.
 */
void virCommandNonblockingFDs(virCommandPtr cmd);

/*
 * Add an environment variable to the child
 * using separate name & value strings
 */
void virCommandAddEnvPair(virCommandPtr cmd,
                          const char *name,
                          const char *value) ATTRIBUTE_NONNULL(2);

/*
 * Add an environemnt variable to the child
 * using a preformated env string FOO=BAR
 */
void virCommandAddEnvString(virCommandPtr cmd,
                            const char *str) ATTRIBUTE_NONNULL(2);
114 115 116 117 118 119 120 121 122

/*
 * Convert a buffer containing preformatted name=value into an
 * environment variable of the child.
 * Correctly transfers memory errors or contents from buf to cmd.
 */
void virCommandAddEnvBuffer(virCommandPtr cmd,
                            virBufferPtr buf);

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/*
 * Pass an environment variable to the child
 * using current process' value
 */
void virCommandAddEnvPass(virCommandPtr cmd,
                          const char *name) ATTRIBUTE_NONNULL(2);
/*
 * Pass a common set of environment variables
 * to the child using current process' values
 */
void virCommandAddEnvPassCommon(virCommandPtr cmd);

/*
 * Add a command line argument to the child
 */
void virCommandAddArg(virCommandPtr cmd,
                      const char *val) ATTRIBUTE_NONNULL(2);

141 142 143 144 145 146 147
/*
 * Convert a buffer into a command line argument to the child.
 * Correctly transfers memory errors or contents from buf to cmd.
 */
void virCommandAddArgBuffer(virCommandPtr cmd,
                            virBufferPtr buf);

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
/*
 * Add a command line argument created by a printf-style format
 */
void virCommandAddArgFormat(virCommandPtr cmd,
                            const char *format, ...)
    ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3);

/*
 * Add a command line argument to the child
 */
void virCommandAddArgPair(virCommandPtr cmd,
                          const char *name,
                          const char *val)
    ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
/*
 * Add a NULL terminated array of args
 */
void virCommandAddArgSet(virCommandPtr cmd,
                         const char *const*vals) ATTRIBUTE_NONNULL(2);
/*
 * Add a NULL terminated list of args
 */
void virCommandAddArgList(virCommandPtr cmd,
                          ... /* const char *arg, ..., NULL */)
    ATTRIBUTE_SENTINEL;

/*
 * Set the working directory of a non-daemon child process, rather
 * than the parent's working directory.  Daemons automatically get /
 * without using this call.
 */
void virCommandSetWorkingDirectory(virCommandPtr cmd,
                                   const char *pwd) ATTRIBUTE_NONNULL(2);

/*
 * Feed the child's stdin from a string buffer.
 *
 * NB: Only works with virCommandRun()
 */
void virCommandSetInputBuffer(virCommandPtr cmd,
                              const char *inbuf) ATTRIBUTE_NONNULL(2);
/*
 * Capture the child's stdout to a string buffer
 *
 * NB: Only works with virCommandRun()
 */
void virCommandSetOutputBuffer(virCommandPtr cmd,
                               char **outbuf) ATTRIBUTE_NONNULL(2);
/*
 * Capture the child's stderr to a string buffer
 *
 * NB: Only works with virCommandRun()
 */
void virCommandSetErrorBuffer(virCommandPtr cmd,
                              char **errbuf) ATTRIBUTE_NONNULL(2);

/*
 * Set a file descriptor as the child's stdin
 */
void virCommandSetInputFD(virCommandPtr cmd,
                          int infd);
/*
 * Set a file descriptor as the child's stdout
 */
void virCommandSetOutputFD(virCommandPtr cmd,
                           int *outfd) ATTRIBUTE_NONNULL(2);
/*
 * Set a file descriptor as the child's stderr
 */
void virCommandSetErrorFD(virCommandPtr cmd,
                          int *errfd) ATTRIBUTE_NONNULL(2);

/*
 * A hook function to run between fork + exec
 */
void virCommandSetPreExecHook(virCommandPtr cmd,
                              virExecHook hook,
                              void *opaque) ATTRIBUTE_NONNULL(2);

/*
 * Call after adding all arguments and environment settings, but before
 * Run/RunAsync, to immediately output the environment and arguments of
 * cmd to logfd.  If virCommandRun cannot succeed (because of an
 * out-of-memory condition while building cmd), nothing will be logged.
 */
void virCommandWriteArgLog(virCommandPtr cmd,
                           int logfd);

/*
 * Call after adding all arguments and environment settings, but before
 * Run/RunAsync, to return a string representation of the environment and
 * arguments of cmd.  If virCommandRun cannot succeed (because of an
 * out-of-memory condition while building cmd), NULL will be returned.
 * Caller is responsible for freeing the resulting string.
 */
char *virCommandToString(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;

245 246 247 248 249 250

/*
 * Translate an exit status into a malloc'd string.
 */
char *virCommandTranslateStatus(int exitstatus) ATTRIBUTE_RETURN_CHECK;

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
/*
 * Run the command and wait for completion.
 * Returns -1 on any error executing the
 * command. Returns 0 if the command executed,
 * with the exit status set
 */
int virCommandRun(virCommandPtr cmd,
                  int *exitstatus) ATTRIBUTE_RETURN_CHECK;

/*
 * Run the command asynchronously
 * Returns -1 on any error executing the
 * command. Returns 0 if the command executed.
 */
int virCommandRunAsync(virCommandPtr cmd,
                       pid_t *pid) ATTRIBUTE_RETURN_CHECK;

/*
 * Wait for the async command to complete.
 * Return -1 on any error waiting for
 * completion. Returns 0 if the command
 * finished with the exit status set
 */
int virCommandWait(virCommandPtr cmd,
                   int *exitstatus) ATTRIBUTE_RETURN_CHECK;

/*
278 279 280 281 282 283 284 285 286 287 288
 * Abort an async command if it is running, without issuing
 * any errors or affecting errno.  Designed for error paths
 * where some but not all paths to the cleanup code might
 * have started the child process.
 */
void virCommandAbort(virCommandPtr cmd);

/*
 * Release all resources.  The only exception is that if you called
 * virCommandRunAsync with a non-null pid, then the asynchronous child
 * is not reaped, and you must call waitpid() yourself.
289 290 291 292 293
 */
void virCommandFree(virCommandPtr cmd);


#endif /* __VIR_COMMAND_H__ */