libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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. }