libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

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