libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmExec.c 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "cmGlobal.h"
  2. #include "cmRpt.h"
  3. #include "cmErr.h"
  4. #include "cmExec.h"
  5. #include <sys/wait.h>
  6. cmExRC_t cmExecV( cmErr_t* err, int* returnValRef, const cmChar_t* pgmFn, va_list vl0 )
  7. {
  8. cmExRC_t rc = kOkExRC;
  9. int n = 0;
  10. int i = 0;
  11. pid_t pid;
  12. va_list vl1;
  13. if( pgmFn == NULL )
  14. return cmErrMsg(err,kInvalidPgmFnExRC,"No executable program file name given in call to %s.",__FUNCTION__);
  15. // get the count of arguments
  16. va_copy(vl1,vl0);
  17. while( va_arg(vl1,cmChar_t*)!=NULL )
  18. ++n;
  19. va_end(vl1);
  20. // load argv with ptrs to the args
  21. cmChar_t* argv[n+2];
  22. argv[0] = (cmChar_t*)pgmFn;
  23. for(i=0; i<n+1; ++i)
  24. argv[i+1] = va_arg(vl0,cmChar_t*);
  25. argv[n+1] = NULL;
  26. errno = 0;
  27. switch( pid = fork())
  28. {
  29. case -1:
  30. rc = cmErrSysMsg(err,kForkFailExRC,errno,"Fork failed.");
  31. break;
  32. case 0:
  33. // we are in the child process - never to return
  34. execvp(pgmFn,argv);
  35. // under normal conditions execlp() does not return so we should never get here.
  36. rc = cmErrSysMsg(err,kExecFailExRC,errno,"Fork to '%s' failed. Is '%s' installed and on the execution path?",pgmFn,pgmFn);
  37. break;
  38. default:
  39. {
  40. int rv;
  41. int wrc;
  42. // we are in the parent process - wait for the child to return
  43. if((wrc = waitpid(pid,&rv,0))==-1)
  44. {
  45. rc = cmErrSysMsg(err,kWaitFailExRC,errno,"Wait failed on call to '%s'.",pgmFn);
  46. goto errLabel;
  47. }
  48. if( returnValRef != NULL )
  49. *returnValRef = rv;
  50. if( WEXITSTATUS(rv) != 0 )
  51. rc = cmErrMsg(err,kPgmFailExRC,"'%s' failed.",pgmFn);
  52. }
  53. break;
  54. }
  55. errLabel:
  56. return rc;
  57. }
  58. cmExRC_t cmExec( cmErr_t* err, int* returnValRef, const cmChar_t* pgmFn, ... )
  59. {
  60. va_list vl;
  61. va_start(vl,pgmFn);
  62. cmExRC_t rc = cmExecV(err,returnValRef,pgmFn,vl);
  63. va_end(vl);
  64. return rc;
  65. }