提交 42891145 编写于 作者: E Eric Blake

command: move all docs into .c file

We already have a precedent of function documentation in C files,
where it is closer to the implementation (witness libvirt.h vs.
libvirt.c); maintaining docs in both files risks docs going stale.

While I was at it, I used consistent doxygen style on all comments.

* src/util/command.h: Remove duplicate docs, and move unique
documentation...
* src/util/command.c: ...here.
Suggested by Matthias Bolte.
上级 fbd5465a
...@@ -130,23 +130,25 @@ static int virClearCapabilities(void) ...@@ -130,23 +130,25 @@ static int virClearCapabilities(void)
# endif # endif
/* virFork() - fork a new process while avoiding various race/deadlock /**
conditions * virFork:
* @pid - a pointer to a pid_t that will receive the return value from
@pid - a pointer to a pid_t that will receive the return value from * fork()
fork() *
* fork a new process while avoiding various race/deadlock conditions
on return from virFork(), if *pid < 0, the fork failed and there is *
no new process. Otherwise, just like fork(), if *pid == 0, it is the * on return from virFork(), if *pid < 0, the fork failed and there is
child process returning, and if *pid > 0, it is the parent. * no new process. Otherwise, just like fork(), if *pid == 0, it is the
* child process returning, and if *pid > 0, it is the parent.
Even if *pid >= 0, if the return value from virFork() is < 0, it *
indicates a failure that occurred in the parent or child process * Even if *pid >= 0, if the return value from virFork() is < 0, it
after the fork. In this case, the child process should call * indicates a failure that occurred in the parent or child process
_exit(EXIT_FAILURE) after doing any additional error reporting. * after the fork. In this case, the child process should call
* _exit(EXIT_FAILURE) after doing any additional error reporting.
*/ */
int virFork(pid_t *pid) { int
virFork(pid_t *pid)
{
sigset_t oldmask, newmask; sigset_t oldmask, newmask;
struct sigaction sig_action; struct sigaction sig_action;
int saved_errno, ret = -1; int saved_errno, ret = -1;
...@@ -573,6 +575,7 @@ virExecWithHook(const char *const*argv, ...@@ -573,6 +575,7 @@ virExecWithHook(const char *const*argv,
} }
/** /**
* virRun:
* @argv NULL terminated argv to run * @argv NULL terminated argv to run
* @status optional variable to return exit status in * @status optional variable to return exit status in
* *
...@@ -645,8 +648,13 @@ virFork(pid_t *pid) ...@@ -645,8 +648,13 @@ virFork(pid_t *pid)
#endif /* WIN32 */ #endif /* WIN32 */
/* /**
* Create a new command for named binary * virCommandNew:
* @binary: program to run
*
* Create a new command for named binary. If @binary is relative,
* it will be found via a PATH search of the parent's PATH (and not
* any altered PATH set by virCommandAddEnv* commands).
*/ */
virCommandPtr virCommandPtr
virCommandNew(const char *binary) virCommandNew(const char *binary)
...@@ -656,9 +664,13 @@ virCommandNew(const char *binary) ...@@ -656,9 +664,13 @@ virCommandNew(const char *binary)
return virCommandNewArgs(args); return virCommandNewArgs(args);
} }
/* /**
* virCommandNewArgs:
* @args: array of arguments
*
* Create a new command with a NULL terminated * Create a new command with a NULL terminated
* set of args, taking binary from args[0] * set of args, taking binary from args[0]. More arguments can
* be added later. @args[0] is handled like @binary of virCommandNew.
*/ */
virCommandPtr virCommandPtr
virCommandNewArgs(const char *const*args) virCommandNewArgs(const char *const*args)
...@@ -684,9 +696,14 @@ virCommandNewArgs(const char *const*args) ...@@ -684,9 +696,14 @@ virCommandNewArgs(const char *const*args)
return cmd; return cmd;
} }
/* /**
* virCommandNewArgList:
* @binary: program to run
* @...: additional arguments
*
* Create a new command with a NULL terminated * Create a new command with a NULL terminated
* list of args, starting with the binary to run * list of args, starting with the binary to run. More arguments can
* be added later. @binary is handled as in virCommandNew.
*/ */
virCommandPtr virCommandPtr
virCommandNewArgList(const char *binary, ...) virCommandNewArgList(const char *binary, ...)
...@@ -730,9 +747,13 @@ virCommandKeepFD(virCommandPtr cmd, int fd, bool transfer) ...@@ -730,9 +747,13 @@ virCommandKeepFD(virCommandPtr cmd, int fd, bool transfer)
FD_SET(fd, &cmd->transfer); FD_SET(fd, &cmd->transfer);
} }
/* /**
* virCommandPreserveFD:
* @cmd: the command to modify
* @fd: fd to mark for inheritance into child
*
* Preserve the specified file descriptor * Preserve the specified file descriptor
* in the child, instead of closing it. * in the child, instead of closing it on exec.
* The parent is still responsible for managing fd. * The parent is still responsible for managing fd.
*/ */
void void
...@@ -741,9 +762,13 @@ virCommandPreserveFD(virCommandPtr cmd, int fd) ...@@ -741,9 +762,13 @@ virCommandPreserveFD(virCommandPtr cmd, int fd)
return virCommandKeepFD(cmd, fd, false); return virCommandKeepFD(cmd, fd, false);
} }
/* /**
* virCommandTransferFD:
* @cmd: the command to modify
* @fd: fd to reassign to the child
*
* Transfer the specified file descriptor * Transfer the specified file descriptor
* to the child, instead of closing it. * to the child, instead of closing it on exec.
* Close the fd in the parent during Run/RunAsync/Free. * Close the fd in the parent during Run/RunAsync/Free.
*/ */
void void
...@@ -753,8 +778,13 @@ virCommandTransferFD(virCommandPtr cmd, int fd) ...@@ -753,8 +778,13 @@ virCommandTransferFD(virCommandPtr cmd, int fd)
} }
/* /**
* Save the child PID in a pidfile * virCommandSetPidFile:
* @cmd: the command to modify
* @pidfile: filename to use
*
* Save the child PID in a pidfile. The pidfile will be populated
* before the exec of the child.
*/ */
void void
virCommandSetPidFile(virCommandPtr cmd, const char *pidfile) virCommandSetPidFile(virCommandPtr cmd, const char *pidfile)
...@@ -769,8 +799,11 @@ virCommandSetPidFile(virCommandPtr cmd, const char *pidfile) ...@@ -769,8 +799,11 @@ virCommandSetPidFile(virCommandPtr cmd, const char *pidfile)
} }
/* /**
* Remove all capabilities from the child * virCommandClearCaps:
* @cmd: the command to modify
*
* Remove all capabilities from the child, after any hooks have been run.
*/ */
void void
virCommandClearCaps(virCommandPtr cmd) virCommandClearCaps(virCommandPtr cmd)
...@@ -783,7 +816,11 @@ virCommandClearCaps(virCommandPtr cmd) ...@@ -783,7 +816,11 @@ virCommandClearCaps(virCommandPtr cmd)
#if 0 /* XXX Enable if we have a need for capability management. */ #if 0 /* XXX Enable if we have a need for capability management. */
/* /**
* virCommandAllowCap:
* @cmd: the command to modify
* @capability: what to allow
*
* Re-allow a specific capability * Re-allow a specific capability
*/ */
void void
...@@ -799,8 +836,13 @@ virCommandAllowCap(virCommandPtr cmd, ...@@ -799,8 +836,13 @@ virCommandAllowCap(virCommandPtr cmd,
#endif /* 0 */ #endif /* 0 */
/* /**
* Daemonize the child process * virCommandDaemonize:
* @cmd: the command to modify
*
* Daemonize the child process. The child will have a current working
* directory of /, and must be started with virCommandRun, which will
* complete as soon as the daemon grandchild has started.
*/ */
void void
virCommandDaemonize(virCommandPtr cmd) virCommandDaemonize(virCommandPtr cmd)
...@@ -811,7 +853,10 @@ virCommandDaemonize(virCommandPtr cmd) ...@@ -811,7 +853,10 @@ virCommandDaemonize(virCommandPtr cmd)
cmd->flags |= VIR_EXEC_DAEMON; cmd->flags |= VIR_EXEC_DAEMON;
} }
/* /**
* virCommandNonblockingFDs:
* @cmd: the command to modify
*
* Set FDs created by virCommandSetOutputFD and virCommandSetErrorFD * Set FDs created by virCommandSetOutputFD and virCommandSetErrorFD
* as non-blocking in the parent. * as non-blocking in the parent.
*/ */
...@@ -824,8 +869,13 @@ virCommandNonblockingFDs(virCommandPtr cmd) ...@@ -824,8 +869,13 @@ virCommandNonblockingFDs(virCommandPtr cmd)
cmd->flags |= VIR_EXEC_NONBLOCK; cmd->flags |= VIR_EXEC_NONBLOCK;
} }
/* /**
* Add an environment variable to the child created by a printf-style format * virCommandAddEnvFormat:
* @cmd: the command to modify
* @format: format of arguments, end result must be in name=value format
* @...: arguments to be formatted
*
* Add an environment variable to the child created by a printf-style format.
*/ */
void void
virCommandAddEnvFormat(virCommandPtr cmd, const char *format, ...) virCommandAddEnvFormat(virCommandPtr cmd, const char *format, ...)
...@@ -854,7 +904,12 @@ virCommandAddEnvFormat(virCommandPtr cmd, const char *format, ...) ...@@ -854,7 +904,12 @@ virCommandAddEnvFormat(virCommandPtr cmd, const char *format, ...)
cmd->env[cmd->nenv++] = env; cmd->env[cmd->nenv++] = env;
} }
/* /**
* virCommandAddEnvPair:
* @cmd: the command to modify
* @name: variable name, must not contain =
* @value: value to assign to name
*
* Add an environment variable to the child * Add an environment variable to the child
* using separate name & value strings * using separate name & value strings
*/ */
...@@ -865,7 +920,11 @@ virCommandAddEnvPair(virCommandPtr cmd, const char *name, const char *value) ...@@ -865,7 +920,11 @@ virCommandAddEnvPair(virCommandPtr cmd, const char *name, const char *value)
} }
/* /**
* virCommandAddEnvString:
* @cmd: the command to modify
* @str: name=value format
*
* Add an environment variable to the child * Add an environment variable to the child
* using a preformatted env string FOO=BAR * using a preformatted env string FOO=BAR
*/ */
...@@ -893,7 +952,11 @@ virCommandAddEnvString(virCommandPtr cmd, const char *str) ...@@ -893,7 +952,11 @@ virCommandAddEnvString(virCommandPtr cmd, const char *str)
} }
/* /**
* virCommandAddEnvBuffer:
* @cmd: the command to modify
* @buf: buffer that contains name=value string, which will be reset on return
*
* Convert a buffer containing preformatted name=value into an * Convert a buffer containing preformatted name=value into an
* environment variable of the child. * environment variable of the child.
* Correctly transfers memory errors or contents from buf to cmd. * Correctly transfers memory errors or contents from buf to cmd.
...@@ -918,7 +981,11 @@ virCommandAddEnvBuffer(virCommandPtr cmd, virBufferPtr buf) ...@@ -918,7 +981,11 @@ virCommandAddEnvBuffer(virCommandPtr cmd, virBufferPtr buf)
} }
/* /**
* virCommandAddEnvPass:
* @cmd: the command to modify
* @name: the name to look up in current environment
*
* Pass an environment variable to the child * Pass an environment variable to the child
* using current process' value * using current process' value
*/ */
...@@ -935,9 +1002,12 @@ virCommandAddEnvPass(virCommandPtr cmd, const char *name) ...@@ -935,9 +1002,12 @@ virCommandAddEnvPass(virCommandPtr cmd, const char *name)
} }
/* /**
* virCommandAddEnvPassCommon:
* @cmd: the command to modify
*
* Set LC_ALL to C, and propagate other essential environment * Set LC_ALL to C, and propagate other essential environment
* variables from the parent process. * variables (such as PATH) from the parent process.
*/ */
void void
virCommandAddEnvPassCommon(virCommandPtr cmd) virCommandAddEnvPassCommon(virCommandPtr cmd)
...@@ -960,7 +1030,11 @@ virCommandAddEnvPassCommon(virCommandPtr cmd) ...@@ -960,7 +1030,11 @@ virCommandAddEnvPassCommon(virCommandPtr cmd)
virCommandAddEnvPass(cmd, "TMPDIR"); virCommandAddEnvPass(cmd, "TMPDIR");
} }
/* /**
* virCommandAddArg:
* @cmd: the command to modify
* @val: the argument to add
*
* Add a command line argument to the child * Add a command line argument to the child
*/ */
void void
...@@ -987,7 +1061,11 @@ virCommandAddArg(virCommandPtr cmd, const char *val) ...@@ -987,7 +1061,11 @@ virCommandAddArg(virCommandPtr cmd, const char *val)
} }
/* /**
* virCommandAddArgBuffer:
* @cmd: the command to modify
* @buf: buffer that contains argument string, which will be reset on return
*
* Convert a buffer into a command line argument to the child. * Convert a buffer into a command line argument to the child.
* Correctly transfers memory errors or contents from buf to cmd. * Correctly transfers memory errors or contents from buf to cmd.
*/ */
...@@ -1011,8 +1089,13 @@ virCommandAddArgBuffer(virCommandPtr cmd, virBufferPtr buf) ...@@ -1011,8 +1089,13 @@ virCommandAddArgBuffer(virCommandPtr cmd, virBufferPtr buf)
} }
/* /**
* Add a command line argument created by a printf-style format * virCommandAddArgFormat:
* @cmd: the command to modify
* @format: format of arguments, end result must be in name=value format
* @...: arguments to be formatted
*
* Add a command line argument created by a printf-style format.
*/ */
void void
virCommandAddArgFormat(virCommandPtr cmd, const char *format, ...) virCommandAddArgFormat(virCommandPtr cmd, const char *format, ...)
...@@ -1041,7 +1124,12 @@ virCommandAddArgFormat(virCommandPtr cmd, const char *format, ...) ...@@ -1041,7 +1124,12 @@ virCommandAddArgFormat(virCommandPtr cmd, const char *format, ...)
cmd->args[cmd->nargs++] = arg; cmd->args[cmd->nargs++] = arg;
} }
/* /**
* virCommandAddArgPair:
* @cmd: the command to modify
* @name: left half of argument
* @value: right half of argument
*
* Add "NAME=VAL" as a single command line argument to the child * Add "NAME=VAL" as a single command line argument to the child
*/ */
void void
...@@ -1050,7 +1138,11 @@ virCommandAddArgPair(virCommandPtr cmd, const char *name, const char *val) ...@@ -1050,7 +1138,11 @@ virCommandAddArgPair(virCommandPtr cmd, const char *name, const char *val)
virCommandAddArgFormat(cmd, "%s=%s", name, val); virCommandAddArgFormat(cmd, "%s=%s", name, val);
} }
/* /**
* virCommandAddArgSet:
* @cmd: the command to modify
* @vals: array of arguments to add
*
* Add a NULL terminated list of args * Add a NULL terminated list of args
*/ */
void void
...@@ -1086,8 +1178,12 @@ virCommandAddArgSet(virCommandPtr cmd, const char *const*vals) ...@@ -1086,8 +1178,12 @@ virCommandAddArgSet(virCommandPtr cmd, const char *const*vals)
} }
} }
/* /**
* Add a NULL terminated list of args * virCommandAddArgList:
* @cmd: the command to modify
* @...: list of arguments to add
*
* Add a NULL terminated list of args.
*/ */
void void
virCommandAddArgList(virCommandPtr cmd, ...) virCommandAddArgList(virCommandPtr cmd, ...)
...@@ -1125,7 +1221,11 @@ virCommandAddArgList(virCommandPtr cmd, ...) ...@@ -1125,7 +1221,11 @@ virCommandAddArgList(virCommandPtr cmd, ...)
va_end(list); va_end(list);
} }
/* /**
* virCommandSetWorkingDirectory:
* @cmd: the command to modify
* @pwd: directory to use
*
* Set the working directory of a non-daemon child process, rather * Set the working directory of a non-daemon child process, rather
* than the parent's working directory. Daemons automatically get / * than the parent's working directory. Daemons automatically get /
* without using this call. * without using this call.
...@@ -1147,8 +1247,13 @@ virCommandSetWorkingDirectory(virCommandPtr cmd, const char *pwd) ...@@ -1147,8 +1247,13 @@ virCommandSetWorkingDirectory(virCommandPtr cmd, const char *pwd)
} }
/* /**
* Feed the child's stdin from a string buffer * virCommandSetInputBuffer:
* @cmd: the command to modify
* @inbuf: string to feed to stdin
*
* Feed the child's stdin from a string buffer. This requires the use
* of virCommandRun().
*/ */
void void
virCommandSetInputBuffer(virCommandPtr cmd, const char *inbuf) virCommandSetInputBuffer(virCommandPtr cmd, const char *inbuf)
...@@ -1168,11 +1273,16 @@ virCommandSetInputBuffer(virCommandPtr cmd, const char *inbuf) ...@@ -1168,11 +1273,16 @@ virCommandSetInputBuffer(virCommandPtr cmd, const char *inbuf)
} }
/* /**
* virCommandSetOutputBuffer:
* @cmd: the command to modify
* @outbuf: address of variable to store malloced result buffer
*
* Capture the child's stdout to a string buffer. *outbuf is * Capture the child's stdout to a string buffer. *outbuf is
* guaranteed to be allocated after successful virCommandRun or * guaranteed to be allocated after successful virCommandRun or
* virCommandWait, and is best-effort allocated after failed * virCommandWait, and is best-effort allocated after failed
* virCommandRun; caller is responsible for freeing *outbuf. * virCommandRun; caller is responsible for freeing *outbuf.
* This requires the use of virCommandRun.
*/ */
void void
virCommandSetOutputBuffer(virCommandPtr cmd, char **outbuf) virCommandSetOutputBuffer(virCommandPtr cmd, char **outbuf)
...@@ -1192,11 +1302,16 @@ virCommandSetOutputBuffer(virCommandPtr cmd, char **outbuf) ...@@ -1192,11 +1302,16 @@ virCommandSetOutputBuffer(virCommandPtr cmd, char **outbuf)
} }
/* /**
* virCommandSetErrorBuffer:
* @cmd: the command to modify
* @errbuf: address of variable to store malloced result buffer
*
* Capture the child's stderr to a string buffer. *errbuf is * Capture the child's stderr to a string buffer. *errbuf is
* guaranteed to be allocated after successful virCommandRun or * guaranteed to be allocated after successful virCommandRun or
* virCommandWait, and is best-effort allocated after failed * virCommandWait, and is best-effort allocated after failed
* virCommandRun; caller is responsible for freeing *errbuf. * virCommandRun; caller is responsible for freeing *errbuf.
* This requires the use of virCommandRun.
*/ */
void void
virCommandSetErrorBuffer(virCommandPtr cmd, char **errbuf) virCommandSetErrorBuffer(virCommandPtr cmd, char **errbuf)
...@@ -1216,7 +1331,11 @@ virCommandSetErrorBuffer(virCommandPtr cmd, char **errbuf) ...@@ -1216,7 +1331,11 @@ virCommandSetErrorBuffer(virCommandPtr cmd, char **errbuf)
} }
/* /**
* virCommandSetInputFD:
* @cmd: the command to modify
* @infd: the descriptor to use
*
* Attach a file descriptor to the child's stdin * Attach a file descriptor to the child's stdin
*/ */
void void
...@@ -1240,8 +1359,14 @@ virCommandSetInputFD(virCommandPtr cmd, int infd) ...@@ -1240,8 +1359,14 @@ virCommandSetInputFD(virCommandPtr cmd, int infd)
} }
/* /**
* Attach a file descriptor to the child's stdout * virCommandSetOutputFD:
* @cmd: the command to modify
* @outfd: location of output fd
*
* Attach a file descriptor to the child's stdout. If *@outfd is -1 on
* entry, then a pipe will be created and returned in this variable when
* the child is run. Otherwise, *@outfd is used as the output.
*/ */
void void
virCommandSetOutputFD(virCommandPtr cmd, int *outfd) virCommandSetOutputFD(virCommandPtr cmd, int *outfd)
...@@ -1259,8 +1384,15 @@ virCommandSetOutputFD(virCommandPtr cmd, int *outfd) ...@@ -1259,8 +1384,15 @@ virCommandSetOutputFD(virCommandPtr cmd, int *outfd)
} }
/* /**
* Attach a file descriptor to the child's stderr * virCommandSetErrorFD:
* @cmd: the command to modify
* @errfd: location of error fd
*
* Attach a file descriptor to the child's stderr. If *@errfd is -1 on
* entry, then a pipe will be created and returned in this variable when
* the child is run. Otherwise, *@errfd is used for error collection,
* and may be the same as outfd given to virCommandSetOutputFD().
*/ */
void void
virCommandSetErrorFD(virCommandPtr cmd, int *errfd) virCommandSetErrorFD(virCommandPtr cmd, int *errfd)
...@@ -1278,10 +1410,18 @@ virCommandSetErrorFD(virCommandPtr cmd, int *errfd) ...@@ -1278,10 +1410,18 @@ virCommandSetErrorFD(virCommandPtr cmd, int *errfd)
} }
/* /**
* virCommandSetPreExecHook:
* @cmd: the command to modify
* @hook: the hook to run
* @opaque: argument to pass to the hook
*
* Run HOOK(OPAQUE) in the child as the last thing before changing * Run HOOK(OPAQUE) in the child as the last thing before changing
* directories, dropping capabilities, and executing the new process. * directories, dropping capabilities, and executing the new process.
* Force the child to fail if HOOK does not return zero. * Force the child to fail if HOOK does not return zero.
*
* Since @hook runs in the child, it should be careful to avoid
* any functions that are not async-signal-safe.
*/ */
void void
virCommandSetPreExecHook(virCommandPtr cmd, virExecHook hook, void *opaque) virCommandSetPreExecHook(virCommandPtr cmd, virExecHook hook, void *opaque)
...@@ -1299,7 +1439,11 @@ virCommandSetPreExecHook(virCommandPtr cmd, virExecHook hook, void *opaque) ...@@ -1299,7 +1439,11 @@ virCommandSetPreExecHook(virCommandPtr cmd, virExecHook hook, void *opaque)
} }
/* /**
* virCommandWriteArgLog:
* @cmd: the command to log
* @logfd: where to log the results
*
* Call after adding all arguments and environment settings, but before * Call after adding all arguments and environment settings, but before
* Run/RunAsync, to immediately output the environment and arguments of * Run/RunAsync, to immediately output the environment and arguments of
* cmd to logfd. If virCommandRun cannot succeed (because of an * cmd to logfd. If virCommandRun cannot succeed (because of an
...@@ -1337,7 +1481,10 @@ virCommandWriteArgLog(virCommandPtr cmd, int logfd) ...@@ -1337,7 +1481,10 @@ virCommandWriteArgLog(virCommandPtr cmd, int logfd)
} }
/* /**
* virCommandToString:
* @cmd: the command to convert
*
* Call after adding all arguments and environment settings, but before * Call after adding all arguments and environment settings, but before
* Run/RunAsync, to return a string representation of the environment and * Run/RunAsync, to return a string representation of the environment and
* arguments of cmd. If virCommandRun cannot succeed (because of an * arguments of cmd. If virCommandRun cannot succeed (because of an
...@@ -1382,10 +1529,13 @@ virCommandToString(virCommandPtr cmd) ...@@ -1382,10 +1529,13 @@ virCommandToString(virCommandPtr cmd)
} }
/* /**
* virCommandTranslateStatus:
* @status: child exit status to translate
*
* Translate an exit status into a malloc'd string. Generic helper * Translate an exit status into a malloc'd string. Generic helper
* for virCommandRun, virCommandWait, and virPidWait status argument, * for virCommandRun(), virCommandWait(), virRun(), and virPidWait()
* as well as raw waitpid and older virRun status. * status argument, as well as raw waitpid().
*/ */
char * char *
virCommandTranslateStatus(int status) virCommandTranslateStatus(int status)
...@@ -1551,10 +1701,13 @@ cleanup: ...@@ -1551,10 +1701,13 @@ cleanup:
return ret; return ret;
} }
/* /**
* virCommandExec:
* @cmd: command to run
*
* Exec the command, replacing the current process. Meant to be called * Exec the command, replacing the current process. Meant to be called
* after already forking / cloning, so does not attempt to daemonize or * in the hook after already forking / cloning, so does not attempt to
* preserve any FDs. * daemonize or preserve any FDs.
* *
* Returns -1 on any error executing the command. * Returns -1 on any error executing the command.
* Will not return on success. * Will not return on success.
...@@ -1587,11 +1740,16 @@ int virCommandExec(virCommandPtr cmd ATTRIBUTE_UNUSED) ...@@ -1587,11 +1740,16 @@ int virCommandExec(virCommandPtr cmd ATTRIBUTE_UNUSED)
} }
#endif #endif
/* /**
* virCommandRun:
* @cmd: command to run
* @exitstatus: optional status collection
*
* Run the command and wait for completion. * Run the command and wait for completion.
* Returns -1 on any error executing the * Returns -1 on any error executing the
* command. Returns 0 if the command executed, * command. Returns 0 if the command executed,
* with the exit status set * with the exit status set. If @exitstatus is NULL, then the
* child must exit with status 0 for this to succeed.
*/ */
int int
virCommandRun(virCommandPtr cmd, int *exitstatus) virCommandRun(virCommandPtr cmd, int *exitstatus)
...@@ -1803,7 +1961,11 @@ virCommandHook(void *data) ...@@ -1803,7 +1961,11 @@ virCommandHook(void *data)
} }
/* /**
* virCommandRunAsync:
* @cmd: command to start
* @pid: optional variable to track child pid
*
* Run the command asynchronously * Run the command asynchronously
* Returns -1 on any error executing the * Returns -1 on any error executing the
* command. Returns 0 if the command executed. * command. Returns 0 if the command executed.
...@@ -1909,11 +2071,16 @@ virCommandRunAsync(virCommandPtr cmd, pid_t *pid) ...@@ -1909,11 +2071,16 @@ virCommandRunAsync(virCommandPtr cmd, pid_t *pid)
} }
/* /**
* virPidWait:
* @pid: child to wait on
* @exitstatus: optional status collection
*
* Wait for a child process to complete. * Wait for a child process to complete.
* Return -1 on any error waiting for * Return -1 on any error waiting for
* completion. Returns 0 if the command * completion. Returns 0 if the command
* finished with the exit status set * finished with the exit status set. If @exitstatus is NULL, then the
* child must exit with status 0 for this to succeed.
*/ */
int int
virPidWait(pid_t pid, int *exitstatus) virPidWait(pid_t pid, int *exitstatus)
...@@ -1951,11 +2118,16 @@ virPidWait(pid_t pid, int *exitstatus) ...@@ -1951,11 +2118,16 @@ virPidWait(pid_t pid, int *exitstatus)
return 0; return 0;
} }
/* /**
* Wait for the async command to complete. * virCommandWait:
* Return -1 on any error waiting for * @cmd: command to wait on
* @exitstatus: optional status collection
*
* Wait for the command previously started with virCommandRunAsync()
* to complete. Return -1 on any error waiting for
* completion. Returns 0 if the command * completion. Returns 0 if the command
* finished with the exit status set * finished with the exit status set. If @exitstatus is NULL, then the
* child must exit with status 0 for this to succeed.
*/ */
int int
virCommandWait(virCommandPtr cmd, int *exitstatus) virCommandWait(virCommandPtr cmd, int *exitstatus)
...@@ -2006,11 +2178,15 @@ virCommandWait(virCommandPtr cmd, int *exitstatus) ...@@ -2006,11 +2178,15 @@ virCommandWait(virCommandPtr cmd, int *exitstatus)
#ifndef WIN32 #ifndef WIN32
/* /**
* virPidAbort:
* @pid: child process to kill
*
* Abort a child process if PID is positive and that child is still * Abort a child process if PID is positive and that child is still
* running, without issuing any errors or affecting errno. Designed * running, without issuing any errors or affecting errno. Designed
* for error paths where some but not all paths to the cleanup code * for error paths where some but not all paths to the cleanup code
* might have started the child process. * might have started the child process. If @pid is 0 or negative,
* this does nothing.
*/ */
void void
virPidAbort(pid_t pid) virPidAbort(pid_t pid)
...@@ -2063,7 +2239,10 @@ cleanup: ...@@ -2063,7 +2239,10 @@ cleanup:
errno = saved_errno; errno = saved_errno;
} }
/* /**
* virCommandAbort:
* @cmd: command to abort
*
* Abort an async command if it is running, without issuing * Abort an async command if it is running, without issuing
* any errors or affecting errno. Designed for error paths * any errors or affecting errno. Designed for error paths
* where some but not all paths to the cleanup code might * where some but not all paths to the cleanup code might
...@@ -2096,6 +2275,15 @@ virCommandAbort(virCommandPtr cmd ATTRIBUTE_UNUSED) ...@@ -2096,6 +2275,15 @@ virCommandAbort(virCommandPtr cmd ATTRIBUTE_UNUSED)
#endif #endif
/**
* virCommandRequireHandshake:
* @cmd: command to modify
*
* Request that the child perform a handshake with
* the parent when the hook function has completed
* execution. The child will not exec() until the
* parent has notified
*/
void virCommandRequireHandshake(virCommandPtr cmd) void virCommandRequireHandshake(virCommandPtr cmd)
{ {
if (!cmd || cmd->has_error) if (!cmd || cmd->has_error)
...@@ -2125,6 +2313,13 @@ void virCommandRequireHandshake(virCommandPtr cmd) ...@@ -2125,6 +2313,13 @@ void virCommandRequireHandshake(virCommandPtr cmd)
cmd->handshake = true; cmd->handshake = true;
} }
/**
* virCommandHandshakeWait:
* @cmd: command to wait on
*
* Wait for the child to complete execution of its
* hook function. To be called in the parent.
*/
int virCommandHandshakeWait(virCommandPtr cmd) int virCommandHandshakeWait(virCommandPtr cmd)
{ {
char c; char c;
...@@ -2178,6 +2373,13 @@ int virCommandHandshakeWait(virCommandPtr cmd) ...@@ -2178,6 +2373,13 @@ int virCommandHandshakeWait(virCommandPtr cmd)
return 0; return 0;
} }
/**
* virCommandHandshakeNotify:
* @cmd: command to resume
*
* Notify the child that it is OK to exec() the
* real binary now. To be called in the parent.
*/
int virCommandHandshakeNotify(virCommandPtr cmd) int virCommandHandshakeNotify(virCommandPtr cmd)
{ {
char c = '1'; char c = '1';
...@@ -2208,10 +2410,13 @@ int virCommandHandshakeNotify(virCommandPtr cmd) ...@@ -2208,10 +2410,13 @@ int virCommandHandshakeNotify(virCommandPtr cmd)
} }
/* /**
* virCommandFree:
* @cmd: optional command to free
*
* Release all resources. The only exception is that if you called * Release all resources. The only exception is that if you called
* virCommandRunAsync with a non-null pid, then the asynchronous child * virCommandRunAsync with a non-null pid, then the asynchronous child
* is not reaped, and you must call virPidWait() yourself. * is not reaped, and you must call virPidWait() or virPidAbort() yourself.
*/ */
void void
virCommandFree(virCommandPtr cmd) virCommandFree(virCommandPtr cmd)
......
...@@ -30,34 +30,18 @@ typedef struct _virCommand virCommand; ...@@ -30,34 +30,18 @@ typedef struct _virCommand virCommand;
typedef virCommand *virCommandPtr; typedef virCommand *virCommandPtr;
/* This will execute in the context of the first child /* This will execute in the context of the first child
* after fork() but before execve() */ * after fork() but before execve(). As such, it is unsafe to
* call any function that is not async-signal-safe. */
typedef int (*virExecHook)(void *data); typedef int (*virExecHook)(void *data);
/*
* Fork wrapper with extra error checking
*/
int virFork(pid_t *pid) ATTRIBUTE_RETURN_CHECK; int virFork(pid_t *pid) ATTRIBUTE_RETURN_CHECK;
/*
* Simple synchronous command wrapper
*/
int virRun(const char *const*argv, int *status) ATTRIBUTE_RETURN_CHECK; int virRun(const char *const*argv, int *status) ATTRIBUTE_RETURN_CHECK;
/*
* Create a new command for named binary
*/
virCommandPtr virCommandNew(const char *binary) ATTRIBUTE_NONNULL(1); 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); 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, ...) virCommandPtr virCommandNewArgList(const char *binary, ...)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_SENTINEL; ATTRIBUTE_NONNULL(1) ATTRIBUTE_SENTINEL;
...@@ -65,310 +49,125 @@ virCommandPtr virCommandNewArgList(const char *binary, ...) ...@@ -65,310 +49,125 @@ virCommandPtr virCommandNewArgList(const char *binary, ...)
* delayed until the Run/RunAsync methods * 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, void virCommandPreserveFD(virCommandPtr cmd,
int fd); 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, void virCommandTransferFD(virCommandPtr cmd,
int fd); int fd);
/*
* Save the child PID in a pidfile
*/
void virCommandSetPidFile(virCommandPtr cmd, void virCommandSetPidFile(virCommandPtr cmd,
const char *pidfile) ATTRIBUTE_NONNULL(2); const char *pidfile) ATTRIBUTE_NONNULL(2);
/*
* Remove all capabilities from the child
*/
void virCommandClearCaps(virCommandPtr cmd); void virCommandClearCaps(virCommandPtr cmd);
# if 0 # if 0
/*
* Re-allow a specific capability
*/
void virCommandAllowCap(virCommandPtr cmd, void virCommandAllowCap(virCommandPtr cmd,
int capability); int capability);
# endif # endif
/*
* Daemonize the child process
*/
void virCommandDaemonize(virCommandPtr cmd); void virCommandDaemonize(virCommandPtr cmd);
/*
* Set FDs created by virCommandSetOutputFD and virCommandSetErrorFD
* as non-blocking in the parent.
*/
void virCommandNonblockingFDs(virCommandPtr cmd); void virCommandNonblockingFDs(virCommandPtr cmd);
/* void virCommandAddEnvFormat(virCommandPtr cmd, const char *format, ...)
* Add an environment variable to the child created by a printf-style format ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3);
*/
void
virCommandAddEnvFormat(virCommandPtr cmd, const char *format, ...)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3);
/*
* Add an environment variable to the child
* using separate name & value strings
*/
void virCommandAddEnvPair(virCommandPtr cmd, void virCommandAddEnvPair(virCommandPtr cmd,
const char *name, const char *name,
const char *value) ATTRIBUTE_NONNULL(2); const char *value) ATTRIBUTE_NONNULL(2);
/*
* Add an environemnt variable to the child
* using a preformated env string FOO=BAR
*/
void virCommandAddEnvString(virCommandPtr cmd, void virCommandAddEnvString(virCommandPtr cmd,
const char *str) ATTRIBUTE_NONNULL(2); const char *str) ATTRIBUTE_NONNULL(2);
/*
* 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, void virCommandAddEnvBuffer(virCommandPtr cmd,
virBufferPtr buf); virBufferPtr buf);
/*
* Pass an environment variable to the child
* using current process' value
*/
void virCommandAddEnvPass(virCommandPtr cmd, void virCommandAddEnvPass(virCommandPtr cmd,
const char *name) ATTRIBUTE_NONNULL(2); const char *name) ATTRIBUTE_NONNULL(2);
/*
* Pass a common set of environment variables
* to the child using current process' values
*/
void virCommandAddEnvPassCommon(virCommandPtr cmd); void virCommandAddEnvPassCommon(virCommandPtr cmd);
/*
* Add a command line argument to the child
*/
void virCommandAddArg(virCommandPtr cmd, void virCommandAddArg(virCommandPtr cmd,
const char *val) ATTRIBUTE_NONNULL(2); const char *val) ATTRIBUTE_NONNULL(2);
/*
* 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, void virCommandAddArgBuffer(virCommandPtr cmd,
virBufferPtr buf); virBufferPtr buf);
/*
* Add a command line argument created by a printf-style format
*/
void virCommandAddArgFormat(virCommandPtr cmd, void virCommandAddArgFormat(virCommandPtr cmd,
const char *format, ...) const char *format, ...)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3); ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3);
/*
* Add a command line argument to the child
*/
void virCommandAddArgPair(virCommandPtr cmd, void virCommandAddArgPair(virCommandPtr cmd,
const char *name, const char *name,
const char *val) const char *val)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
/*
* Add a NULL terminated array of args
*/
void virCommandAddArgSet(virCommandPtr cmd, void virCommandAddArgSet(virCommandPtr cmd,
const char *const*vals) ATTRIBUTE_NONNULL(2); const char *const*vals) ATTRIBUTE_NONNULL(2);
/*
* Add a NULL terminated list of args
*/
void virCommandAddArgList(virCommandPtr cmd, void virCommandAddArgList(virCommandPtr cmd,
... /* const char *arg, ..., NULL */) ... /* const char *arg, ..., NULL */)
ATTRIBUTE_SENTINEL; 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, void virCommandSetWorkingDirectory(virCommandPtr cmd,
const char *pwd) ATTRIBUTE_NONNULL(2); const char *pwd) ATTRIBUTE_NONNULL(2);
/*
* Feed the child's stdin from a string buffer.
*
* NB: Only works with virCommandRun()
*/
void virCommandSetInputBuffer(virCommandPtr cmd, void virCommandSetInputBuffer(virCommandPtr cmd,
const char *inbuf) ATTRIBUTE_NONNULL(2); const char *inbuf) ATTRIBUTE_NONNULL(2);
/*
* Capture the child's stdout to a string buffer
*
* NB: Only works with virCommandRun()
*/
void virCommandSetOutputBuffer(virCommandPtr cmd, void virCommandSetOutputBuffer(virCommandPtr cmd,
char **outbuf) ATTRIBUTE_NONNULL(2); char **outbuf) ATTRIBUTE_NONNULL(2);
/*
* Capture the child's stderr to a string buffer
*
* NB: Only works with virCommandRun()
*/
void virCommandSetErrorBuffer(virCommandPtr cmd, void virCommandSetErrorBuffer(virCommandPtr cmd,
char **errbuf) ATTRIBUTE_NONNULL(2); char **errbuf) ATTRIBUTE_NONNULL(2);
/*
* Set a file descriptor as the child's stdin
*/
void virCommandSetInputFD(virCommandPtr cmd, void virCommandSetInputFD(virCommandPtr cmd,
int infd); int infd);
/*
* Set a file descriptor as the child's stdout
*/
void virCommandSetOutputFD(virCommandPtr cmd, void virCommandSetOutputFD(virCommandPtr cmd,
int *outfd) ATTRIBUTE_NONNULL(2); int *outfd) ATTRIBUTE_NONNULL(2);
/*
* Set a file descriptor as the child's stderr
*/
void virCommandSetErrorFD(virCommandPtr cmd, void virCommandSetErrorFD(virCommandPtr cmd,
int *errfd) ATTRIBUTE_NONNULL(2); int *errfd) ATTRIBUTE_NONNULL(2);
/*
* A hook function to run between fork + exec
*/
void virCommandSetPreExecHook(virCommandPtr cmd, void virCommandSetPreExecHook(virCommandPtr cmd,
virExecHook hook, virExecHook hook,
void *opaque) ATTRIBUTE_NONNULL(2); 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, void virCommandWriteArgLog(virCommandPtr cmd,
int logfd); 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; char *virCommandToString(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;
/*
* Translate an exit status into a malloc'd string.
*/
char *virCommandTranslateStatus(int exitstatus) ATTRIBUTE_RETURN_CHECK; char *virCommandTranslateStatus(int exitstatus) ATTRIBUTE_RETURN_CHECK;
/*
* Exec the command, replacing the current process. Meant to be called
* after already forking / cloning, so does not attempt to daemonize or
* preserve any FDs.
*
* Returns -1 on any error executing the command.
* Will not return on success.
*/
int virCommandExec(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK; int virCommandExec(virCommandPtr cmd) ATTRIBUTE_RETURN_CHECK;
/*
* 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 virCommandRun(virCommandPtr cmd,
int *exitstatus) ATTRIBUTE_RETURN_CHECK; int *exitstatus) ATTRIBUTE_RETURN_CHECK;
/*
* Run the command asynchronously
* Returns -1 on any error executing the
* command. Returns 0 if the command executed.
*
* There are two approaches to child process cleanup.
* 1. Use auto-cleanup, by passing NULL for pid. The child will be
* auto-reaped by virCommandFree, unless you reap it earlier via
* virCommandWait or virCommandAbort. Good for where cmd is in
* scope for the duration of the child process.
* 2. Use manual cleanup, by passing the address of a pid_t variable
* for pid. While cmd is still in scope, you may reap the child via
* virCommandWait or virCommandAbort. But after virCommandFree, if
* you have not yet reaped the child, then it continues to run until
* you call virPidWait or virPidAbort.
*/
int virCommandRunAsync(virCommandPtr cmd, int virCommandRunAsync(virCommandPtr cmd,
pid_t *pid) ATTRIBUTE_RETURN_CHECK; pid_t *pid) ATTRIBUTE_RETURN_CHECK;
/*
* Wait for a child process to complete.
* Return -1 on any error waiting for
* completion. Returns 0 if the command
* finished with the exit status set.
*/
int virPidWait(pid_t pid, int virPidWait(pid_t pid,
int *exitstatus) ATTRIBUTE_RETURN_CHECK; int *exitstatus) 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 virCommandWait(virCommandPtr cmd,
int *exitstatus) ATTRIBUTE_RETURN_CHECK; int *exitstatus) ATTRIBUTE_RETURN_CHECK;
/*
* Request that the child perform a handshake with
* the parent when the hook function has completed
* execution. The child will not exec() until the
* parent has notified
*/
void virCommandRequireHandshake(virCommandPtr cmd); void virCommandRequireHandshake(virCommandPtr cmd);
/*
* Wait for the child to complete execution of its
* hook function
*/
int virCommandHandshakeWait(virCommandPtr cmd) int virCommandHandshakeWait(virCommandPtr cmd)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;
/*
* Notify the child that it is OK to exec() the
* real binary now
*/
int virCommandHandshakeNotify(virCommandPtr cmd) int virCommandHandshakeNotify(virCommandPtr cmd)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;
/*
* Abort a child process if PID is positive and that child is still
* 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 virPidAbort(pid_t pid); void virPidAbort(pid_t pid);
/*
* 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); 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 virPidWait() yourself.
*/
void virCommandFree(virCommandPtr cmd); void virCommandFree(virCommandPtr cmd);
#endif /* __VIR_COMMAND_H__ */ #endif /* __VIR_COMMAND_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册