Browse Source

cmExec.h/c, Makefile.am : Initial commit.

master
Kevin Larke 9 years ago
parent
commit
d72ce9d0bb
3 changed files with 112 additions and 2 deletions
  1. 2
    2
      Makefile.am
  2. 81
    0
      cmExec.c
  3. 29
    0
      cmExec.h

+ 2
- 2
Makefile.am View File

@@ -9,8 +9,8 @@ cmSRC += src/libcm/cmErr.c src/libcm/cmCtx.c src/libcm/cmRpt.c src/libcm/cmGloba
9 9
 cmHDR += src/libcm/cmSerialize.h src/libcm/cmSymTbl.h src/libcm/cmHashTbl.h src/libcm/cmFileSys.h src/libcm/cmFile.h 
10 10
 cmSRC += src/libcm/cmSerialize.c src/libcm/cmSymTbl.c src/libcm/cmHashTbl.c src/libcm/cmFileSys.c src/libcm/cmFile.c 
11 11
 
12
-cmHDR += src/libcm/cmMem.h src/libcm/cmTime.h src/libcm/cmPgmOpts.h
13
-cmSRC += src/libcm/cmMem.c src/libcm/cmTime.c src/libcm/cmPgmOpts.c
12
+cmHDR += src/libcm/cmMem.h src/libcm/cmTime.h src/libcm/cmExec.h src/libcm/cmPgmOpts.h
13
+cmSRC += src/libcm/cmMem.c src/libcm/cmTime.c src/libcm/cmExec.c src/libcm/cmPgmOpts.c
14 14
 
15 15
 cmHDR += src/libcm/cmData.h src/libcm/cmLib.h src/libcm/cmText.h src/libcm/cmTextTemplate.h
16 16
 cmSRC += src/libcm/cmData.c src/libcm/cmLib.c src/libcm/cmText.c src/libcm/cmTextTemplate.c

+ 81
- 0
cmExec.c View File

@@ -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
+}

+ 29
- 0
cmExec.h View File

@@ -0,0 +1,29 @@
1
+#ifndef cmExec_h
2
+#define cmExec_h
3
+
4
+
5
+#ifdef __cplusplus
6
+extern "C" {
7
+#endif
8
+
9
+  enum
10
+  {
11
+    kOkExRC,
12
+    kInvalidPgmFnExRC, // pgmFn was NULL
13
+    kForkFailExRC,     // internal fork() failed
14
+    kExecFailExRC,     // internal exec() failed.
15
+    kPgmFailExRC,      // pgm returned a non-zero exit status
16
+    kWaitFailExRC      // internal waitpid() failed
17
+  };
18
+
19
+  typedef unsigned cmExRC_t;
20
+
21
+  // If returnValRef is non-NULL *returnValRef is set to the program return value.
22
+  cmExRC_t cmExecV( cmErr_t* err, int* returnValRef, const cmChar_t* pgmFn, va_list vl );
23
+  cmExRC_t cmExec(  cmErr_t* err, int* returnValRef, const cmChar_t* pgmFn, ... );  
24
+
25
+#ifdef __cplusplus
26
+}
27
+#endif
28
+
29
+#endif

Loading…
Cancel
Save