# __pmprocessexec

## NAME



           **__pmProcessAddArg** , **__pmProcessUnpickArgs** , **__pmProcessExec** -
           process execution support
    


## C SYNOPSIS



           **#include "pmapi.h"**
           **#include "libpcp.h"**
    
           **int __pmProcessAddArg(__pmExecCtl_t ****_handle_**, const char ***_arg_**);**
           **int __pmProcessUnpickArgs(__pmExecCtl_t ****_handle_**,**
                                     **const char ***_command_**);**
           **int __pmProcessExec(__pmExecCtl_t ****_handle_**, int** _toss_**, int** _wait_**);**
    
           **cc ... -lpcp**
    


## CAVEAT



           This  documentation  is intended for internal Performance Co-Pilot
           (PCP) developer use.
    
           These interfaces are not part of the PCP APIs that are  guaranteed
           to  remain  fixed  across  releases, and they may not work, or may
           provide different semantics at some point in the future.
    


## DESCRIPTION



           Within the libraries and applications of the Performance  Co-Pilot
           (PCP) these routines are provide a convenient and safe alternative
           to system(3) for executing commands in a separate process.
    
           Use **__pmProcessAddArg** to register the executable and command argu‐
           ments  in  order.   _handle_  should be set to **NULL** before the first
           call to **__pmProcessAddArg** for a particular command  execution  and
           it  will  be  set to an opaque pointer to data structures that are
           manipulated in **__pmProcessAddArg** , **__pmProcessExec** and the  related
           __pmProcessPipe(3) routines.
    
           When  called with _handle_ set to **NULL** _arg_ is treated as the name of
           the command to be executed and subsequent calls (if any)  are  for
           the  arguments  to that command.  The name of the command can be a
           full pathname, or the name of an executable that can be  found  on
           the  current  **$PATH** as per the rules of **execvp**(2) that is used by
           **__pmProcessExec**.
    
           **__pmProcessUnpickArgs** is a convenience wrapper to  assist  conver‐
           sion  of code that assumes the _command_ is a shell command that has
           been prepared for use with system(3) or popen(3) in existing code.
           The arguments in _command_ are picked off  one-by-one  and  used  to
           call  **__pmProcessAddArg**.   The parser is simple, as the routine is
           designed for simple shell command syntax, where arguments are sep‐
           arated by one or more spaces but embedded spaces within  an  argu‐
           ment  are  allowed if the argument is enclosed in single or double
           quotes.  More advanced shell syntax like escape characters and in‐
           put-output redirection are not recognized.
    
           Once all the command name and arguments have been registered call‐
           ing **__pmProcessExec** uses a fork(2) and **execvp**(2) sequence to  exe‐
           cute the command.
    
           The  argument  _toss_ may be used to assign some or all of the stan‐
           dard I/O streams for the command to _/dev/null_ - specifically  _toss_
           is  either  **PM_EXEC_TOSS_NONE** to keep all I/O streams the same as
           the parent process, else the  bit-wise  or  of  **PM_EXEC_TOSS_STDIN**
           and/or  **PM_EXEC_TOSS_STDOUT** and/or **PM_EXEC_TOSS_STDERR** to reassign
           **stdin** , **stdout** and **stderr** respectively.  **PM_EXEC_TOSS_ALL** is a con‐
           venience  macro  equivalent   to   **PM_EXEC_TOSS_STDIN   |   PM_EX‐**
           **EC_TOSS_STDOUT | PM_EXEC_TOSS_STDERR**.
    
           The _wait_ argument should be **PM_EXEC_WAIT** if **__pmProcessExec** should
           wait  for  completion  of the command and harvest the exit status,
           else **PM_EXEC_NOWAIT** in which case **__pmProcessExec** returns  immedi‐
           ately (effectively running the command in the background).
    
           Nested calling of **__pmProcessExec** and/or __pmProcessPipe(3) is not
           allowed.  Once **__pmProcessAddArg** is called with _handle_ set to **NULL**
           to  start  the  registration and execution sequence any attempt to
           start a second registration sequence will  be  blocked  until  the
           first  one  is  completed  by  calling  **__pmProcessExec** or  **__pm‐**
           **ProcessPipe**(3).
    


## DIAGNOSTICS



           If successful **__pmProcessAddArg** returns 0.  Other  conditions  are
           rare  (e.g.  memory allocation failure) and are indicated by a re‐
           turn value that can be decoded using pmErrStr(3).  When  an  error
           does occur **__pmProcessAddArg** cleans up any allocations made in the
           current  call  and uses _handle_ to clean up any allocations made by
           previous calls so there is no need for the caller to  worry  about
           memory leaks, and then (re)sets _handle_ to **NULL** before returning.
    
           **__pmProcessUnpickArgs** returns 0 on success.  In the case of an un‐
           terminated  string,  a  message is generated and **PM_ERR_GENERIC** is
           returned.  Other return values less than 0 indicate a more serious
           error and the value can be decoded using pmErrStr(3).  When an er‐
           ror does occur the clean up is  similar  to  **__pmProcessAddArg** so
           there is no need for the caller to worry about memory leaks.
    
           The  return  status  from **__pmProcessExec** is more complicated.  If
           either **PM_EXEC_NOWAIT** is specified, or the command completes  with
           an  exit  status  of 0, the return value is 0.  Return values less
           than 0 indicate a more serious error and the value can be  decoded
           using  pmErrStr(3).  If the command was executed, but did not exit
           with status of 0 then the return  value  is  an  encoding  of  the
           waitpid(2)  status  as  follows:  2000  if  something unknown went
           wrong, else if 1000 + signal number of the command was  killed  or
           stopped by a signal, else the exit status of the command.
    


* * *