2017-05-19 23:37:19 +02:00
|
|
|
#ifndef NDO_LIBNAGIOS_RUNCMD_H_INCLUDED
|
|
|
|
#define NDO_LIBNAGIOS_RUNCMD_H_INCLUDED
|
|
|
|
#include <signal.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file runcmd.h
|
|
|
|
* @brief runcmd library function declarations
|
|
|
|
*
|
|
|
|
* A simple interface to executing programs from other programs, using an
|
|
|
|
* optimized and safer popen()-like implementation. It is considered safer in
|
|
|
|
* that no shell needs to be spawned for simple commands, and the environment
|
|
|
|
* passed to the execve()'d program is essentially empty.
|
|
|
|
*
|
|
|
|
* This code is based on popen.c, which in turn was taken from
|
|
|
|
* "Advanced Programming in the UNIX Environment" by W. Richard Stevens.
|
|
|
|
*
|
|
|
|
* Care has been taken to make sure the functions are async-safe. The exception
|
|
|
|
* is runcmd_init() which multithreaded applications or plugins must call in a
|
|
|
|
* non-reentrant manner before calling any other runcmd function.
|
|
|
|
*
|
|
|
|
* @note This is inherited from the nagiosplugins project, although
|
|
|
|
* it might need refactoring for performance later.
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** Return code bitflags for runcmd_cmd2strv() */
|
|
|
|
#define RUNCMD_HAS_REDIR (1 << 0) /**< I/O redirection */
|
|
|
|
#define RUNCMD_HAS_SUBCOMMAND (1 << 1) /**< subcommands present */
|
|
|
|
#define RUNCMD_HAS_PAREN (1 << 2) /**< parentheses present in command */
|
|
|
|
#define RUNCMD_HAS_JOBCONTROL (1 << 3) /**< job control stuff present */
|
|
|
|
#define RUNCMD_HAS_UBSQ (1 << 4) /**< unbalanced single quotes */
|
|
|
|
#define RUNCMD_HAS_UBDQ (1 << 5) /**< unbalanced double quotes */
|
|
|
|
#define RUNCMD_HAS_WILDCARD (1 << 6) /**< wildcards present */
|
|
|
|
#define RUNCMD_HAS_SHVAR (1 << 7) /**< shell variables present */
|
|
|
|
|
|
|
|
|
|
|
|
#define RUNCMD_EFD (-1) /**< Failed to pipe() or open() */
|
|
|
|
#define RUNCMD_EALLOC (-2) /**< Failed to alloc */
|
|
|
|
#define RUNCMD_ECMD (-3) /**< Bad command */
|
|
|
|
#define RUNCMD_EFORK (-4) /**< Failed to fork() */
|
|
|
|
#define RUNCMD_EINVAL (-5) /**< Invalid parameters */
|
|
|
|
#define RUNCMD_EWAIT (-6) /**< Failed to wait() */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the runcmd library.
|
|
|
|
*
|
|
|
|
* Only multi-threaded programs that might launch the first external
|
|
|
|
* program from multiple threads simultaneously need to bother with
|
|
|
|
* this, and they must ensure this is called at least once in a non-reentrant
|
|
|
|
* manner before calling any other runcmd function.
|
|
|
|
*/
|
|
|
|
extern void runcmd_init(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return pid of a command with a specific file descriptor
|
|
|
|
* @param[in] fd stdout filedescriptor of the child to get pid from
|
|
|
|
* @return pid of the child, or 0 on errors
|
|
|
|
*/
|
|
|
|
extern pid_t runcmd_pid(int fd);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return explanation of which system call or operation failed
|
|
|
|
* @param code Error code returned by a library function
|
|
|
|
* @return A non-free()'able string explaining where the error occurred
|
|
|
|
*/
|
|
|
|
extern const char *runcmd_strerror(int code);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start a command from a command string
|
|
|
|
* @param[in] cmd The command to launch
|
|
|
|
* @param[out] pfd Child's stdout filedescriptor
|
|
|
|
* @param[out] pfderr Child's stderr filedescriptor
|
|
|
|
* @param[in] env Currently ignored for portability
|
|
|
|
* @param[in] iobreg The callback function to register the iobrokers for the read ends of the pipe
|
|
|
|
* @param[in] iobregarg The "arg" value to pass to iobroker_register()
|
|
|
|
*/
|
|
|
|
extern int runcmd_open(const char *cmd, int *pfd, int *pfderr, char **env,
|
2019-04-18 17:09:18 +02:00
|
|
|
void (*iobreg)(int, int, void *), void *iobregarg);
|
2017-05-19 23:37:19 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Close a command and return its exit status
|
|
|
|
* @note Don't use this. It's a retarded way to reap children suitable
|
|
|
|
* only for launching a one-shot program.
|
|
|
|
*
|
|
|
|
* @param[in] fd The child's stdout filedescriptor
|
|
|
|
* @return exit-status of the child, or -1 in case of errors
|
|
|
|
*/
|
|
|
|
extern int runcmd_close(int fd);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a string to a vector of arguments like a shell would
|
|
|
|
* @note This might have bugs and is only tested to behave similar
|
|
|
|
* to how /bin/sh does things. For csh or other non bash-ish shells
|
|
|
|
* there are no guarantees.
|
|
|
|
* @note The out_argv array has to be large enough to hold all strings
|
|
|
|
* found in the command.
|
|
|
|
* @param[in] str The string to convert to an argument vector
|
|
|
|
* @param[out] out_argc The number of arguments found
|
|
|
|
* @param[out] out_argv The argument vector
|
|
|
|
* @return 0 on (great) success, or a bitmask of failure-codes
|
|
|
|
* representing f.e. unclosed quotes, job control or output redirection.
|
|
|
|
* See the RUNCMD_HAS_* and their ilk to find out about the flag.
|
|
|
|
*/
|
|
|
|
extern int runcmd_cmd2strv(const char *str, int *out_argc, char **out_argv);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If you're using libnagios to execute a remote command, the
|
|
|
|
* static pid_t pids is not freed after runcmd_open
|
|
|
|
* You can call this function when you're sure pids is no longer
|
|
|
|
* in use, to keep down memory leaks
|
|
|
|
*/
|
|
|
|
extern void runcmd_free_pids(void);
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
/* INCLUDE_runcmd_h__ */
|
|
|
|
#endif
|