00001 #ifndef LIBNAGIOS_runcmd_h__ 00002 #define LIBNAGIOS_runcmd_h__ 00003 #include <signal.h> 00004 00005 /** 00006 * @file runcmd.h 00007 * @brief runcmd library function declarations 00008 * 00009 * A simple interface to executing programs from other programs, using an 00010 * optimized and safer popen()-like implementation. It is considered safer in 00011 * that no shell needs to be spawned for simple commands, and the environment 00012 * passed to the execve()'d program is essentially empty. 00013 * 00014 * This code is based on popen.c, which in turn was taken from 00015 * "Advanced Programming in the UNIX Environment" by W. Richard Stevens. 00016 * 00017 * Care has been taken to make sure the functions are async-safe. The exception 00018 * is runcmd_init() which multithreaded applications or plugins must call in a 00019 * non-reentrant manner before calling any other runcmd function. 00020 * 00021 * @note This is inherited from the nagiosplugins project, although 00022 * it might need refactoring for performance later. 00023 * @{ 00024 */ 00025 00026 /** Return code bitflags for runcmd_cmd2strv() */ 00027 #define RUNCMD_HAS_REDIR (1 << 0) /**< I/O redirection */ 00028 #define RUNCMD_HAS_SUBCOMMAND (1 << 1) /**< subcommands present */ 00029 #define RUNCMD_HAS_PAREN (1 << 2) /**< parentheses present in command */ 00030 #define RUNCMD_HAS_JOBCONTROL (1 << 3) /**< job control stuff present */ 00031 #define RUNCMD_HAS_UBSQ (1 << 4) /**< unbalanced single quotes */ 00032 #define RUNCMD_HAS_UBDQ (1 << 5) /**< unbalanced double quotes */ 00033 #define RUNCMD_HAS_WILDCARD (1 << 6) /**< wildcards present */ 00034 #define RUNCMD_HAS_SHVAR (1 << 7) /**< shell variables present */ 00035 00036 00037 #define RUNCMD_EFD (-1) /**< Failed to pipe() or open() */ 00038 #define RUNCMD_EALLOC (-2) /**< Failed to alloc */ 00039 #define RUNCMD_ECMD (-3) /**< Bad command */ 00040 #define RUNCMD_EFORK (-4) /**< Failed to fork() */ 00041 #define RUNCMD_EINVAL (-5) /**< Invalid parameters */ 00042 #define RUNCMD_EWAIT (-6) /**< Failed to wait() */ 00043 00044 /** 00045 * Initialize the runcmd library. 00046 * 00047 * Only multi-threaded programs that might launch the first external 00048 * program from multiple threads simultaneously need to bother with 00049 * this, and they must ensure this is called at least once in a non-reentrant 00050 * manner before calling any other runcmd function. 00051 */ 00052 extern void runcmd_init(void); 00053 00054 /** 00055 * Return pid of a command with a specific file descriptor 00056 * @param[in] fd stdout filedescriptor of the child to get pid from 00057 * @return pid of the child, or 0 on errors 00058 */ 00059 extern pid_t runcmd_pid(int fd); 00060 00061 /** 00062 * Return explanation of which system call or operation failed 00063 * @param code Error code returned by a library function 00064 * @return A non-free()'able string explaining where the error occurred 00065 */ 00066 extern const char *runcmd_strerror(int code); 00067 00068 /** 00069 * Start a command from a command string 00070 * @param[in] cmdstring The command to launch 00071 * @param[out] pfd Child's stdout filedescriptor 00072 * @param[out] pfderr Child's stderr filedescriptor 00073 * @param[in] env Currently ignored for portability 00074 * @param[in] iobreg The callback function to register the iobrokers for the read ends of the pipe 00075 * @param[in] iobregarg The "arg" value to pass to iobroker_register() 00076 */ 00077 extern int runcmd_open(const char *cmd, int *pfd, int *pfderr, char **env, 00078 void (*iobreg)(int, int, void *), void *iobregarg) 00079 __attribute__((__nonnull__(1, 2, 3, 5, 6))); 00080 00081 /** 00082 * Close a command and return its exit status 00083 * @note Don't use this. It's a retarded way to reap children suitable 00084 * only for launching a one-shot program. 00085 * 00086 * @param[in] fd The child's stdout filedescriptor 00087 * @return exit-status of the child, or -1 in case of errors 00088 */ 00089 extern int runcmd_close(int fd); 00090 00091 /** 00092 * Convert a string to a vector of arguments like a shell would 00093 * @note This might have bugs and is only tested to behave similar 00094 * to how /bin/sh does things. For csh or other non bash-ish shells 00095 * there are no guarantees. 00096 * @note The out_argv array has to be large enough to hold all strings 00097 * found in the command. 00098 * @param[in] str The string to convert to an argument vector 00099 * @param[out] out_argc The number of arguments found 00100 * @param[out] out_argv The argument vector 00101 * @return 0 on (great) success, or a bitmask of failure-codes 00102 * representing f.e. unclosed quotes, job control or output redirection. 00103 * See the RUNCMD_HAS_* and their ilk to find out about the flag. 00104 */ 00105 extern int runcmd_cmd2strv(const char *str, int *out_argc, char **out_argv); 00106 00107 /** @} */ 00108 /* INCLUDE_runcmd_h__ */ 00109 #endif