1. 程式人生 > >execvp:在程式中調子程式並獲取返回值

execvp:在程式中調子程式並獲取返回值

在linux中我們可以很方便的使用system啟動子程式,但是system有個不足就是它對子程式的掌控很弱,連返回數值都很難獲取。

下面是一段使用execvp來呼叫子程式的示例程式碼,關於下面的程式碼有幾點特殊說明:

1)  folk(): 會從主程式中複製出一個新的程式,如果folk返回0就是子程式,否則那就是還是當前的程式。

2)  wait() : 在主程式中你可以自己決定要等待子程式返回才繼續運算這樣保持同步還是非同步的不等子程式的結果就繼續往下執行。

3)  WEXITSTATUS: 用來獲取子程式的返回值

4) freopen: 預設情況下子程式的log會和主程式的一起都在終端中打印出來,這可能不是我們想要的,所以要把子程式的log重新匯入到其他的log

5) execvp: 這個函式如果正常執行是不會有返回的,有返回說明啟動的程式出現異常。對於沒有返回的函式理解起來比較費勁,因為通常我們講函式都會有返回的,但如果想到這個是一個獨立的程序,那就可以理解了。

#include <sys/types.h>
#include <sys/wait.h>
int callApp (char* program, char** arg_list, bool isWaiting) {
  pid_t child_pid;
  /* Duplicate this process. */
  child_pid = fork ();
  //return child_pid;
  if (child_pid != 0){
    /* This is the parent process. */
	if(isWaiting == true){
	    /* Wait for the child process to complete. */
	    int child_status;
	    wait (&child_status);
        int retCode = WIFEXITED (child_status); 
        // cout << "Finish " << program << " " << retCode << " "  <<  WEXITSTATUS (child_status) << endl; 
	    if (retCode){
	    	// printf ("the child process exited normally, with exit code %d\n", WEXITSTATUS (child_status));
            return WEXITSTATUS(child_status); 
        } else{
	    	// printf ("the child process exited abnormally\n");
            return -1; 
        }
	}
  }else {
      /* Now execute PROGRAM, searching for it in the path. */
      string fLog = _temp_path+"/subprocess_log.log"; 
      freopen(fLog.c_str(), "w", stdout); 
      string fErrorLog = _temp_path+"/subprocess.log"; 
      freopen(fErrorLog.c_str(), "w", stderr); 
      chdir(_temp_path.c_str()); 
      int ret = execvp (program, arg_list);
      fclose(stdout); 
      /* The execvp function returns only if an error occurs. */
      cout << "execvp failed with error code " << ret << endl; 
      abort(); 
      return -1; 
  }
}
// call sample
char subProcessBin[1024] = "myBin";
char* configFile = "myConfig"; 
char* arg_list[]= {
        subProcessBin, 
        "-c", 
        configFile, 
        NULL
    }; 
int  retCode = callApp(subProcessBin, arg_list, true);