libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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