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