/* Plugin compile time variables */
#define PLUGINPREFIX "execprog:"
+
/*
* Terminate the connection represented by BPIPE object.
* it shows a debug and job messages when connection close is unsuccessful
* out:
* none
*/
-void EXECPROG::terminate(bpContext *ctx, bool raise_error)
+int EXECPROG::terminate(bpContext *ctx, bool raise_error)
{
- if (is_closed())
- {
- return;
- }
+ // clear status
+ tstatus = 0;
+ pm_strcpy(m_errmsg, NULL);
- // after close_bpipe it is no longer available
- tstatus = close_bpipe(bpipe);
- if (tstatus && raise_error)
+ if (!is_closed())
{
- /* error during close */
+ // after close_bpipe it is no longer available
+ pid_t wpid = bpipe->worker_pid;
+
+
+ tstatus = close_bpipe(bpipe);
berrno be;
- DMSG(ctx, DERROR, "Error closing command. Err=%s\n", be.bstrerror(tstatus));
- JMSG(ctx, M_ERROR, "Error closing command. Err=%s\n", be.bstrerror(tstatus));
- }
+ pm_strcpy(m_errmsg, be.bstrerror(tstatus));
+ if (tstatus)
+ {
+ /* error during close */
+ DMSG(ctx, DERROR, "Error closing command. Err=%s (%d)\n", m_errmsg.c_str());
+ if (raise_error)
+ {
+ // raise it on request
+ JMSG(ctx, M_ERROR, "Error closing command. Err=%s (%d)\n", m_errmsg.c_str());
+ }
+ }
+
+ if (wpid)
+ {
+ /* terminate the process command */
+ kill(wpid, SIGTERM);
+ }
- // TODO: is it required to terminate the backend process?
- // if (bpipe->worker_pid){
- // /* terminate the process command */
- // kill(bpipe->worker_pid, SIGTERM);
- // }
+ bpipe = NULL;
+ }
- bpipe = NULL;
-};
+ return tstatus;
+}
/*
* Run command and prepared parameters.
int wfd; // backend `stdin` to plugin file descriptor
int efd; // backend `stderr` to plugin file descriptor
int maxfd; // max file descriptors from bpipe channels
- POOL_MEM errmsg; // message buffer for error string
+ POOL_MEM m_errmsg; /// message buffer for error string
int extpipe; // set when data blast is performed using external pipe/file
POOL_MEM extpipename; // name of the external pipe/file for restore
bool f_eod; // the backend signaled EOD
wfd(0),
efd(0),
maxfd(0),
- errmsg(PM_MESSAGE),
+ m_errmsg(PM_MESSAGE),
extpipe(-1),
extpipename(PM_FNAME),
f_eod(false),
* @return true if connection is closed and we can't use bpipe object
* @return false if connection is available
*/
- inline bool is_open() { return bpipe != NULL; };
+ inline bool is_open() { return bpipe != NULL; }
/**
* @brief Checks if connection is closed and we can't use a bpipe object for communication.
* @return true if connection is closed and we can't use bpipe object
* @return false if connection is available
*/
- inline bool is_closed() { return bpipe == NULL; };
+ inline bool is_closed() { return bpipe == NULL; }
/**
* @brief Checks if backend sent us some error, backend error message is flagged on f_error.
* @return true
* @return false
*/
- inline bool is_error() { return f_error || f_fatal; };
+ inline bool is_error() { return f_error || f_fatal; }
/**
* @brief Checks if backend sent us fatal error, backend error message is flagged on f_fatal.
* @return true
* @return false
*/
- inline bool is_fatal() { return f_fatal || (f_error && abort_on_error); };
+ inline bool is_fatal() { return f_fatal || (f_error && abort_on_error); }
/**
* @brief Set the abort on error object
*
*/
- inline void set_abort_on_error() { abort_on_error = true; };
+ inline void set_abort_on_error() { abort_on_error = true; }
/**
* @brief Clear abort_on_error flag.
*
*/
- inline void clear_abort_on_error() { abort_on_error = false; };
+ inline void clear_abort_on_error() { abort_on_error = false; }
/**
* @brief Return abort_on_error flag.
* @return true
* @return false
*/
- inline bool is_abort_on_error() { return abort_on_error; };
+ inline bool is_abort_on_error() { return abort_on_error; }
/**
* @brief Checks if backend signaled EOD, eod from backend is flagged on f_eod.
* @return true when backend signaled EOD on last packet
* @return false when backend did not signal EOD
*/
- inline bool is_eod() { return f_eod; };
+ inline bool is_eod() { return f_eod; }
/**
* @brief Clears the EOD from backend flag, f_eod.
* The eod flag is set when EOD message received from backend and not cleared
* until next recvbackend() call.
*/
- inline void clear_eod() { f_eod = false; };
+ inline void clear_eod() { f_eod = false; }
/**
* @brief Get the cmd pid.
return -1;
};
- inline int get_terminate_status() { return tstatus; };
+ inline int get_terminate_status() { return tstatus; }
/* all you need is to simply execute the command first */
bool execute_command(bpContext *ctx, const char *cmd, const char *args = "");
int32_t write_data(bpContext *ctx, POOLMEM *buf, int32_t len);
/* and finally terminate execution when finish */
- void terminate(bpContext *ctx, bool raise_error = true);
+ int terminate(bpContext *ctx, bool raise_error = true);
- POOLMEM *get_error(bpContext *ctx);
+ inline POOL_MEM &get_error() noexcept { return m_errmsg; }
+ inline char *get_error_str() noexcept { return m_errmsg.c_str(); }
/* direct pipe management */
inline int close_wpipe() { return ::close_wpipe(bpipe); }